Merge branch 'for-3.3/mtip32xx' into for-3.3/drivers
authorJens Axboe <axboe@kernel.dk>
Sun, 15 Jan 2012 09:39:35 +0000 (10:39 +0100)
committerJens Axboe <axboe@kernel.dk>
Sun, 15 Jan 2012 09:39:35 +0000 (10:39 +0100)
4183 files changed:
.mailmap
CREDITS
Documentation/ABI/stable/sysfs-acpi-pmprofile [new file with mode: 0644]
Documentation/ABI/testing/sysfs-block
Documentation/DocBook/drm.tmpl
Documentation/DocBook/mtdnand.tmpl
Documentation/DocBook/uio-howto.tmpl
Documentation/blockdev/cciss.txt
Documentation/cgroups/freezer-subsystem.txt
Documentation/devicetree/bindings/mtd/atmel-dataflash.txt [new file with mode: 0644]
Documentation/devicetree/bindings/powerpc/fsl/board.txt
Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt [new file with mode: 0644]
Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/filesystems/btrfs.txt
Documentation/i2c/ten-bit-addresses
Documentation/kernel-parameters.txt
Documentation/networking/ip-sysctl.txt
Documentation/oops-tracing.txt
Documentation/power/devices.txt
Documentation/power/freezing-of-tasks.txt
Documentation/power/runtime_pm.txt
Documentation/serial/serial-rs485.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sound/alsa/HD-Audio.txt
Documentation/sound/alsa/soc/machine.txt
Documentation/usb/linux-cdc-acm.inf
Documentation/watchdog/convert_drivers_to_kernel_api.txt [new file with mode: 0644]
Kbuild
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/kernel/core_irongate.c
arch/alpha/kernel/pci-sysfs.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/setup.c
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/dts/tegra-ventana.dts
arch/arm/common/gic.c
arch/arm/common/it8152.c
arch/arm/common/pl330.c
arch/arm/common/scoop.c
arch/arm/configs/at91cap9_defconfig [new file with mode: 0644]
arch/arm/configs/at91cap9adk_defconfig [deleted file]
arch/arm/configs/at91rm9200_defconfig
arch/arm/configs/at91sam9260_defconfig [new file with mode: 0644]
arch/arm/configs/at91sam9260ek_defconfig [deleted file]
arch/arm/configs/at91sam9g20_defconfig [new file with mode: 0644]
arch/arm/configs/at91sam9g20ek_defconfig [deleted file]
arch/arm/configs/at91sam9g45_defconfig
arch/arm/configs/at91sam9rl_defconfig [new file with mode: 0644]
arch/arm/configs/at91sam9rlek_defconfig [deleted file]
arch/arm/configs/exynos4_defconfig
arch/arm/configs/ezx_defconfig
arch/arm/configs/imote2_defconfig
arch/arm/configs/magician_defconfig
arch/arm/configs/omap1_defconfig
arch/arm/configs/u300_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/configs/zeus_defconfig
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/topology.h
arch/arm/include/asm/unistd.h
arch/arm/kernel/armksyms.c
arch/arm/kernel/bios32.c
arch/arm/kernel/calls.S
arch/arm/kernel/devtree.c
arch/arm/kernel/elf.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/etm.c
arch/arm/kernel/head.S
arch/arm/kernel/io.c
arch/arm/kernel/irq.c
arch/arm/kernel/kprobes-arm.c
arch/arm/kernel/kprobes-test-arm.c
arch/arm/kernel/kprobes-test-thumb.c
arch/arm/kernel/kprobes-test.h
arch/arm/kernel/leds.c
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/pj4-cp0.c
arch/arm/kernel/pmu.c
arch/arm/kernel/process.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/return_address.c
arch/arm/kernel/setup.c
arch/arm/kernel/stacktrace.c
arch/arm/kernel/sys_arm.c
arch/arm/kernel/time.c
arch/arm/kernel/topology.c
arch/arm/kernel/unwind.c
arch/arm/kernel/xscale-cp0.c
arch/arm/lib/bitops.h
arch/arm/lib/changebit.S
arch/arm/lib/clearbit.S
arch/arm/lib/setbit.S
arch/arm/lib/testchangebit.S
arch/arm/lib/testclearbit.S
arch/arm/lib/testsetbit.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/at91cap9_devices.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91sam9260.c
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/board-afeb-9260v1.c
arch/arm/mach-at91/board-cam60.c
arch/arm/mach-at91/board-cap9adk.c
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-neocore926.c
arch/arm/mach-at91/board-qil-a9260.c
arch/arm/mach-at91/board-rm9200dk.c
arch/arm/mach-at91/board-sam9-l9260.c
arch/arm/mach-at91/board-sam9260ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/board-sam9rlek.c
arch/arm/mach-at91/board-snapper9260.c
arch/arm/mach-at91/board-usb-a926x.c
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/cpuidle.c
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/system_rev.h
arch/arm/mach-at91/include/mach/vmalloc.h
arch/arm/mach-bcmring/core.c
arch/arm/mach-bcmring/dma.c
arch/arm/mach-bcmring/mm.c
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-mityomapl138.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-tnetv107x-evm.c
arch/arm/mach-davinci/cdce949.c
arch/arm/mach-davinci/cpufreq.c
arch/arm/mach-davinci/cpuidle.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/gpio.h
arch/arm/mach-davinci/include/mach/nand.h
arch/arm/mach-davinci/include/mach/psc.h
arch/arm/mach-davinci/psc.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-exynos/Kconfig [new file with mode: 0644]
arch/arm/mach-exynos/Makefile [new file with mode: 0644]
arch/arm/mach-exynos/Makefile.boot [new file with mode: 0644]
arch/arm/mach-exynos/clock-exynos4210.c [new file with mode: 0644]
arch/arm/mach-exynos/clock-exynos4212.c [new file with mode: 0644]
arch/arm/mach-exynos/clock.c [new file with mode: 0644]
arch/arm/mach-exynos/cpu.c [new file with mode: 0644]
arch/arm/mach-exynos/cpuidle.c [new file with mode: 0644]
arch/arm/mach-exynos/dev-ahci.c [new file with mode: 0644]
arch/arm/mach-exynos/dev-audio.c [new file with mode: 0644]
arch/arm/mach-exynos/dev-dwmci.c [new file with mode: 0644]
arch/arm/mach-exynos/dev-pd.c [new file with mode: 0644]
arch/arm/mach-exynos/dev-sysmmu.c [new file with mode: 0644]
arch/arm/mach-exynos/dma.c [new file with mode: 0644]
arch/arm/mach-exynos/headsmp.S [new file with mode: 0644]
arch/arm/mach-exynos/hotplug.c [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/dwmci.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/exynos4-clock.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/map.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/pm-core.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/pmu.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-audss.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-gpio.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-irq.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-mct.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-mem.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-pmu.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-sysmmu.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/regs-usb-phy.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/sysmmu.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-exynos/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-exynos/init.c [new file with mode: 0644]
arch/arm/mach-exynos/irq-combiner.c [new file with mode: 0644]
arch/arm/mach-exynos/irq-eint.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-armlex4210.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-nuri.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-origen.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-smdk4x12.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-smdkv310.c [new file with mode: 0644]
arch/arm/mach-exynos/mach-universal_c210.c [new file with mode: 0644]
arch/arm/mach-exynos/mct.c [new file with mode: 0644]
arch/arm/mach-exynos/platsmp.c [new file with mode: 0644]
arch/arm/mach-exynos/pm.c [new file with mode: 0644]
arch/arm/mach-exynos/pmu.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-fimc.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-fimd0.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c1.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c2.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c3.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c4.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c5.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c6.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-i2c7.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-keypad.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-sdhci-gpio.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-sdhci.c [new file with mode: 0644]
arch/arm/mach-exynos/setup-usb-phy.c [new file with mode: 0644]
arch/arm/mach-exynos4/Kconfig [deleted file]
arch/arm/mach-exynos4/Makefile [deleted file]
arch/arm/mach-exynos4/Makefile.boot [deleted file]
arch/arm/mach-exynos4/clock-exynos4210.c [deleted file]
arch/arm/mach-exynos4/clock-exynos4212.c [deleted file]
arch/arm/mach-exynos4/clock.c [deleted file]
arch/arm/mach-exynos4/cpu.c [deleted file]
arch/arm/mach-exynos4/cpuidle.c [deleted file]
arch/arm/mach-exynos4/dev-ahci.c [deleted file]
arch/arm/mach-exynos4/dev-audio.c [deleted file]
arch/arm/mach-exynos4/dev-dwmci.c [deleted file]
arch/arm/mach-exynos4/dev-pd.c [deleted file]
arch/arm/mach-exynos4/dev-sysmmu.c [deleted file]
arch/arm/mach-exynos4/dma.c [deleted file]
arch/arm/mach-exynos4/headsmp.S [deleted file]
arch/arm/mach-exynos4/hotplug.c [deleted file]
arch/arm/mach-exynos4/include/mach/clkdev.h [deleted file]
arch/arm/mach-exynos4/include/mach/debug-macro.S [deleted file]
arch/arm/mach-exynos4/include/mach/dma.h [deleted file]
arch/arm/mach-exynos4/include/mach/dwmci.h [deleted file]
arch/arm/mach-exynos4/include/mach/entry-macro.S [deleted file]
arch/arm/mach-exynos4/include/mach/exynos4-clock.h [deleted file]
arch/arm/mach-exynos4/include/mach/gpio.h [deleted file]
arch/arm/mach-exynos4/include/mach/hardware.h [deleted file]
arch/arm/mach-exynos4/include/mach/io.h [deleted file]
arch/arm/mach-exynos4/include/mach/irqs.h [deleted file]
arch/arm/mach-exynos4/include/mach/map.h [deleted file]
arch/arm/mach-exynos4/include/mach/memory.h [deleted file]
arch/arm/mach-exynos4/include/mach/pm-core.h [deleted file]
arch/arm/mach-exynos4/include/mach/pmu.h [deleted file]
arch/arm/mach-exynos4/include/mach/pwm-clock.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-audss.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-clock.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-gpio.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-irq.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-mct.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-mem.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-pmu.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-sysmmu.h [deleted file]
arch/arm/mach-exynos4/include/mach/regs-usb-phy.h [deleted file]
arch/arm/mach-exynos4/include/mach/sysmmu.h [deleted file]
arch/arm/mach-exynos4/include/mach/system.h [deleted file]
arch/arm/mach-exynos4/include/mach/timex.h [deleted file]
arch/arm/mach-exynos4/include/mach/uncompress.h [deleted file]
arch/arm/mach-exynos4/include/mach/vmalloc.h [deleted file]
arch/arm/mach-exynos4/init.c [deleted file]
arch/arm/mach-exynos4/irq-combiner.c [deleted file]
arch/arm/mach-exynos4/irq-eint.c [deleted file]
arch/arm/mach-exynos4/mach-armlex4210.c [deleted file]
arch/arm/mach-exynos4/mach-nuri.c [deleted file]
arch/arm/mach-exynos4/mach-origen.c [deleted file]
arch/arm/mach-exynos4/mach-smdk4x12.c [deleted file]
arch/arm/mach-exynos4/mach-smdkv310.c [deleted file]
arch/arm/mach-exynos4/mach-universal_c210.c [deleted file]
arch/arm/mach-exynos4/mct.c [deleted file]
arch/arm/mach-exynos4/platsmp.c [deleted file]
arch/arm/mach-exynos4/pm.c [deleted file]
arch/arm/mach-exynos4/pmu.c [deleted file]
arch/arm/mach-exynos4/setup-fimc.c [deleted file]
arch/arm/mach-exynos4/setup-fimd0.c [deleted file]
arch/arm/mach-exynos4/setup-i2c0.c [deleted file]
arch/arm/mach-exynos4/setup-i2c1.c [deleted file]
arch/arm/mach-exynos4/setup-i2c2.c [deleted file]
arch/arm/mach-exynos4/setup-i2c3.c [deleted file]
arch/arm/mach-exynos4/setup-i2c4.c [deleted file]
arch/arm/mach-exynos4/setup-i2c5.c [deleted file]
arch/arm/mach-exynos4/setup-i2c6.c [deleted file]
arch/arm/mach-exynos4/setup-i2c7.c [deleted file]
arch/arm/mach-exynos4/setup-keypad.c [deleted file]
arch/arm/mach-exynos4/setup-sdhci-gpio.c [deleted file]
arch/arm/mach-exynos4/setup-sdhci.c [deleted file]
arch/arm/mach-exynos4/setup-usb-phy.c [deleted file]
arch/arm/mach-exynos4/sleep.S [deleted file]
arch/arm/mach-highbank/highbank.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile.boot
arch/arm/mach-imx/clock-imx6q.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-mx31lilly.c
arch/arm/mach-imx/mach-mx31lite.c
arch/arm/mach-imx/mach-mx31moboard.c
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/src.c
arch/arm/mach-iop13xx/pci.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp4xx/common-pci.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-kirkwood/cpuidle.c
arch/arm/mach-mmp/Makefile
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/brownstone.c
arch/arm/mach-mmp/gplugd.c
arch/arm/mach-mmp/include/mach/gpio-pxa.h
arch/arm/mach-mmp/include/mach/mmp2.h
arch/arm/mach-mmp/include/mach/sram.h [new file with mode: 0644]
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/sram.c [new file with mode: 0644]
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/board-msm7x30.c
arch/arm/mach-msm/board-msm8960.c
arch/arm/mach-msm/board-msm8x60.c
arch/arm/mach-msm/devices-iommu.c
arch/arm/mach-msm/io.c
arch/arm/mach-msm/scm.c
arch/arm/mach-mx5/clock-mx51-mx53.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/imx51-dt.c
arch/arm/mach-mx5/imx53-dt.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-mxs/include/mach/mx28.h
arch/arm/mach-mxs/include/mach/mxs.h
arch/arm/mach-mxs/mach-m28evk.c
arch/arm/mach-mxs/mach-mx28evk.c
arch/arm/mach-mxs/mach-stmp378x_devb.c
arch/arm/mach-mxs/module-tx28.c
arch/arm/mach-netx/xc.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/clock_data.c
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/mailbox.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/clkt_dpll.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clock2420_data.c
arch/arm/mach-omap2/clock2430_data.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clock44xx.h
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/display.h [new file with mode: 0644]
arch/arm/mach-omap2/dpll3xxx.c
arch/arm/mach-omap2/dpll44xx.c
arch/arm/mach-omap2/dsp.c
arch/arm/mach-omap2/gpmc-onenand.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/io.h [deleted file]
arch/arm/mach-omap2/mailbox.c
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.h
arch/arm/mach-omap2/omap_l3_noc.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/powerdomain.h
arch/arm/mach-omap2/prcm.c
arch/arm/mach-omap2/smartreflex.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/twl-common.c
arch/arm/mach-omap2/twl-common.h
arch/arm/mach-omap2/usb-musb.c
arch/arm/mach-omap2/usb-tusb6010.c
arch/arm/mach-omap2/voltage.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-picoxcell/include/mach/debug-macro.S
arch/arm/mach-prima2/pm.c
arch/arm/mach-prima2/prima2.c
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa270.c
arch/arm/mach-pxa/colibri-pxa320.c
arch/arm/mach-pxa/colibri-pxa3xx.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/eseries.h
arch/arm/mach-pxa/gumstix.c
arch/arm/mach-pxa/include/mach/gpio-pxa.h
arch/arm/mach-pxa/include/mach/palm27x.h
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/mxm8x10.c
arch/arm/mach-pxa/palm27x.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/include/mach/fb.h
arch/arm/mach-s3c2410/include/mach/gpio-fns.h
arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
arch/arm/mach-s3c2410/include/mach/gpio-track.h
arch/arm/mach-s3c2410/include/mach/irqs.h
arch/arm/mach-s3c2410/include/mach/map.h
arch/arm/mach-s3c2410/include/mach/pm-core.h
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-qt2410.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2412/gpio.c [new file with mode: 0644]
arch/arm/mach-s3c2416/Kconfig
arch/arm/mach-s3c2416/clock.c
arch/arm/mach-s3c2416/s3c2416.c
arch/arm/mach-s3c2416/setup-sdhci.c
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/mach-rx1950.c
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2440/s3c2442.c
arch/arm/mach-s3c2443/Kconfig
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-s3c2443/s3c2443.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/clock.c
arch/arm/mach-s3c64xx/cpu.c
arch/arm/mach-s3c64xx/dev-audio.c
arch/arm/mach-s3c64xx/dev-onenand1.c [deleted file]
arch/arm/mach-s3c64xx/dev-spi.c
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/gpiolib.c [deleted file]
arch/arm/mach-s3c64xx/include/mach/clkdev.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/crag6410.h [new file with mode: 0644]
arch/arm/mach-s3c64xx/include/mach/pll.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/pm-core.h
arch/arm/mach-s3c64xx/include/mach/pwm-clock.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/regs-sys.h
arch/arm/mach-s3c64xx/include/mach/s3c6400.h [deleted file]
arch/arm/mach-s3c64xx/include/mach/s3c6410.h [deleted file]
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410-module.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smartq5.c
arch/arm/mach-s3c64xx/mach-smartq7.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s3c64xx/s3c6400.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s3c64xx/setup-fb-24bpp.c
arch/arm/mach-s3c64xx/setup-sdhci.c
arch/arm/mach-s5p64x0/Kconfig
arch/arm/mach-s5p64x0/Makefile
arch/arm/mach-s5p64x0/clock-s5p6440.c
arch/arm/mach-s5p64x0/clock-s5p6450.c
arch/arm/mach-s5p64x0/cpu.c
arch/arm/mach-s5p64x0/include/mach/clkdev.h [deleted file]
arch/arm/mach-s5p64x0/include/mach/irqs.h
arch/arm/mach-s5p64x0/include/mach/map.h
arch/arm/mach-s5p64x0/include/mach/pm-core.h [new file with mode: 0644]
arch/arm/mach-s5p64x0/include/mach/pwm-clock.h [deleted file]
arch/arm/mach-s5p64x0/include/mach/regs-clock.h
arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
arch/arm/mach-s5p64x0/irq-eint.c
arch/arm/mach-s5p64x0/irq-pm.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/mach-smdk6440.c
arch/arm/mach-s5p64x0/mach-smdk6450.c
arch/arm/mach-s5p64x0/pm.c [new file with mode: 0644]
arch/arm/mach-s5p64x0/setup-fb-24bpp.c [new file with mode: 0644]
arch/arm/mach-s5pc100/clock.c
arch/arm/mach-s5pc100/dma.c
arch/arm/mach-s5pc100/include/mach/clkdev.h [deleted file]
arch/arm/mach-s5pc100/include/mach/pwm-clock.h [deleted file]
arch/arm/mach-s5pc100/setup-sdhci.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/cpu.c
arch/arm/mach-s5pv210/dma.c
arch/arm/mach-s5pv210/include/mach/clkdev.h [deleted file]
arch/arm/mach-s5pv210/include/mach/irqs.h
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/include/mach/pm-core.h
arch/arm/mach-s5pv210/include/mach/pwm-clock.h [deleted file]
arch/arm/mach-s5pv210/include/mach/regs-clock.h
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/setup-sdhci.c
arch/arm/mach-s5pv210/sleep.S [deleted file]
arch/arm/mach-sa1100/Makefile.boot
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-kota2.c [new file with mode: 0644]
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock.c
arch/arm/mach-shmobile/cpuidle.c
arch/arm/mach-shmobile/include/mach/common.h
arch/arm/mach-shmobile/include/mach/intc.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/sh73a0.h
arch/arm/mach-shmobile/intc-sh7367.c
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/intc-sh7377.c
arch/arm/mach-shmobile/intc-sh73a0.c
arch/arm/mach-shmobile/pfc-sh7367.c
arch/arm/mach-shmobile/pfc-sh7372.c
arch/arm/mach-shmobile/pfc-sh7377.c
arch/arm/mach-shmobile/pfc-sh73a0.c
arch/arm/mach-shmobile/platsmp.c
arch/arm/mach-shmobile/pm-sh7372.c
arch/arm/mach-shmobile/pm_runtime.c [deleted file]
arch/arm/mach-tegra/board-dt.c
arch/arm/mach-tegra/board-harmony-pinmux.c
arch/arm/mach-tegra/board-paz00-pinmux.c
arch/arm/mach-tegra/board-seaboard-pinmux.c
arch/arm/mach-tegra/board-trimslice-pinmux.c
arch/arm/mach-tegra/pcie.c
arch/arm/mach-w90x900/dev.c
arch/arm/mach-w90x900/include/mach/mfp.h
arch/arm/mach-w90x900/include/mach/nuc900_spi.h
arch/arm/mach-w90x900/mfp.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/init.c
arch/arm/mm/mmap.c
arch/arm/plat-iop/gpio.c
arch/arm/plat-iop/time.c
arch/arm/plat-mxc/Kconfig
arch/arm/plat-mxc/avic.c
arch/arm/plat-mxc/gic.c
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/entry-macro.S
arch/arm/plat-mxc/include/mach/mxc.h
arch/arm/plat-mxc/include/mach/system.h
arch/arm/plat-mxc/system.c
arch/arm/plat-mxc/tzic.c
arch/arm/plat-omap/clock.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/i2c.c
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/common.h
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/dmtimer.h
arch/arm/plat-omap/include/plat/omap-alsa.h [deleted file]
arch/arm/plat-omap/include/plat/omap-pm.h
arch/arm/plat-omap/include/plat/omap_device.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/mailbox.c
arch/arm/plat-omap/omap-pm-noop.c
arch/arm/plat-omap/omap_device.c
arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/Makefile
arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
arch/arm/plat-s3c24xx/dev-uart.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/devs.c [deleted file]
arch/arm/plat-s3c24xx/gpio.c [deleted file]
arch/arm/plat-s3c24xx/gpiolib.c [deleted file]
arch/arm/plat-s3c24xx/include/mach/clkdev.h [deleted file]
arch/arm/plat-s3c24xx/include/mach/pwm-clock.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/audio-simtec.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/common-smdk.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/fiq.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/irq.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/mci.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/pll.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/regs-dma.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/regs-iis.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/regs-spi.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/regs-udc.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/s3c2410.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/s3c2412.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/s3c2416.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/s3c2443.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/s3c244x.h [deleted file]
arch/arm/plat-s3c24xx/include/plat/udc.h [deleted file]
arch/arm/plat-s3c24xx/s3c2443-clock.c
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/cpu.c
arch/arm/plat-s5p/dev-csis0.c [deleted file]
arch/arm/plat-s5p/dev-csis1.c [deleted file]
arch/arm/plat-s5p/dev-ehci.c [deleted file]
arch/arm/plat-s5p/dev-fimc0.c [deleted file]
arch/arm/plat-s5p/dev-fimc1.c [deleted file]
arch/arm/plat-s5p/dev-fimc2.c [deleted file]
arch/arm/plat-s5p/dev-fimc3.c [deleted file]
arch/arm/plat-s5p/dev-fimd0.c [deleted file]
arch/arm/plat-s5p/dev-mfc.c
arch/arm/plat-s5p/dev-onenand.c [deleted file]
arch/arm/plat-s5p/dev-pmu.c [deleted file]
arch/arm/plat-s5p/include/plat/camport.h [deleted file]
arch/arm/plat-s5p/include/plat/ehci.h [deleted file]
arch/arm/plat-s5p/include/plat/exynos4.h [deleted file]
arch/arm/plat-s5p/include/plat/irqs.h [deleted file]
arch/arm/plat-s5p/include/plat/mfc.h [deleted file]
arch/arm/plat-s5p/include/plat/mipi_csis.h [deleted file]
arch/arm/plat-s5p/include/plat/pll.h [deleted file]
arch/arm/plat-s5p/include/plat/regs-srom.h [deleted file]
arch/arm/plat-s5p/include/plat/reset.h [deleted file]
arch/arm/plat-s5p/include/plat/s5p-clock.h [deleted file]
arch/arm/plat-s5p/include/plat/s5p-time.h [deleted file]
arch/arm/plat-s5p/include/plat/s5p6440.h [deleted file]
arch/arm/plat-s5p/include/plat/s5p6450.h [deleted file]
arch/arm/plat-s5p/include/plat/s5pc100.h [deleted file]
arch/arm/plat-s5p/include/plat/s5pv210.h [deleted file]
arch/arm/plat-s5p/include/plat/sysmmu.h [deleted file]
arch/arm/plat-s5p/include/plat/system-reset.h [deleted file]
arch/arm/plat-s5p/include/plat/usb-phy.h [deleted file]
arch/arm/plat-s5p/irq-gpioint.c
arch/arm/plat-s5p/sleep.S [new file with mode: 0644]
arch/arm/plat-s5p/sysmmu.c
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/adc.c
arch/arm/plat-samsung/dev-adc.c [deleted file]
arch/arm/plat-samsung/dev-asocdma.c [deleted file]
arch/arm/plat-samsung/dev-backlight.c
arch/arm/plat-samsung/dev-fb.c [deleted file]
arch/arm/plat-samsung/dev-hsmmc.c [deleted file]
arch/arm/plat-samsung/dev-hsmmc1.c [deleted file]
arch/arm/plat-samsung/dev-hsmmc2.c [deleted file]
arch/arm/plat-samsung/dev-hsmmc3.c [deleted file]
arch/arm/plat-samsung/dev-hwmon.c [deleted file]
arch/arm/plat-samsung/dev-i2c0.c [deleted file]
arch/arm/plat-samsung/dev-i2c1.c [deleted file]
arch/arm/plat-samsung/dev-i2c2.c [deleted file]
arch/arm/plat-samsung/dev-i2c3.c [deleted file]
arch/arm/plat-samsung/dev-i2c4.c [deleted file]
arch/arm/plat-samsung/dev-i2c5.c [deleted file]
arch/arm/plat-samsung/dev-i2c6.c [deleted file]
arch/arm/plat-samsung/dev-i2c7.c [deleted file]
arch/arm/plat-samsung/dev-ide.c [deleted file]
arch/arm/plat-samsung/dev-keypad.c [deleted file]
arch/arm/plat-samsung/dev-nand.c [deleted file]
arch/arm/plat-samsung/dev-onenand.c [deleted file]
arch/arm/plat-samsung/dev-pwm.c [deleted file]
arch/arm/plat-samsung/dev-rtc.c [deleted file]
arch/arm/plat-samsung/dev-ts.c [deleted file]
arch/arm/plat-samsung/dev-usb-hsotg.c [deleted file]
arch/arm/plat-samsung/dev-usb.c [deleted file]
arch/arm/plat-samsung/dev-wdt.c [deleted file]
arch/arm/plat-samsung/devs.c [new file with mode: 0644]
arch/arm/plat-samsung/dma-ops.c
arch/arm/plat-samsung/gpio-config.c [deleted file]
arch/arm/plat-samsung/gpio.c [deleted file]
arch/arm/plat-samsung/include/plat/adc-core.h
arch/arm/plat-samsung/include/plat/audio-simtec.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/camport.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/common-smdk.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/cpu-freq-core.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/ehci.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/exynos4.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/fb-s3c2410.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/fb.h
arch/arm/plat-samsung/include/plat/fiq.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/include/plat/gpio-core.h
arch/arm/plat-samsung/include/plat/gpio-fns.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/iic.h
arch/arm/plat-samsung/include/plat/irq.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/irqs.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/mci.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/mfc.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/mipi_csis.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/pll.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/pll6553x.h [deleted file]
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/plat-samsung/include/plat/pwm-clock.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-adc.h
arch/arm/plat-samsung/include/plat/regs-dma.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-iis.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-spi.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-srom.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/regs-udc.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/reset.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c2410.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c2412.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c2416.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c2443.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c244x.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c6400.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c6410.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5p-clock.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5p-time.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5p6440.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5p6450.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5pc100.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s5pv210.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/sdhci.h
arch/arm/plat-samsung/include/plat/sysmmu.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/system-reset.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/tv-core.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/udc.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/usb-phy.h [new file with mode: 0644]
arch/arm/plat-samsung/pd.c
arch/arm/plat-samsung/platformdata.c
arch/arm/plat-samsung/pm-gpio.c
arch/arm/plat-samsung/pm.c
arch/arm/plat-samsung/pwm-clock.c
arch/arm/plat-samsung/pwm.c
arch/arm/plat-samsung/s3c-dma-ops.c
arch/arm/tools/mach-types
arch/arm/vfp/vfpmodule.c
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/mach-at32ap/clock.c
arch/avr32/mach-at32ap/cpufreq.c
arch/avr32/mach-at32ap/include/mach/board.h
arch/avr32/mach-at32ap/intc.c
arch/avr32/mach-at32ap/pio.c
arch/avr32/mm/dma-coherent.c
arch/blackfin/include/asm/bfin_serial.h
arch/blackfin/kernel/dma-mapping.c
arch/blackfin/kernel/perf_event.c
arch/blackfin/kernel/sys_bfin.c
arch/blackfin/mach-bf518/boards/ezbrd.c
arch/blackfin/mach-bf518/boards/tcm-bf518.c
arch/blackfin/mach-bf527/boards/ad7160eval.c
arch/blackfin/mach-bf527/boards/cm_bf527.c
arch/blackfin/mach-bf527/boards/ezbrd.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf527/boards/tll6527m.c
arch/blackfin/mach-bf533/boards/H8606.c
arch/blackfin/mach-bf533/boards/blackstamp.c
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/ip0x.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf537/boards/cm_bf537e.c
arch/blackfin/mach-bf537/boards/cm_bf537u.c
arch/blackfin/mach-bf537/boards/dnp5370.c
arch/blackfin/mach-bf537/boards/minotaur.c
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/boards/tcm_bf537.c
arch/blackfin/mach-bf538/boards/ezkit.c
arch/blackfin/mach-bf548/boards/cm_bf548.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf561/boards/acvilon.c
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/boards/tepla.c
arch/blackfin/mach-common/cpufreq.c
arch/blackfin/mm/init.c
arch/cris/arch-v10/drivers/Kconfig
arch/cris/arch-v32/drivers/Kconfig
arch/cris/arch-v32/drivers/mach-a3/nandflash.c
arch/cris/arch-v32/drivers/mach-fs/nandflash.c
arch/ia64/hp/common/hwsw_iommu.c
arch/ia64/include/asm/xen/grant_table.h [deleted file]
arch/ia64/include/asm/xen/interface.h
arch/ia64/kernel/dma-mapping.c
arch/ia64/kernel/topology.c
arch/ia64/pci/pci.c
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/io_init.c
arch/ia64/sn/pci/pcibr/pcibr_dma.c
arch/ia64/sn/pci/pcibr/pcibr_provider.c
arch/ia64/sn/pci/tioca_provider.c
arch/ia64/xen/grant-table.c
arch/ia64/xen/hypervisor.c
arch/m32r/Kconfig
arch/m68k/Kconfig
arch/m68k/Kconfig.bus
arch/m68k/Kconfig.devices
arch/m68k/amiga/amiints.c
arch/m68k/amiga/cia.c
arch/m68k/apollo/dn_ints.c
arch/m68k/atari/ataints.c
arch/m68k/atari/time.c
arch/m68k/bvme6000/config.c
arch/m68k/hp300/time.c
arch/m68k/include/asm/hardirq.h
arch/m68k/include/asm/irq.h
arch/m68k/include/asm/macintosh.h
arch/m68k/include/asm/q40ints.h
arch/m68k/include/asm/unistd.h
arch/m68k/kernel/Makefile
arch/m68k/kernel/dma_mm.c
arch/m68k/kernel/dma_no.c
arch/m68k/kernel/entry_mm.S
arch/m68k/kernel/ints.c
arch/m68k/kernel/syscalltable.S
arch/m68k/mac/baboon.c
arch/m68k/mac/iop.c
arch/m68k/mac/macints.c
arch/m68k/mac/oss.c
arch/m68k/mac/psc.c
arch/m68k/mac/via.c
arch/m68k/mvme147/config.c
arch/m68k/mvme16x/config.c
arch/m68k/q40/q40ints.c
arch/m68k/sun3/sun3ints.c
arch/microblaze/include/asm/namei.h [deleted file]
arch/microblaze/kernel/dma.c
arch/microblaze/kernel/irq.c
arch/microblaze/mm/init.c
arch/microblaze/pci/iomap.c
arch/microblaze/pci/pci-common.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/setup.c
arch/mips/cavium-octeon/csrc-octeon.c
arch/mips/cavium-octeon/dma-octeon.c
arch/mips/cavium-octeon/flash_setup.c
arch/mips/cavium-octeon/smp.c
arch/mips/emma/common/prom.c
arch/mips/include/asm/mach-bcm47xx/gpio.h
arch/mips/include/asm/unistd.h
arch/mips/kernel/8250-platform.c
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/cpufreq/loongson2_clock.c
arch/mips/kernel/i8253.c
arch/mips/kernel/init_task.c
arch/mips/kernel/irq-msc01.c
arch/mips/kernel/irq.c
arch/mips/kernel/mips-mt.c
arch/mips/kernel/mips_ksyms.c
arch/mips/kernel/module.c
arch/mips/kernel/perf_event_mipsxx.c
arch/mips/kernel/process.c
arch/mips/kernel/prom.c
arch/mips/kernel/reset.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/setup.c
arch/mips/kernel/spinlock_test.c
arch/mips/kernel/stacktrace.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/kernel/vpe.c
arch/mips/lantiq/clk.c
arch/mips/lantiq/devices.c
arch/mips/lantiq/prom.c
arch/mips/lantiq/setup.c
arch/mips/lantiq/xway/clk-ase.c
arch/mips/lantiq/xway/clk-xway.c
arch/mips/lantiq/xway/devices.c
arch/mips/lantiq/xway/dma.c
arch/mips/lantiq/xway/gpio.c
arch/mips/lantiq/xway/gpio_ebu.c
arch/mips/lantiq/xway/gpio_stp.c
arch/mips/lantiq/xway/prom-ase.c
arch/mips/lantiq/xway/prom-xway.c
arch/mips/lantiq/xway/reset.c
arch/mips/loongson/common/platform.c
arch/mips/nxp/pnx8550/common/pci.c [deleted file]
arch/mips/nxp/pnx8550/common/setup.c [deleted file]
arch/mips/pci/pci-alchemy.c
arch/mips/pci/pci-ip27.c
arch/mips/pci/pci-lantiq.c
arch/mips/pci/pci.c
arch/mips/pmc-sierra/yosemite/prom.c
arch/mips/powertv/Kconfig
arch/mips/powertv/asic/Kconfig [deleted file]
arch/mips/powertv/pci/fixup-powertv.c
arch/mips/powertv/powertv-usb.c
arch/mips/rb532/gpio.c
arch/mips/rb532/setup.c
arch/mips/txx9/generic/spi_eeprom.c
arch/mips/txx9/rbtx4939/setup.c
arch/mips/vr41xx/common/giu.c
arch/mips/vr41xx/common/rtc.c
arch/openrisc/Kconfig
arch/parisc/kernel/drivers.c
arch/parisc/kernel/pci-dma.c
arch/parisc/kernel/setup.c
arch/parisc/lib/iomap.c
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/charon.dts [new file with mode: 0644]
arch/powerpc/boot/dts/digsy_mtc.dts
arch/powerpc/boot/dts/gef_ppc9a.dts
arch/powerpc/boot/dts/gef_sbc310.dts
arch/powerpc/boot/dts/gef_sbc610.dts
arch/powerpc/boot/dts/hcu4.dts [deleted file]
arch/powerpc/boot/dts/ksi8560.dts
arch/powerpc/boot/dts/mgcoge.dts
arch/powerpc/boot/dts/mpc5200b.dtsi
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/p1022ds.dts
arch/powerpc/boot/dts/p1023rds.dts
arch/powerpc/boot/dts/p2020ds.dts
arch/powerpc/boot/dts/p2040rdb.dts [deleted file]
arch/powerpc/boot/dts/p2040si.dtsi [deleted file]
arch/powerpc/boot/dts/p2041rdb.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p2041si.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/p3041ds.dts
arch/powerpc/boot/dts/p3041si.dtsi
arch/powerpc/boot/dts/p3060qds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p3060si.dtsi [new file with mode: 0644]
arch/powerpc/boot/dts/p4080ds.dts
arch/powerpc/boot/dts/p4080si.dtsi
arch/powerpc/boot/dts/p5020ds.dts
arch/powerpc/boot/dts/p5020si.dtsi
arch/powerpc/boot/dts/sbc8560.dts
arch/powerpc/boot/dts/yosemite.dts
arch/powerpc/configs/40x/hcu4_defconfig [deleted file]
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/85xx/p1023rds_defconfig
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/mgcoge_defconfig
arch/powerpc/configs/mpc512x_defconfig
arch/powerpc/configs/mpc5200_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/ppc40x_defconfig
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ppc6xx_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/atomic.h
arch/powerpc/include/asm/bitops.h
arch/powerpc/include/asm/device.h
arch/powerpc/include/asm/firmware.h
arch/powerpc/include/asm/floppy.h
arch/powerpc/include/asm/futex.h
arch/powerpc/include/asm/hugetlb.h
arch/powerpc/include/asm/kexec.h
arch/powerpc/include/asm/kvm.h
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/lv1call.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mmu-book3e.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/mpic.h
arch/powerpc/include/asm/opal.h [new file with mode: 0644]
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/page_64.h
arch/powerpc/include/asm/pte-book3e.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/include/asm/sections.h
arch/powerpc/include/asm/smp.h
arch/powerpc/include/asm/sparsemem.h
arch/powerpc/include/asm/spu.h
arch/powerpc/include/asm/synch.h
arch/powerpc/include/asm/topology.h
arch/powerpc/include/asm/udbg.h
arch/powerpc/include/asm/xics.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/clock.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/dma-iommu.c
arch/powerpc/kernel/dma-swiotlb.c
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/firmware.c
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_40x.S
arch/powerpc/kernel/head_44x.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/hw_breakpoint.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/idle_e500.S
arch/powerpc/kernel/init_task.c
arch/powerpc/kernel/io-workarounds.c
arch/powerpc/kernel/io.c
arch/powerpc/kernel/iomap.c
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/isa-bridge.c
arch/powerpc/kernel/jump_label.c
arch/powerpc/kernel/kvm.c
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/module.c
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/pmc.c
arch/powerpc/kernel/power6-pmu.c
arch/powerpc/kernel/power7-pmu.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_init_check.sh
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/stacktrace.c
arch/powerpc/kernel/swsusp.c
arch/powerpc/kernel/swsusp_64.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/udbg.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vio.c
arch/powerpc/kvm/44x.c
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_exports.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_builtin.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/lib/checksum_wrappers_64.c
arch/powerpc/lib/devres.c
arch/powerpc/lib/feature-fixups.c
arch/powerpc/lib/locks.c
arch/powerpc/lib/rheap.c
arch/powerpc/math-emu/math_efp.c
arch/powerpc/mm/Makefile
arch/powerpc/mm/dma-noncoherent.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/hugetlbpage-book3e.c [new file with mode: 0644]
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_hash32.c
arch/powerpc/mm/mmu_context_hash64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/slice.c
arch/powerpc/mm/tlb_hash32.c
arch/powerpc/mm/tlb_low_64e.S
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/40x/Makefile
arch/powerpc/platforms/40x/hcu4.c [deleted file]
arch/powerpc/platforms/44x/warp.c
arch/powerpc/platforms/512x/Kconfig
arch/powerpc/platforms/512x/clock.c
arch/powerpc/platforms/52xx/mpc5200_simple.c
arch/powerpc/platforms/52xx/mpc52xx_common.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
arch/powerpc/platforms/82xx/km82xx.c
arch/powerpc/platforms/83xx/Kconfig
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/83xx/suspend.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/85xx/p2040_rdb.c [deleted file]
arch/powerpc/platforms/85xx/p2041_rdb.c [new file with mode: 0644]
arch/powerpc/platforms/85xx/p3060_qds.c [new file with mode: 0644]
arch/powerpc/platforms/85xx/sbc8548.c
arch/powerpc/platforms/85xx/sbc8560.c
arch/powerpc/platforms/85xx/smp.c
arch/powerpc/platforms/86xx/Kconfig
arch/powerpc/platforms/86xx/gef_gpio.c
arch/powerpc/platforms/8xx/tqm8xx_setup.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/Makefile
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat.c
arch/powerpc/platforms/cell/beat_spu_priv1.c
arch/powerpc/platforms/cell/beat_wrapper.h
arch/powerpc/platforms/cell/cbe_cpufreq.c
arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
arch/powerpc/platforms/cell/cbe_powerbutton.c
arch/powerpc/platforms/cell/cbe_regs.c
arch/powerpc/platforms/cell/celleb_scc_pciex.c
arch/powerpc/platforms/cell/celleb_setup.c
arch/powerpc/platforms/cell/cpufreq_spudemand.c
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/pmu.c
arch/powerpc/platforms/cell/qpace_setup.c
arch/powerpc/platforms/cell/setup.c
arch/powerpc/platforms/cell/smp.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/cell/spu_callbacks.c
arch/powerpc/platforms/cell/spu_fault.c
arch/powerpc/platforms/cell/spu_manage.c
arch/powerpc/platforms/cell/spu_notify.c
arch/powerpc/platforms/cell/spu_priv1_mmio.c
arch/powerpc/platforms/cell/spufs/backing_ops.c
arch/powerpc/platforms/cell/spufs/context.c
arch/powerpc/platforms/cell/spufs/coredump.c
arch/powerpc/platforms/cell/spufs/fault.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/hw_ops.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/switch.c
arch/powerpc/platforms/cell/spufs/syscalls.c
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/embedded6xx/holly.c
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
arch/powerpc/platforms/iseries/hvlpconfig.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/iseries/ksyms.c
arch/powerpc/platforms/iseries/lpardata.c
arch/powerpc/platforms/iseries/lpevents.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/iseries/setup.c
arch/powerpc/platforms/iseries/smp.c
arch/powerpc/platforms/iseries/vio.c
arch/powerpc/platforms/iseries/viopath.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/pasemi/cpufreq.c
arch/powerpc/platforms/pasemi/dma_lib.c
arch/powerpc/platforms/pasemi/setup.c
arch/powerpc/platforms/powermac/backlight.c
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/nvram.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/powernv/Kconfig [new file with mode: 0644]
arch/powerpc/platforms/powernv/Makefile [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-nvram.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-rtc.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-takeover.S [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-wrappers.S [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/pci-p5ioc2.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/pci.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/pci.h [new file with mode: 0644]
arch/powerpc/platforms/powernv/powernv.h [new file with mode: 0644]
arch/powerpc/platforms/powernv/setup.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/smp.c [new file with mode: 0644]
arch/powerpc/platforms/prep/Kconfig
arch/powerpc/platforms/ps3/Kconfig
arch/powerpc/platforms/ps3/Makefile
arch/powerpc/platforms/ps3/device-init.c
arch/powerpc/platforms/ps3/exports.c
arch/powerpc/platforms/ps3/gelic_udbg.c [new file with mode: 0644]
arch/powerpc/platforms/ps3/interrupt.c
arch/powerpc/platforms/ps3/mm.c
arch/powerpc/platforms/ps3/os-area.c
arch/powerpc/platforms/ps3/platform.h
arch/powerpc/platforms/ps3/repository.c
arch/powerpc/platforms/ps3/setup.c
arch/powerpc/platforms/ps3/smp.c
arch/powerpc/platforms/ps3/spu.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/eeh_event.c
arch/powerpc/platforms/pseries/eeh_sysfs.c
arch/powerpc/platforms/pseries/hotplug-cpu.c
arch/powerpc/platforms/pseries/hvconsole.c
arch/powerpc/platforms/pseries/io_event_irq.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/platforms/pseries/mobility.c
arch/powerpc/platforms/pseries/nvram.c
arch/powerpc/platforms/pseries/pci_dlpar.c
arch/powerpc/platforms/pseries/plpar_wrappers.h
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/platforms/pseries/suspend.c
arch/powerpc/platforms/wsp/Kconfig
arch/powerpc/platforms/wsp/Makefile
arch/powerpc/platforms/wsp/ics.c
arch/powerpc/platforms/wsp/ics.h
arch/powerpc/platforms/wsp/msi.c [new file with mode: 0644]
arch/powerpc/platforms/wsp/msi.h [new file with mode: 0644]
arch/powerpc/platforms/wsp/psr2.c
arch/powerpc/platforms/wsp/wsp.h
arch/powerpc/platforms/wsp/wsp_pci.c [new file with mode: 0644]
arch/powerpc/platforms/wsp/wsp_pci.h [new file with mode: 0644]
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/bestcomm/sram.c
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/dcr.c
arch/powerpc/sysdev/ehv_pic.c
arch/powerpc/sysdev/fsl_gtm.c
arch/powerpc/sysdev/fsl_lbc.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_msi.h
arch/powerpc/sysdev/fsl_pmc.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/mpc5xxx_clocks.c
arch/powerpc/sysdev/mpc8xx_pic.c
arch/powerpc/sysdev/mpc8xxx_gpio.c [deleted file]
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mv64x60_pci.c
arch/powerpc/sysdev/pmi.c
arch/powerpc/sysdev/ppc4xx_msi.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/ppc4xx_pci.h
arch/powerpc/sysdev/ppc4xx_soc.c
arch/powerpc/sysdev/qe_lib/gpio.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/powerpc/sysdev/qe_lib/ucc.c
arch/powerpc/sysdev/qe_lib/ucc_fast.c
arch/powerpc/sysdev/qe_lib/ucc_slow.c
arch/powerpc/sysdev/qe_lib/usb.c
arch/powerpc/sysdev/rtc_cmos_setup.c
arch/powerpc/sysdev/scom.c
arch/powerpc/sysdev/simple_gpio.c
arch/powerpc/sysdev/tsi108_dev.c
arch/powerpc/sysdev/xics/Makefile
arch/powerpc/sysdev/xics/icp-native.c
arch/powerpc/sysdev/xics/ics-opal.c [new file with mode: 0644]
arch/powerpc/sysdev/xics/xics-common.c
arch/powerpc/xmon/xmon.c
arch/s390/Kconfig
arch/s390/crypto/crypt_s390.h
arch/s390/crypto/sha_common.c
arch/s390/include/asm/kvm_host.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/timex.h
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/early.c
arch/s390/kernel/jump_label.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/topology.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/kvm/diag.c
arch/s390/kvm/intercept.c
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/priv.c
arch/s390/kvm/sigp.c
arch/s390/mm/fault.c
arch/s390/mm/init.c
arch/score/Kconfig
arch/sh/drivers/dma/dma-sysfs.c
arch/sh/drivers/pci/pci.c
arch/sh/include/asm/page.h
arch/sh/include/asm/unistd_32.h
arch/sh/include/asm/unistd_64.h
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/shmobile/cpuidle.c
arch/sh/kernel/perf_event.c
arch/sh/kernel/syscalls_32.S
arch/sh/kernel/syscalls_64.S
arch/sh/kernel/topology.c
arch/sh/mm/init.c
arch/sparc/Kconfig
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/asm/pgtable_64.h
arch/sparc/include/asm/termios.h
arch/sparc/include/asm/unistd.h
arch/sparc/kernel/apc.c
arch/sparc/kernel/auxio_32.c
arch/sparc/kernel/btext.c
arch/sparc/kernel/central.c
arch/sparc/kernel/cpu.c
arch/sparc/kernel/cpumap.c
arch/sparc/kernel/dma.c
arch/sparc/kernel/ebus.c
arch/sparc/kernel/entry.h
arch/sparc/kernel/hvapi.c
arch/sparc/kernel/idprom.c
arch/sparc/kernel/iommu.c
arch/sparc/kernel/irq_32.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/jump_label.c
arch/sparc/kernel/ldc.c
arch/sparc/kernel/leon_kernel.c
arch/sparc/kernel/leon_pci.c
arch/sparc/kernel/leon_pci_grpci2.c
arch/sparc/kernel/mdesc.c
arch/sparc/kernel/module.c
arch/sparc/kernel/nmi.c
arch/sparc/kernel/of_device_32.c
arch/sparc/kernel/of_device_64.c
arch/sparc/kernel/of_device_common.c
arch/sparc/kernel/pci.c
arch/sparc/kernel/pci_fire.c
arch/sparc/kernel/pci_psycho.c
arch/sparc/kernel/pci_sabre.c
arch/sparc/kernel/pci_schizo.c
arch/sparc/kernel/pci_sun4v.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/pcr.c
arch/sparc/kernel/pmc.c
arch/sparc/kernel/power.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/prom_32.c
arch/sparc/kernel/prom_64.c
arch/sparc/kernel/prom_common.c
arch/sparc/kernel/reboot.c
arch/sparc/kernel/sbus.c
arch/sparc/kernel/setup_32.c
arch/sparc/kernel/setup_64.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/sigutil_64.c
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/sparc_ksyms_64.c
arch/sparc/kernel/stacktrace.c
arch/sparc/kernel/sys_sparc32.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/kernel/systbls_32.S
arch/sparc/kernel/systbls_64.S
arch/sparc/kernel/time_64.c
arch/sparc/kernel/traps_32.c
arch/sparc/kernel/unaligned_32.c
arch/sparc/kernel/vio.c
arch/sparc/kernel/viohs.c
arch/sparc/mm/Makefile
arch/sparc/mm/fault_32.c
arch/sparc/mm/generic_32.c [deleted file]
arch/sparc/mm/generic_64.c [deleted file]
arch/sparc/mm/highmem.c
arch/sparc/mm/hugetlbpage.c
arch/tile/include/asm/irq.h
arch/tile/kernel/irq.c
arch/tile/kernel/pci-dma.c
arch/tile/kernel/pci.c
arch/tile/kernel/sysfs.c
arch/tile/lib/exports.c
arch/tile/mm/homecache.c
arch/unicore32/Kconfig
arch/unicore32/Kconfig.debug
arch/unicore32/boot/compressed/Makefile
arch/unicore32/include/asm/bitops.h
arch/unicore32/include/asm/processor.h
arch/unicore32/kernel/ksyms.c
arch/unicore32/lib/findbit.S
arch/unicore32/mm/init.c
arch/x86/Kconfig
arch/x86/crypto/aes_glue.c
arch/x86/crypto/aesni-intel_glue.c
arch/x86/include/asm/apic.h
arch/x86/include/asm/e820.h
arch/x86/include/asm/efi.h
arch/x86/include/asm/intel_scu_ipc.h
arch/x86/include/asm/mach_traps.h
arch/x86/include/asm/mce.h
arch/x86/include/asm/mrst.h
arch/x86/include/asm/msr.h
arch/x86/include/asm/system.h
arch/x86/include/asm/timer.h
arch/x86/include/asm/uv/uv_mmrs.h
arch/x86/include/asm/x86_init.h
arch/x86/include/asm/xen/grant_table.h [deleted file]
arch/x86/include/asm/xen/hypercall.h
arch/x86/include/asm/xen/interface.h
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/mcheck/mce-apei.c
arch/x86/kernel/cpu/mcheck/mce-inject.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_amd_ibs.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_p4.c
arch/x86/kernel/devicetree.c
arch/x86/kernel/e820.c
arch/x86/kernel/hpet.c
arch/x86/kernel/irq.c
arch/x86/kernel/irq_64.c
arch/x86/kernel/jump_label.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/microcode_core.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/nmi.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/probe_roms.c
arch/x86/kernel/process.c
arch/x86/kernel/quirks.c
arch/x86/kernel/reboot.c
arch/x86/kernel/rtc.c
arch/x86/kernel/setup.c
arch/x86/kernel/smp.c
arch/x86/kernel/tboot.c
arch/x86/kernel/time.c
arch/x86/kernel/topology.c
arch/x86/kernel/vsyscall_64.c
arch/x86/kernel/x86_init.c
arch/x86/kvm/vmx.c
arch/x86/lguest/boot.c
arch/x86/mm/gup.c
arch/x86/mm/highmem_32.c
arch/x86/oprofile/init.c
arch/x86/pci/i386.c
arch/x86/pci/legacy.c
arch/x86/platform/ce4100/ce4100.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_32.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/mrst/mrst.c
arch/x86/platform/mrst/pmu.c
arch/x86/platform/mrst/vrtc.c
arch/x86/platform/olpc/olpc-xo1-pm.c
arch/x86/platform/uv/bios_uv.c
arch/x86/power/cpu.c
arch/x86/um/Kconfig
arch/x86/um/asm/processor.h
arch/x86/video/fbdev.c
arch/x86/xen/enlighten.c
arch/x86/xen/grant-table.c
arch/x86/xen/setup.c
arch/x86/xen/time.c
block/blk-cgroup.c
block/blk-core.c
block/blk-exec.c
block/blk-integrity.c
block/blk-ioc.c
block/blk-map.c
block/blk-sysfs.c
block/blk-throttle.c
block/blk.h
block/bsg-lib.c
block/bsg.c
block/cfq-iosched.c
block/deadline-iosched.c
block/elevator.c
block/genhd.c
block/ioctl.c
block/noop-iosched.c
crypto/ablkcipher.c
crypto/aead.c
crypto/ahash.c
crypto/async_tx/async_memcpy.c
crypto/async_tx/async_pq.c
crypto/async_tx/async_raid6_recov.c
crypto/async_tx/async_tx.c
crypto/async_tx/async_xor.c
crypto/async_tx/raid6test.c
crypto/blkcipher.c
crypto/crypto_user.c
crypto/crypto_wq.c
crypto/md4.c
crypto/pcompress.c
crypto/proc.c
crypto/rng.c
crypto/shash.c
crypto/vmac.c
crypto/xcbc.c
drivers/acpi/acpica/evxface.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/evxfregn.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/hwtimer.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/acpica/nsxfeval.c
drivers/acpi/acpica/nsxfname.c
drivers/acpi/acpica/nsxfobj.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utdecode.c
drivers/acpi/acpica/utglobal.c
drivers/acpi/acpica/utxface.c
drivers/acpi/acpica/utxferror.c
drivers/acpi/apei/erst.c
drivers/acpi/atomicio.c
drivers/acpi/blacklist.c
drivers/acpi/bus.c
drivers/acpi/debugfs.c
drivers/acpi/ec_sys.c
drivers/acpi/event.c
drivers/acpi/glue.c
drivers/acpi/proc.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_idle.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/video_detect.c
drivers/ata/ahci.c
drivers/ata/ahci_platform.c
drivers/ata/libata-eh.c
drivers/ata/libata-pmp.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_of_platform.c
drivers/ata/sata_sis.c
drivers/base/base.h
drivers/base/core.c
drivers/base/dma-coherent.c
drivers/base/dma-mapping.c
drivers/base/hypervisor.c
drivers/base/node.c
drivers/base/power/clock_ops.c
drivers/base/power/common.c
drivers/base/power/generic_ops.c
drivers/base/power/main.c
drivers/base/power/opp.c
drivers/base/power/qos.c
drivers/base/power/runtime.c
drivers/base/power/sysfs.c
drivers/base/power/trace.c
drivers/base/power/wakeup.c
drivers/base/regmap/regcache.c
drivers/base/transport_class.c
drivers/bcma/core.c
drivers/bcma/driver_chipcommon.c
drivers/bcma/driver_chipcommon_pmu.c
drivers/bcma/driver_pci.c
drivers/bcma/host_pci.c
drivers/bcma/main.c
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoechr.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/loop.c
drivers/block/paride/pg.c
drivers/block/ps3disk.c
drivers/block/ps3vram.c
drivers/block/sx8.c
drivers/block/virtio_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/bcm203x.c
drivers/bluetooth/bfusb.c
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btusb.c
drivers/bluetooth/btwilink.c
drivers/char/agp/intel-gtt.c
drivers/char/hw_random/virtio-rng.c
drivers/char/mem.c
drivers/char/ps3flash.c
drivers/char/ramoops.c
drivers/char/random.c
drivers/char/ttyprintk.c
drivers/char/virtio_console.c
drivers/clocksource/sh_cmt.c
drivers/clocksource/sh_mtu2.c
drivers/clocksource/sh_tmu.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/db8500-cpufreq.c
drivers/cpufreq/s3c64xx-cpufreq.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/driver.c
drivers/cpuidle/governors/ladder.c
drivers/cpuidle/governors/menu.c
drivers/cpuidle/sysfs.c
drivers/crypto/mv_cesa.c
drivers/dca/dca-core.c
drivers/dca/dca-sysfs.c
drivers/devfreq/Kconfig
drivers/devfreq/devfreq.c
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/intel_mid_dma.c
drivers/dma/ipu/ipu_idmac.c
drivers/dma/ste_dma40.c
drivers/edac/cpc925_edac.c
drivers/edac/mce_amd_inj.c
drivers/edac/mpc85xx_edac.c
drivers/edac/ppc4xx_edac.c
drivers/firewire/core-iso.c
drivers/firmware/dmi_scan.c
drivers/firmware/edd.c
drivers/firmware/efivars.c
drivers/firmware/google/gsmi.c
drivers/firmware/sigma.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-74x164.c
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-exynos4.c [deleted file]
drivers/gpio/gpio-mc33880.c
drivers/gpio/gpio-mcp23s08.c
drivers/gpio/gpio-ml-ioh.c
drivers/gpio/gpio-mpc5200.c
drivers/gpio/gpio-mpc8xxx.c [new file with mode: 0644]
drivers/gpio/gpio-mxc.c
drivers/gpio/gpio-mxs.c
drivers/gpio/gpio-omap.c
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpio-pcf857x.c
drivers/gpio/gpio-pch.c
drivers/gpio/gpio-plat-samsung.c [deleted file]
drivers/gpio/gpio-s5pc100.c [deleted file]
drivers/gpio/gpio-s5pv210.c [deleted file]
drivers/gpio/gpio-samsung.c [new file with mode: 0644]
drivers/gpio/gpio-xilinx.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/ati_pcigart.c
drivers/gpu/drm/drm_buffer.c
drivers/gpu/drm/drm_bufs.c
drivers/gpu/drm/drm_cache.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_debugfs.c
drivers/gpu/drm/drm_dma.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_encoder_slave.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_hashtab.c
drivers/gpu/drm/drm_ioc32.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_memory.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c
drivers/gpu/drm/drm_proc.c
drivers/gpu/drm/drm_sman.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/drm_usb.c
drivers/gpu/drm/drm_vm.c
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_buf.h
drivers/gpu/drm/exynos/exynos_drm_connector.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_crtc.h
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_encoder.h
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/i2c/ch7006_drv.c
drivers/gpu/drm/i2c/sil164_drv.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/mga/mga_drv.c
drivers/gpu/drm/mga/mga_warp.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_i2c.c
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_perf.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_temp.c
drivers/gpu/drm/nouveau/nv40_pm.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_grctx.c
drivers/gpu/drm/nouveau/nv50_vram.c
drivers/gpu/drm/nouveau/nvc0_graph.c
drivers/gpu/drm/nouveau/nvc0_grctx.c
drivers/gpu/drm/nouveau/nvc0_vram.c
drivers/gpu/drm/nouveau/nvd0_display.c
drivers/gpu/drm/r128/r128_cce.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/radeon/Makefile
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/atombios_encoders.c [new file with mode: 0644]
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_blit_kms.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_acpi.c
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_benchmark.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_legacy_crtc.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/savage/savage_drv.c
drivers/gpu/drm/sis/sis_drv.c
drivers/gpu/drm/tdfx/tdfx_drv.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_tt.c
drivers/gpu/drm/via/via_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/vga/vgaarb.c
drivers/hid/hid-apple.c
drivers/hid/hid-axff.c
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-dr.c
drivers/hid/hid-emsff.c
drivers/hid/hid-gaff.c
drivers/hid/hid-holtekff.c
drivers/hid/hid-ids.h
drivers/hid/hid-picolcd.c
drivers/hid/hid-pl.c
drivers/hid/hid-roccat-common.c
drivers/hid/hid-roccat.c
drivers/hid/hid-sjoy.c
drivers/hid/hid-tmff.c
drivers/hid/hid-zpff.c
drivers/hid/usbhid/hid-quirks.c
drivers/hwmon/Kconfig
drivers/hwmon/ad7314.c
drivers/hwmon/ads7871.c
drivers/hwmon/coretemp.c
drivers/hwmon/exynos4_tmu.c
drivers/hwmon/gpio-fan.c
drivers/hwmon/jz4740-hwmon.c
drivers/hwmon/ntc_thermistor.c
drivers/hwmon/s3c-hwmon.c
drivers/hwmon/sch5627.c
drivers/hwmon/sch5636.c
drivers/hwmon/twl4030-madc-hwmon.c
drivers/hwmon/ultra45_env.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/wm831x-hwmon.c
drivers/hwmon/wm8350-hwmon.c
drivers/hwspinlock/u8500_hsem.c
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/busses/i2c-nuc900.c
drivers/i2c/busses/i2c-pxa-pci.c
drivers/i2c/busses/i2c-sh7760.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/i2c-boardinfo.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/buddha.c
drivers/ide/cmd640.c
drivers/ide/cy82c693.c
drivers/ide/icside.c
drivers/ide/ide-acpi.c
drivers/ide/ide-atapi.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk_proc.c
drivers/ide/ide-dma-sff.c
drivers/ide/ide-dma.c
drivers/ide/ide-eh.c
drivers/ide/ide-floppy.c
drivers/ide/ide-floppy_proc.c
drivers/ide/ide-io-std.c
drivers/ide/ide-ioctls.c
drivers/ide/ide-legacy.c
drivers/ide/ide-lib.c
drivers/ide/ide-pnp.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide-xfer-mode.c
drivers/ide/macide.c
drivers/ide/piix.c
drivers/ide/pmac.c
drivers/ide/q40ide.c
drivers/ide/setup-pci.c
drivers/ide/tc86c001.c
drivers/ide/triflex.c
drivers/idle/intel_idle.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/fmr_pool.c
drivers/infiniband/core/iwcm.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/multicast.c
drivers/infiniband/core/netlink.c
drivers/infiniband/core/packer.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/umem.c
drivers/infiniband/core/uverbs_marshall.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/cq.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/ipath/ipath_diag.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_sysfs.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mthca/mthca_catas.c
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/qib/qib_diag.c
drivers/infiniband/hw/qib/qib_driver.c
drivers/infiniband/hw/qib/qib_file_ops.c
drivers/infiniband/hw/qib/qib_iba7220.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/hw/qib/qib_pcie.c
drivers/infiniband/hw/qib/qib_qsfp.c
drivers/infiniband/hw/qib/qib_sd7220.c
drivers/infiniband/hw/qib/qib_sdma.c
drivers/infiniband/hw/qib/qib_tx.c
drivers/infiniband/hw/qib/qib_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_fs.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/input/input-compat.c
drivers/input/input-mt.c
drivers/input/input-polldev.c
drivers/input/joystick/as5011.c
drivers/input/keyboard/nomadik-ske-keypad.c
drivers/input/keyboard/tnetv107x-keypad.c
drivers/input/misc/ad714x.c
drivers/input/misc/adxl34x.c
drivers/input/misc/ati_remote2.c
drivers/input/misc/cma3000_d0x.c
drivers/input/misc/dm355evm_keys.c
drivers/input/mouse/elantech.c
drivers/input/serio/ams_delta_serio.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/sparse-keymap.c
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/ad7879-spi.c
drivers/input/touchscreen/ad7879.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/bu21013_ts.c
drivers/iommu/intel-iommu.c
drivers/iommu/intr_remapping.c
drivers/iommu/omap-iommu-debug.c
drivers/iommu/omap-iovmm.c
drivers/isdn/capi/kcapi_proc.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/gigaset/asyncdata.c
drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/dummyll.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/hardware/mISDN/mISDNisar.c
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/mISDN/clock.c
drivers/isdn/mISDN/dsp_audio.c
drivers/isdn/mISDN/dsp_pipeline.c
drivers/isdn/mISDN/socket.c
drivers/leds/dell-led.c
drivers/leds/led-class.c
drivers/leds/leds-88pm860x.c
drivers/leds/leds-asic3.c
drivers/leds/leds-atmel-pwm.c
drivers/leds/leds-cobalt-raq.c
drivers/leds/leds-fsg.c
drivers/leds/leds-gpio.c
drivers/leds/leds-lm3530.c
drivers/leds/leds-locomo.c
drivers/leds/leds-lt3593.c
drivers/leds/leds-net48xx.c
drivers/leds/leds-net5501.c
drivers/leds/leds-ns2.c
drivers/leds/leds-s3c24xx.c
drivers/leds/leds-wm831x-status.c
drivers/leds/leds-wm8350.c
drivers/leds/leds-wrap.c
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/macintosh/via-macii.c
drivers/macintosh/via-maciisi.c
drivers/md/bitmap.c
drivers/md/dm-bufio.c
drivers/md/dm-exception-store.c
drivers/md/dm-log-userspace-base.c
drivers/md/dm-path-selector.c
drivers/md/dm-raid.c
drivers/md/dm-round-robin.c
drivers/md/dm-service-time.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-snap-transient.c
drivers/md/dm-uevent.c
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/persistent-data/dm-btree-remove.c
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-space-map-checker.c
drivers/md/persistent-data/dm-space-map-disk.c
drivers/md/persistent-data/dm-transaction-manager.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_hlp.c
drivers/media/common/saa7146_video.c
drivers/media/common/tuners/tuner-types.c
drivers/media/dvb/dvb-usb/mxl111sf-i2c.c
drivers/media/dvb/dvb-usb/mxl111sf-phy.c
drivers/media/dvb/frontends/dibx000_common.c
drivers/media/dvb/siano/sms-cards.c
drivers/media/dvb/siano/smsendian.c
drivers/media/dvb/siano/smssdio.c
drivers/media/dvb/siano/smsusb.c
drivers/media/media-device.c
drivers/media/radio/radio-timb.c
drivers/media/radio/radio-wl1273.c
drivers/media/radio/si4713-i2c.c
drivers/media/radio/wl128x/fmdrv_v4l2.c
drivers/media/rc/ir-jvc-decoder.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/ir-nec-decoder.c
drivers/media/rc/ir-raw.c
drivers/media/rc/ir-rc5-decoder.c
drivers/media/rc/ir-rc5-sz-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/ir-sony-decoder.c
drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
drivers/media/rc/keymaps/rc-alink-dtu-m.c
drivers/media/rc/keymaps/rc-anysee.c
drivers/media/rc/keymaps/rc-apac-viewcomp.c
drivers/media/rc/keymaps/rc-asus-pc39.c
drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
drivers/media/rc/keymaps/rc-avermedia-a16d.c
drivers/media/rc/keymaps/rc-avermedia-cardbus.c
drivers/media/rc/keymaps/rc-avermedia-dvbt.c
drivers/media/rc/keymaps/rc-avermedia-m135a.c
drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
drivers/media/rc/keymaps/rc-avermedia.c
drivers/media/rc/keymaps/rc-avertv-303.c
drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c
drivers/media/rc/keymaps/rc-behold-columbus.c
drivers/media/rc/keymaps/rc-behold.c
drivers/media/rc/keymaps/rc-budget-ci-old.c
drivers/media/rc/keymaps/rc-cinergy-1400.c
drivers/media/rc/keymaps/rc-cinergy.c
drivers/media/rc/keymaps/rc-dib0700-nec.c
drivers/media/rc/keymaps/rc-dib0700-rc5.c
drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c
drivers/media/rc/keymaps/rc-digittrade.c
drivers/media/rc/keymaps/rc-dm1105-nec.c
drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
drivers/media/rc/keymaps/rc-em-terratec.c
drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
drivers/media/rc/keymaps/rc-encore-enltv.c
drivers/media/rc/keymaps/rc-encore-enltv2.c
drivers/media/rc/keymaps/rc-evga-indtube.c
drivers/media/rc/keymaps/rc-eztv.c
drivers/media/rc/keymaps/rc-flydvb.c
drivers/media/rc/keymaps/rc-flyvideo.c
drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
drivers/media/rc/keymaps/rc-gadmei-rm008z.c
drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
drivers/media/rc/keymaps/rc-gotview7135.c
drivers/media/rc/keymaps/rc-hauppauge.c
drivers/media/rc/keymaps/rc-imon-mce.c
drivers/media/rc/keymaps/rc-imon-pad.c
drivers/media/rc/keymaps/rc-iodata-bctv7e.c
drivers/media/rc/keymaps/rc-kaiomy.c
drivers/media/rc/keymaps/rc-kworld-315u.c
drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
drivers/media/rc/keymaps/rc-leadtek-y04g0051.c
drivers/media/rc/keymaps/rc-lirc.c
drivers/media/rc/keymaps/rc-lme2510.c
drivers/media/rc/keymaps/rc-manli.c
drivers/media/rc/keymaps/rc-msi-digivox-ii.c
drivers/media/rc/keymaps/rc-msi-digivox-iii.c
drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
drivers/media/rc/keymaps/rc-msi-tvanywhere.c
drivers/media/rc/keymaps/rc-nebula.c
drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
drivers/media/rc/keymaps/rc-norwood.c
drivers/media/rc/keymaps/rc-npgtech.c
drivers/media/rc/keymaps/rc-pctv-sedna.c
drivers/media/rc/keymaps/rc-pinnacle-color.c
drivers/media/rc/keymaps/rc-pinnacle-grey.c
drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
drivers/media/rc/keymaps/rc-pixelview-002t.c
drivers/media/rc/keymaps/rc-pixelview-mk12.c
drivers/media/rc/keymaps/rc-pixelview-new.c
drivers/media/rc/keymaps/rc-pixelview.c
drivers/media/rc/keymaps/rc-powercolor-real-angel.c
drivers/media/rc/keymaps/rc-proteus-2309.c
drivers/media/rc/keymaps/rc-purpletv.c
drivers/media/rc/keymaps/rc-pv951.c
drivers/media/rc/keymaps/rc-rc6-mce.c
drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
drivers/media/rc/keymaps/rc-streamzap.c
drivers/media/rc/keymaps/rc-tbs-nec.c
drivers/media/rc/keymaps/rc-technisat-usb2.c
drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
drivers/media/rc/keymaps/rc-terratec-slim-2.c
drivers/media/rc/keymaps/rc-terratec-slim.c
drivers/media/rc/keymaps/rc-tevii-nec.c
drivers/media/rc/keymaps/rc-tivo.c
drivers/media/rc/keymaps/rc-total-media-in-hand.c
drivers/media/rc/keymaps/rc-trekstor.c
drivers/media/rc/keymaps/rc-tt-1500.c
drivers/media/rc/keymaps/rc-twinhan1027.c
drivers/media/rc/keymaps/rc-videomate-m1f.c
drivers/media/rc/keymaps/rc-videomate-s350.c
drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
drivers/media/rc/keymaps/rc-winfast.c
drivers/media/rc/rc-main.c
drivers/media/video/adp1653.c
drivers/media/video/ak881x.c
drivers/media/video/cpia2/cpia2_usb.c
drivers/media/video/cx25840/cx25840-ir.c
drivers/media/video/davinci/dm355_ccdc.c
drivers/media/video/davinci/dm644x_ccdc.c
drivers/media/video/hdpvr/hdpvr-i2c.c
drivers/media/video/hexium_gemini.c
drivers/media/video/hexium_orion.c
drivers/media/video/imx074.c
drivers/media/video/m5mols/m5mols_core.c
drivers/media/video/mt9m001.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9t031.c
drivers/media/video/mt9v011.c
drivers/media/video/mt9v022.c
drivers/media/video/mt9v032.c
drivers/media/video/mxb.c
drivers/media/video/noon010pc30.c
drivers/media/video/omap24xxcam.c
drivers/media/video/ov6650.c
drivers/media/video/pvrusb2/pvrusb2-devattr.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
drivers/media/video/rj54n1cb0c.c
drivers/media/video/s5k6aa.c
drivers/media/video/s5p-mfc/s5p_mfc_dec.c
drivers/media/video/s5p-mfc/s5p_mfc_enc.c
drivers/media/video/sh_mobile_csi2.c
drivers/media/video/sh_vou.c
drivers/media/video/sr030pc30.c
drivers/media/video/tcm825x.c
drivers/media/video/timblogiw.c
drivers/media/video/tvp514x.c
drivers/media/video/tvp5150.c
drivers/media/video/tvp7002.c
drivers/media/video/usbvision/usbvision-cards.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/v4l2-ctrls.c
drivers/media/video/v4l2-device.c
drivers/media/video/v4l2-event.c
drivers/media/video/v4l2-fh.c
drivers/media/video/v4l2-int-device.c
drivers/media/video/v4l2-subdev.c
drivers/media/video/videobuf2-core.c
drivers/memstick/core/memstick.c
drivers/memstick/core/mspro_block.c
drivers/memstick/host/jmb38x_ms.c
drivers/memstick/host/tifm_ms.c
drivers/message/i2o/pci.c
drivers/mfd/ab3100-core.c
drivers/mfd/ab5500-core.c
drivers/mfd/ab5500-debugfs.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/ab8500-sysctrl.c
drivers/mfd/abx500-core.c
drivers/mfd/asic3.c
drivers/mfd/dm355evm_msp.c
drivers/mfd/max8997.c
drivers/mfd/mfd-core.c
drivers/mfd/pcf50633-irq.c
drivers/mfd/tmio_core.c
drivers/mfd/twl-core.c
drivers/mfd/twl6030-irq.c
drivers/mfd/wl1273-core.c
drivers/mfd/wm8400-core.c
drivers/misc/Kconfig
drivers/misc/ab8500-pwm.c
drivers/misc/ad525x_dpot.h
drivers/misc/atmel-ssc.c
drivers/misc/atmel_tclib.c
drivers/misc/bh1780gli.c
drivers/misc/carma/carma-fpga-program.c
drivers/misc/carma/carma-fpga.c
drivers/misc/eeprom/Kconfig
drivers/misc/kgdbts.c
drivers/misc/pch_phub.c
drivers/misc/sgi-gru/grukservices.c
drivers/misc/spear13xx_pcie_gadget.c
drivers/misc/ti-st/st_kim.c
drivers/misc/tifm_7xx1.c
drivers/misc/tifm_core.c
drivers/mmc/core/bus.c
drivers/mmc/core/debugfs.c
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/quirks.c
drivers/mmc/core/sd.c
drivers/mmc/core/sd_ops.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_io.c
drivers/mmc/core/sdio_irq.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-tegra.c
drivers/mtd/Kconfig
drivers/mtd/Makefile
drivers/mtd/afs.c
drivers/mtd/ar7part.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/fwh_lock.h
drivers/mtd/chips/jedec_probe.c
drivers/mtd/cmdlinepart.c
drivers/mtd/devices/Kconfig
drivers/mtd/devices/Makefile
drivers/mtd/devices/doc2000.c
drivers/mtd/devices/doc2001.c
drivers/mtd/devices/doc2001plus.c
drivers/mtd/devices/docecc.c
drivers/mtd/devices/docg3.c [new file with mode: 0644]
drivers/mtd/devices/docg3.h [new file with mode: 0644]
drivers/mtd/devices/docprobe.c
drivers/mtd/devices/lart.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/devices/sst25l.c
drivers/mtd/ftl.c
drivers/mtd/inftlcore.c
drivers/mtd/inftlmount.c
drivers/mtd/lpddr/lpddr_cmds.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/bcm963xx-flash.c
drivers/mtd/maps/bfin-async-flash.c
drivers/mtd/maps/ceiva.c [deleted file]
drivers/mtd/maps/dc21285.c
drivers/mtd/maps/edb7312.c [deleted file]
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/h720x-flash.c
drivers/mtd/maps/impa7.c
drivers/mtd/maps/intel_vr_nor.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lantiq-flash.c
drivers/mtd/maps/latch-addr-flash.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/physmap.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/maps/rbtx4939-flash.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/maps/solutionengine.c
drivers/mtd/maps/wr_sbc82xx_flash.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdblock_ro.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdcore.c
drivers/mtd/mtdcore.h
drivers/mtd/mtdoops.c
drivers/mtd/mtdpart.c
drivers/mtd/mtdsuper.c
drivers/mtd/mtdswap.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/cafe_nand.c
drivers/mtd/nand/cmx270_nand.c
drivers/mtd/nand/cs553x_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/edb7312.c [deleted file]
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/fsmc_nand.c
drivers/mtd/nand/gpmi-nand/Makefile [new file with mode: 0644]
drivers/mtd/nand/gpmi-nand/bch-regs.h [new file with mode: 0644]
drivers/mtd/nand/gpmi-nand/gpmi-lib.c [new file with mode: 0644]
drivers/mtd/nand/gpmi-nand/gpmi-nand.c [new file with mode: 0644]
drivers/mtd/nand/gpmi-nand/gpmi-nand.h [new file with mode: 0644]
drivers/mtd/nand/gpmi-nand/gpmi-regs.h [new file with mode: 0644]
drivers/mtd/nand/h1910.c
drivers/mtd/nand/jz4740_nand.c
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bch.c
drivers/mtd/nand/nand_ecc.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/nomadik_nand.c
drivers/mtd/nand/nuc900_nand.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nand/pasemi_nand.c
drivers/mtd/nand/plat_nand.c
drivers/mtd/nand/ppchameleonevb.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/r852.c
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/sm_common.c
drivers/mtd/nand/socrates_nand.c
drivers/mtd/nand/tmio_nand.c
drivers/mtd/nand/txx9ndfmc.c
drivers/mtd/nftlcore.c
drivers/mtd/nftlmount.c
drivers/mtd/ofpart.c
drivers/mtd/onenand/generic.c
drivers/mtd/onenand/omap2.c
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/onenand_bbt.c
drivers/mtd/onenand/samsung.c
drivers/mtd/redboot.c
drivers/mtd/rfd_ftl.c
drivers/mtd/sm_ftl.c
drivers/mtd/ssfdc.c
drivers/mtd/tests/mtd_oobtest.c
drivers/mtd/tests/mtd_pagetest.c
drivers/mtd/tests/mtd_readtest.c
drivers/mtd/tests/mtd_speedtest.c
drivers/mtd/tests/mtd_stresstest.c
drivers/mtd/tests/mtd_subpagetest.c
drivers/mtd/tests/mtd_torturetest.c
drivers/mtd/ubi/eba.c
drivers/mtd/ubi/io.c
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/misc.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vtbl.c
drivers/net/Kconfig
drivers/net/arcnet/Kconfig
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_procfs.c
drivers/net/bonding/bond_sysfs.c
drivers/net/can/sja1000/peak_pci.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h
drivers/net/ethernet/brocade/bna/bnad.c
drivers/net/ethernet/cadence/Kconfig
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
drivers/net/ethernet/chelsio/cxgb3/l2t.c
drivers/net/ethernet/chelsio/cxgb4/l2t.c
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/ethoc.c
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/ibm/ehea/ehea.h
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/ibm/iseries_veth.c
drivers/net/ethernet/intel/Kconfig
drivers/net/ethernet/intel/e1000e/param.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
drivers/net/ethernet/jme.c
drivers/net/ethernet/jme.h
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/marvell/sky2.h
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/catas.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/intf.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/pd.c
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/net/ethernet/natsemi/Kconfig
drivers/net/ethernet/neterion/vxge/vxge-main.c
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/octeon/octeon_mgmt.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
drivers/net/ethernet/pasemi/Makefile
drivers/net/ethernet/qlogic/qlge/qlge.h
drivers/net/ethernet/rdc/r6040.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/smsc/smsc9420.c
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/sunhme.c
drivers/net/ethernet/tile/tilepro.c
drivers/net/ethernet/toshiba/ps3_gelic_net.c
drivers/net/ethernet/toshiba/ps3_gelic_net.h
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/net/hippi/Kconfig
drivers/net/macvlan.c
drivers/net/phy/Kconfig
drivers/net/phy/realtek.c
drivers/net/usb/asix.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/lg-vl600.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/usbnet.c
drivers/net/veth.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wimax/i2400m/control.c
drivers/net/wimax/i2400m/debugfs.c
drivers/net/wimax/i2400m/fw.c
drivers/net/wimax/i2400m/netdev.c
drivers/net/wimax/i2400m/rx.c
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/tx.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/adm8211.c
drivers/net/wireless/ath/ath5k/debug.c
drivers/net/wireless/ath/ath5k/pci.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath9k/ahb.c
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ar9002_mac.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9485_initvals.h
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/calib.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/ath/debug.c
drivers/net/wireless/ath/hw.c
drivers/net/wireless/ath/key.c
drivers/net/wireless/ath/regd.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pcmcia.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/brcm80211/brcmsmac/dma.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_info.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_proc.c
drivers/net/wireless/iwlegacy/iwl-debugfs.c
drivers/net/wireless/iwlegacy/iwl-rx.c
drivers/net/wireless/iwlegacy/iwl-scan.c
drivers/net/wireless/iwlegacy/iwl-sta.c
drivers/net/wireless/iwlegacy/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwmc3200wifi/commands.c
drivers/net/wireless/iwmc3200wifi/debugfs.c
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/sdio.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cfg.h
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/if_usb.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/orinoco/fw.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtl818x/rtl8180/dev.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192c/main.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/rtlwifi/rtl8192se/sw.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/xen-netback/common.h
drivers/net/xen-netback/netback.c
drivers/nfc/nfcwilink.c
drivers/of/fdt.c
drivers/of/irq.c
drivers/of/of_net.c
drivers/of/of_pci.c
drivers/of/of_pci_irq.c
drivers/of/of_spi.c
drivers/oprofile/oprof.c
drivers/oprofile/timer_int.c
drivers/parisc/ccio-dma.c
drivers/parisc/sba_iommu.c
drivers/pci/Kconfig
drivers/pci/ats.c
drivers/pci/hotplug-pci.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/pciehp_acpi.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pcihp_slot.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/htirq.c
drivers/pci/ioapic.c
drivers/pci/iov.c
drivers/pci/irq.c
drivers/pci/msi.c
drivers/pci/pci-sysfs.c
drivers/pci/quirks.c
drivers/pci/rom.c
drivers/pci/setup-res.c
drivers/pci/slot.c
drivers/pci/vpd.c
drivers/pcmcia/db1xxx_ss.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/pxa2xx_cm_x255.c
drivers/pcmcia/pxa2xx_cm_x270.c
drivers/pcmcia/pxa2xx_cm_x2xx.c
drivers/pinctrl/Kconfig
drivers/pinctrl/core.c
drivers/platform/x86/Kconfig
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/wmi.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/rsparser.c
drivers/power/intel_mid_battery.c
drivers/power/max17042_battery.c
drivers/power/max8903_charger.c
drivers/power/max8997_charger.c
drivers/power/max8998_charger.c
drivers/power/power_supply_sysfs.c
drivers/ps3/ps3-vuart.c
drivers/ps3/ps3stor_lib.c
drivers/ps3/sys-manager-core.c
drivers/ptp/ptp_clock.c
drivers/rapidio/devices/tsi721.c
drivers/rapidio/devices/tsi721.h
drivers/rapidio/switches/idt_gen2.c
drivers/regulator/88pm8607.c
drivers/regulator/aat2870-regulator.c
drivers/regulator/ab8500.c
drivers/regulator/bq24022.c
drivers/regulator/core.c
drivers/regulator/da903x.c
drivers/regulator/db8500-prcmu.c
drivers/regulator/dummy.c
drivers/regulator/fixed.c
drivers/regulator/lp3971.c
drivers/regulator/lp3972.c
drivers/regulator/max8925-regulator.c
drivers/regulator/max8997.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/mc13892-regulator.c
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/tps65910-regulator.c
drivers/regulator/twl-regulator.c
drivers/regulator/userspace-consumer.c
drivers/regulator/virtual.c
drivers/regulator/wm8400-regulator.c
drivers/rtc/class.c
drivers/rtc/interface.c
drivers/rtc/rtc-dm355evm.c
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-em3027.c
drivers/rtc/rtc-isl12022.c
drivers/rtc/rtc-mrst.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-puv3.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-stk17ta8.c
drivers/rtc/rtc-tx4939.c
drivers/rtc/rtc-x1205.c
drivers/s390/char/fs3270.c
drivers/s390/char/sclp_cpi_sys.c
drivers/s390/char/vmcp.c
drivers/s390/char/vmur.c
drivers/s390/char/zcore.c
drivers/s390/cio/chp.c
drivers/s390/cio/chsc.c
drivers/s390/cio/cio.h
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/io_sch.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_setup.c
drivers/s390/crypto/ap_bus.c
drivers/s390/kvm/kvm_virtio.c
drivers/s390/net/Kconfig
drivers/s390/net/lcs.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/net/qeth_l3_sys.c
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_dbf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/Kconfig
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/linit.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/bfa/bfad_debugfs.c
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bnx2fc/bnx2fc.h
drivers/scsi/bnx2fc/bnx2fc_els.c
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/device_handler/scsi_dh.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_hp_sw.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/gvp11.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/hpsa_cmd.h
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/isci/host.c
drivers/scsi/isci/init.c
drivers/scsi/isci/port.c
drivers/scsi/isci/port.h
drivers/scsi/isci/probe_roms.h
drivers/scsi/isci/remote_device.c
drivers/scsi/isci/remote_device.h
drivers/scsi/isci/request.c
drivers/scsi/isci/request.h
drivers/scsi/isci/task.c
drivers/scsi/isci/task.h
drivers/scsi/iscsi_tcp.c
drivers/scsi/libfc/fc_disc.c
drivers/scsi/libfc/fc_elsct.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_libfc.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_npiv.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/libiscsi.c
drivers/scsi/libiscsi_tcp.c
drivers/scsi/libsas/sas_host_smp.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/libsas/sas_task.c
drivers/scsi/libsrp.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/mac53c94.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/mpt2sas/mpi/mpi2.h
drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h
drivers/scsi/mpt2sas/mpt2sas_config.c
drivers/scsi/mpt2sas/mpt2sas_ctl.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/scsi/mvsas/mv_init.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/pmcraid.c
drivers/scsi/ps3rom.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib_dma.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_pm.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_tgt_if.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/sr_ioctl.c
drivers/scsi/st.c
drivers/sfi/sfi_core.h
drivers/sh/Makefile
drivers/sh/clk/core.c
drivers/sh/intc/chip.c
drivers/sh/intc/core.c
drivers/sh/intc/dynamic.c
drivers/sh/intc/virq.c
drivers/sh/maple/maple.c
drivers/sh/pm_runtime.c [new file with mode: 0644]
drivers/spi/Kconfig
drivers/spi/spi-altera.c
drivers/spi/spi-ath79.c
drivers/spi/spi-atmel.c
drivers/spi/spi-au1550.c
drivers/spi/spi-bitbang.c
drivers/spi/spi-butterfly.c
drivers/spi/spi-dw-mmio.c
drivers/spi/spi-dw-pci.c
drivers/spi/spi-dw.c
drivers/spi/spi-gpio.c
drivers/spi/spi-nuc900.c
drivers/spi/spi-oc-tiny.c
drivers/spi/spi-omap-uwire.c
drivers/spi/spi-orion.c
drivers/spi/spi-pl022.c
drivers/spi/spi-pxa2xx-pci.c
drivers/spi/spi-s3c24xx.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sh-sci.c
drivers/spi/spi-ti-ssp.c
drivers/spi/spi-tle62x0.c
drivers/spi/spi-txx9.c
drivers/spi/spi.c
drivers/ssb/b43_pci_bridge.c
drivers/ssb/driver_chipcommon.c
drivers/ssb/driver_chipcommon_pmu.c
drivers/ssb/driver_gige.c
drivers/ssb/driver_pcicore.c
drivers/ssb/embedded.c
drivers/ssb/main.c
drivers/ssb/pcihost_wrapper.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/cxt1e1/linux.c
drivers/staging/et131x/Kconfig
drivers/staging/et131x/et131x.c
drivers/staging/gma500/intel_i2c.c
drivers/staging/gma500/mdfld_dsi_output.c
drivers/staging/gma500/mdfld_output.c
drivers/staging/gma500/mid_bios.c
drivers/staging/gma500/mrst_hdmi_i2c.c
drivers/staging/gma500/psb_drv.c
drivers/staging/iio/accel/adis16201_ring.c
drivers/staging/iio/accel/adis16201_trigger.c
drivers/staging/iio/accel/adis16203_ring.c
drivers/staging/iio/accel/adis16203_trigger.c
drivers/staging/iio/accel/adis16204_ring.c
drivers/staging/iio/accel/adis16204_trigger.c
drivers/staging/iio/accel/adis16209_ring.c
drivers/staging/iio/accel/adis16209_trigger.c
drivers/staging/iio/accel/adis16240_ring.c
drivers/staging/iio/accel/adis16240_trigger.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/adc/ad7793.c
drivers/staging/iio/dac/ad5686.c
drivers/staging/iio/gyro/adis16060_core.c
drivers/staging/iio/gyro/adis16260_ring.c
drivers/staging/iio/gyro/adis16260_trigger.c
drivers/staging/iio/iio_simple_dummy_buffer.c
drivers/staging/iio/imu/adis16400_ring.c
drivers/staging/iio/imu/adis16400_trigger.c
drivers/staging/iio/industrialio-buffer.c
drivers/staging/iio/industrialio-core.c
drivers/staging/iio/meter/ade7758_ring.c
drivers/staging/iio/meter/ade7758_trigger.c
drivers/staging/intel_sst/intel_sst.c
drivers/staging/intel_sst/intel_sst_drv_interface.c
drivers/staging/line6/audio.c
drivers/staging/media/as102/as102_drv.c
drivers/staging/media/as102/as102_drv.h
drivers/staging/media/solo6x10/g723.c
drivers/staging/octeon/ethernet-tx.c
drivers/staging/rts5139/rts51x_scsi.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/slicoss/Kconfig
drivers/staging/spectra/lld_mtd.c
drivers/staging/usbip/usbip_common.c
drivers/staging/usbip/usbip_event.c
drivers/staging/usbip/vhci_rx.c
drivers/staging/winbond/wbusb.c
drivers/staging/wlags49_h2/wl_cs.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_auth.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_core.h
drivers/target/iscsi/iscsi_target_erl1.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_nego.c
drivers/target/iscsi/iscsi_target_stat.c
drivers/target/loopback/tcm_loop.c
drivers/target/target_core_alua.c
drivers/target/target_core_alua.h
drivers/target/target_core_cdb.c
drivers/target/target_core_cdb.h [new file with mode: 0644]
drivers/target/target_core_configfs.c
drivers/target/target_core_device.c
drivers/target/target_core_fabric_lib.c
drivers/target/target_core_file.c
drivers/target/target_core_hba.c
drivers/target/target_core_iblock.c
drivers/target/target_core_pr.c
drivers/target/target_core_pr.h
drivers/target/target_core_pscsi.c
drivers/target/target_core_rd.c
drivers/target/target_core_tmr.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/target/tcm_fc/tcm_fc.h
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_conf.c
drivers/thermal/thermal_sys.c
drivers/tty/hvc/Kconfig
drivers/tty/hvc/Makefile
drivers/tty/hvc/hvc_console.c
drivers/tty/hvc/hvc_dcc.c
drivers/tty/hvc/hvc_iseries.c
drivers/tty/hvc/hvc_opal.c [new file with mode: 0644]
drivers/tty/hvc/hvc_vio.c
drivers/tty/hvc/hvcs.c
drivers/tty/hvc/hvsi_lib.c
drivers/tty/n_gsm.c
drivers/tty/serial/8250.c
drivers/tty/serial/Kconfig
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/crisv10.c
drivers/tty/serial/jsm/jsm_driver.c
drivers/tty/serial/kgdboc.c
drivers/tty/serial/max3100.c
drivers/tty/serial/max3107-aava.c
drivers/tty/serial/max3107.c
drivers/tty/serial/mfd.c
drivers/tty/serial/nwpserial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/timbuart.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_ldisc.c
drivers/tty/vt/vc_screen.c
drivers/uio/uio_pdrv.c
drivers/uio/uio_pdrv_genirq.c
drivers/usb/c67x00/c67x00-drv.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/driver.c
drivers/usb/core/hub.c
drivers/usb/core/notify.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/cdc2.c
drivers/usb/gadget/ci13xxx_msm.c
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/dbgp.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_midi.c
drivers/usb/gadget/f_obex.c
drivers/usb/gadget/f_phonet.c
drivers/usb/gadget/f_serial.c
drivers/usb/gadget/f_sourcesink.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_mxc_udc.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/fsl_usb2_udc.h
drivers/usb/gadget/fusb300_udc.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/pch_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c-hsudc.c
drivers/usb/gadget/u_serial.c
drivers/usb/gadget/udc-core.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-xls.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci.h
drivers/usb/host/pci-quirks.c
drivers/usb/host/whci/debug.c
drivers/usb/host/whci/hcd.c
drivers/usb/host/whci/qset.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_stat.c
drivers/usb/mon/mon_text.c
drivers/usb/musb/Kconfig
drivers/usb/musb/am35x.c
drivers/usb/musb/da8xx.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/otg/gpio_vbus.c
drivers/usb/otg/otg.c
drivers/usb/otg/ulpi.c
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/renesas_usbhs/mod.h
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/renesas_usbhs/mod_host.c
drivers/usb/serial/aircable.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/qcserial.c
drivers/usb/storage/ene_ub6250.c
drivers/usb/storage/option_ms.c
drivers/usb/storage/protocol.c
drivers/usb/storage/sierra_ms.c
drivers/usb/storage/transport.c
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/wusbcore/devconnect.c
drivers/usb/wusbcore/mmc.c
drivers/usb/wusbcore/rh.c
drivers/usb/wusbcore/security.c
drivers/usb/wusbcore/wa-hc.c
drivers/usb/wusbcore/wa-rpipe.c
drivers/usb/wusbcore/wa-xfer.c
drivers/uwb/est.c
drivers/uwb/i1480/dfu/dfu.c
drivers/uwb/ie.c
drivers/uwb/lc-dev.c
drivers/uwb/lc-rc.c
drivers/uwb/neh.c
drivers/uwb/pal.c
drivers/uwb/radio.c
drivers/uwb/reset.c
drivers/uwb/rsv.c
drivers/uwb/scan.c
drivers/uwb/umc-bus.c
drivers/uwb/umc-dev.c
drivers/uwb/umc-drv.c
drivers/uwb/whci.c
drivers/video/atmel_lcdfb.c
drivers/video/backlight/88pm860x_bl.c
drivers/video/backlight/adp5520_bl.c
drivers/video/backlight/ams369fg06.c
drivers/video/backlight/da903x_bl.c
drivers/video/backlight/ep93xx_bl.c
drivers/video/backlight/l4f00242t03.c
drivers/video/backlight/ld9040.c
drivers/video/backlight/lms283gf05.c
drivers/video/backlight/max8925_bl.c
drivers/video/backlight/s6e63m0.c
drivers/video/backlight/wm831x_bl.c
drivers/video/carminefb.c
drivers/video/cobalt_lcdfb.c
drivers/video/da8xx-fb.c
drivers/video/ep93xx-fb.c
drivers/video/fb_ddc.c
drivers/video/fb_notify.c
drivers/video/mb862xx/mb862xx-i2c.c
drivers/video/mb862xx/mb862xxfbdrv.c
drivers/video/msm/mdp.c
drivers/video/omap/dispc.c
drivers/video/omap/lcd_mipid.c
drivers/video/omap/omapfb_main.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dpi.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/sdi.c
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/savage/savagefb_accel.c
drivers/video/sh_mipi_dsi.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/via/share.h
drivers/video/via/via-gpio.c
drivers/video/w100fb.c
drivers/virt/fsl_hypervisor.c
drivers/virtio/Kconfig
drivers/virtio/virtio.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci.c
drivers/virtio/virtio_ring.c
drivers/w1/w1_family.c
drivers/w1/w1_int.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/adx_wdt.c [deleted file]
drivers/watchdog/coh901327_wdt.c
drivers/watchdog/eurotechwdt.c
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/mpcore_wdt.c
drivers/watchdog/octeon-wdt-main.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/sb_wdog.c
drivers/watchdog/sc520_wdt.c
drivers/watchdog/stmp3xxx_wdt.c
drivers/watchdog/w83627hf_wdt.c
drivers/watchdog/wdt.c
drivers/watchdog/wdt_pci.c
drivers/watchdog/wm831x_wdt.c
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/gntalloc.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/manage.c
drivers/xen/pci.c
drivers/xen/swiotlb-xen.c
drivers/xen/xen-balloon.c
drivers/xen/xen-pciback/conf_space.c
drivers/xen/xenbus/xenbus_client.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe.h
drivers/xen/xenbus/xenbus_probe_backend.c
drivers/xen/xenbus/xenbus_probe_frontend.c
drivers/zorro/proc.c
fs/bio-integrity.c
fs/bio.c
fs/btrfs/Makefile
fs/btrfs/acl.c
fs/btrfs/backref.c [new file with mode: 0644]
fs/btrfs/backref.h [new file with mode: 0644]
fs/btrfs/btrfs_inode.h
fs/btrfs/compression.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode-map.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/print-tree.c
fs/btrfs/reada.c [new file with mode: 0644]
fs/btrfs/relocation.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/btrfs/xattr.c
fs/buffer.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/readdir.c
fs/cifs/smbencrypt.c
fs/dcache.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/exofs/ore.c
fs/exofs/super.c
fs/ext4/balloc.c
fs/ext4/inode.c
fs/ext4/super.c
fs/fs-writeback.c
fs/fuse/cuse.c
fs/gfs2/ops_fstype.c
fs/hfs/trans.c
fs/ioprio.c
fs/jffs2/compr.c
fs/jffs2/compr.h
fs/jffs2/fs.c
fs/jffs2/jffs2_fs_sb.h
fs/jffs2/os-linux.h
fs/jffs2/scan.c
fs/jffs2/super.c
fs/jffs2/wbuf.c
fs/jfs/jfs_logmgr.c
fs/logfs/super.c
fs/minix/bitmap.c
fs/minix/inode.c
fs/minix/minix.h
fs/namei.c
fs/namespace.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs3proc.c
fs/nfs/nfs4filelayout.c
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfs/pnfs_dev.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs4acl.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/cluster/tcp.h
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdebug.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlmglue.c
fs/ocfs2/extent_map.c
fs/ocfs2/extent_map.h
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
fs/ocfs2/mmap.c
fs/ocfs2/move_extents.c
fs/ocfs2/ocfs2.h
fs/ocfs2/quota_local.c
fs/ocfs2/slot_map.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/super.c
fs/ocfs2/xattr.c
fs/proc/base.c
fs/proc/meminfo.c
fs/proc/stat.c
fs/proc/vmcore.c
fs/pstore/platform.c
fs/quota/quota.c
fs/seq_file.c
fs/sync.c
fs/ubifs/budget.c
fs/ubifs/debug.c
fs/ubifs/debug.h
fs/ubifs/recovery.c
fs/ubifs/sb.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_aops.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dquot_item.c
fs/xfs/xfs_export.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log.h
fs/xfs/xfs_qm.c
fs/xfs/xfs_sync.c
fs/xfs/xfs_trace.h
fs/xfs/xfs_trans.h
fs/xfs/xfs_vnodeops.c
include/acpi/acpi_drivers.h
include/acpi/actypes.h
include/acpi/platform/aclinux.h
include/acpi/processor.h
include/asm-generic/unistd.h
include/drm/drmP.h
include/drm/drm_dp_helper.h
include/drm/drm_mode.h
include/drm/drm_pciids.h
include/drm/exynos_drm.h
include/drm/radeon_drm.h
include/drm/vmwgfx_drm.h
include/linux/backing-dev.h
include/linux/bcma/bcma.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/ceph/osd_client.h
include/linux/clocksource.h
include/linux/compat.h
include/linux/cpu.h
include/linux/cpuidle.h
include/linux/crypto.h
include/linux/dcache.h
include/linux/devfreq.h
include/linux/device.h
include/linux/device_cgroup.h
include/linux/dma-mapping.h
include/linux/dmaengine.h
include/linux/elevator.h
include/linux/ethtool.h
include/linux/export.h [new file with mode: 0644]
include/linux/firmware.h
include/linux/freezer.h
include/linux/fs.h
include/linux/ftrace.h
include/linux/ftrace_event.h
include/linux/gameport.h
include/linux/genhd.h
include/linux/hid.h
include/linux/hugetlb.h
include/linux/hwspinlock.h
include/linux/i2c.h
include/linux/inet_diag.h
include/linux/init_task.h
include/linux/iocontext.h
include/linux/ipmi.h
include/linux/ipmi_smi.h
include/linux/irq.h
include/linux/irqdesc.h
include/linux/jump_label.h
include/linux/kernel.h
include/linux/kvm.h
include/linux/mdio-bitbang.h
include/linux/mfd/tps65910.h
include/linux/mfd/wm8994/registers.h
include/linux/miscdevice.h
include/linux/mm.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/mtd/bbm.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/onenand.h
include/linux/mtd/partitions.h
include/linux/mtd/physmap.h
include/linux/netdevice.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/of.h
include/linux/of_platform.h
include/linux/opp.h
include/linux/pci-ats.h
include/linux/pci.h
include/linux/pci_hotplug.h
include/linux/pci_ids.h
include/linux/perf_event.h
include/linux/pinctrl/pinctrl.h
include/linux/pkt_sched.h
include/linux/pm.h
include/linux/pm_runtime.h
include/linux/pstore.h
include/linux/regmap.h
include/linux/regulator/driver.h
include/linux/sched.h
include/linux/serial.h
include/linux/serial_sci.h
include/linux/serio.h
include/linux/sh_clk.h
include/linux/sh_pfc.h
include/linux/shrinker.h
include/linux/sigma.h
include/linux/ssb/ssb.h
include/linux/stop_machine.h
include/linux/sunrpc/svc_xprt.h
include/linux/sysdev.h
include/linux/textsearch.h
include/linux/topology.h
include/linux/uio_driver.h
include/linux/usb.h
include/linux/uwb.h
include/linux/uwb/umc.h
include/linux/vermagic.h
include/linux/virtio_config.h
include/linux/virtio_mmio.h
include/linux/vlynq.h
include/linux/vmalloc.h
include/linux/writeback.h
include/media/saa7146.h
include/media/v4l2-int-device.h
include/mtd/mtd-abi.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/bluetooth/rfcomm.h
include/net/cfg80211.h
include/net/dst.h
include/net/dst_ops.h
include/net/inet_sock.h
include/net/inet_timewait_sock.h
include/net/inetpeer.h
include/net/ip_vs.h
include/net/lib80211.h
include/net/mac80211.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netlink.h
include/net/netns/conntrack.h
include/net/red.h
include/net/route.h
include/net/sch_generic.h
include/net/sock.h
include/sound/core.h
include/target/target_core_base.h
include/target/target_core_device.h
include/target/target_core_fabric_ops.h
include/target/target_core_transport.h
include/trace/define_trace.h
include/trace/events/module.h
include/trace/events/writeback.h
include/video/omapdss.h
include/xen/grant_table.h
include/xen/interface/io/blkif.h
include/xen/interface/platform.h [new file with mode: 0644]
include/xen/interface/xen.h
include/xen/platform_pci.h
include/xen/xenbus.h
init/main.c
kernel/async.c
kernel/audit.c
kernel/auditsc.c
kernel/capability.c
kernel/cgroup_freezer.c
kernel/compat.c
kernel/cpu.c
kernel/cpuset.c
kernel/crash_dump.c
kernel/cred.c
kernel/debug/kdb/kdb_debugger.c
kernel/dma.c
kernel/events/core.c
kernel/events/internal.h
kernel/events/ring_buffer.c
kernel/fork.c
kernel/freezer.c
kernel/futex.c
kernel/groups.c
kernel/hrtimer.c
kernel/hung_task.c
kernel/irq/generic-chip.c
kernel/irq/irqdesc.c
kernel/irq/manage.c
kernel/irq/spurious.c
kernel/irq_work.c
kernel/jump_label.c
kernel/kfifo.c
kernel/kprobes.c
kernel/ksysfs.c
kernel/kthread.c
kernel/latencytop.c
kernel/lockdep.c
kernel/lockdep_proc.c
kernel/module.c
kernel/mutex-debug.c
kernel/mutex.c
kernel/notifier.c
kernel/nsproxy.c
kernel/padata.c
kernel/panic.c
kernel/params.c
kernel/pid.c
kernel/posix-timers.c
kernel/power/hibernate.c
kernel/power/main.c
kernel/power/qos.c
kernel/power/suspend.c
kernel/power/user.c
kernel/printk.c
kernel/profile.c
kernel/ptrace.c
kernel/range.c
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutiny_plugin.h
kernel/rcutree.c
kernel/relay.c
kernel/resource.c
kernel/rtmutex-debug.c
kernel/rtmutex-tester.c
kernel/rtmutex.c
kernel/rwsem.c
kernel/sched.c
kernel/sched_clock.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_rt.c
kernel/semaphore.c
kernel/signal.c
kernel/smp.c
kernel/softirq.c
kernel/spinlock.c
kernel/srcu.c
kernel/stacktrace.c
kernel/stop_machine.c
kernel/sys.c
kernel/time.c
kernel/time/alarmtimer.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/posix-clock.c
kernel/time/tick-broadcast.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_syscalls.c
kernel/up.c
kernel/user-return-notifier.c
kernel/user.c
kernel/user_namespace.c
kernel/utsname.c
kernel/utsname_sysctl.c
kernel/wait.c
kernel/workqueue.c
lib/dma-debug.c
lib/nlattr.c
lib/raid6/algos.c
lib/raid6/mktables.c
lib/raid6/recov.c
mm/backing-dev.c
mm/bootmem.c
mm/bounce.c
mm/dmapool.c
mm/filemap.c
mm/filemap_xip.c
mm/fremap.c
mm/highmem.c
mm/huge_memory.c
mm/hugetlb.c
mm/kmemleak.c
mm/maccess.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mempool.c
mm/migrate.c
mm/mlock.c
mm/mm_init.c
mm/mmap.c
mm/mmu_context.c
mm/mmu_notifier.c
mm/mmzone.c
mm/nobootmem.c
mm/nommu.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/percpu-vm.c
mm/percpu.c
mm/quicklist.c
mm/readahead.c
mm/rmap.c
mm/shmem.c
mm/slab.c
mm/slob.c
mm/slub.c
mm/sparse-vmemmap.c
mm/sparse.c
mm/swap.c
mm/swap_state.c
mm/swapfile.c
mm/truncate.c
mm/util.c
mm/vmalloc.c
mm/vmscan.c
net/802/fc.c
net/802/garp.c
net/802/stp.c
net/8021q/vlan_core.c
net/8021q/vlan_netlink.c
net/appletalk/aarp.c
net/appletalk/atalk_proc.c
net/atm/pvc.c
net/atm/svc.c
net/ax25/ax25_route.c
net/ax25/ax25_uid.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sysfs.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/rfcomm/core.c
net/bridge/br_input.c
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_stp.c
net/bridge/br_stp_if.c
net/caif/caif_dev.c
net/caif/cffrml.c
net/caif/cfpkt_skbuff.c
net/ceph/messenger.c
net/ceph/osd_client.c
net/compat.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/fib_rules.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/net-traces.c
net/core/net_namespace.c
net/core/netevent.c
net/core/netpoll.c
net/core/request_sock.c
net/core/secure_seq.c
net/core/skbuff.c
net/core/timestamping.c
net/core/user_dma.c
net/dcb/dcbevent.c
net/dcb/dcbnl.c
net/dccp/ackvec.c
net/dccp/ccids/lib/tfrc.c
net/dccp/ipv4.c
net/dccp/timer.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/decnet/dn_timer.c
net/dsa/dsa.c
net/ieee802154/nl-mac.c
net/ipv4/ah4.c
net/ipv4/devinet.c
net/ipv4/fib_rules.c
net/ipv4/fib_trie.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_forward.c
net/ipv4/ip_options.c
net/ipv4/ipconfig.c
net/ipv4/ipmr.c
net/ipv4/netfilter.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
net/ipv4/netfilter/nf_nat_proto_common.c
net/ipv4/netfilter/nf_nat_proto_icmp.c
net/ipv4/netfilter/nf_nat_proto_sctp.c
net/ipv4/netfilter/nf_nat_proto_tcp.c
net/ipv4/netfilter/nf_nat_proto_udp.c
net/ipv4/netfilter/nf_nat_proto_udplite.c
net/ipv4/ping.c
net/ipv4/proc.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/udplite.c
net/ipv4/xfrm4_state.c
net/ipv6/addrconf.c
net/ipv6/addrconf_core.c
net/ipv6/ah6.c
net/ipv6/exthdrs.c
net/ipv6/exthdrs_core.c
net/ipv6/fib6_rules.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_input.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6mr.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/ipv6/netfilter/Kconfig
net/ipv6/proc.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/sysctl_net_ipv6.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udplite.c
net/ipv6/xfrm6_state.c
net/ipx/ipx_proc.c
net/irda/discovery.c
net/irda/irda_device.c
net/irda/irttp.c
net/irda/qos.c
net/l2tp/l2tp_core.c
net/llc/llc_input.c
net/llc/llc_output.c
net/llc/llc_proc.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/debugfs_sta.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/key.c
net/mac80211/led.c
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/offchannel.c
net/mac80211/rate.c
net/mac80211/rc80211_minstrel_debugfs.c
net/mac80211/rc80211_minstrel_ht_debugfs.c
net/mac80211/rc80211_pid_debugfs.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/status.c
net/mac80211/tkip.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/work.c
net/netfilter/Kconfig
net/netfilter/ipset/ip_set_getport.c
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c
net/netfilter/ipset/pfxlen.c
net/netfilter/nf_conntrack_acct.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/x_tables.c
net/netfilter/xt_quota.c
net/netfilter/xt_statistic.c
net/netlabel/netlabel_kapi.c
net/netrom/nr_route.c
net/nfc/af_nfc.c
net/nfc/nci/core.c
net/nfc/rawsock.c
net/phonet/datagram.c
net/phonet/pep.c
net/phonet/socket.c
net/rds/Kconfig
net/rds/cong.c
net/rds/connection.c
net/rds/ib.c
net/rds/info.c
net/rds/iw.c
net/rds/message.c
net/rds/page.c
net/rds/rdma_transport.c
net/rds/recv.c
net/rds/send.c
net/rds/stats.c
net/rds/tcp.c
net/rds/threads.c
net/rfkill/input.c
net/rose/rose_route.c
net/rxrpc/ar-output.c
net/rxrpc/ar-recvmsg.c
net/sched/act_api.c
net/sched/cls_flow.c
net/sched/sch_mq.c
net/sched/sch_mqprio.c
net/sched/sch_red.c
net/sched/sch_teql.c
net/sctp/auth.c
net/sctp/proc.c
net/sctp/socket.c
net/sunrpc/addr.c
net/sunrpc/backchannel_rqst.c
net/sunrpc/socklib.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtsock.c
net/sysctl_net.c
net/tipc/core.c
net/tipc/socket.c
net/unix/af_unix.c
net/wanrouter/wanproc.c
net/wimax/op-msg.c
net/wimax/op-reset.c
net/wimax/op-rfkill.c
net/wimax/stack.c
net/wireless/ibss.c
net/wireless/mesh.c
net/wireless/nl80211.c
net/wireless/radiotap.c
net/wireless/reg.c
net/wireless/scan.c
net/wireless/sme.c
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext-core.c
net/wireless/wext-sme.c
net/wireless/wext-spy.c
net/x25/x25_proc.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_proc.c
net/xfrm/xfrm_replay.c
samples/Kconfig
scripts/Makefile.build
scripts/Makefile.lib
scripts/basic/fixdep.c
scripts/checkpatch.pl
scripts/extract-vmlinux [new file with mode: 0755]
scripts/genksyms/genksyms.c
scripts/genksyms/genksyms.h
scripts/genksyms/lex.l
scripts/genksyms/lex.lex.c_shipped
scripts/genksyms/parse.tab.c_shipped
scripts/genksyms/parse.tab.h_shipped
scripts/genksyms/parse.y
scripts/kconfig/Makefile
scripts/kconfig/confdata.c
scripts/kconfig/lxdialog/textbox.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
scripts/kconfig/nconf.c
scripts/kconfig/nconf.gui.c
scripts/kconfig/nconf.h
scripts/kconfig/streamline_config.pl
scripts/mod/modpost.c
scripts/tags.sh
security/apparmor/path.c
security/keys/encrypted-keys/Makefile
security/keys/encrypted-keys/encrypted.c
security/keys/encrypted-keys/encrypted.h
security/keys/user_defined.c
security/selinux/hooks.c
security/selinux/netlink.c
security/smack/smackfs.c
security/tomoyo/realpath.c
sound/aoa/soundbus/i2sbus/pcm.c
sound/arm/pxa2xx-ac97-lib.c
sound/arm/pxa2xx-pcm.c
sound/core/control.c
sound/core/device.c
sound/core/hwdep.c
sound/core/info.c
sound/core/info_oss.c
sound/core/init.c
sound/core/isadma.c
sound/core/jack.c
sound/core/memory.c
sound/core/misc.c
sound/core/oss/mixer_oss.c
sound/core/oss/pcm_oss.c
sound/core/pcm.c
sound/core/pcm_lib.c
sound/core/pcm_memory.c
sound/core/pcm_misc.c
sound/core/pcm_native.c
sound/core/rawmidi.c
sound/core/seq/oss/seq_oss.c
sound/core/seq/oss/seq_oss_init.c
sound/core/seq/oss/seq_oss_synth.c
sound/core/seq/seq.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_device.c
sound/core/seq/seq_dummy.c
sound/core/seq/seq_info.c
sound/core/seq/seq_lock.c
sound/core/seq/seq_memory.c
sound/core/seq/seq_midi.c
sound/core/seq/seq_midi_emul.c
sound/core/seq/seq_midi_event.c
sound/core/seq/seq_ports.c
sound/core/seq/seq_system.c
sound/core/seq/seq_virmidi.c
sound/core/sound.c
sound/core/sound_oss.c
sound/core/timer.c
sound/core/vmaster.c
sound/drivers/aloop.c
sound/drivers/dummy.c
sound/drivers/ml403-ac97cr.c
sound/drivers/mpu401/mpu401.c
sound/drivers/mpu401/mpu401_uart.c
sound/drivers/mtpav.c
sound/drivers/mts64.c
sound/drivers/opl3/opl3_lib.c
sound/drivers/opl3/opl3_oss.c
sound/drivers/opl3/opl3_seq.c
sound/drivers/opl3/opl3_synth.c
sound/drivers/opl4/opl4_lib.c
sound/drivers/opl4/opl4_proc.c
sound/drivers/opl4/opl4_seq.c
sound/drivers/pcsp/pcsp.c
sound/drivers/portman2x4.c
sound/drivers/serial-u16550.c
sound/drivers/virmidi.c
sound/drivers/vx/vx_core.c
sound/drivers/vx/vx_hwdep.c
sound/firewire/iso-resources.c
sound/firewire/packets-buffer.c
sound/i2c/cs8427.c
sound/i2c/i2c.c
sound/i2c/other/ak4113.c
sound/i2c/other/ak4114.c
sound/i2c/other/ak4117.c
sound/i2c/other/ak4xxx-adda.c
sound/i2c/other/pt2258.c
sound/i2c/other/tea575x-tuner.c
sound/i2c/tea6330t.c
sound/isa/ad1816a/ad1816a.c
sound/isa/ad1848/ad1848.c
sound/isa/als100.c
sound/isa/azt2320.c
sound/isa/cmi8330.c
sound/isa/cs423x/cs4231.c
sound/isa/cs423x/cs4236.c
sound/isa/es1688/es1688.c
sound/isa/es1688/es1688_lib.c
sound/isa/es18xx.c
sound/isa/gus/gus_main.c
sound/isa/gus/gus_volume.c
sound/isa/gus/gusclassic.c
sound/isa/gus/gusextreme.c
sound/isa/gus/gusmax.c
sound/isa/gus/interwave.c
sound/isa/msnd/msnd.c
sound/isa/msnd/msnd_midi.c
sound/isa/msnd/msnd_pinnacle_mixer.c
sound/isa/opl3sa2.c
sound/isa/opti9xx/miro.c
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/sb/emu8000.c
sound/isa/sb/emu8000_callback.c
sound/isa/sb/emu8000_patch.c
sound/isa/sb/emu8000_synth.c
sound/isa/sb/sb16.c
sound/isa/sb/sb16_csp.c
sound/isa/sb/sb16_main.c
sound/isa/sb/sb8.c
sound/isa/sb/sb8_main.c
sound/isa/sb/sb_common.c
sound/isa/sscape.c
sound/isa/wavefront/wavefront.c
sound/isa/wavefront/wavefront_fx.c
sound/isa/wavefront/wavefront_synth.c
sound/isa/wss/wss_lib.c
sound/mips/au1x00.c
sound/mips/hal2.c
sound/mips/sgio2audio.c
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_pcm.c
sound/pci/ad1889.c
sound/pci/ak4531_codec.c
sound/pci/ali5451/ali5451.c
sound/pci/als300.c
sound/pci/als4000.c
sound/pci/asihpi/asihpi.c
sound/pci/asihpi/hpioctl.c
sound/pci/atiixp.c
sound/pci/atiixp_modem.c
sound/pci/au88x0/au88x0.c
sound/pci/au88x0/au88x0_game.c
sound/pci/aw2/aw2-alsa.c
sound/pci/azt3328.c
sound/pci/bt87x.c
sound/pci/ca0106/ca0106_main.c
sound/pci/cmipci.c
sound/pci/cs4281.c
sound/pci/cs46xx/cs46xx.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs5530.c
sound/pci/cs5535audio/cs5535audio.c
sound/pci/cs5535audio/cs5535audio_pcm.c
sound/pci/ctxfi/xfi.c
sound/pci/echoaudio/darla20.c
sound/pci/echoaudio/darla24.c
sound/pci/echoaudio/echo3g.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/gina20.c
sound/pci/echoaudio/gina24.c
sound/pci/echoaudio/indigo.c
sound/pci/echoaudio/indigodj.c
sound/pci/echoaudio/indigodjx.c
sound/pci/echoaudio/indigoio.c
sound/pci/echoaudio/indigoiox.c
sound/pci/echoaudio/layla20.c
sound/pci/echoaudio/layla24.c
sound/pci/echoaudio/mia.c
sound/pci/echoaudio/mona.c
sound/pci/emu10k1/emu10k1.c
sound/pci/emu10k1/emu10k1_callback.c
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emu10k1_synth.c
sound/pci/emu10k1/emu10k1x.c
sound/pci/emu10k1/io.c
sound/pci/emu10k1/memory.c
sound/pci/emu10k1/voice.c
sound/pci/ens1370.c
sound/pci/es1938.c
sound/pci/es1968.c
sound/pci/fm801.c
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_ca0110.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_cmedia.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/ice1712/ak4xxx.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1724.c
sound/pci/intel8x0.c
sound/pci/intel8x0m.c
sound/pci/korg1212/korg1212.c
sound/pci/lola/lola.c
sound/pci/lx6464es/lx_core.c
sound/pci/lx6464es/lx_core.h
sound/pci/maestro3.c
sound/pci/mixart/mixart.c
sound/pci/mixart/mixart_hwdep.c
sound/pci/nm256/nm256.c
sound/pci/oxygen/oxygen.c
sound/pci/oxygen/oxygen_io.c
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/virtuoso.c
sound/pci/pcxhr/pcxhr.c
sound/pci/pcxhr/pcxhr_hwdep.c
sound/pci/riptide/riptide.c
sound/pci/rme32.c
sound/pci/rme96.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/pci/sis7019.c
sound/pci/sonicvibes.c
sound/pci/trident/trident.c
sound/pci/trident/trident_main.c
sound/pci/via82xx.c
sound/pci/via82xx_modem.c
sound/pci/vx222/vx222.c
sound/pci/ymfpci/ymfpci.c
sound/pci/ymfpci/ymfpci_main.c
sound/pcmcia/pdaudiocf/pdaudiocf.c
sound/pcmcia/vx/vxpocket.c
sound/ppc/powermac.c
sound/ppc/snd_ps3.c
sound/sh/aica.c
sound/sh/sh_dac_audio.c
sound/soc/atmel/Kconfig
sound/soc/atmel/Makefile
sound/soc/atmel/playpaq_wm8510.c [deleted file]
sound/soc/blackfin/bf5xx-sport.c
sound/soc/blackfin/bfin-eval-adav80x.c
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1836.h
sound/soc/codecs/adau1373.c
sound/soc/codecs/ads117x.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/dmic.c
sound/soc/codecs/max9877.c
sound/soc/codecs/pcm3008.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/sta32x.h
sound/soc/codecs/uda1380.c
sound/soc/codecs/wl1273.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9090.c
sound/soc/codecs/wm_hubs.c
sound/soc/ep93xx/edb93xx.c
sound/soc/ep93xx/snappercl15.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/imx/Kconfig
sound/soc/imx/wm1133-ev1.c
sound/soc/kirkwood/Kconfig
sound/soc/mid-x86/mfld_machine.c
sound/soc/mid-x86/sst_platform.c
sound/soc/nuc900/nuc900-ac97.c
sound/soc/omap/am3517evm.c
sound/soc/omap/ams-delta.c
sound/soc/omap/igep0020.c
sound/soc/omap/n810.c
sound/soc/omap/omap-pcm.c
sound/soc/omap/omap3beagle.c
sound/soc/omap/omap3evm.c
sound/soc/omap/omap3pandora.c
sound/soc/omap/omap4-hdmi-card.c
sound/soc/omap/osk5912.c
sound/soc/omap/overo.c
sound/soc/omap/rx51.c
sound/soc/omap/sdp3430.c
sound/soc/omap/sdp4430.c
sound/soc/omap/zoom2.c
sound/soc/pxa/Kconfig
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/samsung/ac97.c
sound/soc/samsung/dma.c
sound/soc/samsung/goni_wm8994.c
sound/soc/samsung/h1940_uda1380.c
sound/soc/samsung/i2s.c
sound/soc/samsung/idma.c
sound/soc/samsung/jive_wm8750.c
sound/soc/samsung/ln2440sbc_alc650.c
sound/soc/samsung/pcm.c
sound/soc/samsung/rx1950_uda1380.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c24xx-i2s.c
sound/soc/samsung/s3c24xx_simtec.c
sound/soc/samsung/s3c24xx_simtec_hermes.c
sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
sound/soc/samsung/s3c24xx_uda134x.c
sound/soc/samsung/smartq_wm8987.c
sound/soc/samsung/smdk_spdif.c
sound/soc/samsung/smdk_wm8580.c
sound/soc/samsung/smdk_wm8580pcm.c
sound/soc/samsung/smdk_wm8994.c
sound/soc/samsung/smdk_wm8994pcm.c
sound/soc/samsung/smdk_wm9713.c
sound/soc/samsung/spdif.c
sound/soc/samsung/speyside.c
sound/soc/samsung/speyside_wm8962.c
sound/soc/sh/fsi-ak4642.c
sound/soc/sh/fsi-da7210.c
sound/soc/sh/fsi-hdmi.c
sound/soc/sh/fsi.c
sound/soc/sh/siu_dai.c
sound/soc/soc-cache.c
sound/soc/soc-core.c
sound/soc/soc-io.c
sound/soc/soc-jack.c
sound/soc/soc-utils.c
sound/soc/tegra/tegra_asoc_utils.c
sound/sparc/dbri.c
sound/synth/emux/emux.c
sound/synth/emux/emux_oss.c
sound/synth/emux/emux_seq.c
sound/synth/emux/emux_synth.c
sound/synth/emux/soundfont.c
sound/synth/util_mem.c
sound/usb/6fire/firmware.c
sound/usb/card.c
sound/usb/midi.c
sound/usb/misc/ua101.c
sound/usb/mixer.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/usx2y/us122l.c
sound/usb/usx2y/usbusx2yaudio.c
tools/perf/builtin-record.c
tools/perf/builtin-stat.c
tools/perf/builtin-test.c
tools/perf/builtin-top.c
tools/perf/util/annotate.c
tools/perf/util/debug.c
tools/perf/util/debug.h
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/python.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/top.h
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/perf/util/ui/browser.c
tools/perf/util/ui/browser.h
tools/perf/util/ui/browsers/annotate.c
tools/perf/util/ui/browsers/hists.c
tools/perf/util/ui/helpline.c
tools/perf/util/ui/helpline.h
tools/perf/util/ui/progress.c
tools/perf/util/ui/progress.h
tools/perf/util/ui/setup.c
tools/perf/util/ui/ui.h
tools/perf/util/ui/util.c
tools/perf/util/ui/util.h
tools/power/x86/turbostat/turbostat.c
tools/testing/ktest/ktest.pl
tools/testing/ktest/sample.conf
virt/kvm/iommu.c

index a4806f0de852079a2b2d093c30ba05d478df7ec5..9b0d0267a3c3f1ea75a674fe858fac2165a8b683 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -68,6 +68,7 @@ Juha Yrjola <juha.yrjola@solidboot.com>
 Kay Sievers <kay.sievers@vrfy.org>
 Kenneth W Chen <kenneth.w.chen@intel.com>
 Koushik <raghavendra.koushik@neterion.com>
+Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 Leonid I Ananiev <leonid.i.ananiev@intel.com>
 Linas Vepstas <linas@austin.ibm.com>
 Mark Brown <broonie@sirena.org.uk>
@@ -111,3 +112,4 @@ Uwe Kleine-König <ukl@pengutronix.de>
 Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
 Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
 Takashi YOSHII <takashi.yoshii.zj@renesas.com>
+Yusuke Goda <goda.yusuke@renesas.com>
diff --git a/CREDITS b/CREDITS
index 07e32a87d956808fbb8b979fb38d434d93c879fc..44fce988eaac8cd22bfe5a5e753ae1bb58b3476d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -688,10 +688,13 @@ S: Oxfordshire, UK.
 
 N: Kees Cook
 E: kees@outflux.net
-W: http://outflux.net/
-P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30  1975 1FFF 4BA9 1706 3E6D
-D: Minor updates to SCSI types, added /proc/pid/maps protection
+E: kees@ubuntu.com
+E: keescook@chromium.org
+W: http://outflux.net/blog/
+P: 4096R/DC6DC026 A5C3 F68F 229D D60F 723E  6E13 8972 F4DF DC6D C026
+D: Various security things, bug fixes, and documentation.
 S: (ask for current address)
+S: Portland, Oregon
 S: USA
 
 N: Robin Cornelius
diff --git a/Documentation/ABI/stable/sysfs-acpi-pmprofile b/Documentation/ABI/stable/sysfs-acpi-pmprofile
new file mode 100644 (file)
index 0000000..964c7a8
--- /dev/null
@@ -0,0 +1,22 @@
+What:          /sys/firmware/acpi/pm_profile
+Date:          03-Nov-2011
+KernelVersion: v3.2
+Contact:       linux-acpi@vger.kernel.org
+Description:   The ACPI pm_profile sysfs interface exports the platform
+               power management (and performance) requirement expectations
+               as provided by BIOS. The integer value is directly passed as
+               retrieved from the FADT ACPI table.
+Values:         For possible values see ACPI specification:
+               5.2.9 Fixed ACPI Description Table (FADT)
+               Field: Preferred_PM_Profile
+
+               Currently these values are defined by spec:
+               0 Unspecified
+               1 Desktop
+               2 Mobile
+               3 Workstation
+               4 Enterprise Server
+               5 SOHO Server
+               6 Appliance PC
+               7 Performance Server
+               >7 Reserved
index 2b5d56127fce4d7f9a6f83b535cdfcf469f83e0b..c1eb41cb9876083d3df79a6a995b692762acd21b 100644 (file)
@@ -206,16 +206,3 @@ Description:
                when a discarded area is read the discard_zeroes_data
                parameter will be set to one. Otherwise it will be 0 and
                the result of reading a discarded area is undefined.
-What:          /sys/block/<disk>/alias
-Date:          Aug 2011
-Contact:       Nao Nishijima <nao.nishijima.xt@hitachi.com>
-Description:
-               A raw device name of a disk does not always point a same disk
-               each boot-up time. Therefore, users have to use persistent
-               device names, which udev creates when the kernel finds a disk,
-               instead of raw device name. However, kernel doesn't show those
-               persistent names on its messages (e.g. dmesg).
-               This file can store an alias of the disk and it would be
-               appeared in kernel messages if it is set. A disk can have an
-               alias which length is up to 255bytes. Users can use alphabets,
-               numbers, "-" and "_" in alias name. This file is writeonce.
index c2791589397479594eb1d06e61567f404f3057c4..196b8b9dba1112b245e331a76b62e804604b191a 100644 (file)
@@ -32,7 +32,7 @@
       The Linux DRM layer contains code intended to support the needs
       of complex graphics devices, usually containing programmable
       pipelines well suited to 3D graphics acceleration.  Graphics
-      drivers in the kernel can make use of DRM functions to make
+      drivers in the kernel may make use of DRM functions to make
       tasks like memory management, interrupt handling and DMA easier,
       and provide a uniform interface to applications.
     </para>
       existing drivers.
     </para>
     <para>
-      First, we'll go over some typical driver initialization
+      First, we go over some typical driver initialization
       requirements, like setting up command buffers, creating an
       initial output configuration, and initializing core services.
-      Subsequent sections will cover core internals in more detail,
+      Subsequent sections cover core internals in more detail,
       providing implementation notes and examples.
     </para>
     <para>
@@ -74,7 +74,7 @@
     </para>
     <para>
       The core of every DRM driver is struct drm_driver.  Drivers
-      will typically statically initialize a drm_driver structure,
+      typically statically initialize a drm_driver structure,
       then pass it to drm_init() at load time.
     </para>
 
@@ -88,8 +88,8 @@
     </para>
     <programlisting>
       static struct drm_driver driver = {
-       /* don't use mtrr's here, the Xserver or user space app should
-        * deal with them for intel hardware.
+       /* Don't use MTRRs here; the Xserver or userspace app should
+        * deal with them for Intel hardware.
         */
        .driver_features =
            DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
     </programlisting>
     <para>
       In the example above, taken from the i915 DRM driver, the driver
-      sets several flags indicating what core features it supports.
-      We'll go over the individual callbacks in later sections.  Since
+      sets several flags indicating what core features it supports;
+      we go over the individual callbacks in later sections.  Since
       flags indicate which features your driver supports to the DRM
       core, you need to set most of them prior to calling drm_init().  Some,
       like DRIVER_MODESET can be set later based on user supplied parameters,
        <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
        <listitem>
          <para>
-           DRIVER_HAVE_IRQ indicates whether the driver has a IRQ
-           handler, DRIVER_IRQ_SHARED indicates whether the device &amp;
+           DRIVER_HAVE_IRQ indicates whether the driver has an IRQ
+           handler DRIVER_IRQ_SHARED indicates whether the device &amp;
            handler support shared IRQs (note that this is required of
            PCI drivers).
          </para>
        <term>DRIVER_DMA_QUEUE</term>
        <listitem>
          <para>
-           If the driver queues DMA requests and completes them
-           asynchronously, this flag should be set.  Deprecated.
+           Should be set if the driver queues DMA requests and completes them
+           asynchronously.  Deprecated.
          </para>
        </listitem>
       </varlistentry>
     </variablelist>
     <para>
       In this specific case, the driver requires AGP and supports
-      IRQs.  DMA, as we'll see, is handled by device specific ioctls
+      IRQs.  DMA, as discussed later, is handled by device-specific ioctls
       in this case.  It also supports the kernel mode setting APIs, though
       unlike in the actual i915 driver source, this example unconditionally
       exports KMS capability.
       initial output configuration.
     </para>
     <para>
-      Note that the tasks performed at driver load time must not
-      conflict with DRM client requirements.  For instance, if user
+      If compatibility is a concern (e.g. with drivers converted over
+      to the new interfaces from the old ones), care must be taken to
+      prevent device initialization and control that is incompatible with
+      currently active userspace drivers.  For instance, if user
       level mode setting drivers are in use, it would be problematic
       to perform output discovery &amp; configuration at load time.
-      Likewise, if pre-memory management aware user level drivers are
+      Likewise, if user-level drivers unaware of memory management are
       in use, memory management and command buffer setup may need to
-      be omitted.  These requirements are driver specific, and care
+      be omitted.  These requirements are driver-specific, and care
       needs to be taken to keep both old and new applications and
       libraries working.  The i915 driver supports the "modeset"
       module parameter to control whether advanced features are
-      enabled at load time or in legacy fashion.  If compatibility is
-      a concern (e.g. with drivers converted over to the new interfaces
-      from the old ones), care must be taken to prevent incompatible
-      device initialization and control with the currently active
-      userspace drivers.
+      enabled at load time or in legacy fashion.
     </para>
 
     <sect2>
       <title>Driver private &amp; performance counters</title>
       <para>
        The driver private hangs off the main drm_device structure and
-       can be used for tracking various device specific bits of
+       can be used for tracking various device-specific bits of
        information, like register offsets, command buffer status,
        register state for suspend/resume, etc.  At load time, a
-       driver can simply allocate one and set drm_device.dev_priv
-       appropriately; at unload the driver can free it and set
-       drm_device.dev_priv to NULL.
+       driver may simply allocate one and set drm_device.dev_priv
+       appropriately; it should be freed and drm_device.dev_priv set
+       to NULL when the driver is unloaded.
       </para>
       <para>
-       The DRM supports several counters which can be used for rough
+       The DRM supports several counters which may be used for rough
        performance characterization.  Note that the DRM stat counter
        system is not often used by applications, and supporting
        additional counters is completely optional.
        These interfaces are deprecated and should not be used.  If performance
        monitoring is desired, the developer should investigate and
        potentially enhance the kernel perf and tracing infrastructure to export
-       GPU related performance information to performance monitoring
-       tools and applications.
+       GPU related performance information for consumption by performance
+       monitoring tools and applications.
       </para>
     </sect2>
 
     <sect2>
       <title>Configuring the device</title>
       <para>
-       Obviously, device configuration will be device specific.
+       Obviously, device configuration is device-specific.
        However, there are several common operations: finding a
        device's PCI resources, mapping them, and potentially setting
        up an IRQ handler.
       <para>
        Finding &amp; mapping resources is fairly straightforward.  The
        DRM wrapper functions, drm_get_resource_start() and
-       drm_get_resource_len() can be used to find BARs on the given
+       drm_get_resource_len(), may be used to find BARs on the given
        drm_device struct.  Once those values have been retrieved, the
        driver load function can call drm_addmap() to create a new
-       mapping for the BAR in question.  Note you'll probably want a
+       mapping for the BAR in question.  Note that you probably want a
        drm_local_map_t in your driver private structure to track any
        mappings you create.
 <!-- !Fdrivers/gpu/drm/drm_bufs.c drm_get_resource_* -->
       <para>
        if compatibility with other operating systems isn't a concern
        (DRM drivers can run under various BSD variants and OpenSolaris),
-       native Linux calls can be used for the above, e.g. pci_resource_*
+       native Linux calls may be used for the above, e.g. pci_resource_*
        and iomap*/iounmap.  See the Linux device driver book for more
        info.
       </para>
       <para>
-       Once you have a register map, you can use the DRM_READn() and
+       Once you have a register map, you may use the DRM_READn() and
        DRM_WRITEn() macros to access the registers on your device, or
-       use driver specific versions to offset into your MMIO space
-       relative to a driver specific base pointer (see I915_READ for
-       example).
+       use driver-specific versions to offset into your MMIO space
+       relative to a driver-specific base pointer (see I915_READ for
+       an example).
       </para>
       <para>
        If your device supports interrupt generation, you may want to
-       setup an interrupt handler at driver load time as well.  This
+       set up an interrupt handler when the driver is loaded.  This
        is done using the drm_irq_install() function.  If your device
        supports vertical blank interrupts, it should call
        drm_vblank_init() to initialize the core vblank handling code before
       </para>
 <!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
       <para>
-       Once your interrupt handler is registered (it'll use your
+       Once your interrupt handler is registered (it uses your
        drm_driver.irq_handler as the actual interrupt handling
        function), you can safely enable interrupts on your device,
        assuming any other state your interrupt handler uses is also
        using the pci_map_rom() call, a convenience function that
        takes care of mapping the actual ROM, whether it has been
        shadowed into memory (typically at address 0xc0000) or exists
-       on the PCI device in the ROM BAR.  Note that once you've
-       mapped the ROM and extracted any necessary information, be
-       sure to unmap it; on many devices the ROM address decoder is
-       shared with other BARs, so leaving it mapped can cause
+       on the PCI device in the ROM BAR.  Note that after the ROM
+       has been mapped and any necessary information has been extracted,
+       it should be unmapped; on many devices, the ROM address decoder is
+       shared with other BARs, so leaving it mapped could cause
        undesired behavior like hangs or memory corruption.
 <!--!Fdrivers/pci/rom.c pci_map_rom-->
       </para>
        should support a memory manager.
       </para>
       <para>
-       If your driver supports memory management (it should!), you'll
+       If your driver supports memory management (it should!), you
        need to set that up at load time as well.  How you initialize
-       it depends on which memory manager you're using, TTM or GEM.
+       it depends on which memory manager you're using: TTM or GEM.
       </para>
       <sect3>
        <title>TTM initialization</title>
          and devices with dedicated video RAM (VRAM), i.e. most discrete
          graphics devices.  If your device has dedicated RAM, supporting
          TTM is desirable.  TTM also integrates tightly with your
-         driver specific buffer execution function.  See the radeon
+         driver-specific buffer execution function.  See the radeon
          driver for examples.
        </para>
        <para>
          created by the memory manager at runtime.  Your global TTM should
          have a type of TTM_GLOBAL_TTM_MEM.  The size field for the global
          object should be sizeof(struct ttm_mem_global), and the init and
-         release hooks should point at your driver specific init and
-         release routines, which will probably eventually call
-         ttm_mem_global_init and ttm_mem_global_release respectively.
+         release hooks should point at your driver-specific init and
+         release routines, which probably eventually call
+         ttm_mem_global_init and ttm_mem_global_release, respectively.
        </para>
        <para>
          Once your global TTM accounting structure is set up and initialized
-         (done by calling ttm_global_item_ref on the global object you
-         just created), you'll need to create a buffer object TTM to
+         by calling ttm_global_item_ref() on it,
+         you need to create a buffer object TTM to
          provide a pool for buffer object allocation by clients and the
          kernel itself.  The type of this object should be TTM_GLOBAL_TTM_BO,
          and its size should be sizeof(struct ttm_bo_global).  Again,
-         driver specific init and release functions can be provided,
-         likely eventually calling ttm_bo_global_init and
-         ttm_bo_global_release, respectively.  Also like the previous
-         object, ttm_global_item_ref is used to create an initial reference
+         driver-specific init and release functions may be provided,
+         likely eventually calling ttm_bo_global_init() and
+         ttm_bo_global_release(), respectively.  Also, like the previous
+         object, ttm_global_item_ref() is used to create an initial reference
          count for the TTM, which will call your initialization function.
        </para>
       </sect3>
          GEM is an alternative to TTM, designed specifically for UMA
          devices.  It has simpler initialization and execution requirements
          than TTM, but has no VRAM management capability.  Core GEM
-         initialization is comprised of a basic drm_mm_init call to create
+         is initialized by calling drm_mm_init() to create
          a GTT DRM MM object, which provides an address space pool for
-         object allocation.  In a KMS configuration, the driver will
-         need to allocate and initialize a command ring buffer following
-         basic GEM initialization.  Most UMA devices have a so-called
+         object allocation.  In a KMS configuration, the driver
+         needs to allocate and initialize a command ring buffer following
+         core GEM initialization.  A UMA device usually has what is called a
          "stolen" memory region, which provides space for the initial
          framebuffer and large, contiguous memory regions required by the
-         device.  This space is not typically managed by GEM, and must
+         device.  This space is not typically managed by GEM, and it must
          be initialized separately into its own DRM MM object.
        </para>
        <para>
-         Initialization will be driver specific, and will depend on
-         the architecture of the device.  In the case of Intel
+         Initialization is driver-specific. In the case of Intel
          integrated graphics chips like 965GM, GEM initialization can
          be done by calling the internal GEM init function,
          i915_gem_do_init().  Since the 965GM is a UMA device
-         (i.e. it doesn't have dedicated VRAM), GEM will manage
+         (i.e. it doesn't have dedicated VRAM), GEM manages
          making regular RAM available for GPU operations.  Memory set
          aside by the BIOS (called "stolen" memory by the i915
-         driver) will be managed by the DRM memrange allocator; the
-         rest of the aperture will be managed by GEM.
+         driver) is managed by the DRM memrange allocator; the
+         rest of the aperture is managed by GEM.
          <programlisting>
            /* Basic memrange allocator for stolen space (aka vram) */
            drm_memrange_init(&amp;dev_priv->vram, 0, prealloc_size);
 <!--!Edrivers/char/drm/drm_memrange.c-->
        </para>
        <para>
-         Once the memory manager has been set up, we can allocate the
+         Once the memory manager has been set up, we may allocate the
          command buffer.  In the i915 case, this is also done with a
          GEM function, i915_gem_init_ringbuffer().
        </para>
     <sect2>
       <title>Output configuration</title>
       <para>
-       The final initialization task is output configuration.  This involves
-       finding and initializing the CRTCs, encoders and connectors
-       for your device, creating an initial configuration and
-       registering a framebuffer console driver.
+       The final initialization task is output configuration.  This involves:
+       <itemizedlist>
+         <listitem>
+           Finding and initializing the CRTCs, encoders, and connectors
+           for the device.
+         </listitem>
+         <listitem>
+           Creating an initial configuration.
+         </listitem>
+         <listitem>
+           Registering a framebuffer console driver.
+         </listitem>
+       </itemizedlist>
       </para>
       <sect3>
        <title>Output discovery and initialization</title>
        <para>
-         Several core functions exist to create CRTCs, encoders and
-         connectors, namely drm_crtc_init(), drm_connector_init() and
+         Several core functions exist to create CRTCs, encoders, and
+         connectors, namely: drm_crtc_init(), drm_connector_init(), and
          drm_encoder_init(), along with several "helper" functions to
          perform common tasks.
        </para>
@@ -555,10 +561,10 @@ void intel_crt_init(struct drm_device *dev)
        </programlisting>
        <para>
          In the example above (again, taken from the i915 driver), a
-         CRT connector and encoder combination is created.  A device
-         specific i2c bus is also created, for fetching EDID data and
+         CRT connector and encoder combination is created.  A device-specific
+         i2c bus is also created for fetching EDID data and
          performing monitor detection.  Once the process is complete,
-         the new connector is registered with sysfs, to make its
+         the new connector is registered with sysfs to make its
          properties available to applications.
        </para>
        <sect4>
@@ -567,12 +573,12 @@ void intel_crt_init(struct drm_device *dev)
            Since many PC-class graphics devices have similar display output
            designs, the DRM provides a set of helper functions to make
            output management easier.  The core helper routines handle
-           encoder re-routing and disabling of unused functions following
-           mode set.  Using the helpers is optional, but recommended for
+           encoder re-routing and the disabling of unused functions following
+           mode setting.  Using the helpers is optional, but recommended for
            devices with PC-style architectures (i.e. a set of display planes
            for feeding pixels to encoders which are in turn routed to
            connectors).  Devices with more complex requirements needing
-           finer grained management can opt to use the core callbacks
+           finer grained management may opt to use the core callbacks
            directly.
          </para>
          <para>
@@ -580,17 +586,25 @@ void intel_crt_init(struct drm_device *dev)
          </para>
        </sect4>
        <para>
-         For each encoder, CRTC and connector, several functions must
-         be provided, depending on the object type.  Encoder objects
-         need to provide a DPMS (basically on/off) function, mode fixup
-         (for converting requested modes into native hardware timings),
-         and prepare, set and commit functions for use by the core DRM
-         helper functions.  Connector helpers need to provide mode fetch and
-         validity functions as well as an encoder matching function for
-         returning an ideal encoder for a given connector.  The core
-         connector functions include a DPMS callback, (deprecated)
-         save/restore routines, detection, mode probing, property handling,
-         and cleanup functions.
+         Each encoder object needs to provide:
+         <itemizedlist>
+           <listitem>
+             A DPMS (basically on/off) function.
+           </listitem>
+           <listitem>
+             A mode-fixup function (for converting requested modes into
+             native hardware timings).
+           </listitem>
+           <listitem>
+             Functions (prepare, set, and commit) for use by the core DRM
+             helper functions.
+           </listitem>
+         </itemizedlist>
+         Connector helpers need to provide functions (mode-fetch, validity,
+         and encoder-matching) for returning an ideal encoder for a given
+         connector.  The core connector functions include a DPMS callback,
+         save/restore routines (deprecated), detection, mode probing,
+         property handling, and cleanup functions.
        </para>
 <!--!Edrivers/char/drm/drm_crtc.h-->
 <!--!Edrivers/char/drm/drm_crtc.c-->
@@ -605,22 +619,33 @@ void intel_crt_init(struct drm_device *dev)
     <title>VBlank event handling</title>
     <para>
       The DRM core exposes two vertical blank related ioctls:
-      DRM_IOCTL_WAIT_VBLANK and DRM_IOCTL_MODESET_CTL.
+      <variablelist>
+        <varlistentry>
+          <term>DRM_IOCTL_WAIT_VBLANK</term>
+          <listitem>
+            <para>
+              This takes a struct drm_wait_vblank structure as its argument,
+              and it is used to block or request a signal when a specified
+              vblank event occurs.
+            </para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>DRM_IOCTL_MODESET_CTL</term>
+          <listitem>
+            <para>
+              This should be called by application level drivers before and
+              after mode setting, since on many devices the vertical blank
+              counter is reset at that time.  Internally, the DRM snapshots
+              the last vblank count when the ioctl is called with the
+              _DRM_PRE_MODESET command, so that the counter won't go backwards
+              (which is dealt with when _DRM_POST_MODESET is used).
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
 <!--!Edrivers/char/drm/drm_irq.c-->
     </para>
-    <para>
-      DRM_IOCTL_WAIT_VBLANK takes a struct drm_wait_vblank structure
-      as its argument, and is used to block or request a signal when a
-      specified vblank event occurs.
-    </para>
-    <para>
-      DRM_IOCTL_MODESET_CTL should be called by application level
-      drivers before and after mode setting, since on many devices the
-      vertical blank counter will be reset at that time.  Internally,
-      the DRM snapshots the last vblank count when the ioctl is called
-      with the _DRM_PRE_MODESET command so that the counter won't go
-      backwards (which is dealt with when _DRM_POST_MODESET is used).
-    </para>
     <para>
       To support the functions above, the DRM core provides several
       helper functions for tracking vertical blank counters, and
@@ -632,24 +657,24 @@ void intel_crt_init(struct drm_device *dev)
       register.  The enable and disable vblank callbacks should enable
       and disable vertical blank interrupts, respectively.  In the
       absence of DRM clients waiting on vblank events, the core DRM
-      code will use the disable_vblank() function to disable
-      interrupts, which saves power.  They'll be re-enabled again when
+      code uses the disable_vblank() function to disable
+      interrupts, which saves power.  They are re-enabled again when
       a client calls the vblank wait ioctl above.
     </para>
     <para>
-      Devices that don't provide a count register can simply use an
+      A device that doesn't provide a count register may simply use an
       internal atomic counter incremented on every vertical blank
-      interrupt, and can make their enable and disable vblank
-      functions into no-ops.
+      interrupt (and then treat the enable_vblank() and disable_vblank()
+      callbacks as no-ops).
     </para>
   </sect1>
 
   <sect1>
     <title>Memory management</title>
     <para>
-      The memory manager lies at the heart of many DRM operations, and
-      is also required to support advanced client features like OpenGL
-      pbuffers.  The DRM currently contains two memory managers, TTM
+      The memory manager lies at the heart of many DRM operations; it
+      is required to support advanced client features like OpenGL
+      pbuffers.  The DRM currently contains two memory managers: TTM
       and GEM.
     </para>
 
@@ -679,41 +704,46 @@ void intel_crt_init(struct drm_device *dev)
       <para>
        GEM-enabled drivers must provide gem_init_object() and
        gem_free_object() callbacks to support the core memory
-       allocation routines.  They should also provide several driver
-       specific ioctls to support command execution, pinning, buffer
+       allocation routines.  They should also provide several driver-specific
+       ioctls to support command execution, pinning, buffer
        read &amp; write, mapping, and domain ownership transfers.
       </para>
       <para>
-       On a fundamental level, GEM involves several operations: memory
-       allocation and freeing, command execution, and aperture management
-       at command execution time.  Buffer object allocation is relatively
+       On a fundamental level, GEM involves several operations:
+       <itemizedlist>
+         <listitem>Memory allocation and freeing</listitem>
+         <listitem>Command execution</listitem>
+         <listitem>Aperture management at command execution time</listitem>
+       </itemizedlist>
+       Buffer object allocation is relatively
        straightforward and largely provided by Linux's shmem layer, which
        provides memory to back each object.  When mapped into the GTT
        or used in a command buffer, the backing pages for an object are
        flushed to memory and marked write combined so as to be coherent
-       with the GPU.  Likewise, when the GPU finishes rendering to an object,
-       if the CPU accesses it, it must be made coherent with the CPU's view
+       with the GPU.  Likewise, if the CPU accesses an object after the GPU
+       has finished rendering to the object, then the object must be made
+       coherent with the CPU's view
        of memory, usually involving GPU cache flushing of various kinds.
-       This core CPU&lt;-&gt;GPU coherency management is provided by the GEM
-       set domain function, which evaluates an object's current domain and
+       This core CPU&lt;-&gt;GPU coherency management is provided by a
+       device-specific ioctl, which evaluates an object's current domain and
        performs any necessary flushing or synchronization to put the object
        into the desired coherency domain (note that the object may be busy,
-       i.e. an active render target; in that case the set domain function
-       will block the client and wait for rendering to complete before
+       i.e. an active render target; in that case, setting the domain
+       blocks the client and waits for rendering to complete before
        performing any necessary flushing operations).
       </para>
       <para>
        Perhaps the most important GEM function is providing a command
        execution interface to clients.  Client programs construct command
-       buffers containing references to previously allocated memory objects
-       and submit them to GEM.  At that point, GEM will take care to bind
+       buffers containing references to previously allocated memory objects,
+       and then submit them to GEM.  At that point, GEM takes care to bind
        all the objects into the GTT, execute the buffer, and provide
        necessary synchronization between clients accessing the same buffers.
        This often involves evicting some objects from the GTT and re-binding
        others (a fairly expensive operation), and providing relocation
        support which hides fixed GTT offsets from clients.  Clients must
        take care not to submit command buffers that reference more objects
-       than can fit in the GTT or GEM will reject them and no rendering
+       than can fit in the GTT; otherwise, GEM will reject them and no rendering
        will occur.  Similarly, if several objects in the buffer require
        fence registers to be allocated for correct rendering (e.g. 2D blits
        on pre-965 chips), care must be taken not to require more fence
@@ -729,7 +759,7 @@ void intel_crt_init(struct drm_device *dev)
     <title>Output management</title>
     <para>
       At the core of the DRM output management code is a set of
-      structures representing CRTCs, encoders and connectors.
+      structures representing CRTCs, encoders, and connectors.
     </para>
     <para>
       A CRTC is an abstraction representing a part of the chip that
@@ -765,21 +795,19 @@ void intel_crt_init(struct drm_device *dev)
   <sect1>
     <title>Framebuffer management</title>
     <para>
-      In order to set a mode on a given CRTC, encoder and connector
-      configuration, clients need to provide a framebuffer object which
-      will provide a source of pixels for the CRTC to deliver to the encoder(s)
-      and ultimately the connector(s) in the configuration.  A framebuffer
-      is fundamentally a driver specific memory object, made into an opaque
-      handle by the DRM addfb function.  Once an fb has been created this
-      way it can be passed to the KMS mode setting routines for use in
-      a configuration.
+      Clients need to provide a framebuffer object which provides a source
+      of pixels for a CRTC to deliver to the encoder(s) and ultimately the
+      connector(s). A framebuffer is fundamentally a driver-specific memory
+      object, made into an opaque handle by the DRM's addfb() function.
+      Once a framebuffer has been created this way, it may be passed to the
+      KMS mode setting routines for use in a completed configuration.
     </para>
   </sect1>
 
   <sect1>
     <title>Command submission &amp; fencing</title>
     <para>
-      This should cover a few device specific command submission
+      This should cover a few device-specific command submission
       implementations.
     </para>
   </sect1>
@@ -789,7 +817,7 @@ void intel_crt_init(struct drm_device *dev)
     <para>
       The DRM core provides some suspend/resume code, but drivers
       wanting full suspend/resume support should provide save() and
-      restore() functions.  These will be called at suspend,
+      restore() functions.  These are called at suspend,
       hibernate, or resume time, and should perform any state save or
       restore required by your device across suspend or hibernate
       states.
@@ -812,8 +840,8 @@ void intel_crt_init(struct drm_device *dev)
     <para>
       The DRM core exports several interfaces to applications,
       generally intended to be used through corresponding libdrm
-      wrapper functions.  In addition, drivers export device specific
-      interfaces for use by userspace drivers &amp; device aware
+      wrapper functions.  In addition, drivers export device-specific
+      interfaces for use by userspace drivers &amp; device-aware
       applications through ioctls and sysfs files.
     </para>
     <para>
@@ -822,8 +850,8 @@ void intel_crt_init(struct drm_device *dev)
       management, memory management, and output management.
     </para>
     <para>
-      Cover generic ioctls and sysfs layout here.  Only need high
-      level info, since man pages will cover the rest.
+      Cover generic ioctls and sysfs layout here.  We only need high-level
+      info, since man pages should cover the rest.
     </para>
   </chapter>
 
index 17910e2052addefcc2a581fa810991fde2545820..0c674be0d3c6de3d05e1903f6fac4beecff51133 100644 (file)
@@ -572,7 +572,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip)
                        </para>
                        <para>
                                The simplest way to activate the FLASH based bad block table support 
-                               is to set the option NAND_USE_FLASH_BBT in the option field of
+                               is to set the option NAND_BBT_USE_FLASH in the bbt_option field of
                                the nand chip structure before calling nand_scan(). For AG-AND
                                chips is this done by default.
                                This activates the default FLASH based bad block table functionality 
@@ -773,20 +773,6 @@ struct nand_oobinfo {
                                done according to the default builtin scheme.
                        </para>
                </sect2>
-               <sect2 id="User_space_placement_selection">
-                       <title>User space placement selection</title>
-               <para>
-                       All non ecc functions like mtd->read and mtd->write use an internal 
-                       structure, which can be set by an ioctl. This structure is preset 
-                       to the autoplacement default.
-                       <programlisting>
-       ioctl (fd, MEMSETOOBSEL, oobsel);
-                       </programlisting>
-                       oobsel is a pointer to a user supplied structure of type
-                       nand_oobconfig. The contents of this structure must match the 
-                       criteria of the filesystem, which will be used. See an example in utils/nandwrite.c.
-               </para>
-               </sect2>
        </sect1>        
        <sect1 id="Spare_area_autoplacement_default">
                <title>Spare area autoplacement default schemes</title>
@@ -1158,9 +1144,6 @@ in this page</entry>
                These constants are defined in nand.h. They are ored together to describe
                the functionality.
                <programlisting>
-/* Use a flash based bad block table. This option is parsed by the
- * default bad block table function (nand_default_bbt). */
-#define NAND_USE_FLASH_BBT     0x00010000
 /* The hw ecc generator provides a syndrome instead a ecc value on read 
  * This can only work if we have the ecc bytes directly behind the 
  * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
index 54883de5d5f9b598ab981de82269c908dec86114..ac3d0018140cd34cd7dd242334de64713406c6b6 100644 (file)
@@ -520,6 +520,11 @@ Here's a description of the fields of <varname>struct uio_mem</varname>:
 </para>
 
 <itemizedlist>
+<listitem><para>
+<varname>const char *name</varname>: Optional. Set this to help identify
+the memory region, it will show up in the corresponding sysfs node.
+</para></listitem>
+
 <listitem><para>
 <varname>int memtype</varname>: Required if the mapping is used. Set this to
 <varname>UIO_MEM_PHYS</varname> if you you have physical memory on your
@@ -553,7 +558,7 @@ instead to remember such an address.
 </itemizedlist>
 
 <para>
-Please do not touch the <varname>kobj</varname> element of
+Please do not touch the <varname>map</varname> element of
 <varname>struct uio_mem</varname>! It is used by the UIO framework
 to set up sysfs files for this mapping. Simply leave it alone.
 </para>
index 71464e09ec1841a39f031d972b281488e5d703af..b79d0a13e7cddf2512ef29069d60a54bf0399b02 100644 (file)
@@ -98,14 +98,12 @@ You must enable "SCSI tape drive support for Smart Array 5xxx" and
 "SCSI support" in your kernel configuration to be able to use SCSI
 tape drives with your Smart Array 5xxx controller.
 
-Additionally, note that the driver will not engage the SCSI core at init 
-time.  The driver must be directed to dynamically engage the SCSI core via 
-the /proc filesystem entry which the "block" side of the driver creates as 
-/proc/driver/cciss/cciss* at runtime.  This is because at driver init time, 
-the SCSI core may not yet be initialized (because the driver is a block 
-driver) and attempting to register it with the SCSI core in such a case 
-would cause a hang.  This is best done via an initialization script 
-(typically in /etc/init.d, but could vary depending on distribution). 
+Additionally, note that the driver will engage the SCSI core at init
+time if any tape drives or medium changers are detected.  The driver may
+also be directed to dynamically engage the SCSI core via the /proc filesystem
+entry which the "block" side of the driver creates as
+/proc/driver/cciss/cciss* at runtime.  This is best done via a script.
+
 For example:
 
        for x in /proc/driver/cciss/cciss[0-9]*
index c21d77742a0799424b09466857681ddcc7100f8b..7e62de1e59ff037af36728a6ec8bd3f79a822464 100644 (file)
@@ -33,9 +33,9 @@ demonstrate this problem using nested bash shells:
 
        From a second, unrelated bash shell:
        $ kill -SIGSTOP 16690
-       $ kill -SIGCONT 16990
+       $ kill -SIGCONT 16690
 
-       <at this point 16990 exits and causes 16644 to exit too>
+       <at this point 16690 exits and causes 16644 to exit too>
 
 This happens because bash can observe both signals and choose how it
 responds to them.
diff --git a/Documentation/devicetree/bindings/mtd/atmel-dataflash.txt b/Documentation/devicetree/bindings/mtd/atmel-dataflash.txt
new file mode 100644 (file)
index 0000000..ef66ddd
--- /dev/null
@@ -0,0 +1,14 @@
+* Atmel Data Flash
+
+Required properties:
+- compatible : "atmel,<model>", "atmel,<series>", "atmel,dataflash".
+
+Example:
+
+flash@1 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+       spi-max-frequency = <25000000>;
+       reg = <1>;
+};
index 39e941515a36ee18ab3ca59d0b71e4e4ae93c53c..380914e965e084c7f6f61e1444eac87bcef3dc81 100644 (file)
@@ -1,3 +1,8 @@
+Freescale Reference Board Bindings
+
+This document describes device tree bindings for various devices that
+exist on some Freescale reference boards.
+
 * Board Control and Status (BCSR)
 
 Required properties:
@@ -12,25 +17,26 @@ Example:
                reg = <f8000000 8000>;
        };
 
-* Freescale on board FPGA
+* Freescale on-board FPGA
 
 This is the memory-mapped registers for on board FPGA.
 
 Required properities:
-- compatible : should be "fsl,fpga-pixis".
-- reg : should contain the address and the length of the FPPGA register
-  set.
+- compatible: should be a board-specific string followed by a string
+  indicating the type of FPGA.  Example:
+       "fsl,<board>-fpga", "fsl,fpga-pixis"
+- reg: should contain the address and the length of the FPGA register set.
 - interrupt-parent: should specify phandle for the interrupt controller.
-- interrupts : should specify event (wakeup) IRQ.
+- interrupts: should specify event (wakeup) IRQ.
 
-Example (MPC8610HPCD):
+Example (P1022DS):
 
-       board-control@e8000000 {
-               compatible = "fsl,fpga-pixis";
-               reg = <0xe8000000 32>;
-               interrupt-parent = <&mpic>;
-               interrupts = <8 8>;
-       };
+        board-control@3,0 {
+                compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
+                reg = <3 0 0x30>;
+                interrupt-parent = <&mpic>;
+                interrupts = <8 8 0 0>;
+        };
 
 * Freescale BCSR GPIO banks
 
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt b/Documentation/devicetree/bindings/powerpc/fsl/dcsr.txt
new file mode 100644 (file)
index 0000000..9d54eb5
--- /dev/null
@@ -0,0 +1,395 @@
+===================================================================
+Debug Control and Status Register (DCSR) Binding
+Copyright 2011 Freescale Semiconductor Inc.
+
+NOTE: The bindings described in this document are preliminary and subject
+to change.  Some of the compatible strings that contain only generic names
+may turn out to be inappropriate, or need additional properties to describe
+the integration of the block with the rest of the chip.
+
+=====================================================================
+Debug Control and Status Register Memory Map
+
+Description
+
+This node defines the base address and range for the
+defined DCSR Memory Map. Child nodes will describe the individual
+debug blocks defined within this memory space.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr" and "simple-bus".
+       The DCSR space exists in the memory-mapped bus.
+
+       - #address-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+       or representing physical addresses in child nodes.
+
+       - #size-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+       or representing the size of physical addresses in
+       child nodes.
+
+       - ranges
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property. Specifies the physical address
+       range of the DCSR space.
+
+EXAMPLE
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
+=====================================================================
+Event Processing Unit
+
+This node represents the region of DCSR space allocated to the EPU
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr-epu"
+
+       - interrupts
+       Usage: required
+       Value type: <prop_encoded-array>
+       Definition:  Specifies the interrupts generated by the EPU.
+       The value of the interrupts property consists of three
+       interrupt specifiers. The format of the specifier is defined
+       by the binding document describing the node's interrupt parent.
+
+       The EPU counters can be configured to assert the performance
+       monitor interrupt signal based on either counter overflow or value
+       match. Which counter asserted the interrupt is captured in an EPU
+       Counter Interrupt Status Register (EPCPUISR).
+
+       The EPU unit can also be configured to assert either or both of
+       two interrupt signals based on debug event sources within the SoC.
+       The interrupt signals are epu_xt_int0 and epu_xt_int1.
+       Which event source asserted the interrupt is captured in an EPU
+       Interrupt Status Register (EPISR0,EPISR1).
+
+       Interrupt numbers are lised in order (perfmon, event0, event1).
+
+       - interrupt-parent
+       Usage: required
+       Value type: <phandle>
+       Definition: A single <phandle> value that points
+       to the interrupt parent to which the child domain
+       is being mapped. Value must be "&mpic"
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+       dcsr-epu@0 {
+               compatible = "fsl,dcsr-epu";
+               interrupts = <52 2 0 0
+                             84 2 0 0
+                             85 2 0 0>;
+               interrupt-parent = <&mpic>;
+               reg = <0x0 0x1000>;
+       };
+
+=======================================================================
+Nexus Port Controller
+
+This node represents the region of DCSR space allocated to the NPC
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr-npc"
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+       The Nexus Port controller occupies two regions in the DCSR space
+       with distinct functionality.
+
+       The first register range describes the Nexus Port Controller
+       control and status registers.
+
+       The second register range describes the Nexus Port Controller
+       internal trace buffer. The NPC trace buffer is a small memory buffer
+       which stages the nexus trace data for transmission via the Aurora port
+       or to a DDR based trace buffer. In some configurations the NPC trace
+       buffer can be the only trace buffer used.
+
+
+EXAMPLE
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+
+=======================================================================
+Nexus Concentrator
+
+This node represents the region of DCSR space allocated to the NXC
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr-nxc"
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+=======================================================================
+CoreNet Debug Controller
+
+This node represents the region of DCSR space allocated to
+the CoreNet Debug controller.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr-corenet"
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+       The CoreNet Debug controller occupies two regions in the DCSR space
+       with distinct functionality.
+
+       The first register range describes the CoreNet Debug Controller
+       functionalty to perform transaction and transaction attribute matches.
+
+       The second register range describes the CoreNet Debug Controller
+       functionalty to trigger event notifications and debug traces.
+
+EXAMPLE
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+
+=======================================================================
+Data Path Debug controller
+
+This node represents the region of DCSR space allocated to
+the DPAA Debug Controller. This controller controls debug configuration
+for the QMAN and FMAN blocks.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include both an identifier specific to the SoC
+       or Debug IP of the form "fsl,<soc>-dcsr-dpaa" in addition to the
+       generic compatible string "fsl,dcsr-dpaa".
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+
+=======================================================================
+OCeaN Debug controller
+
+This node represents the region of DCSR space allocated to
+the OCN Debug Controller.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include both an identifier specific to the SoC
+       or Debug IP of the form "fsl,<soc>-dcsr-ocn" in addition to the
+       generic compatible string "fsl,dcsr-ocn".
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+
+=======================================================================
+DDR Controller Debug controller
+
+This node represents the region of DCSR space allocated to
+the OCN Debug Controller.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include "fsl,dcsr-ddr"
+
+       - dev-handle
+       Usage: required
+       Definition: A phandle to associate this debug node with its
+       component controller.
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr1>;
+                       reg = <0x12000 0x1000>;
+               };
+
+=======================================================================
+Nexus Aurora Link Controller
+
+This node represents the region of DCSR space allocated to
+the NAL Controller.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include both an identifier specific to the SoC
+       or Debug IP of the form "fsl,<soc>-dcsr-nal" in addition to the
+       generic compatible string "fsl,dcsr-nal".
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-nal@18000 {
+                       compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+
+
+=======================================================================
+Run Control and Power Management
+
+This node represents the region of DCSR space allocated to
+the RCPM Debug Controller. This functionlity is limited to the
+control the debug operations of the SoC and cores.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include both an identifier specific to the SoC
+       or Debug IP of the form "fsl,<soc>-dcsr-rcpm" in addition to the
+       generic compatible string "fsl,dcsr-rcpm".
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+
+=======================================================================
+Core Service Bridge Proxy
+
+This node represents the region of DCSR space allocated to
+the Core Service Bridge Proxies.
+There is one Core Service Bridge Proxy device for each CPU in the system.
+This functionlity provides access to the debug operations of the CPU.
+
+PROPERTIES
+
+       - compatible
+       Usage: required
+       Value type: <string>
+       Definition: Must include both an identifier specific to the cpu
+       of the form "fsl,dcsr-<cpu>-sb-proxy" in addition to the
+       generic compatible string "fsl,dcsr-cpu-sb-proxy".
+
+       - cpu-handle
+       Usage: required
+       Definition: A phandle to associate this debug node with its cpu.
+
+       - reg
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+       offset and length of the DCSR space registers of the device
+       configuration block.
+
+EXAMPLE
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy",
+                                    "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy",
+                                    "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+
+=======================================================================
index 70558c3f3682935e7efddec0ac32371516277132..5d586e1ccaf504d6a6834b38605f864fd168eb23 100644 (file)
@@ -25,6 +25,16 @@ Required properties:
   are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed
   to MPIC.
 
+Optional properties:
+- msi-address-64: 64-bit PCI address of the MSIIR register. The MSIIR register
+  is used for MSI messaging.  The address of MSIIR in PCI address space is
+  the MSI message address.
+
+  This property may be used in virtualized environments where the hypervisor
+  has created an alternate mapping for the MSIR block.  See below for an
+  explanation.
+
+
 Example:
        msi@41600 {
                compatible = "fsl,mpc8610-msi", "fsl,mpic-msi";
@@ -41,3 +51,35 @@ Example:
                        0xe7 0>;
                interrupt-parent = <&mpic>;
        };
+
+The Freescale hypervisor and msi-address-64
+-------------------------------------------
+Normally, PCI devices have access to all of CCSR via an ATMU mapping.  The
+Freescale MSI driver calculates the address of MSIIR (in the MSI register
+block) and sets that address as the MSI message address.
+
+In a virtualized environment, the hypervisor may need to create an IOMMU
+mapping for MSIIR.  The Freescale ePAPR hypervisor has this requirement
+because of hardware limitations of the Peripheral Access Management Unit
+(PAMU), which is currently the only IOMMU that the hypervisor supports.
+The ATMU is programmed with the guest physical address, and the PAMU
+intercepts transactions and reroutes them to the true physical address.
+
+In the PAMU, each PCI controller is given only one primary window.  The
+PAMU restricts DMA operations so that they can only occur within a window.
+Because PCI devices must be able to DMA to memory, the primary window must
+be used to cover all of the guest's memory space.
+
+PAMU primary windows can be divided into 256 subwindows, and each
+subwindow can have its own address mapping ("guest physical" to "true
+physical").  However, each subwindow has to have the same alignment, which
+means they cannot be located at just any address.  Because of these
+restrictions, it is usually impossible to create a 4KB subwindow that
+covers MSIIR where it's normally located.
+
+Therefore, the hypervisor has to create a subwindow inside the same
+primary window used for memory, but mapped to the MSIR block (where MSIIR
+lives).  The first subwindow after the end of guest memory is used for
+this.  The address specified in the msi-address-64 property is the PCI
+address of MSIIR.  The hypervisor configures the PAMU to map that address to
+the true physical address of MSIIR.
index e8552782b440af99ed14a6e851e3db5ed47d05fd..874921e97802d1d8c0e7cc2b694cca4bc3f18bf4 100644 (file)
@@ -33,6 +33,7 @@ qcom  Qualcomm, Inc.
 ramtron        Ramtron International
 samsung        Samsung Semiconductor
 schindler      Schindler
+sil    Silicon Image
 simtek
 sirf   SiRF Technology, Inc.
 stericsson     ST-Ericsson
index 64087c34327fe0ba11e790e0a41224b8e7c1d30c..7671352216f1369d8d3c7dd02f9ae06fd9f90c87 100644 (file)
@@ -63,8 +63,8 @@ IRC network.
 Userspace tools for creating and manipulating Btrfs file systems are
 available from the git repository at the following location:
 
- http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs-unstable.git
- git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs-unstable.git
+ http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs.git
+ git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs.git
 
 These include the following tools:
 
index e9890709c508b25ed9878ab979797d1fc58a7a4b..cdfe13901b99cb64a9bbc2484b13ca7cd174e878 100644 (file)
@@ -1,22 +1,24 @@
 The I2C protocol knows about two kinds of device addresses: normal 7 bit
 addresses, and an extended set of 10 bit addresses. The sets of addresses
 do not intersect: the 7 bit address 0x10 is not the same as the 10 bit
-address 0x10 (though a single device could respond to both of them). You
-select a 10 bit address by adding an extra byte after the address
-byte:
-  S Addr7 Rd/Wr ....
-becomes
-  S 11110 Addr10 Rd/Wr
-S is the start bit, Rd/Wr the read/write bit, and if you count the number
-of bits, you will see the there are 8 after the S bit for 7 bit addresses,
-and 16 after the S bit for 10 bit addresses.
+address 0x10 (though a single device could respond to both of them).
 
-WARNING! The current 10 bit address support is EXPERIMENTAL. There are
-several places in the code that will cause SEVERE PROBLEMS with 10 bit
-addresses, even though there is some basic handling and hooks. Also,
-almost no supported adapter handles the 10 bit addresses correctly.
+I2C messages to and from 10-bit address devices have a different format.
+See the I2C specification for the details.
 
-As soon as a real 10 bit address device is spotted 'in the wild', we
-can and will add proper support. Right now, 10 bit address devices
-are defined by the I2C protocol, but we have never seen a single device
-which supports them.
+The current 10 bit address support is minimal. It should work, however
+you can expect some problems along the way:
+* Not all bus drivers support 10-bit addresses. Some don't because the
+  hardware doesn't support them (SMBus doesn't require 10-bit address
+  support for example), some don't because nobody bothered adding the
+  code (or it's there but not working properly.) Software implementation
+  (i2c-algo-bit) is known to work.
+* Some optional features do not support 10-bit addresses. This is the
+  case of automatic detection and instantiation of devices by their,
+  drivers, for example.
+* Many user-space packages (for example i2c-tools) lack support for
+  10-bit addresses.
+
+Note that 10-bit address devices are still pretty rare, so the limitations
+listed above could stay for a long time, maybe even forever if nobody
+needs them to be fixed.
index a0c5c5f4fce6e9587346a4a049c9725e5ca45de5..81c287fad79d6370d0d697d5ddf33b8af756a036 100644 (file)
@@ -315,12 +315,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        CPU-intensive style benchmark, and it can vary highly in
                        a microbenchmark depending on workload and compiler.
 
-                       1: only for 32-bit processes
-                       2: only for 64-bit processes
+                       32: only for 32-bit processes
+                       64: only for 64-bit processes
                        on: enable for both 32- and 64-bit processes
                        off: disable for both 32- and 64-bit processes
 
-       amd_iommu=      [HW,X86-84]
+       amd_iommu=      [HW,X86-64]
                        Pass parameters to the AMD IOMMU driver in the system.
                        Possible values are:
                        fullflush - enable flushing of IO/TLB entries when
index cb7f3148035dbeaabbcc514ddf53705733321d66..589f2da5d5454dd96f828c01168aecb84770473f 100644 (file)
@@ -20,7 +20,7 @@ ip_no_pmtu_disc - BOOLEAN
        default FALSE
 
 min_pmtu - INTEGER
-       default 562 - minimum discovered Path MTU
+       default 552 - minimum discovered Path MTU
 
 route/max_size - INTEGER
        Maximum number of routes allowed in the kernel.  Increase
@@ -282,11 +282,11 @@ tcp_max_ssthresh - INTEGER
        Default: 0 (off)
 
 tcp_max_syn_backlog - INTEGER
-       Maximal number of remembered connection requests, which are
-       still did not receive an acknowledgment from connecting client.
-       Default value is 1024 for systems with more than 128Mb of memory,
-       and 128 for low memory machines. If server suffers of overload,
-       try to increase this number.
+       Maximal number of remembered connection requests, which have not
+       received an acknowledgment from connecting client.
+       The minimal value is 128 for low memory machines, and it will
+       increase in proportion to the memory of machine.
+       If server suffers from overload, try increasing this number.
 
 tcp_max_tw_buckets - INTEGER
        Maximal number of timewait sockets held by system simultaneously.
index 6fe9001b92634ec306a745d5842883640db79597..13032c0140d430b3bc15a5e4a5771eecfc208f4e 100644 (file)
@@ -263,6 +263,8 @@ characters, each representing a particular tainted value.
  12: 'I' if the kernel is working around a severe bug in the platform
      firmware (BIOS or similar).
 
+ 13: 'O' if an externally-built ("out-of-tree") module has been loaded.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent: even if an offending module is
index 646a89e0c07d50c682912ef0200dc087363cd37f..3139fb505dcec97cb609e02326110e8b5725a43a 100644 (file)
@@ -123,9 +123,10 @@ please refer directly to the source code for more information about it.
 Subsystem-Level Methods
 -----------------------
 The core methods to suspend and resume devices reside in struct dev_pm_ops
-pointed to by the pm member of struct bus_type, struct device_type and
-struct class.  They are mostly of interest to the people writing infrastructure
-for buses, like PCI or USB, or device type and device class drivers.
+pointed to by the ops member of struct dev_pm_domain, or by the pm member of
+struct bus_type, struct device_type and struct class.  They are mostly of
+interest to the people writing infrastructure for platforms and buses, like PCI
+or USB, or device type and device class drivers.
 
 Bus drivers implement these methods as appropriate for the hardware and the
 drivers using it; PCI works differently from USB, and so on.  Not many people
@@ -139,41 +140,57 @@ sequencing in the driver model tree.
 
 /sys/devices/.../power/wakeup files
 -----------------------------------
-All devices in the driver model have two flags to control handling of wakeup
-events (hardware signals that can force the device and/or system out of a low
-power state).  These flags are initialized by bus or device driver code using
+All device objects in the driver model contain fields that control the handling
+of system wakeup events (hardware signals that can force the system out of a
+sleep state).  These fields are initialized by bus or device driver code using
 device_set_wakeup_capable() and device_set_wakeup_enable(), defined in
 include/linux/pm_wakeup.h.
 
-The "can_wakeup" flag just records whether the device (and its driver) can
+The "power.can_wakeup" flag just records whether the device (and its driver) can
 physically support wakeup events.  The device_set_wakeup_capable() routine
-affects this flag.  The "should_wakeup" flag controls whether the device should
-try to use its wakeup mechanism.  device_set_wakeup_enable() affects this flag;
-for the most part drivers should not change its value.  The initial value of
-should_wakeup is supposed to be false for the majority of devices; the major
-exceptions are power buttons, keyboards, and Ethernet adapters whose WoL
-(wake-on-LAN) feature has been set up with ethtool.  It should also default
-to true for devices that don't generate wakeup requests on their own but merely
-forward wakeup requests from one bus to another (like PCI bridges).
+affects this flag.  The "power.wakeup" field is a pointer to an object of type
+struct wakeup_source used for controlling whether or not the device should use
+its system wakeup mechanism and for notifying the PM core of system wakeup
+events signaled by the device.  This object is only present for wakeup-capable
+devices (i.e. devices whose "can_wakeup" flags are set) and is created (or
+removed) by device_set_wakeup_capable().
 
 Whether or not a device is capable of issuing wakeup events is a hardware
 matter, and the kernel is responsible for keeping track of it.  By contrast,
 whether or not a wakeup-capable device should issue wakeup events is a policy
 decision, and it is managed by user space through a sysfs attribute: the
-power/wakeup file.  User space can write the strings "enabled" or "disabled" to
-set or clear the "should_wakeup" flag, respectively.  This file is only present
-for wakeup-capable devices (i.e. devices whose "can_wakeup" flags are set)
-and is created (or removed) by device_set_wakeup_capable().  Reads from the
-file will return the corresponding string.
-
-The device_may_wakeup() routine returns true only if both flags are set.
+"power/wakeup" file.  User space can write the strings "enabled" or "disabled"
+to it to indicate whether or not, respectively, the device is supposed to signal
+system wakeup.  This file is only present if the "power.wakeup" object exists
+for the given device and is created (or removed) along with that object, by
+device_set_wakeup_capable().  Reads from the file will return the corresponding
+string.
+
+The "power/wakeup" file is supposed to contain the "disabled" string initially
+for the majority of devices; the major exceptions are power buttons, keyboards,
+and Ethernet adapters whose WoL (wake-on-LAN) feature has been set up with
+ethtool.  It should also default to "enabled" for devices that don't generate
+wakeup requests on their own but merely forward wakeup requests from one bus to
+another (like PCI Express ports).
+
+The device_may_wakeup() routine returns true only if the "power.wakeup" object
+exists and the corresponding "power/wakeup" file contains the string "enabled".
 This information is used by subsystems, like the PCI bus type code, to see
 whether or not to enable the devices' wakeup mechanisms.  If device wakeup
 mechanisms are enabled or disabled directly by drivers, they also should use
 device_may_wakeup() to decide what to do during a system sleep transition.
-However for runtime power management, wakeup events should be enabled whenever
-the device and driver both support them, regardless of the should_wakeup flag.
-
+Device drivers, however, are not supposed to call device_set_wakeup_enable()
+directly in any case.
+
+It ought to be noted that system wakeup is conceptually different from "remote
+wakeup" used by runtime power management, although it may be supported by the
+same physical mechanism.  Remote wakeup is a feature allowing devices in
+low-power states to trigger specific interrupts to signal conditions in which
+they should be put into the full-power state.  Those interrupts may or may not
+be used to signal system wakeup events, depending on the hardware design.  On
+some systems it is impossible to trigger them from system sleep states.  In any
+case, remote wakeup should always be enabled for runtime power management for
+all devices and drivers that support it.
 
 /sys/devices/.../power/control files
 ------------------------------------
@@ -249,20 +266,31 @@ for every device before the next phase begins.  Not all busses or classes
 support all these callbacks and not all drivers use all the callbacks.  The
 various phases always run after tasks have been frozen and before they are
 unfrozen.  Furthermore, the *_noirq phases run at a time when IRQ handlers have
-been disabled (except for those marked with the IRQ_WAKEUP flag).
-
-All phases use bus, type, or class callbacks (that is, methods defined in
-dev->bus->pm, dev->type->pm, or dev->class->pm).  These callbacks are mutually
-exclusive, so if the device type provides a struct dev_pm_ops object pointed to
-by its pm field (i.e. both dev->type and dev->type->pm are defined), the
-callbacks included in that object (i.e. dev->type->pm) will be used.  Otherwise,
-if the class provides a struct dev_pm_ops object pointed to by its pm field
-(i.e. both dev->class and dev->class->pm are defined), the PM core will use the
-callbacks from that object (i.e. dev->class->pm).  Finally, if the pm fields of
-both the device type and class objects are NULL (or those objects do not exist),
-the callbacks provided by the bus (that is, the callbacks from dev->bus->pm)
-will be used (this allows device types to override callbacks provided by bus
-types or classes if necessary).
+been disabled (except for those marked with the IRQF_NO_SUSPEND flag).
+
+All phases use PM domain, bus, type, or class callbacks (that is, methods
+defined in dev->pm_domain->ops, dev->bus->pm, dev->type->pm, or dev->class->pm).
+These callbacks are regarded by the PM core as mutually exclusive.  Moreover,
+PM domain callbacks always take precedence over bus, type and class callbacks,
+while type callbacks take precedence over bus and class callbacks, and class
+callbacks take precedence over bus callbacks.  To be precise, the following
+rules are used to determine which callback to execute in the given phase:
+
+    1. If dev->pm_domain is present, the PM core will attempt to execute the
+       callback included in dev->pm_domain->ops.  If that callback is not
+       present, no action will be carried out for the given device.
+
+    2. Otherwise, if both dev->type and dev->type->pm are present, the callback
+       included in dev->type->pm will be executed.
+
+    3. Otherwise, if both dev->class and dev->class->pm are present, the
+       callback included in dev->class->pm will be executed.
+
+    4. Otherwise, if both dev->bus and dev->bus->pm are present, the callback
+       included in dev->bus->pm will be executed.
+
+This allows PM domains and device types to override callbacks provided by bus
+types or device classes if necessary.
 
 These callbacks may in turn invoke device- or driver-specific methods stored in
 dev->driver->pm, but they don't have to.
@@ -283,9 +311,8 @@ When the system goes into the standby or memory sleep state, the phases are:
 
        After the prepare callback method returns, no new children may be
        registered below the device.  The method may also prepare the device or
-       driver in some way for the upcoming system power transition (for
-       example, by allocating additional memory required for this purpose), but
-       it should not put the device into a low-power state.
+       driver in some way for the upcoming system power transition, but it
+       should not put the device into a low-power state.
 
     2. The suspend methods should quiesce the device to stop it from performing
        I/O.  They also may save the device registers and put it into the
index 38b57248fd61f5755528837145052c5c998c17b7..316c2ba187f49980a96a80ec460510013c5aacdb 100644 (file)
@@ -22,12 +22,12 @@ try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
 either wakes them up, if they are kernel threads, or sends fake signals to them,
 if they are user space processes.  A task that has TIF_FREEZE set, should react
 to it by calling the function called refrigerator() (defined in
-kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
+kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state
 to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
 Then, we say that the task is 'frozen' and therefore the set of functions
 handling this mechanism is referred to as 'the freezer' (these functions are
-defined in kernel/power/process.c and include/linux/freezer.h).  User space
-processes are generally frozen before kernel threads.
+defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h).
+User space processes are generally frozen before kernel threads.
 
 It is not recommended to call refrigerator() directly.  Instead, it is
 recommended 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
 additional memory and we prevent them from doing that by freezing them earlier.
 [Of course, this also means that device drivers should not allocate substantial
 amounts of memory from their .suspend() callbacks before hibernation, but this
-is e separate issue.]
+is a separate issue.]
 
 3. The third reason is to prevent user space processes and some kernel threads
 from interfering with the suspending and resuming of devices.  A user space
index 0e856088db7c87b66d2284aaabb03501bea95415..c2ae8bf77d46d6fbd12490a6a9aacc14c11c4931 100644 (file)
@@ -44,25 +44,33 @@ struct dev_pm_ops {
 };
 
 The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks
-are executed by the PM core for either the power domain, or the device type
-(if the device power domain's struct dev_pm_ops does not exist), or the class
-(if the device power domain's and type's struct dev_pm_ops object does not
-exist), or the bus type (if the device power domain's, type's and class'
-struct dev_pm_ops objects do not exist) of the given device, so the priority
-order of callbacks from high to low is that power domain callbacks, device
-type callbacks, class callbacks and bus type callbacks, and the high priority
-one will take precedence over low priority one. The bus type, device type and
-class callbacks are referred to as subsystem-level callbacks in what follows,
-and generally speaking, the power domain callbacks are used for representing
-power domains within a SoC.
+are executed by the PM core for the device's subsystem that may be either of
+the following:
+
+  1. PM domain of the device, if the device's PM domain object, dev->pm_domain,
+     is present.
+
+  2. Device type of the device, if both dev->type and dev->type->pm are present.
+
+  3. Device class of the device, if both dev->class and dev->class->pm are
+     present.
+
+  4. Bus type of the device, if both dev->bus and dev->bus->pm are present.
+
+The PM core always checks which callback to use in the order given above, so the
+priority order of callbacks from high to low is: PM domain, device type, class
+and bus type.  Moreover, the high-priority one will always take precedence over
+a low-priority one.  The PM domain, bus type, device type and class callbacks
+are referred to as subsystem-level callbacks in what follows.
 
 By default, the callbacks are always invoked in process context with interrupts
 enabled.  However, subsystems can use the pm_runtime_irq_safe() helper function
-to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume()
-callbacks should be invoked in atomic context with interrupts disabled.
-This implies that these callback routines must not block or sleep, but it also
-means that the synchronous helper functions listed at the end of Section 4 can
-be used within an interrupt handler or in an atomic context.
+to tell the PM core that their ->runtime_suspend(), ->runtime_resume() and
+->runtime_idle() callbacks may be invoked in atomic context with interrupts
+disabled for a given device.  This implies that the callback routines in
+question must not block or sleep, but it also means that the synchronous helper
+functions listed at the end of Section 4 may be used for that device within an
+interrupt handler or generally in an atomic context.
 
 The subsystem-level suspend callback is _entirely_ _responsible_ for handling
 the suspend of the device as appropriate, which may, but need not include
@@ -789,6 +797,16 @@ will behave normally, not taking the autosuspend delay into account.
 Similarly, if the power.use_autosuspend field isn't set then the autosuspend
 helper functions will behave just like the non-autosuspend counterparts.
 
+Under some circumstances a driver or subsystem may want to prevent a device
+from autosuspending immediately, even though the usage counter is zero and the
+autosuspend delay time has expired.  If the ->runtime_suspend() callback
+returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
+in the future (as it normally would be if the callback invoked
+pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
+autosuspend.  The ->runtime_suspend() callback can't do this rescheduling
+itself because no suspend requests of any kind are accepted while the device is
+suspending (i.e., while the callback is running).
+
 The implementation is well suited for asynchronous use in interrupt contexts.
 However such use inevitably involves races, because the PM core can't
 synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
index 079cb3df62cf6ff9908bebe493344d1cfdd99846..41c8378c0b2fb9ee86d3a781e8aaff6cad33ff9a 100644 (file)
 
        struct serial_rs485 rs485conf;
 
-       /* Set RS485 mode: */
+       /* Enable RS485 mode: */
        rs485conf.flags |= SER_RS485_ENABLED;
 
+       /* Set logical level for RTS pin equal to 1 when sending: */
+       rs485conf.flags |= SER_RS485_RTS_ON_SEND;
+       /* or, set logical level for RTS pin equal to 0 when sending: */
+       rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
+
+       /* Set logical level for RTS pin equal to 1 after sending: */
+       rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
+       /* or, set logical level for RTS pin equal to 0 after sending: */
+       rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
+
        /* Set rts delay before send, if needed: */
-       rs485conf.flags |= SER_RS485_RTS_BEFORE_SEND;
        rs485conf.delay_rts_before_send = ...;
 
        /* Set rts delay after send, if needed: */
-       rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
        rs485conf.delay_rts_after_send = ...;
 
        /* Set this flag if you want to receive data even whilst sending data */
index 4f3443230d896b92c6a5aa7b37dfd5b63e272d9b..edad99abec215d4412d139a46b5cee8a8493ca43 100644 (file)
@@ -349,6 +349,7 @@ STAC92HD83*
   ref          Reference board
   mic-ref      Reference board with power management for ports
   dell-s14     Dell laptop
+  dell-vostro-3500     Dell Vostro 3500 laptop
   hp           HP laptops with (inverted) mute-LED
   hp-dv7-4000  HP dv-7 4000
   auto         BIOS setup (default)
index 03e2771ddeef53545357cc4bfbde29a378f9206d..91fee3b45fb80f75ac406dfbba093f1f49a418c1 100644 (file)
@@ -579,7 +579,7 @@ Development Tree
 ~~~~~~~~~~~~~~~~
 The latest development codes for HD-audio are found on sound git tree:
 
-- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
+- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
 
 The master branch or for-next branches can be used as the main
 development branches in general while the HD-audio specific patches
@@ -594,7 +594,7 @@ is, installed via the usual spells: configure, make and make
 install(-modules).  See INSTALL in the package.  The snapshot tarballs
 are found at:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/snapshot/
+- ftp://ftp.suse.com/pub/people/tiwai/snapshot/
 
 
 Sending a Bug Report
@@ -696,7 +696,7 @@ via hda-verb won't change the mixer value.
 
 The hda-verb program is found in the ftp directory:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
+- ftp://ftp.suse.com/pub/people/tiwai/misc/
 
 Also a git repository is available:
 
@@ -764,7 +764,7 @@ operation, the jack plugging simulation, etc.
 
 The package is found in:
 
-- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/
+- ftp://ftp.suse.com/pub/people/tiwai/misc/
 
 A git repository is available:
 
index 3e2ec9cbf3976d0d21c6ee90d7fe075a210a33eb..d50c14df34112ed2095942062bcaab90d90697bd 100644 (file)
@@ -50,8 +50,7 @@ Machine DAI Configuration
 The machine DAI configuration glues all the codec and CPU DAIs together. It can
 also be used to set up the DAI system clock and for any machine related DAI
 initialisation e.g. the machine audio map can be connected to the codec audio
-map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c
-for examples.
+map, unconnected codec pins can be set as such.
 
 struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.
 
@@ -83,8 +82,7 @@ Machine Power Map
 The machine driver can optionally extend the codec power map and to become an
 audio power map of the audio subsystem. This allows for automatic power up/down
 of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack
-sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for
-details.
+sockets in the machine init function.
 
 
 Machine Controls
index 37a02ce5484176670fde42a5bb915427316587f3..f0ffc27d4c0ac9d52efa62ecc0f775fd877b7387 100644 (file)
@@ -90,10 +90,10 @@ ServiceBinary=%12%\USBSER.sys
 [SourceDisksFiles]
 [SourceDisksNames]
 [DeviceList]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
 
 [DeviceList.NTamd64]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
 
 
 ;------------------------------------------------------------------------------
diff --git a/Documentation/watchdog/convert_drivers_to_kernel_api.txt b/Documentation/watchdog/convert_drivers_to_kernel_api.txt
new file mode 100644 (file)
index 0000000..ae1e900
--- /dev/null
@@ -0,0 +1,195 @@
+Converting old watchdog drivers to the watchdog framework
+by Wolfram Sang <w.sang@pengutronix.de>
+=========================================================
+
+Before the watchdog framework came into the kernel, every driver had to
+implement the API on its own. Now, as the framework factored out the common
+components, those drivers can be lightened making it a user of the framework.
+This document shall guide you for this task. The necessary steps are described
+as well as things to look out for.
+
+
+Remove the file_operations struct
+---------------------------------
+
+Old drivers define their own file_operations for actions like open(), write(),
+etc... These are now handled by the framework and just call the driver when
+needed. So, in general, the 'file_operations' struct and assorted functions can
+go. Only very few driver-specific details have to be moved to other functions.
+Here is a overview of the functions and probably needed actions:
+
+- open: Everything dealing with resource management (file-open checks, magic
+  close preparations) can simply go. Device specific stuff needs to go to the
+  driver specific start-function. Note that for some drivers, the start-function
+  also serves as the ping-function. If that is the case and you need start/stop
+  to be balanced (clocks!), you are better off refactoring a separate start-function.
+
+- close: Same hints as for open apply.
+
+- write: Can simply go, all defined behaviour is taken care of by the framework,
+  i.e. ping on write and magic char ('V') handling.
+
+- ioctl: While the driver is allowed to have extensions to the IOCTL interface,
+  the most common ones are handled by the framework, supported by some assistance
+  from the driver:
+
+       WDIOC_GETSUPPORT:
+               Returns the mandatory watchdog_info struct from the driver
+
+       WDIOC_GETSTATUS:
+               Needs the status-callback defined, otherwise returns 0
+
+       WDIOC_GETBOOTSTATUS:
+               Needs the bootstatus member properly set. Make sure it is 0 if you
+               don't have further support!
+
+       WDIOC_SETOPTIONS:
+               No preparations needed
+
+       WDIOC_KEEPALIVE:
+               If wanted, options in watchdog_info need to have WDIOF_KEEPALIVEPING
+               set
+
+       WDIOC_SETTIMEOUT:
+               Options in watchdog_info need to have WDIOF_SETTIMEOUT set
+               and a set_timeout-callback has to be defined. The core will also
+               do limit-checking, if min_timeout and max_timeout in the watchdog
+               device are set. All is optional.
+
+       WDIOC_GETTIMEOUT:
+               No preparations needed
+
+  Other IOCTLs can be served using the ioctl-callback. Note that this is mainly
+  intended for porting old drivers; new drivers should not invent private IOCTLs.
+  Private IOCTLs are processed first. When the callback returns with
+  -ENOIOCTLCMD, the IOCTLs of the framework will be tried, too. Any other error
+  is directly given to the user.
+
+Example conversion:
+
+-static const struct file_operations s3c2410wdt_fops = {
+-       .owner          = THIS_MODULE,
+-       .llseek         = no_llseek,
+-       .write          = s3c2410wdt_write,
+-       .unlocked_ioctl = s3c2410wdt_ioctl,
+-       .open           = s3c2410wdt_open,
+-       .release        = s3c2410wdt_release,
+-};
+
+Check the functions for device-specific stuff and keep it for later
+refactoring. The rest can go.
+
+
+Remove the miscdevice
+---------------------
+
+Since the file_operations are gone now, you can also remove the 'struct
+miscdevice'. The framework will create it on watchdog_dev_register() called by
+watchdog_register_device().
+
+-static struct miscdevice s3c2410wdt_miscdev = {
+-       .minor          = WATCHDOG_MINOR,
+-       .name           = "watchdog",
+-       .fops           = &s3c2410wdt_fops,
+-};
+
+
+Remove obsolete includes and defines
+------------------------------------
+
+Because of the simplifications, a few defines are probably unused now. Remove
+them. Includes can be removed, too. For example:
+
+- #include <linux/fs.h>
+- #include <linux/miscdevice.h> (if MODULE_ALIAS_MISCDEV is not used)
+- #include <linux/uaccess.h> (if no custom IOCTLs are used)
+
+
+Add the watchdog operations
+---------------------------
+
+All possible callbacks are defined in 'struct watchdog_ops'. You can find it
+explained in 'watchdog-kernel-api.txt' in this directory. start(), stop() and
+owner must be set, the rest are optional. You will easily find corresponding
+functions in the old driver. Note that you will now get a pointer to the
+watchdog_device as a parameter to these functions, so you probably have to
+change the function header. Other changes are most likely not needed, because
+here simply happens the direct hardware access. If you have device-specific
+code left from the above steps, it should be refactored into these callbacks.
+
+Here is a simple example:
+
++static struct watchdog_ops s3c2410wdt_ops = {
++       .owner = THIS_MODULE,
++       .start = s3c2410wdt_start,
++       .stop = s3c2410wdt_stop,
++       .ping = s3c2410wdt_keepalive,
++       .set_timeout = s3c2410wdt_set_heartbeat,
++};
+
+A typical function-header change looks like:
+
+-static void s3c2410wdt_keepalive(void)
++static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
+ {
+...
++
++       return 0;
+ }
+
+...
+
+-       s3c2410wdt_keepalive();
++       s3c2410wdt_keepalive(&s3c2410_wdd);
+
+
+Add the watchdog device
+-----------------------
+
+Now we need to create a 'struct watchdog_device' and populate it with the
+necessary information for the framework. The struct is also explained in detail
+in 'watchdog-kernel-api.txt' in this directory. We pass it the mandatory
+watchdog_info struct and the newly created watchdog_ops. Often, old drivers
+have their own record-keeping for things like bootstatus and timeout using
+static variables. Those have to be converted to use the members in
+watchdog_device. Note that the timeout values are unsigned int. Some drivers
+use signed int, so this has to be converted, too.
+
+Here is a simple example for a watchdog device:
+
++static struct watchdog_device s3c2410_wdd = {
++       .info = &s3c2410_wdt_ident,
++       .ops = &s3c2410wdt_ops,
++};
+
+
+Register the watchdog device
+----------------------------
+
+Replace misc_register(&miscdev) with watchdog_register_device(&watchdog_dev).
+Make sure the return value gets checked and the error message, if present,
+still fits. Also convert the unregister case.
+
+-       ret = misc_register(&s3c2410wdt_miscdev);
++       ret = watchdog_register_device(&s3c2410_wdd);
+
+...
+
+-       misc_deregister(&s3c2410wdt_miscdev);
++       watchdog_unregister_device(&s3c2410_wdd);
+
+
+Update the Kconfig-entry
+------------------------
+
+The entry for the driver now needs to select WATCHDOG_CORE:
+
++       select WATCHDOG_CORE
+
+
+Create a patch and send it to upstream
+--------------------------------------
+
+Make sure you understood Documentation/SubmittingPatches and send your patch to
+linux-watchdog@vger.kernel.org. We are looking forward to it :)
+
diff --git a/Kbuild b/Kbuild
index 2114113ceca2801770c57ac07c78fff2b0b8a477..b8b708ad6dc3815eb0d23bfea2c972d03b9477c0 100644 (file)
--- a/Kbuild
+++ b/Kbuild
@@ -88,11 +88,13 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
 # 3) Check for missing system calls
 #
 
+always += missing-syscalls
+targets += missing-syscalls
+
 quiet_cmd_syscalls = CALL    $<
-      cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags)
+      cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags)
 
-PHONY += missing-syscalls
-missing-syscalls: scripts/checksyscalls.sh FORCE
+missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE
        $(call cmd,syscalls)
 
 # Keep these two files during make clean
index a6afe342f0fc767fb4b90bb48a37786bc1ade371..b9db108f01c8ae2d27575ae73bb0206e361c028c 100644 (file)
@@ -511,8 +511,8 @@ M:  Joerg Roedel <joerg.roedel@amd.com>
 L:     iommu@lists.linux-foundation.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
 S:     Supported
-F:     arch/x86/kernel/amd_iommu*.c
-F:     arch/x86/include/asm/amd_iommu*.h
+F:     drivers/iommu/amd_iommu*.[ch]
+F:     include/linux/amd-iommu.h
 
 AMD MICROCODE UPDATE SUPPORT
 M:     Andreas Herrmann <andreas.herrmann3@amd.com>
@@ -789,6 +789,7 @@ L:  linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 T:     git git://git.pengutronix.de/git/imx/linux-2.6.git
 F:     arch/arm/mach-mx*/
+F:     arch/arm/mach-imx/
 F:     arch/arm/plat-mxc/
 
 ARM/FREESCALE IMX51
@@ -804,6 +805,13 @@ S: Maintained
 T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
 F:     arch/arm/mach-imx/*imx6*
 
+ARM/FREESCALE MXS ARM ARCHITECTURE
+M:     Shawn Guo <shawn.guo@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+T:     git git://git.linaro.org/people/shawnguo/linux-2.6.git
+F:     arch/arm/mach-mxs/
+
 ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1032,6 +1040,7 @@ F:        arch/arm/include/asm/hardware/ioc.h
 F:     arch/arm/include/asm/hardware/iomd.h
 F:     arch/arm/include/asm/hardware/memc.h
 F:     arch/arm/mach-rpc/
+F:     drivers/net/ethernet/8390/etherh.c
 F:     drivers/net/ethernet/i825xx/ether1*
 F:     drivers/net/ethernet/seeq/ether3*
 F:     drivers/scsi/arm/
@@ -1045,35 +1054,18 @@ ARM/SAMSUNG ARM ARCHITECTURES
 M:     Ben Dooks <ben-linux@fluff.org>
 M:     Kukjin Kim <kgene.kim@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 W:     http://www.fluff.org/ben/linux/
 S:     Maintained
 F:     arch/arm/plat-samsung/
 F:     arch/arm/plat-s3c24xx/
 F:     arch/arm/plat-s5p/
+F:     arch/arm/mach-s3c24*/
+F:     arch/arm/mach-s3c64xx/
 F:     drivers/*/*s3c2410*
 F:     drivers/*/*/*s3c2410*
-
-ARM/S3C2410 ARM ARCHITECTURE
-M:     Ben Dooks <ben-linux@fluff.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.fluff.org/ben/linux/
-S:     Maintained
-F:     arch/arm/mach-s3c2410/
-
-ARM/S3C244x ARM ARCHITECTURE
-M:     Ben Dooks <ben-linux@fluff.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.fluff.org/ben/linux/
-S:     Maintained
-F:     arch/arm/mach-s3c2440/
-F:     arch/arm/mach-s3c2443/
-
-ARM/S3C64xx ARM ARCHITECTURE
-M:     Ben Dooks <ben-linux@fluff.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.fluff.org/ben/linux/
-S:     Maintained
-F:     arch/arm/mach-s3c64xx/
+F:     drivers/spi/spi-s3c*
+F:     sound/soc/samsung/*
 
 ARM/S5P EXYNOS ARM ARCHITECTURES
 M:     Kukjin Kim <kgene.kim@samsung.com>
@@ -1105,6 +1097,7 @@ F:        drivers/media/video/s5p-fimc/
 ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
 M:     Kyungmin Park <kyungmin.park@samsung.com>
 M:     Kamil Debski <k.debski@samsung.com>
+M:     Jeongtae Park <jtp.park@samsung.com>
 L:     linux-arm-kernel@lists.infradead.org
 L:     linux-media@vger.kernel.org
 S:     Maintained
@@ -1787,6 +1780,14 @@ F:       include/net/cfg80211.h
 F:     net/wireless/*
 X:     net/wireless/wext*
 
+CHAR and MISC DRIVERS
+M:     Arnd Bergmann <arnd@arndb.de>
+M:     Greg Kroah-Hartman <greg@kroah.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
+S:     Maintained
+F:     drivers/char/*
+F:     drivers/misc/*
+
 CHECKPATCH
 M:     Andy Whitcroft <apw@canonical.com>
 S:     Supported
@@ -1925,9 +1926,11 @@ S:       Maintained
 F:     drivers/connector/
 
 CONTROL GROUPS (CGROUPS)
-M:     Paul Menage <paul@paulmenage.org>
+M:     Tejun Heo <tj@kernel.org>
 M:     Li Zefan <lizf@cn.fujitsu.com>
 L:     containers@lists.linux-foundation.org
+L:     cgroups@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git
 S:     Maintained
 F:     include/linux/cgroup*
 F:     kernel/cgroup*
@@ -2341,6 +2344,13 @@ S:       Supported
 F:     drivers/gpu/drm/i915
 F:     include/drm/i915*
 
+DRM DRIVERS FOR EXYNOS
+M:     Inki Dae <inki.dae@samsung.com>
+L:     dri-devel@lists.freedesktop.org
+S:     Supported
+F:     drivers/gpu/drm/exynos
+F:     include/drm/exynos*
+
 DSCC4 DRIVER
 M:     Francois Romieu <romieu@fr.zoreil.com>
 L:     netdev@vger.kernel.org
@@ -2387,7 +2397,7 @@ F:        include/linux/netfilter_bridge/ebt_*.h
 F:     net/bridge/netfilter/ebt*.c
 
 ECRYPT FILE SYSTEM
-M:     Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+M:     Tyler Hicks <tyhicks@canonical.com>
 M:     Dustin Kirkland <kirkland@canonical.com>
 L:     ecryptfs@vger.kernel.org
 W:     https://launchpad.net/ecryptfs
@@ -2575,7 +2585,7 @@ S:        Maintained
 F:     drivers/net/ethernet/i825xx/eexpress.*
 
 ETHERNET BRIDGE
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     bridge@lists.linux-foundation.org
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net:Bridge
@@ -3709,7 +3719,7 @@ F:        fs/jbd2/
 F:     include/linux/jbd2.h
 
 JSM Neo PCI based serial card
-M:     Breno Leitao <leitao@linux.vnet.ibm.com>
+M:     Lucas Tavares <lucaskt@linux.vnet.ibm.com>
 L:     linux-serial@vger.kernel.org
 S:     Maintained
 F:     drivers/tty/serial/jsm/
@@ -4292,9 +4302,11 @@ F:       include/linux/mm.h
 F:     mm/
 
 MEMORY RESOURCE CONTROLLER
+M:     Johannes Weiner <hannes@cmpxchg.org>
+M:     Michal Hocko <mhocko@suse.cz>
 M:     Balbir Singh <bsingharora@gmail.com>
-M:     Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
 M:     KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+L:     cgroups@vger.kernel.org
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     mm/memcontrol.c
@@ -4328,7 +4340,7 @@ MIPS
 M:     Ralf Baechle <ralf@linux-mips.org>
 L:     linux-mips@linux-mips.org
 W:     http://www.linux-mips.org/
-T:     git git://git.linux-mips.org/pub/scm/linux.git
+T:     git git://git.linux-mips.org/pub/scm/ralf/linux.git
 Q:     http://patchwork.linux-mips.org/project/linux-mips/list/
 S:     Supported
 F:     Documentation/mips/
@@ -4461,7 +4473,7 @@ S:        Supported
 F:     drivers/infiniband/hw/nes/
 
 NETEM NETWORK EMULATOR
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     netem@lists.linux-foundation.org
 S:     Maintained
 F:     net/sched/sch_netem.c
@@ -4672,7 +4684,7 @@ L:        linux-omap@vger.kernel.org
 W:     http://www.muru.com/linux/omap/
 W:     http://linux.omap.com/
 Q:     http://patchwork.kernel.org/project/linux-omap/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
 S:     Maintained
 F:     arch/arm/*omap*/
 
@@ -4938,7 +4950,7 @@ F:        drivers/char/ppdev.c
 F:     include/linux/ppdev.h
 
 PARAVIRT_OPS INTERFACE
-M:     Jeremy Fitzhardinge <jeremy@xensource.com>
+M:     Jeremy Fitzhardinge <jeremy@goop.org>
 M:     Chris Wright <chrisw@sous-sol.org>
 M:     Alok Kataria <akataria@vmware.com>
 M:     Rusty Russell <rusty@rustcorp.com.au>
@@ -5470,7 +5482,7 @@ S:        Maintained
 F:     drivers/net/ethernet/rdc/r6040.c
 
 RDS - RELIABLE DATAGRAM SOCKETS
-M:     Andy Grover <andy.grover@oracle.com>
+M:     Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
 L:     rds-devel@oss.oracle.com (moderated for non-subscribers)
 S:     Supported
 F:     net/rds/
@@ -5647,7 +5659,6 @@ F:        drivers/media/video/*7146*
 F:     include/media/*7146*
 
 SAMSUNG AUDIO (ASoC) DRIVERS
-M:     Jassi Brar <jassisinghbrar@gmail.com>
 M:     Sangbeom Kim <sbkim73@samsung.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
@@ -5976,7 +5987,7 @@ S:        Maintained
 F:     drivers/usb/misc/sisusbvga/
 
 SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
-M:     Stephen Hemminger <shemminger@linux-foundation.org>
+M:     Stephen Hemminger <shemminger@vyatta.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/marvell/sk*
@@ -6121,7 +6132,7 @@ F:        sound/
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
 M:     Liam Girdwood <lrg@ti.com>
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 W:     http://alsa-project.org/main/index.php/ASoC
 S:     Supported
@@ -7390,8 +7401,8 @@ S:        Maintained
 F:     arch/x86/kernel/cpu/mcheck/*
 
 XEN HYPERVISOR INTERFACE
-M:     Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+M:     Jeremy Fitzhardinge <jeremy@goop.org>
 L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
 L:     virtualization@lists.linux-foundation.org
 S:     Supported
@@ -7424,7 +7435,8 @@ F:        drivers/xen/*swiotlb*
 
 XFS FILESYSTEM
 P:     Silicon Graphics Inc
-M:     Alex Elder <aelder@sgi.com>
+M:     Ben Myers <bpm@sgi.com>
+M:     Alex Elder <elder@kernel.org>
 M:     xfs-masters@oss.sgi.com
 L:     xfs@oss.sgi.com
 W:     http://oss.sgi.com/projects/xfs
index 07bc92544e9cab9ea9fd201b8a5f36fb9dbb9168..d1ea73f74c2f42b2c4297fc6d45b75e38d561853 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 3
-PATCHLEVEL = 1
+PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION =
-NAME = "Divemaster Edition"
+EXTRAVERSION = -rc5
+NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -983,7 +983,6 @@ archprepare: prepare1 scripts_basic
 
 prepare0: archprepare FORCE
        $(Q)$(MAKE) $(build)=.
-       $(Q)$(MAKE) $(build)=. missing-syscalls
 
 # All the preparing..
 prepare: prepare0
@@ -1198,7 +1197,7 @@ distclean: mrproper
        @find $(srctree) $(RCS_FIND_IGNORE) \
                \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
                -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-               -o -name '.*.rej' -o -size 0 \
+               -o -name '.*.rej' \
                -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
                -type f -print | xargs rm -f
 
@@ -1296,7 +1295,6 @@ help:
        @echo  '                2: warnings which occur quite often but may still be relevant'
        @echo  '                3: more obscure warnings, can most likely be ignored'
        @echo  '                Multiple levels can be combined with W=12 or W=123'
-       @echo  '  make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections'
        @echo  ''
        @echo  'Execute "make" or "make all" to build all targets marked with [*] '
        @echo  'For further info see the ./README file'
index 8bb936226dee6bcc673cdefd623c8d08ca8eeac8..3d74801a40157b09e76263ea5af4546e67fedd30 100644 (file)
@@ -445,11 +445,6 @@ config ALPHA_EV67
          Is this a machine based on the EV67 core?  If in doubt, select N here
          and the machine will be treated as an EV6.
 
-config ALPHA_EV7
-       bool
-       depends on ALPHA_MARVEL
-       default y
-
 config ALPHA_MCPCIA
        bool
        depends on ALPHA_RAWHIDE
index a872078497be7382d37b3326597bf967708ad4a5..00096df0f6ad05e440d1f0f4764bce34e6309816 100644 (file)
@@ -303,6 +303,7 @@ irongate_init_arch(void)
 #include <linux/vmalloc.h>
 #include <linux/agp_backend.h>
 #include <linux/agpgart.h>
+#include <linux/export.h>
 #include <asm/pgalloc.h>
 
 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
index b899e95f79fdb424ea9b07d31153edb0e824ac8e..53649c7d0068f19e4b66b7cf8a6012ad5519f7b3 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/stat.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 
index 022c2748fa410569230094097bb491c8d8595839..43610804987dd454556307627753e79cbc457a94 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/gfp.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
 #include <linux/dma-mapping.h>
index cc0fd862cf26a9565580c9f137e0d67ac3119bab..32de56067e63db5ed8ea6941df1de97540b412b6 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/setup.h>
 #include <asm/io.h>
 #include <linux/log2.h>
+#include <linux/export.h>
 
 extern struct atomic_notifier_head panic_notifier_list;
 static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
index fe6b0526b3a6fb3f52d35730b84930932050d8a9..e084b7e981e8ff301aaae64ef3a2dc7e66701247 100644 (file)
@@ -595,6 +595,7 @@ config ARCH_MMP
        select TICK_ONESHOT
        select PLAT_PXA
        select SPARSE_IRQ
+       select GENERIC_ALLOCATOR
        help
          Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
 
@@ -769,6 +770,7 @@ config ARCH_S3C64XX
        select CPU_V6
        select ARM_VIC
        select HAVE_CLK
+       select HAVE_TCM
        select CLKDEV_LOOKUP
        select NO_IOPORT
        select ARCH_USES_GETTIMEOFFSET
@@ -777,9 +779,6 @@ config ARCH_S3C64XX
        select SAMSUNG_CLKSRC
        select SAMSUNG_IRQ_VIC_TIMER
        select S3C_GPIO_TRACK
-       select S3C_GPIO_PULL_UPDOWN
-       select S3C_GPIO_CFG_S3C24XX
-       select S3C_GPIO_CFG_S3C64XX
        select S3C_DEV_NAND
        select USB_ARCH_HAS_OHCI
        select SAMSUNG_GPIOLIB_4BIT
@@ -838,8 +837,8 @@ config ARCH_S5PV210
        help
          Samsung S5PV210/S5PC110 series based systems
 
-config ARCH_EXYNOS4
-       bool "Samsung EXYNOS4"
+config ARCH_EXYNOS
+       bool "SAMSUNG EXYNOS"
        select CPU_V7
        select ARCH_SPARSEMEM_ENABLE
        select ARCH_HAS_HOLES_MEMORYMODEL
@@ -853,7 +852,7 @@ config ARCH_EXYNOS4
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select NEED_MACH_MEMORY_H
        help
-         Samsung EXYNOS4 series based systems
+         Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
 
 config ARCH_SHARK
        bool "Shark"
@@ -1080,7 +1079,7 @@ source "arch/arm/mach-s5pc100/Kconfig"
 
 source "arch/arm/mach-s5pv210/Kconfig"
 
-source "arch/arm/mach-exynos4/Kconfig"
+source "arch/arm/mach-exynos/Kconfig"
 
 source "arch/arm/mach-shmobile/Kconfig"
 
@@ -1232,7 +1231,7 @@ config ARM_ERRATA_742231
          capabilities of the processor.
 
 config PL310_ERRATA_588369
-       bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+       bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
        depends on CACHE_L2X0
        help
           The PL310 L2 cache controller implements three types of Clean &
@@ -1257,7 +1256,7 @@ config ARM_ERRATA_720789
          entries regardless of the ASID.
 
 config PL310_ERRATA_727915
-       bool "Background Clean & Invalidate by Way operation can cause data corruption"
+       bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
        depends on CACHE_L2X0
        help
          PL310 implements the Clean & Invalidate by Way L2 cache maintenance
@@ -1290,8 +1289,8 @@ config ARM_ERRATA_751472
          operation is received by a CPU before the ICIALLUIS has completed,
          potentially leading to corrupted entries in the cache or TLB.
 
-config ARM_ERRATA_753970
-       bool "ARM errata: cache sync operation may be faulty"
+config PL310_ERRATA_753970
+       bool "PL310 errata: cache sync operation may be faulty"
        depends on CACHE_PL310
        help
          This option enables the workaround for the 753970 PL310 (r3p0) erratum.
@@ -1353,6 +1352,18 @@ config ARM_ERRATA_764369
          relevant cache maintenance functions and sets a specific bit
          in the diagnostic control register of the SCU.
 
+config PL310_ERRATA_769419
+       bool "PL310 errata: no automatic Store Buffer drain"
+       depends on CACHE_L2X0
+       help
+         On revisions of the PL310 prior to r3p2, the Store Buffer does
+         not automatically drain. This can cause normal, non-cacheable
+         writes to be retained when the memory system is idle, leading
+         to suboptimal I/O performance for drivers using coherent DMA.
+         This option adds a write barrier to the cpu_idle loop so that,
+         on systems with an outer cache, the store buffer is drained
+         explicitly.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -2212,7 +2223,7 @@ menu "Power management options"
 source "kernel/power/Kconfig"
 
 config ARCH_SUSPEND_POSSIBLE
-       depends on !ARCH_S5P64X0 && !ARCH_S5PC100
+       depends on !ARCH_S5PC100
        depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
                CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
        def_bool y
index b7c2d377a6c2330ed194ff931f0a91ec33b0fce8..dfcf3b033e10b465ff44107c43cfa1141fd989f4 100644 (file)
@@ -180,7 +180,7 @@ machine-$(CONFIG_ARCH_S3C64XX)              := s3c64xx
 machine-$(CONFIG_ARCH_S5P64X0)         := s5p64x0
 machine-$(CONFIG_ARCH_S5PC100)         := s5pc100
 machine-$(CONFIG_ARCH_S5PV210)         := s5pv210
-machine-$(CONFIG_ARCH_EXYNOS4)         := exynos4
+machine-$(CONFIG_ARCH_EXYNOS4)         := exynos
 machine-$(CONFIG_ARCH_SA1100)          := sa1100
 machine-$(CONFIG_ARCH_SHARK)           := shark
 machine-$(CONFIG_ARCH_SHMOBILE)        := shmobile
index 176062ac7f07305014357372c42285ff07a09c68..5df26a9976a26c10ddfcf0f788302dd2caeb8769 100644 (file)
@@ -65,6 +65,8 @@ $(obj)/%.dtb: $(src)/dts/%.dts
 
 $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
 
+clean-files := *.dtb
+
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
                   -C none -a $(LOADADDR) -e $(STARTADDR) \
index 9b29a623aaf1a4296d45fb8c45c835466617619c..3f9abd6b6964546014490a3942abce3675e6e254 100644 (file)
        sdhci@c8000400 {
                cd-gpios = <&gpio 69 0>; /* gpio PI5 */
                wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-               power-gpios = <&gpio 155 0>; /* gpio PT3 */
+               power-gpios = <&gpio 70 0>; /* gpio PI6 */
        };
 
        sdhci@c8000600 {
-               power-gpios = <&gpio 70 0>; /* gpio PI6 */
                support-8bit;
        };
 };
index 0e6ae470c94f26589c0721a059dfaded9b2f30b1..410a546060a2eecf82859d76c528223e8796f9f4 100644 (file)
@@ -526,7 +526,8 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
                sizeof(u32));
        BUG_ON(!gic->saved_ppi_conf);
 
-       cpu_pm_register_notifier(&gic_notifier_block);
+       if (gic == &gic_data[0])
+               cpu_pm_register_notifier(&gic_notifier_block);
 }
 #else
 static void __init gic_pm_init(struct gic_chip_data *gic)
@@ -581,13 +582,16 @@ void __init gic_init(unsigned int gic_nr, int irq_start,
         * For primary GICs, skip over SGIs.
         * For secondary GICs, skip over PPIs, too.
         */
+       domain->hwirq_base = 32;
        if (gic_nr == 0) {
                gic_cpu_base_addr = cpu_base;
-               domain->hwirq_base = 16;
-               if (irq_start > 0)
-                       irq_start = (irq_start & ~31) + 16;
-       } else
-               domain->hwirq_base = 32;
+
+               if ((irq_start & 31) > 0) {
+                       domain->hwirq_base = 16;
+                       if (irq_start != -1)
+                               irq_start = (irq_start & ~31) + 16;
+               }
+       }
 
        /*
         * Find out how many interrupts are supported.
index a7934ba9e1dfcc89ce97812d8b361b5375e1cc43..b539ec855e1a60180cbc519f7b23125338141720 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ioport.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include <asm/mach/pci.h>
 #include <asm/hardware/it8152.h>
index 7129cfbdacd6887920cf28994625be7b35f65503..f407a6b35d3dd1e6ad1e72afec38837dcfdd796a 100644 (file)
@@ -1211,8 +1211,8 @@ static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
        ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
        ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
 
-       ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
-       ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+       ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT);
+       ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT);
 
        ccr |= (rqc->swap << CC_SWAP_SHFT);
 
@@ -1623,6 +1623,11 @@ static inline int _alloc_event(struct pl330_thread *thrd)
        return -1;
 }
 
+static bool _chan_ns(const struct pl330_info *pi, int i)
+{
+       return pi->pcfg.irq_ns & (1 << i);
+}
+
 /* Upon success, returns IdentityToken for the
  * allocated channel, NULL otherwise.
  */
@@ -1647,7 +1652,8 @@ void *pl330_request_channel(const struct pl330_info *pi)
 
        for (i = 0; i < chans; i++) {
                thrd = &pl330->channels[i];
-               if (thrd->free) {
+               if ((thrd->free) && (!_manager_ns(thrd) ||
+                                       _chan_ns(pi, i))) {
                        thrd->ev = _alloc_event(thrd);
                        if (thrd->ev >= 0) {
                                thrd->free = false;
index 1cde34a080d7e688efbf019aae2e55f8e20895c2..0c616d5fcb0f7bf3a6811ea08f7fd2dcc63c819b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <asm/hardware/scoop.h>
 
diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig
new file mode 100644 (file)
index 0000000..8826eb2
--- /dev/null
@@ -0,0 +1,108 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91CAP9=y
+CONFIG_MACH_AT91CAP9ADK=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig
deleted file mode 100644 (file)
index ffb1edd..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91CAP9=y
-CONFIG_MACH_AT91CAP9ADK=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
index 38cb7c98542623a92cc7791a89f701e9fe5adf48..bbe4e1a1f5d86f81464e393e2fd2ab228e34542c 100644 (file)
@@ -5,7 +5,6 @@ CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
@@ -56,7 +55,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
@@ -75,18 +73,8 @@ CONFIG_IPV6_TUNNEL=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_AFS_PARTS=y
 CONFIG_MTD_CHAR=y
@@ -108,8 +96,6 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_TCLIB=y
-CONFIG_EEPROM_LEGACY=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=m
@@ -119,14 +105,23 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_TUN=m
+CONFIG_ARM_AT91_ETHER=y
 CONFIG_PHYLIB=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_AT91_ETHER=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=y
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
 CONFIG_USB_CATC=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_PEGASUS=m
@@ -139,18 +134,6 @@ CONFIG_USB_NET_RNDIS_HOST=m
 CONFIG_USB_ALI_M5632=y
 CONFIG_USB_AN2720=y
 CONFIG_USB_EPSON2888=y
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
@@ -158,9 +141,9 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_LEGACY_PTY_COUNT=32
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=32
 CONFIG_HW_RANDOM=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -290,7 +273,6 @@ CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
-CONFIG_SMB_FS=m
 CONFIG_CIFS=m
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
@@ -335,7 +317,6 @@ CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_CRYPTO_PCBC=y
 CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/at91sam9260_defconfig b/arch/arm/configs/at91sam9260_defconfig
new file mode 100644 (file)
index 0000000..505b376
--- /dev/null
@@ -0,0 +1,91 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_ARCH_AT91SAM9260_SAM9XE=y
+CONFIG_MACH_AT91SAM9260EK=y
+CONFIG_MACH_CAM60=y
+CONFIG_MACH_SAM9_L9260=y
+CONFIG_MACH_AFEB9260=y
+CONFIG_MACH_USB_A9260=y
+CONFIG_MACH_QIL_A9260=y
+CONFIG_MACH_CPU9260=y
+CONFIG_MACH_FLEXIBITY=y
+CONFIG_MACH_SNAPPER_9260=y
+CONFIG_MACH_AT91SAM_DT=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig
deleted file mode 100644 (file)
index f8a9226..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9260=y
-CONFIG_MACH_AT91SAM9260EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig
new file mode 100644 (file)
index 0000000..9123568
--- /dev/null
@@ -0,0 +1,124 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
+CONFIG_MACH_CPU9G20=y
+CONFIG_MACH_ACMENETUSFOXG20=y
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+CONFIG_MACH_PCONTROL_G20=y
+CONFIG_MACH_GSIA18S=y
+CONFIG_MACH_USB_A9G20=y
+CONFIG_MACH_SNAPPER_9260=y
+CONFIG_MACH_AT91SAM_DT=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig
deleted file mode 100644 (file)
index 9e90e6d..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9G20=y
-CONFIG_MACH_AT91SAM9G20EK=y
-CONFIG_MACH_AT91SAM9G20EK_2MMC=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
-CONFIG_HW_RANDOM=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-CONFIG_SPI_SPIDEV=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_SND_AT73C213=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
index c5876d244f4b2d667db3d4753bdc1bdab1203064..606d48f3b8f81c10370b718d7b2b3475818b9a03 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9G45=y
 CONFIG_MACH_AT91SAM9M10G45EK=y
+CONFIG_MACH_AT91SAM_DT=y
 CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 CONFIG_AT91_SLOW_CLOCK=y
 CONFIG_AEABI=y
@@ -73,11 +74,8 @@ CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_MII=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_DAVICOM_PHY=y
 CONFIG_LIBERTAS_THINFIRM=m
 CONFIG_LIBERTAS_THINFIRM_USB=m
 CONFIG_AT76C50X_USB=m
@@ -131,7 +129,6 @@ CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
 CONFIG_FB=y
 CONFIG_FB_ATMEL=y
 CONFIG_FB_UDL=m
diff --git a/arch/arm/configs/at91sam9rl_defconfig b/arch/arm/configs/at91sam9rl_defconfig
new file mode 100644 (file)
index 0000000..ad562ee
--- /dev/null
@@ -0,0 +1,79 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9RL=y
+CONFIG_MACH_AT91SAM9RLEK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=24576
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig
deleted file mode 100644 (file)
index 75621e4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9RL=y
-CONFIG_MACH_AT91SAM9RLEK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_UNIX=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=4
-CONFIG_BLK_DEV_RAM_SIZE=24576
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
index cd40bb56e5686c58b5c2ad7beab4a2105842d897..bffe68e190a3d93157886557e1958bde59798648 100644 (file)
@@ -4,19 +4,18 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_EXYNOS4=y
+CONFIG_ARCH_EXYNOS=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=1
 CONFIG_MACH_SMDKC210=y
-CONFIG_MACH_SMDKV310=y
 CONFIG_MACH_ARMLEX4210=y
 CONFIG_MACH_UNIVERSAL_C210=y
 CONFIG_MACH_NURI=y
 CONFIG_MACH_ORIGEN=y
+CONFIG_MACH_SMDK4412=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
-CONFIG_HOTPLUG_CPU=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_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
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_S3C_UART=1
 CONFIG_CRC_CCITT=y
index 227a477346edb44a2a83ba49a0f9b7cd2b165ec0..d95763d5f0d83df6543364e3ea648c2ad88994bf 100644 (file)
@@ -287,7 +287,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
index 176ec22af0342f215b59a2778144d69ef0f4c806..fd996bb13022879dee93c308c8e8ad154918ec20 100644 (file)
@@ -263,7 +263,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_MMC=y
index a88e64d4e9a5862c28160c9d1b7d3cd01edf0550..443675d317e6de326c576caf47ae9ff179a0814c 100644 (file)
@@ -132,7 +132,7 @@ CONFIG_USB_MON=m
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_VBUS_DRAW=500
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 # CONFIG_USB_ETH_RNDIS is not set
 CONFIG_USB_GADGETFS=m
index 7b63462b349d7de9965b13bec7c1c85e57c25fcd..945a34f2a34dbd9e711ac440500d1e17cfad2ac0 100644 (file)
@@ -48,13 +48,7 @@ CONFIG_MACH_SX1=y
 CONFIG_MACH_NOKIA770=y
 CONFIG_MACH_AMS_DELTA=y
 CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-CONFIG_OMAP_ARM_216MHZ=y
-CONFIG_OMAP_ARM_195MHZ=y
-CONFIG_OMAP_ARM_192MHZ=y
 CONFIG_OMAP_ARM_182MHZ=y
-CONFIG_OMAP_ARM_168MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
 # CONFIG_ARM_THUMB is not set
 CONFIG_PCCARD=y
 CONFIG_OMAP_CF=y
index 4a5a12681be2038c908318ffc953c3ad7a9bd431..374000ec4e4e9a66bbf07304abd75dced85a0b66 100644 (file)
@@ -14,8 +14,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_U300=y
 CONFIG_MACH_U300=y
 CONFIG_MACH_U300_BS335=y
-CONFIG_MACH_U300_DUAL_RAM=y
-CONFIG_U300_DEBUG=y
 CONFIG_MACH_U300_SPIDUMMY=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -26,19 +24,21 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
 CONFIG_CPU_IDLE=y
 CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
 # CONFIG_SUSPEND is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 # CONFIG_HWMON is not set
@@ -51,6 +51,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_MMC=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_HCTOSYS is not set
@@ -65,10 +66,8 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_CRC32 is not set
index 97d31a4663daf0c6186cd948a05abf35687686d3..2d7b6e7b72713cba72df0349462c29dbe38a67ba 100644 (file)
@@ -10,7 +10,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_U8500=y
 CONFIG_UX500_SOC_DB5500=y
 CONFIG_UX500_SOC_DB8500=y
-CONFIG_MACH_U8500=y
+CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_U5500=y
 CONFIG_NO_HZ=y
@@ -24,6 +24,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -41,11 +42,8 @@ CONFIG_MISC_DEVICES=y
 CONFIG_AB8500_PWM=y
 CONFIG_SENSORS_BH1780=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_SMSC_PHY=y
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
@@ -72,15 +70,12 @@ CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
-# CONFIG_HWMON is not set
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
+CONFIG_AB5500_CORE=y
 CONFIG_AB8500_CORE=y
 CONFIG_REGULATOR_AB8500=y
 # CONFIG_HID_SUPPORT is not set
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_GADGET_MUSB_HDRC=y
-CONFIG_MUSB_PIO_ONLY=y
 CONFIG_USB_GADGET=y
 CONFIG_AB8500_USB=y
 CONFIG_MMC=y
@@ -97,6 +92,7 @@ CONFIG_DMADEVICES=y
 CONFIG_STE_DMA40=y
 CONFIG_STAGING=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_HSEM_U8500=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
index 59577ad3f4efdfda65e65753054673a32614e80f..547a3c1e59dbcd88ea9da77505691110508f9daf 100644 (file)
@@ -140,7 +140,7 @@ CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
 CONFIG_USB_ETH=m
 CONFIG_USB_GADGETFS=m
 CONFIG_USB_FILE_STORAGE=m
index 1db1143a94838cb92419040c40009f17d1ee2f97..7df239bcdf2745b6a3d20e5a90ed3bac27d73ecc 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __ASM_ARM_HARDWARE_L2X0_H
 #define __ASM_ARM_HARDWARE_L2X0_H
 
+#include <linux/errno.h>
+
 #define L2X0_CACHE_ID                  0x000
 #define L2X0_CACHE_TYPE                        0x004
 #define L2X0_CTRL                      0x100
index 7d19425dd496a083eb98557bafe2980843bc9fa3..2b0efc3104ac6f73846fb89cdf0761c400676540 100644 (file)
@@ -13,6 +13,7 @@
 struct tag;
 struct meminfo;
 struct sys_timer;
+struct pt_regs;
 
 struct machine_desc {
        unsigned int            nr;             /* architecture number  */
index 71d99b83cdb980178aac275e487c2db081c041fc..0bda22c094a6dd1b70100444d6e29fa1a41688ef 100644 (file)
@@ -55,16 +55,6 @@ reserve_pmu(enum arm_pmu_type type);
 extern void
 release_pmu(enum arm_pmu_type type);
 
-/**
- * init_pmu() - Initialise the PMU.
- *
- * Initialise the system ready for PMU enabling. This should typically set the
- * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
- * the actual hardware initialisation.
- */
-extern int
-init_pmu(enum arm_pmu_type type);
-
 #else /* CONFIG_CPU_HAS_PMU */
 
 #include <linux/err.h>
index a7e457ed27c31e1185ebe3a0eaa745d88c35029d..58b8b84adcd2cf5f295e6869b68350f9dcadc798 100644 (file)
@@ -25,7 +25,7 @@ extern struct cputopo_arm cpu_topology[NR_CPUS];
 
 void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+const struct cpumask *cpu_coregroup_mask(int cpu);
 
 #else
 
index c60a2944f95b82a0cc9d5bfea32d88c65ecb202f..4a1123783806b79ef559ed51a093353feb67070e 100644 (file)
 #define __NR_syncfs                    (__NR_SYSCALL_BASE+373)
 #define __NR_sendmmsg                  (__NR_SYSCALL_BASE+374)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
+#define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
+#define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
 
 /*
  * The following SWIs are ARM private.
index 8e3c6f11b0a1ad00188b2deda119f83bb17ab735..5b0bce61eb6922049fb509169938209b3755d038 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/cryptohash.h>
index c0d9203fc75ec8725df679ab63ecde20ac15c787..b530e9116a0c76283a1d5839868241abec382a1b 100644 (file)
@@ -5,7 +5,7 @@
  *
  *  Bits taken from various places.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
index 9943e9e74a1bda0b17bc6e1ee93ca3ab2b80f970..463ff4a0ec8acaa69372b8abd40a39260ee91736 100644 (file)
                CALL(sys_syncfs)
                CALL(sys_sendmmsg)
 /* 375 */      CALL(sys_setns)
+               CALL(sys_process_vm_readv)
+               CALL(sys_process_vm_writev)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index 1a33e9d6bb1fbfb083b602e74f0a4b5f0da7cded..bee7f9d47f02f2b702bb59df7fee1f81e34590eb 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
index 9b05c6a0dceac54615e1dfa472bf28ca946616ac..ddba41d1fcf148ab1a3bde141dff1087dcb6919d 100644 (file)
@@ -1,4 +1,4 @@
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
index 9ad50c4208aebf5aaf7ee245444da5789935b269..b145f16c91bc786db82fcd3cd66ccdee7b740aa4 100644 (file)
@@ -497,7 +497,7 @@ ENDPROC(__und_usr)
        .popsection
        .pushsection __ex_table,"a"
        .long   1b, 4b
-#if __LINUX_ARM_ARCH__ >= 7
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
        .long   2b, 4b
        .long   3b, 4b
 #endif
index 1bec8b5f22f05446df1c8fc60b6a9391df48b2dd..36d20bd501200880dad2a662a8a3d29f15506e5c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/miscdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <asm/hardware/coresight.h>
 #include <asm/sections.h>
 
index 566c54c2a1fef28bffea090e89bcec998b73ede6..08c82fd844a8683533216048b54ff2f210729fb6 100644 (file)
@@ -360,7 +360,7 @@ __secondary_data:
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
        orr     r0, r0, #CR_A
 #else
        bic     r0, r0, #CR_A
index f4470307edb8f4a9a3327e700d620de1f9124616..dcd5b4d8614374519a80eb0772c8cd12df1320e0 100644 (file)
@@ -1,4 +1,4 @@
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/io.h>
 
index 7cb29261249af0c74157fd362d15827723ee1715..3efd82cc95f06a8196b6a20e8c9fa65121d66009 100644 (file)
@@ -22,7 +22,6 @@
  *  Naturally it's not a 1:1 relation, but there are similarities.
  */
 #include <linux/kernel_stat.h>
-#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
index 9fe8910308af922eda3c17ffee908c99652c1a1f..8a30c89da70ec104d4c1499f3a88a1dc4721e6e0 100644 (file)
@@ -519,10 +519,12 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
 static const union decode_item arm_cccc_0001_____1001_table[] = {
        /* Synchronization primitives                                   */
 
+#if __LINUX_ARM_ARCH__ < 6
+       /* Deprecated on ARMv6 and may be UNDEFINED on v7               */
        /* SMP/SWPB             cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
        DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
                                                 REGS(NOPC, NOPC, 0, 0, NOPC)),
-
+#endif
        /* LDREX/STREX{,D,B,H}  cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
        /* And unallocated instructions...                              */
        DECODE_END
index fc82de8bdcce1081801cece62fa3d97480d520e1..ba32b393b3f0c514c83799687348d52655bfe1da 100644 (file)
@@ -427,18 +427,25 @@ void kprobe_arm_test_cases(void)
 
        TEST_GROUP("Synchronization primitives")
 
-       /*
-        * Use hard coded constants for SWP instructions to avoid warnings
-        * about deprecated instructions.
-        */
-       TEST_RP( ".word 0xe108e097 @ swp        lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x610d0091 @ swpvs      r0, r",1,VAL1,", [sp]")
-       TEST_RP( ".word 0xe10cd09e @ swp        sp, r",14,VAL2,", [r",12,13*4,"]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swp    lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvs  r0, r",1,VAL1,", [sp]")
+       TEST_RP("swp    sp, r",14,VAL2,", [r",12,13*4,"]")
+#else
+       TEST_UNSUPPORTED(".word 0xe108e097 @ swp        lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x610d0091 @ swpvs      r0, r1, [sp]")
+       TEST_UNSUPPORTED(".word 0xe10cd09e @ swp        sp, r14 [r12]")
+#endif
        TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]")
        TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]")
        TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]")
-       TEST_RP( ".word 0xe148e097 @ swpb       lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x614d0091 @ swpvsb     r0, r",1,VAL1,", [sp]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swpb   lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvsb r0, r",1,VAL1,", [sp]")
+#else
+       TEST_UNSUPPORTED(".word 0xe148e097 @ swpb       lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x614d0091 @ swpvsb     r0, r1, [sp]")
+#endif
        TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]")
 
        TEST_UNSUPPORTED(".word 0xe1100090") /* Unallocated space */
@@ -550,7 +557,7 @@ void kprobe_arm_test_cases(void)
        TEST_RPR(  "strccd      r",8, VAL2,", [r",13,0, ", r",12,48,"]")
        TEST_RPR(  "strd        r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
        TEST_RPR(  "strcsd      r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
-       TEST_RPR(  "strd        r",2, VAL1,", [r",3, 24,"], r",4,48,"")
+       TEST_RPR(  "strd        r",2, VAL1,", [r",5, 24,"], r",4,48,"")
        TEST_RPR(  "strd        r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
        TEST_UNSUPPORTED(".word 0xe1afc0fa      @ strd r12, [pc, r10]!")
 
index 5e726c31c45aef5084a7e7ddf07bb1762ed4c403..5d8b857922220b4be4e9babf6e050c94625a56eb 100644 (file)
@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
 DONT_TEST_IN_ITBLOCK(
        TEST_BF_R(  "cbnz       r",0,0, ", 2f")
        TEST_BF_R(  "cbz        r",2,-1,", 2f")
-       TEST_BF_RX( "cbnz       r",4,1, ", 2f",0x20)
-       TEST_BF_RX( "cbz        r",7,0, ", 2f",0x40)
+       TEST_BF_RX( "cbnz       r",4,1, ", 2f", SPACE_0x20)
+       TEST_BF_RX( "cbz        r",7,0, ", 2f", SPACE_0x40)
 )
        TEST_R("sxth    r0, r",7, HH1,"")
        TEST_R("sxth    r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
        TESTCASE_START(code)            \
        TEST_ARG_PTR(13, offset)        \
        TEST_ARG_END("")                \
-       TEST_BRANCH_F(code,0)           \
+       TEST_BRANCH_F(code)             \
        TESTCASE_END
 
        TEST("push      {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
 
        TEST_BF(  "b    2f")
        TEST_BB(  "b    2b")
-       TEST_BF_X("b    2f", 0x400)
-       TEST_BB_X("b    2b", 0x400)
+       TEST_BF_X("b    2f", SPACE_0x400)
+       TEST_BB_X("b    2b", SPACE_0x400)
 
        TEST_GROUP("Testing instructions in IT blocks")
 
@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
        TEST_BB("bne.w  2b")
        TEST_BF("bgt.w  2f")
        TEST_BB("blt.w  2b")
-       TEST_BF_X("bpl.w        2f",0x1000)
+       TEST_BF_X("bpl.w        2f", SPACE_0x1000)
 )
 
        TEST_UNSUPPORTED("msr   cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
 
        TEST_BF(  "b.w  2f")
        TEST_BB(  "b.w  2b")
-       TEST_BF_X("b.w  2f", 0x1000)
+       TEST_BF_X("b.w  2f", SPACE_0x1000)
 
        TEST_BF(  "bl.w 2f")
        TEST_BB(  "bl.w 2b")
-       TEST_BB_X("bl.w 2b", 0x1000)
+       TEST_BB_X("bl.w 2b", SPACE_0x1000)
 
        TEST_X( "blx    __dummy_arm_subroutine",
                ".arm                           \n\t"
index 0dc5d77b9356bcd86b4b0c087bf642bc6396e06e..e28a869b1ae4b7be5abfb7d088c3214bfe2caab7 100644 (file)
@@ -149,23 +149,31 @@ struct test_arg_end {
        "1:     "instruction"                           \n\t"   \
        "       nop                                     \n\t"
 
-#define TEST_BRANCH_F(instruction, xtra_dist)                  \
+#define TEST_BRANCH_F(instruction)                             \
        TEST_INSTRUCTION(instruction)                           \
-       ".if "#xtra_dist"                               \n\t"   \
        "       b       99f                             \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       "2:     nop                                     \n\t"
+
+#define TEST_BRANCH_B(instruction)                             \
+       "       b       50f                             \n\t"   \
+       "       b       99f                             \n\t"   \
+       "2:     nop                                     \n\t"   \
+       "       b       99f                             \n\t"   \
+       TEST_INSTRUCTION(instruction)
+
+#define TEST_BRANCH_FX(instruction, codex)                     \
+       TEST_INSTRUCTION(instruction)                           \
+       "       b       99f                             \n\t"   \
+       codex"                                          \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"
 
-#define TEST_BRANCH_B(instruction, xtra_dist)                  \
+#define TEST_BRANCH_BX(instruction, codex)                     \
        "       b       50f                             \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"   \
        "       b       99f                             \n\t"   \
-       ".if "#xtra_dist"                               \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       codex"                                          \n\t"   \
        TEST_INSTRUCTION(instruction)
 
 #define TESTCASE_END                                           \
@@ -301,47 +309,60 @@ struct test_arg_end {
        TESTCASE_START(code1 #reg1 code2)       \
        TEST_ARG_PTR(reg1, val1)                \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code1 #reg1 code2, 0)     \
+       TEST_BRANCH_F(code1 #reg1 code2)        \
        TESTCASE_END
 
-#define TEST_BF_X(code, xtra_dist)             \
+#define TEST_BF(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code, xtra_dist)          \
+       TEST_BRANCH_F(code)                     \
        TESTCASE_END
 
-#define TEST_BB_X(code, xtra_dist)             \
+#define TEST_BB(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_B(code, xtra_dist)          \
+       TEST_BRANCH_B(code)                     \
        TESTCASE_END
 
-#define TEST_BF_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_F(code1 #reg code2, xtra_dist)      \
+#define TEST_BF_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_F(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BB_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_B(code1 #reg code2, xtra_dist)      \
+#define TEST_BB_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_B(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BF(code)  TEST_BF_X(code, 0)
-#define TEST_BB(code)  TEST_BB_X(code, 0)
-
-#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0)
-#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0)
-
 #define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3)        \
        TESTCASE_START(code1 #reg1 code2 #reg2 code3)           \
        TEST_ARG_REG(reg1, val1)                                \
        TEST_ARG_REG(reg2, val2)                                \
        TEST_ARG_END("")                                        \
-       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0)         \
+       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3)            \
+       TESTCASE_END
+
+#define TEST_BF_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_FX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BB_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_BX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BF_RX(code1, reg, val, code2, codex)      \
+       TESTCASE_START(code1 #reg code2)                \
+       TEST_ARG_REG(reg, val)                          \
+       TEST_ARG_END("")                                \
+       TEST_BRANCH_FX(code1 #reg code2, codex)         \
        TESTCASE_END
 
 #define TEST_X(code, codex)                    \
@@ -372,6 +393,25 @@ struct test_arg_end {
        TESTCASE_END
 
 
+/*
+ * Macros for defining space directives spread over multiple lines.
+ * These are required so the compiler guesses better the length of inline asm
+ * code and will spill the literal pool early enough to avoid generating PC
+ * relative loads with out of range offsets.
+ */
+#define TWICE(x)       x x
+#define SPACE_0x8      TWICE(".space 4\n\t")
+#define SPACE_0x10     TWICE(SPACE_0x8)
+#define SPACE_0x20     TWICE(SPACE_0x10)
+#define SPACE_0x40     TWICE(SPACE_0x20)
+#define SPACE_0x80     TWICE(SPACE_0x40)
+#define SPACE_0x100    TWICE(SPACE_0x80)
+#define SPACE_0x200    TWICE(SPACE_0x100)
+#define SPACE_0x400    TWICE(SPACE_0x200)
+#define SPACE_0x800    TWICE(SPACE_0x400)
+#define SPACE_0x1000   TWICE(SPACE_0x800)
+
+
 /* Various values used in test cases... */
 #define N(val) (val ^ 0xffffffff)
 #define VAL1   0x12345678
index 0f107dcb034790d3be0b7405b7c235034d495868..0bcd383415731befa58ec5b874f38ef9a816ba1e 100644 (file)
@@ -7,10 +7,11 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/syscore_ops.h>
+#include <linux/string.h>
 
 #include <asm/leds.h>
 
index c1b4463dcc839c781004080d7426e78771bad15a..e59bbd496c39174da0a6ee4094fe6f717df97a67 100644 (file)
@@ -32,24 +32,6 @@ static atomic_t waiting_for_crash_ipi;
 
 int machine_kexec_prepare(struct kimage *image)
 {
-       unsigned long page_list;
-       void *reboot_code_buffer;
-       page_list = image->head & PAGE_MASK;
-
-       reboot_code_buffer = page_address(image->control_code_page);
-
-       /* Prepare parameters for reboot_code_buffer*/
-       kexec_start_address = image->start;
-       kexec_indirection_page = page_list;
-       kexec_mach_type = machine_arch_type;
-       kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
-
-       /* copy our kernel relocation code to the control code page */
-       memcpy(reboot_code_buffer,
-              relocate_new_kernel, relocate_new_kernel_size);
-
-       flush_icache_range((unsigned long) reboot_code_buffer,
-                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
        return 0;
 }
 
@@ -100,14 +82,31 @@ void (*kexec_reinit)(void);
 
 void machine_kexec(struct kimage *image)
 {
+       unsigned long page_list;
        unsigned long reboot_code_buffer_phys;
        void *reboot_code_buffer;
 
+
+       page_list = image->head & PAGE_MASK;
+
        /* we need both effective and real address here */
        reboot_code_buffer_phys =
            page_to_pfn(image->control_code_page) << PAGE_SHIFT;
        reboot_code_buffer = page_address(image->control_code_page);
 
+       /* Prepare parameters for reboot_code_buffer*/
+       kexec_start_address = image->start;
+       kexec_indirection_page = page_list;
+       kexec_mach_type = machine_arch_type;
+       kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
+       /* copy our kernel relocation code to the control code page */
+       memcpy(reboot_code_buffer,
+              relocate_new_kernel, relocate_new_kernel_size);
+
+
+       flush_icache_range((unsigned long) reboot_code_buffer,
+                          (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
        printk(KERN_INFO "Bye!\n");
 
        if (kexec_reinit)
index e6e5d7c84f1a4330bc37e9516694f8d1797be8a9..8e9c98edc0682a8aa23790737a3b63b08dea847f 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/bitmap.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/perf_event.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
@@ -343,19 +343,25 @@ validate_group(struct perf_event *event)
 {
        struct perf_event *sibling, *leader = event->group_leader;
        struct pmu_hw_events fake_pmu;
+       DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
 
-       memset(&fake_pmu, 0, sizeof(fake_pmu));
+       /*
+        * Initialise the fake PMU. We only need to populate the
+        * used_mask for the purposes of validation.
+        */
+       memset(fake_used_mask, 0, sizeof(fake_used_mask));
+       fake_pmu.used_mask = fake_used_mask;
 
        if (!validate_event(&fake_pmu, leader))
-               return -ENOSPC;
+               return -EINVAL;
 
        list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
                if (!validate_event(&fake_pmu, sibling))
-                       return -ENOSPC;
+                       return -EINVAL;
        }
 
        if (!validate_event(&fake_pmu, event))
-               return -ENOSPC;
+               return -EINVAL;
 
        return 0;
 }
@@ -396,6 +402,9 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
        int i, err, irq, irqs;
        struct platform_device *pmu_device = armpmu->plat_device;
 
+       if (!pmu_device)
+               return -ENODEV;
+
        err = reserve_pmu(armpmu->type);
        if (err) {
                pr_warning("unable to reserve pmu\n");
index a4b1b0748fd3e5bdb39f0f299ff2529c283f30aa..679cf4d18c08bfa99fec75cadd24027c192a1706 100644 (file)
@@ -10,7 +10,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
index 2c3407ee857675242c874f49adaf9d26339f79bf..2334bf8a650a16a35d5849a4b6c309d5f19eb1f1 100644 (file)
@@ -33,3 +33,4 @@ release_pmu(enum arm_pmu_type type)
 {
        clear_bit_unlock(type, pmu_lock);
 }
+EXPORT_SYMBOL_GPL(release_pmu);
index fd0814076ff66081c46e2ae34bcd42be5ba62c38..3d0c6fb74ae4efe521cfc563ea11e0fa9738d465 100644 (file)
@@ -10,7 +10,7 @@
  */
 #include <stdarg.h>
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -192,6 +192,9 @@ void cpu_idle(void)
 #endif
 
                        local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+                       wmb();
+#endif
                        if (hlt_counter) {
                                local_irq_enable();
                                cpu_relax();
index 2491f3b406bc1725e99c7ea176e724e0619eb1e6..483727ad68923a3e27af6d693c9132db0148af7f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/elf.h>
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index 0b13a72f855dc4a6723603f937977da000d6a864..8085417555dd7c49176cd06d88354dd1b2faca67 100644 (file)
@@ -8,7 +8,7 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ftrace.h>
 
 #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
index bda0a218f4a55971a0080d198f42ab2aee8f37cb..3448a3f9cc8c90ae71809075f1cc9c2d313fe167 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 #include <linux/ioport.h>
@@ -461,8 +461,10 @@ static void __init setup_processor(void)
               cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
               proc_arch[cpu_architecture()], cr_alignment);
 
-       sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
-       sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
+       snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
+                list->arch_name, ENDIANNESS);
+       snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c",
+                list->elf_name, ENDIANNESS);
        elf_hwcap = list->elf_hwcap;
 #ifndef CONFIG_ARM_THUMB
        elf_hwcap &= ~HWCAP_THUMB;
index 381d23a497c16b2f682da4b7a81c42af92ae9f70..00f79e59985bccaf54bd3b1c8f2e292f49014a47 100644 (file)
@@ -1,4 +1,4 @@
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
 
index 62e7c61d0342754193cf4833b16b57723b081f73..d2b177905cdb4c46def1de346ec7296425e1e315 100644 (file)
@@ -12,7 +12,7 @@
  *  have a non-standard calling sequence on the Linux/arm
  *  platform.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
index 5a54b95d6bd29ddc2c200b0943c4c0e37389abe8..8c57dd3680e9eeee46f5476d10c4c295c8796568 100644 (file)
@@ -11,7 +11,7 @@
  *  This file contains the ARM-specific time handling details:
  *  reading the RTC at bootup, etc...
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/time.h>
index 1040c00405d0f362916c77030249fff754eda5e8..8200deaa14f680b553bdea41652fac0aaa58e23a 100644 (file)
@@ -43,7 +43,7 @@
 
 struct cputopo_arm cpu_topology[NR_CPUS];
 
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+const struct cpumask *cpu_coregroup_mask(int cpu)
 {
        return &cpu_topology[cpu].core_sibling;
 }
index d2cb0b3c987216b4b7eea39289b739fbc7d0136d..e7e8365795c3d3272a4ef56d34d41662acd608b8 100644 (file)
@@ -39,7 +39,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
index 1796157e3dd540dcb3772867a43d2018f10eef11..e42adc6bcdb1d52bacf4bd4020438a02098187e5 100644 (file)
@@ -8,7 +8,6 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
index 10d868a5a48135840278022e153f3610b0b7a640..d6408d1ee543fe5e3ceabbcda01b25efb07676ba 100644 (file)
@@ -1,5 +1,9 @@
+#include <asm/unwind.h>
+
 #if __LINUX_ARM_ARCH__ >= 6
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        bne     1b
        bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        movne   r0, #1
 2:     bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #else
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r2, r0, #31
@@ -49,6 +61,8 @@
        str     r2, [r1, r0, lsl #2]
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
 /**
@@ -59,7 +73,9 @@
  * Note: we can trivially conditionalise the store instruction
  * to avoid dirtying the data cache.
  */
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r3, r0, #31
@@ -73,5 +89,7 @@
        moveq   r0, #0
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #endif
index 68ed5b62e83976d906bad4409fdabda385caaf96..f4027862172f8a4f1082ae06d7568615f3e5ad45 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_change_bit)
-       bitop   eor
-ENDPROC(_change_bit)
+bitop  _change_bit, eor
index 4c04c3b51eeb0d11bc3b755044b0a63ca6f0db1b..f6b75fb64d30557c5b22655adec3ba2bd34b0c07 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_clear_bit)
-       bitop   bic
-ENDPROC(_clear_bit)
+bitop  _clear_bit, bic
index bbee5c66a23e177494875e5db4fc19da97ed0d73..618fedae4b370aac8b65c2a39ae51046b0ff711a 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                .text
 
-ENTRY(_set_bit)
-       bitop   orr
-ENDPROC(_set_bit)
+bitop  _set_bit, orr
index 15a4d431f229440979aaf179fd423eb647b8da0f..4becdc3a59cbb60717bae345ec7b3f58243abdb6 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit)
-       testop  eor, str
-ENDPROC(_test_and_change_bit)
+testop _test_and_change_bit, eor, str
index 521b66b5b95da197fa661f142547414399a0af59..918841dcce7ad57ef5e880f1c09547404070fbe5 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit)
-       testop  bicne, strne
-ENDPROC(_test_and_clear_bit)
+testop _test_and_clear_bit, bicne, strne
index 1c98cc2185bb0885ae0cac805193f52d34345608..8d1b2fe9e4873ba8d53ba75773a7e30e92292b7c 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit)
-       testop  orreq, streq
-ENDPROC(_test_and_set_bit)
+testop _test_and_set_bit, orreq, streq
index a6b7991d7fe8462f325b903a11ea8da25e88f1ad..d111c3e9924986d206d0df439d12674e0a4855c8 100644 (file)
@@ -195,12 +195,6 @@ if ARCH_AT91SAM9260
 
 comment "AT91SAM9260 Variants"
 
-config ARCH_AT91SAM9260_SAM9XE
-       bool "AT91SAM9XE"
-       help
-         Select this if you are using Atmel's AT91SAM9XE System-on-Chip.
-         They are basically AT91SAM9260s with various sizes of embedded Flash.
-
 comment "AT91SAM9260 / AT91SAM9XE Board Type"
 
 config MACH_AT91SAM9260EK
index a4401d6b5b07b98f46492746f2cfbffc0a00d543..adad70db70eb8ce62191a481764efe2d09ee2bae 100644 (file)
@@ -98,7 +98,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
 
 static struct resource usba_udc_resources[] = {
        [0] = {
@@ -1021,8 +1021,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -1035,7 +1035,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 01d8bbd1468ba5900990cd4cc2f53a37166c3281..ad930688358ca1c5683e984dc1b85799b582c5c0 100644 (file)
@@ -83,7 +83,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_GADGET_AT91
+#ifdef CONFIG_USB_AT91
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -877,8 +877,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -891,7 +891,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index b84a9f642f5953a5ff527d3b593b1a628b61232b..0d20677fbef027591c91c2d442d528f7fa6c73f0 100644 (file)
@@ -195,9 +195,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
        CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
        CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
-       CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk),
-       CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk),
-       CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk),
+       CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
+       CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
+       CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
        CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
        /* more usart lookup table for DT entries */
        CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
index 24b6f8c0440ddc0c4b4661bc1bbf8b4f51c9b399..629fa977497239f171d66ef47563c3da9d2b0127 100644 (file)
@@ -84,7 +84,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_GADGET_AT91
+#ifdef CONFIG_USB_AT91
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -837,8 +837,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -851,7 +851,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 3b70b3897d950b5abc0f2f56cb68894b9e873b90..a178b58b0b9c8d59850ca91f0ecab9203198bbcc 100644 (file)
@@ -87,7 +87,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_GADGET_AT91
+#ifdef CONFIG_USB_AT91
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -816,8 +816,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -830,7 +830,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 3faa1fde9ad9541a95baf25b01f1e9ea9a380c1b..d5fbac9ff4faed0da1c112869b5c5144c4cfe2f6 100644 (file)
@@ -92,7 +92,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
  *  USB Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#ifdef CONFIG_USB_GADGET_AT91
+#ifdef CONFIG_USB_AT91
 static struct at91_udc_data udc_data;
 
 static struct resource udc_resources[] = {
@@ -1196,8 +1196,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -1210,7 +1210,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 000b5e1da9650ede46410c619784b3956bf00a9f..09a16d6bd5cdafa5a825fdffa38d769517bd483d 100644 (file)
@@ -197,7 +197,7 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
 static struct resource usba_udc_resources[] = {
        [0] = {
                .start  = AT91SAM9G45_UDPHS_FIFO,
@@ -1332,8 +1332,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -1346,7 +1346,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 305a851b5bff950f60b374fc5ab709f51bbebdaf..628eb566d60ce2e5b7620e903417b010aede16fd 100644 (file)
@@ -75,7 +75,7 @@ void __init at91_add_device_hdmac(void) {}
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
 
 static struct resource usba_udc_resources[] = {
        [0] = {
@@ -908,8 +908,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
 #if defined(CONFIG_SERIAL_ATMEL)
 static struct resource dbgu_resources[] = {
        [0] = {
-               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
-               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .start  = AT91_BASE_SYS + AT91_DBGU,
+               .end    = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -922,7 +922,6 @@ static struct resource dbgu_resources[] = {
 static struct atmel_uart_data dbgu_data = {
        .use_dma_tx     = 0,
        .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
-       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
 };
 
 static u64 dbgu_dmamask = DMA_BIT_MASK(32);
index 0487ea10c2d68bce193eb29c83058e34f3d55550..4282d96dffa808b1ebf059227d088ca3b92ec441 100644 (file)
@@ -130,19 +130,14 @@ static struct mtd_partition __initdata afeb9260_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(afeb9260_nand_partition);
-       return afeb9260_nand_partition;
-}
-
 static struct atmel_nand_data __initdata afeb9260_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
        .bus_width_16   = 0,
+       .parts          = afeb9260_nand_partition,
+       .num_parts      = ARRAY_SIZE(afeb9260_nand_partition),
 };
 
 
index 747b2eaa9737c134ffcb81006b9b5a807087a3d3..f90cfb32bad2b89815c0ed292b15721dcaa393be 100644 (file)
@@ -132,19 +132,14 @@ static struct mtd_partition __initdata cam60_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(cam60_nand_partition);
-       return cam60_nand_partition;
-}
-
 static struct atmel_nand_data __initdata cam60_nand_data = {
        .ale            = 21,
        .cle            = 22,
        // .det_pin     = ... not there
        .rdy_pin        = AT91_PIN_PA9,
        .enable_pin     = AT91_PIN_PA7,
-       .partition_info = nand_partitions,
+       .parts          = cam60_nand_partition,
+       .num_parts      = ARRAY_SIZE(cam60_nand_partition),
 };
 
 static struct sam9_smc_config __initdata cam60_nand_smc_config = {
index 062670351a6a11b9f82551378cdb00dc2675de44..5dffd3be62d25878b52cdbb46150a7d71ad965ac 100644 (file)
@@ -169,19 +169,14 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
-       return cap9adk_nand_partitions;
-}
-
 static struct atmel_nand_data __initdata cap9adk_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
 //     .rdy_pin        = ... not connected
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = cap9adk_nand_partitions,
+       .num_parts      = ARRAY_SIZE(cap9adk_nand_partitions),
 };
 
 static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
index 15a3f1a87ab05f9253dce15afc1bdb4746180665..e61351ffad50c15399dba98cb7b8b7fa9116728e 100644 (file)
@@ -97,19 +97,14 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
-       return kb9202_nand_partition;
-}
-
 static struct atmel_nand_data __initdata kb9202_nand_data = {
        .ale            = 22,
        .cle            = 21,
        // .det_pin     = ... not there
        .rdy_pin        = AT91_PIN_PC29,
        .enable_pin     = AT91_PIN_PC28,
-       .partition_info = nand_partitions,
+       .parts          = kb9202_nand_partition,
+       .num_parts      = ARRAY_SIZE(kb9202_nand_partition),
 };
 
 static void __init kb9202_board_init(void)
index 6094496f7edb3344843cc32b88ff28acdbefde97..ef816c17dc61ebd0a0b9fb0c04ab134912f5b4c7 100644 (file)
@@ -182,19 +182,14 @@ static struct mtd_partition __initdata neocore926_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(neocore926_nand_partition);
-       return neocore926_nand_partition;
-}
-
 static struct atmel_nand_data __initdata neocore926_nand_data = {
        .ale                    = 21,
        .cle                    = 22,
        .rdy_pin                = AT91_PIN_PB19,
        .rdy_pin_active_low     = 1,
        .enable_pin             = AT91_PIN_PD15,
-       .partition_info         = nand_partitions,
+       .parts                  = neocore926_nand_partition,
+       .num_parts              = ARRAY_SIZE(neocore926_nand_partition),
 };
 
 static struct sam9_smc_config __initdata neocore926_nand_smc_config = {
index 938cc390bea3099c59f67a8988fc3fddfe7c9925..07421bdb88eaf7f1b985a39c23bac74a7d61dd08 100644 (file)
@@ -130,19 +130,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index b4ac30e38a9e396102a7a466cd8fb25fc2d05cee..80a8c9c6e92221f53b2024f95d41a1be80e90afe 100644 (file)
@@ -138,19 +138,14 @@ static struct mtd_partition __initdata dk_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(dk_nand_partition);
-       return dk_nand_partition;
-}
-
 static struct atmel_nand_data __initdata dk_nand_data = {
        .ale            = 22,
        .cle            = 21,
        .det_pin        = AT91_PIN_PB1,
        .rdy_pin        = AT91_PIN_PC2,
        // .enable_pin  = ... not there
-       .partition_info = nand_partitions,
+       .parts          = dk_nand_partition,
+       .num_parts      = ARRAY_SIZE(dk_nand_partition),
 };
 
 #define DK_FLASH_BASE  AT91_CHIPSELECT_0
index 2a21e790250e5bcb9baeb2a0588ce37ed68c526a..072d53af98d9ebdd594dc9d17efd68c479341976 100644 (file)
@@ -131,19 +131,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 89c8b579bfda2949cc47c43b7bec46e5bb1efbcc..4f10181a07822b4a4a93b0634aa668f428951a19 100644 (file)
@@ -173,19 +173,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 3741f43cdae908c9fca1836c48215a812bd07555..b005b738e8ff7bc6dc4af3c8e173421bd9b234c7 100644 (file)
@@ -179,19 +179,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 22,
        .cle            = 21,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PC15,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index a580dd451a41549be5dce7ecfa584da7f2ec5081..bccdcf23caa106e392dba97fa4df69f9775a5337 100644 (file)
@@ -180,19 +180,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 8d77c2ff96b2bc3351bd3dc0c237e7e8397fa176..64fc75c9d0ac118730cac024eeb94c4d3da17611 100644 (file)
@@ -157,19 +157,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 /* det_pin is not connected */
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 2d6203ac1a42f87c0bb4b8a3c5774ed7e11e0be1..92de9127923a6dd0ecf6b61780129a1e3e9d6cf2 100644 (file)
@@ -137,19 +137,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 /* det_pin is not connected */
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC8,
        .enable_pin     = AT91_PIN_PC14,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index 39a28effc3df9d2443211e769c7d7de72508957d..b2b748239f365ab77627a6d96a7c442be91fd161 100644 (file)
@@ -88,19 +88,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        },
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PD17,
        .enable_pin     = AT91_PIN_PB6,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
index c73d25e5faea84c876b4b7e539aa0f68eb3e2271..0df01c6e2d0c1b458bc89ac41e46740302eda69b 100644 (file)
@@ -97,18 +97,12 @@ static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
        },
 };
 
-static struct mtd_partition * __init
-snapper9260_nand_partition_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
-       return snapper9260_nand_partitions;
-}
-
 static struct atmel_nand_data __initdata snapper9260_nand_data = {
        .ale            = 21,
        .cle            = 22,
        .rdy_pin        = AT91_PIN_PC13,
-       .partition_info = snapper9260_nand_partition_info,
+       .parts          = snapper9260_nand_partitions,
+       .num_parts      = ARRAY_SIZE(snapper9260_nand_partitions),
        .bus_width_16   = 0,
 };
 
index 5852d3d9890c8d53d90ae185fdad8945f0044963..0a20bab21f998ef5597be890f9ed47977d27d19f 100644 (file)
@@ -190,19 +190,14 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
        }
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(ek_nand_partition);
-       return ek_nand_partition;
-}
-
 static struct atmel_nand_data __initdata ek_nand_data = {
        .ale            = 21,
        .cle            = 22,
 //     .det_pin        = ... not connected
        .rdy_pin        = AT91_PIN_PA22,
        .enable_pin     = AT91_PIN_PD15,
-       .partition_info = nand_partitions,
+       .parts          = ek_nand_partition,
+       .num_parts      = ARRAY_SIZE(ek_nand_partition),
 };
 
 static struct sam9_smc_config __initdata usb_a9260_nand_smc_config = {
index 3c288b396fc4333caca5d1b0710ec9037ffca464..12a3f955162b2eb84ce1346ee2eb090bc0113442 100644 (file)
@@ -172,19 +172,14 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = {
        }
 };
 
-static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(yl9200_nand_partition);
-       return yl9200_nand_partition;
-}
-
 static struct atmel_nand_data __initdata yl9200_nand_data = {
        .ale            = 6,
        .cle            = 7,
        // .det_pin     = ... not connected
        .rdy_pin        = AT91_PIN_PC14,        /* R/!B (Sheet10) */
        .enable_pin     = AT91_PIN_PC15,        /* !CE  (Sheet10) */
-       .partition_info = nand_partitions,
+       .parts          = yl9200_nand_partition,
+       .num_parts      = ARRAY_SIZE(yl9200_nand_partition),
 };
 
 /*
@@ -389,7 +384,7 @@ static struct spi_board_info yl9200_spi_devices[] = {
 #include <video/s1d13xxxfb.h>
 
 
-static void __init yl9200_init_video(void)
+static void yl9200_init_video(void)
 {
        /* NWAIT Signal */
        at91_set_A_periph(AT91_PIN_PC6, 0);
index 1cfeac1483d6d504fd28506f90cb631e35dd6c6a..a851e6c984218d14533fd5157c7e58fc76c5fc81 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/cpuidle.h>
 #include <asm/proc-fns.h>
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include "pm.h"
 
@@ -33,7 +34,8 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-                              struct cpuidle_state *state)
+                       struct cpuidle_driver *drv,
+                              int index)
 {
        struct timeval before, after;
        int idle_time;
@@ -41,10 +43,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 
        local_irq_disable();
        do_gettimeofday(&before);
-       if (state == &dev->states[0])
+       if (index == 0)
                /* Wait for interrupt state */
                cpu_do_idle();
-       else if (state == &dev->states[1]) {
+       else if (index == 1) {
                asm("b 1f; .align 5; 1:");
                asm("mcr p15, 0, r0, c7, c10, 4");      /* drain write buffer */
                saved_lpr = sdram_selfrefresh_enable();
@@ -55,34 +57,38 @@ static int at91_enter_idle(struct cpuidle_device *dev,
        local_irq_enable();
        idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
                        (after.tv_usec - before.tv_usec);
-       return idle_time;
+
+       dev->last_residency = idle_time;
+       return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
 static int at91_init_cpuidle(void)
 {
        struct cpuidle_device *device;
-
-       cpuidle_register_driver(&at91_idle_driver);
+       struct cpuidle_driver *driver = &at91_idle_driver;
 
        device = &per_cpu(at91_cpuidle_device, smp_processor_id());
        device->state_count = AT91_MAX_STATES;
+       driver->state_count = AT91_MAX_STATES;
 
        /* Wait for interrupt state */
-       device->states[0].enter = at91_enter_idle;
-       device->states[0].exit_latency = 1;
-       device->states[0].target_residency = 10000;
-       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[0].name, "WFI");
-       strcpy(device->states[0].desc, "Wait for interrupt");
+       driver->states[0].enter = at91_enter_idle;
+       driver->states[0].exit_latency = 1;
+       driver->states[0].target_residency = 10000;
+       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[0].name, "WFI");
+       strcpy(driver->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and RAM self refresh state */
-       device->states[1].enter = at91_enter_idle;
-       device->states[1].exit_latency = 10;
-       device->states[1].target_residency = 10000;
-       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[1].name, "RAM_SR");
-       strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
+       driver->states[1].enter = at91_enter_idle;
+       driver->states[1].exit_latency = 10;
+       driver->states[1].target_residency = 10000;
+       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[1].name, "RAM_SR");
+       strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");
+
+       cpuidle_register_driver(&at91_idle_driver);
 
        if (cpuidle_register_device(device)) {
                printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
index d07767f4052edf316e74598b8fcc04f121fe7372..eac92e995bb52ba1d0c81cc55af29b4cf6e97b3a 100644 (file)
@@ -117,7 +117,8 @@ struct atmel_nand_data {
        u8              ale;            /* address line number connected to ALE */
        u8              cle;            /* address line number connected to CLE */
        u8              bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition* (*partition_info)(int, int*);
+       struct mtd_partition *parts;
+       unsigned int    num_parts;
 };
 extern void __init at91_add_device_nand(struct atmel_nand_data *data);
 
index 8f4866045b41e213172c761f522ffca720a5802e..ec164a4124c9b27aa0c3b72325dc91ec13ddc673 100644 (file)
@@ -19,7 +19,7 @@
 #define BOARD_HAVE_NAND_16BIT  (1 << 31)
 static inline int board_have_nand_16bit(void)
 {
-       return system_rev & BOARD_HAVE_NAND_16BIT;
+       return (system_rev & BOARD_HAVE_NAND_16BIT) ? 1 : 0;
 }
 
 #endif /* __ARCH_SYSTEM_REV_H__ */
index 8eb459f3f5b7a4c43769c2283bba785ce17131be..8e4a1bd0ab1d6ebd2eaefd443d3b354c99cda8d5 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
+#include <mach/hardware.h>
+
 #define VMALLOC_END            (AT91_VIRT_BASE & PGDIR_MASK)
 
 #endif
index 43eadbcc29ede940fd5c4035c2b6abacbcdb2a3b..430da120a297fe08620eaba672c65e283171bd99 100644 (file)
@@ -235,7 +235,7 @@ void __init bcmring_init_timer(void)
         */
        bcmring_clocksource_init();
 
-       sp804_clockevents_register(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
+       sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
 }
 
 struct sys_timer bcmring_timer = {
index 0ca00050666aa56cc920bc1f81f0af3196bb234a..f4d4d6d174d06e9c049756de6089e02e790abe8a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include <linux/irqreturn.h>
 #include <linux/proc_fs.h>
 #include <linux/slab.h>
@@ -35,6 +36,7 @@
 #include <linux/mm.h>
 #include <linux/pfn.h>
 #include <linux/atomic.h>
+#include <linux/sched.h>
 #include <mach/dma.h>
 
 /* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
index 8616876abb9f92df76fd4a53de0bdc01aefd494b..1adec78ec940ef7a620a23e88752a1f6c0c2d642 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <asm/page.h>
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
index 26d94c0b555cb210d53ebde3df94348e524cc210..11c3db985285880ac7a2f22b13b51ff677fcae46 100644 (file)
@@ -377,7 +377,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = {
        .nr_parts       = ARRAY_SIZE(da830_evm_nand_partitions),
        .ecc_mode       = NAND_ECC_HW,
        .ecc_bits       = 4,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .bbt_td         = &da830_evm_nand_bbt_main_descr,
        .bbt_md         = &da830_evm_nand_bbt_mirror_descr,
        .timing         = &da830_evm_nandflash_timing,
index ec21663f8ddc073516f65a7b5fe7e99b14073de4..6659a90dbcadafffdc6ae4988f1a1c6148a955b5 100644 (file)
@@ -256,7 +256,7 @@ static struct davinci_nand_pdata da850_evm_nandflash_data = {
        .nr_parts       = ARRAY_SIZE(da850_evm_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
        .ecc_bits       = 4,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .timing         = &da850_evm_nandflash_timing,
 };
 
@@ -753,7 +753,7 @@ static struct snd_platform_data da850_evm_snd_data = {
        .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction),
        .tdm_slots      = 2,
        .serial_dir     = da850_iis_serializer_direction,
-       .asp_chan_q     = EVENTQ_1,
+       .asp_chan_q     = EVENTQ_0,
        .version        = MCASP_VERSION_2,
        .txnumevt       = 1,
        .rxnumevt       = 1,
index 65566280b7c987f54243df5559f1c458807e020d..4e0e707c313d7b9e51f87acbece9b3e0af3a97f3 100644 (file)
@@ -77,7 +77,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
        .ecc_bits               = 4,
 };
 
index b307470b071dfd0679ae4f3d2a11d84e0d001810..ff2d2413279a26482411dcbb8728266b93e8bbe4 100644 (file)
@@ -74,7 +74,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW_SYNDROME,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
 };
 
 static struct resource davinci_nand_resources[] = {
index 04c43abcca66f48781e9de61cdd2b1374082beb5..46e1f4173b9735c622c8a95c5c9a605782c1eda6 100644 (file)
@@ -107,7 +107,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
                /* UBL (a few copies) plus U-Boot */
                .name           = "bootloader",
                .offset         = 0,
-               .size           = 28 * NAND_BLOCK_SIZE,
+               .size           = 30 * NAND_BLOCK_SIZE,
                .mask_flags     = MTD_WRITEABLE, /* force read-only */
        }, {
                /* U-Boot environment */
@@ -139,7 +139,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .parts                  = davinci_nand_partitions,
        .nr_parts               = ARRAY_SIZE(davinci_nand_partitions),
        .ecc_mode               = NAND_ECC_HW,
-       .options                = NAND_USE_FLASH_BBT,
+       .bbt_options            = NAND_BBT_USE_FLASH,
        .ecc_bits               = 4,
 };
 
index a005e7691ddd1535845b3e42409e4bc990fa16a5..0cf8abf78d33d878acd1dbf3480e7d92403e2c66 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/phy.h>
 #include <linux/clk.h>
 #include <linux/videodev2.h>
+#include <linux/export.h>
 
 #include <media/tvp514x.h>
 
@@ -150,7 +151,7 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = {
        .parts          = davinci_evm_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(davinci_evm_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .timing         = &davinci_evm_nandflash_timing,
 };
 
index 337c45e3e44dbb8c1ac88365d33777379fb55546..635bf7740157bb7ea88b94580c98ead839f44068 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/clk.h>
+#include <linux/export.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -563,7 +564,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
        int val;
        u32 value;
 
-       if (!vpif_vsclkdis_reg || !cpld_client)
+       if (!vpif_vidclkctl_reg || !cpld_client)
                return -ENXIO;
 
        val = i2c_smbus_read_byte(cpld_client);
@@ -571,7 +572,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
                return val;
 
        spin_lock_irqsave(&vpif_reg_lock, flags);
-       value = __raw_readl(vpif_vsclkdis_reg);
+       value = __raw_readl(vpif_vidclkctl_reg);
        if (mux_mode) {
                val &= VPIF_INPUT_TWO_CHANNEL;
                value |= VIDCH1CLK;
@@ -579,7 +580,7 @@ static int setup_vpif_input_channel_mode(int mux_mode)
                val |= VPIF_INPUT_ONE_CHANNEL;
                value &= ~VIDCH1CLK;
        }
-       __raw_writel(value, vpif_vsclkdis_reg);
+       __raw_writel(value, vpif_vidclkctl_reg);
        spin_unlock_irqrestore(&vpif_reg_lock, flags);
 
        err = i2c_smbus_write_byte(cpld_client, val);
index 6efc84cceca093eff0299da9ddfae3b666c1eadd..3cfff555e8f22a842eb75f3614d5e5605eaf642b 100644 (file)
@@ -396,7 +396,8 @@ static struct davinci_nand_pdata mityomapl138_nandflash_data = {
        .parts          = mityomapl138_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(mityomapl138_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
+       .bbt_options    = NAND_BBT_USE_FLASH,
+       .options        = NAND_BUSWIDTH_16,
        .ecc_bits       = 1, /* 4 bit mode is not supported with 16 bit NAND */
 };
 
index 38d6f644d8b9e39ae32aaeaba4d08d0f00d47915..e5f231aefee428bfd26cde4b4b05d7de45627992 100644 (file)
@@ -87,7 +87,7 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
        .parts          = davinci_ntosd2_nandflash_partition,
        .nr_parts       = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
 };
 
 static struct resource davinci_ntosd2_nandflash_resource[] = {
index 90ee7b5aabdcfabdf1ccaf30ea1129a1377a6a02..f69e40a29e0256005801d46756529dadb3e1d5db 100644 (file)
@@ -144,7 +144,7 @@ static struct davinci_nand_pdata nand_config = {
        .parts          = nand_partitions,
        .nr_parts       = ARRAY_SIZE(nand_partitions),
        .ecc_mode       = NAND_ECC_HW,
-       .options        = NAND_USE_FLASH_BBT,
+       .bbt_options    = NAND_BBT_USE_FLASH,
        .ecc_bits       = 1,
 };
 
index ba8b12b2913ba2324817f55b9a2a9e12b2e933a4..f2232ca6d0707b7f8b5c64b976778000430f4bdf 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
+#include <linux/module.h>
 
 #include <mach/clock.h>
 #include <mach/cdce949.h>
index 41669ecc1f91f14f0d4cade20f2cf502deb8774b..5bba7070f2714a87ab4f5c4f5cb902c7b7642622 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <mach/cpufreq.h>
index 0b314bf16f7f49382622170e23efd94222be5ac6..a30c7c5a6d83a4703b968fe15212faec24ee6db1 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/cpuidle.h>
 #include <linux/io.h>
+#include <linux/export.h>
 #include <asm/proc-fns.h>
 
 #include <mach/cpuidle.h>
@@ -78,9 +79,11 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-                                               struct cpuidle_state *state)
+                               struct cpuidle_driver *drv,
+                                               int index)
 {
-       struct davinci_ops *ops = cpuidle_get_statedata(state);
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
+       struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
        struct timeval before, after;
        int idle_time;
 
@@ -98,13 +101,17 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
        local_irq_enable();
        idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
                        (after.tv_usec - before.tv_usec);
-       return idle_time;
+
+       dev->last_residency = idle_time;
+
+       return index;
 }
 
 static int __init davinci_cpuidle_probe(struct platform_device *pdev)
 {
        int ret;
        struct cpuidle_device *device;
+       struct cpuidle_driver *driver = &davinci_idle_driver;
        struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
 
        device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -116,32 +123,33 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
 
        ddr2_reg_base = pdata->ddr2_ctlr_base;
 
-       ret = cpuidle_register_driver(&davinci_idle_driver);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register driver\n");
-               return ret;
-       }
-
        /* Wait for interrupt state */
-       device->states[0].enter = davinci_enter_idle;
-       device->states[0].exit_latency = 1;
-       device->states[0].target_residency = 10000;
-       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[0].name, "WFI");
-       strcpy(device->states[0].desc, "Wait for interrupt");
+       driver->states[0].enter = davinci_enter_idle;
+       driver->states[0].exit_latency = 1;
+       driver->states[0].target_residency = 10000;
+       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[0].name, "WFI");
+       strcpy(driver->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and DDR self refresh state */
-       device->states[1].enter = davinci_enter_idle;
-       device->states[1].exit_latency = 10;
-       device->states[1].target_residency = 10000;
-       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[1].name, "DDR SR");
-       strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+       driver->states[1].enter = davinci_enter_idle;
+       driver->states[1].exit_latency = 10;
+       driver->states[1].target_residency = 10000;
+       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[1].name, "DDR SR");
+       strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
        if (pdata->ddr2_pdown)
                davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
-       cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
+       cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
 
        device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+       driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+
+       ret = cpuidle_register_driver(&davinci_idle_driver);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register driver\n");
+               return ret;
+       }
 
        ret = cpuidle_register_device(device);
        if (ret) {
index 0b68ed534f8e6d3d0a16effc5cc4811a8f94f85d..af27c130595fb6897cb104253ad157f567d53f04 100644 (file)
@@ -161,7 +161,6 @@ static struct clk dsp_clk = {
        .name = "dsp",
        .parent = &pll1_sysclk1,
        .lpsc = DM646X_LPSC_C64X_CPU,
-       .flags = PSC_DSP,
        .usecount = 1,                  /* REVISIT how to disable? */
 };
 
index fbaae4772b91c6237b2a1499b28af7a79eb2de19..960e9de47e1e7549d30886b09fd4dbcb1c7991af 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <asm-generic/gpio.h>
 
+#define __ARM_GPIOLIB_COMPLEX
+
 /* The inline versions use the static inlines in the driver header */
 #include "gpio-davinci.h"
 
index 025151049f0517a103c4efb96ee86d465c3fff19..1cf555aef896c39342bd7306c09cfa1358451fe6 100644 (file)
@@ -74,8 +74,10 @@ struct davinci_nand_pdata {          /* platform_data */
        nand_ecc_modes_t        ecc_mode;
        u8                      ecc_bits;
 
-       /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+       /* e.g. NAND_BUSWIDTH_16 */
        unsigned                options;
+       /* e.g. NAND_BBT_USE_FLASH */
+       unsigned                bbt_options;
 
        /* Main and mirror bbt descriptor overrides */
        struct nand_bbt_descr   *bbt_td;
index fa59c097223dc85ec965224e9ebfc0ac8dccf2c2..8bc3fc2561711801610461c46b803a7fbfbfde9a 100644 (file)
 #define PTCMD          0x120
 #define PTSTAT         0x128
 #define PDSTAT         0x200
-#define PDCTL1         0x304
+#define PDCTL          0x300
 #define MDSTAT         0x800
 #define MDCTL          0xA00
 
 #define PSC_STATE_ENABLE       3
 
 #define MDSTAT_STATE_MASK      0x3f
+#define PDSTAT_STATE_MASK      0x1f
 #define MDCTL_FORCE            BIT(31)
+#define PDCTL_NEXT             BIT(1)
+#define PDCTL_EPCGOOD          BIT(8)
 
 #ifndef __ASSEMBLER__
 
index 1fb6bdff38c1f5e9ff796e72c4c57be824919209..d7e210f4b55c85d7e2a2fc4831fb3f0a77f72990 100644 (file)
@@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
 void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                unsigned int id, bool enable, u32 flags)
 {
-       u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
+       u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
        void __iomem *psc_base;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        u32 next_state = PSC_STATE_ENABLE;
@@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                mdctl |= MDCTL_FORCE;
        __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
 
-       pdstat = __raw_readl(psc_base + PDSTAT);
-       if ((pdstat & 0x00000001) == 0) {
-               pdctl1 = __raw_readl(psc_base + PDCTL1);
-               pdctl1 |= 0x1;
-               __raw_writel(pdctl1, psc_base + PDCTL1);
+       pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
+       if ((pdstat & PDSTAT_STATE_MASK) == 0) {
+               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
+               pdctl |= PDCTL_NEXT;
+               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
 
                ptcmd = 1 << domain;
                __raw_writel(ptcmd, psc_base + PTCMD);
@@ -92,9 +92,9 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                        epcpr = __raw_readl(psc_base + EPCPR);
                } while ((((epcpr >> domain) & 1) == 0));
 
-               pdctl1 = __raw_readl(psc_base + PDCTL1);
-               pdctl1 |= 0x100;
-               __raw_writel(pdctl1, psc_base + PDCTL1);
+               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
+               pdctl |= PDCTL_EPCGOOD;
+               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
        } else {
                ptcmd = 1 << domain;
                __raw_writel(ptcmd, psc_base + PTCMD);
index 94c78bc662753d54e18a4f819d9992fa2763fd66..2432a6b7dcac79b8f83e8261198835e45d1cd02f 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <mach/fb.h>
index 1ade3c34050741411701d185e224d76cb253a36f..8b2f1435bcacfa2a60ac6a53e75f369ee55a11d8 100644 (file)
@@ -116,8 +116,9 @@ static struct mtd_partition ts72xx_nand_parts[] = {
                .mask_flags     = MTD_WRITEABLE,        /* force read-only */
        }, {
                .name           = "Linux",
-               .offset         = MTDPART_OFS_APPEND,
-               .size           = 0,                    /* filled in later */
+               .offset         = MTDPART_OFS_RETAIN,
+               .size           = TS72XX_REDBOOT_PART_SIZE,
+                               /* leave so much for last partition */
        }, {
                .name           = "RedBoot",
                .offset         = MTDPART_OFS_APPEND,
@@ -126,28 +127,14 @@ static struct mtd_partition ts72xx_nand_parts[] = {
        },
 };
 
-static void ts72xx_nand_set_parts(uint64_t size,
-                                 struct platform_nand_chip *chip)
-{
-       /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
-       if (size == SZ_32M || size == SZ_128M) {
-               /* Set the "Linux" partition size */
-               ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
-
-               chip->partitions = ts72xx_nand_parts;
-               chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
-       } else {
-               pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
-       }
-}
-
 static struct platform_nand_data ts72xx_nand_data = {
        .chip = {
                .nr_chips       = 1,
                .chip_offset    = 0,
                .chip_delay     = 15,
                .part_probe_types = ts72xx_nand_part_probes,
-               .set_parts      = ts72xx_nand_set_parts,
+               .partitions     = ts72xx_nand_parts,
+               .nr_partitions  = ARRAY_SIZE(ts72xx_nand_parts),
        },
        .ctrl = {
                .cmd_ctrl       = ts72xx_nand_hwcontrol,
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
new file mode 100644 (file)
index 0000000..724ec0f
--- /dev/null
@@ -0,0 +1,349 @@
+# arch/arm/mach-exynos/Kconfig
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the EXYNOS4
+
+if ARCH_EXYNOS
+
+menu "SAMSUNG EXYNOS SoCs Support"
+
+choice
+       prompt "EXYNOS System Type"
+       default ARCH_EXYNOS4
+
+config ARCH_EXYNOS4
+       bool "SAMSUNG EXYNOS4"
+       help
+         Samsung EXYNOS4 SoCs based systems
+
+endchoice
+
+comment "EXYNOS SoCs"
+
+config CPU_EXYNOS4210
+       bool "SAMSUNG EXYNOS4210"
+       default y
+       depends on ARCH_EXYNOS4
+       select SAMSUNG_DMADEV
+       select ARM_CPU_SUSPEND if PM
+       select S5P_PM if PM
+       select S5P_SLEEP if PM
+       help
+         Enable EXYNOS4210 CPU support
+
+config SOC_EXYNOS4212
+       bool "SAMSUNG EXYNOS4212"
+       default y
+       depends on ARCH_EXYNOS4
+       select S5P_PM if PM
+       select S5P_SLEEP if PM
+       help
+         Enable EXYNOS4212 SoC support
+
+config SOC_EXYNOS4412
+       bool "SAMSUNG EXYNOS4412"
+       default y
+       depends on ARCH_EXYNOS4
+       help
+         Enable EXYNOS4412 SoC support
+
+config EXYNOS4_MCT
+       bool
+       default y
+       help
+         Use MCT (Multi Core Timer) as kernel timers
+
+config EXYNOS4_DEV_AHCI
+       bool
+       help
+         Compile in platform device definitions for AHCI
+
+config EXYNOS4_SETUP_FIMD0
+       bool
+       help
+         Common setup code for FIMD0.
+
+config EXYNOS4_DEV_PD
+       bool
+       help
+         Compile in platform device definitions for Power Domain
+
+config EXYNOS4_DEV_SYSMMU
+       bool
+       help
+         Common setup code for SYSTEM MMU in EXYNOS4
+
+config EXYNOS4_DEV_DWMCI
+       bool
+       help
+         Compile in platform device definitions for DWMCI
+
+config EXYNOS4_SETUP_I2C1
+       bool
+       help
+         Common setup code for i2c bus 1.
+
+config EXYNOS4_SETUP_I2C2
+       bool
+       help
+         Common setup code for i2c bus 2.
+
+config EXYNOS4_SETUP_I2C3
+       bool
+       help
+         Common setup code for i2c bus 3.
+
+config EXYNOS4_SETUP_I2C4
+       bool
+       help
+         Common setup code for i2c bus 4.
+
+config EXYNOS4_SETUP_I2C5
+       bool
+       help
+         Common setup code for i2c bus 5.
+
+config EXYNOS4_SETUP_I2C6
+       bool
+       help
+         Common setup code for i2c bus 6.
+
+config EXYNOS4_SETUP_I2C7
+       bool
+       help
+         Common setup code for i2c bus 7.
+
+config EXYNOS4_SETUP_KEYPAD
+       bool
+       help
+         Common setup code for keypad.
+
+config EXYNOS4_SETUP_SDHCI
+       bool
+       select EXYNOS4_SETUP_SDHCI_GPIO
+       help
+         Internal helper functions for EXYNOS4 based SDHCI systems.
+
+config EXYNOS4_SETUP_SDHCI_GPIO
+       bool
+       help
+         Common setup code for SDHCI gpio.
+
+config EXYNOS4_SETUP_FIMC
+       bool
+       help
+         Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_USB_PHY
+       bool
+       help
+         Common setup code for USB PHY controller
+
+# machine support
+
+if ARCH_EXYNOS4
+
+comment "EXYNOS4210 Boards"
+
+config MACH_SMDKC210
+       bool "SMDKC210"
+       select MACH_SMDKV310
+       help
+         Machine support for Samsung SMDKC210
+
+config MACH_SMDKV310
+       bool "SMDKV310"
+       select CPU_EXYNOS4210
+       select S5P_DEV_FIMD0
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_I2C1
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_FIMC3
+       select S5P_DEV_I2C_HDMIPHY
+       select S5P_DEV_MFC
+       select S5P_DEV_TV
+       select S5P_DEV_USB_EHCI
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select SAMSUNG_DEV_BACKLIGHT
+       select EXYNOS4_DEV_AHCI
+       select SAMSUNG_DEV_KEYPAD
+       select EXYNOS4_DEV_PD
+       select SAMSUNG_DEV_PWM
+       select EXYNOS4_DEV_SYSMMU
+       select EXYNOS4_SETUP_FIMD0
+       select EXYNOS4_SETUP_I2C1
+       select EXYNOS4_SETUP_KEYPAD
+       select EXYNOS4_SETUP_SDHCI
+       select EXYNOS4_SETUP_USB_PHY
+       help
+         Machine support for Samsung SMDKV310
+
+config MACH_ARMLEX4210
+       bool "ARMLEX4210"
+       select CPU_EXYNOS4210
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select EXYNOS4_DEV_AHCI
+       select EXYNOS4_DEV_SYSMMU
+       select EXYNOS4_SETUP_SDHCI
+       help
+         Machine support for Samsung ARMLEX4210 based on EXYNOS4210
+
+config MACH_UNIVERSAL_C210
+       bool "Mobile UNIVERSAL_C210 Board"
+       select CPU_EXYNOS4210
+       select S5P_GPIO_INT
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_FIMC3
+       select S5P_DEV_CSIS0
+       select S5P_DEV_FIMD0
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S3C_DEV_I2C1
+       select S3C_DEV_I2C3
+       select S3C_DEV_I2C5
+       select S5P_DEV_I2C_HDMIPHY
+       select S5P_DEV_MFC
+       select S5P_DEV_ONENAND
+       select S5P_DEV_TV
+       select EXYNOS4_DEV_PD
+       select EXYNOS4_SETUP_FIMD0
+       select EXYNOS4_SETUP_I2C1
+       select EXYNOS4_SETUP_I2C3
+       select EXYNOS4_SETUP_I2C5
+       select EXYNOS4_SETUP_SDHCI
+       select EXYNOS4_SETUP_FIMC
+       select S5P_SETUP_MIPIPHY
+       help
+         Machine support for Samsung Mobile Universal S5PC210 Reference
+         Board.
+
+config MACH_NURI
+       bool "Mobile NURI Board"
+       select CPU_EXYNOS4210
+       select S5P_GPIO_INT
+       select S3C_DEV_WDT
+       select S3C_DEV_RTC
+       select S5P_DEV_FIMD0
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S3C_DEV_I2C1
+       select S3C_DEV_I2C3
+       select S3C_DEV_I2C5
+       select S5P_DEV_CSIS0
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_FIMC3
+       select S5P_DEV_MFC
+       select S5P_DEV_USB_EHCI
+       select S5P_SETUP_MIPIPHY
+       select EXYNOS4_DEV_PD
+       select EXYNOS4_SETUP_FIMC
+       select EXYNOS4_SETUP_FIMD0
+       select EXYNOS4_SETUP_I2C1
+       select EXYNOS4_SETUP_I2C3
+       select EXYNOS4_SETUP_I2C5
+       select EXYNOS4_SETUP_SDHCI
+       select EXYNOS4_SETUP_USB_PHY
+       select S5P_SETUP_MIPIPHY
+       select SAMSUNG_DEV_PWM
+       select SAMSUNG_DEV_ADC
+       help
+         Machine support for Samsung Mobile NURI Board.
+
+config MACH_ORIGEN
+       bool "ORIGEN"
+       select CPU_EXYNOS4210
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC2
+       select S5P_DEV_FIMC0
+       select S5P_DEV_FIMC1
+       select S5P_DEV_FIMC2
+       select S5P_DEV_FIMC3
+       select S5P_DEV_FIMD0
+       select S5P_DEV_I2C_HDMIPHY
+       select S5P_DEV_MFC
+       select S5P_DEV_TV
+       select S5P_DEV_USB_EHCI
+       select SAMSUNG_DEV_BACKLIGHT
+       select SAMSUNG_DEV_PWM
+       select EXYNOS4_DEV_PD
+       select EXYNOS4_SETUP_FIMD0
+       select EXYNOS4_SETUP_SDHCI
+       select EXYNOS4_SETUP_USB_PHY
+       help
+         Machine support for ORIGEN based on Samsung EXYNOS4210
+
+comment "EXYNOS4212 Boards"
+
+config MACH_SMDK4212
+       bool "SMDK4212"
+       select SOC_EXYNOS4212
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S3C_DEV_I2C1
+       select S3C_DEV_I2C3
+       select S3C_DEV_I2C7
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select SAMSUNG_DEV_BACKLIGHT
+       select SAMSUNG_DEV_KEYPAD
+       select SAMSUNG_DEV_PWM
+       select EXYNOS4_SETUP_I2C1
+       select EXYNOS4_SETUP_I2C3
+       select EXYNOS4_SETUP_I2C7
+       select EXYNOS4_SETUP_KEYPAD
+       select EXYNOS4_SETUP_SDHCI
+       help
+         Machine support for Samsung SMDK4212
+
+comment "EXYNOS4412 Boards"
+
+config MACH_SMDK4412
+       bool "SMDK4412"
+       select SOC_EXYNOS4412
+       select MACH_SMDK4212
+       help
+         Machine support for Samsung SMDK4412
+endif
+
+if ARCH_EXYNOS4
+
+comment "Configuration for HSMMC 8-bit bus width"
+
+config EXYNOS4_SDHCI_CH0_8BIT
+       bool "Channel 0 with 8-bit bus"
+       help
+         Support HSMMC Channel 0 8-bit bus.
+         If selected, Channel 1 is disabled.
+
+config EXYNOS4_SDHCI_CH2_8BIT
+       bool "Channel 2 with 8-bit bus"
+       help
+         Support HSMMC Channel 2 8-bit bus.
+         If selected, Channel 3 is disabled.
+endif
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
new file mode 100644 (file)
index 0000000..59069a3
--- /dev/null
@@ -0,0 +1,60 @@
+# arch/arm/mach-exynos/Makefile
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+# Core support for EXYNOS4 system
+
+obj-$(CONFIG_ARCH_EXYNOS4)     += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o
+obj-$(CONFIG_ARCH_EXYNOS4)     += irq-eint.o dma.o pmu.o
+obj-$(CONFIG_CPU_EXYNOS4210)   += clock-exynos4210.o
+obj-$(CONFIG_SOC_EXYNOS4212)   += clock-exynos4212.o
+obj-$(CONFIG_PM)               += pm.o
+obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
+
+obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
+
+obj-$(CONFIG_EXYNOS4_MCT)      += mct.o
+
+obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDKC210)            += mach-smdkv310.o
+obj-$(CONFIG_MACH_SMDKV310)            += mach-smdkv310.o
+obj-$(CONFIG_MACH_ARMLEX4210)          += mach-armlex4210.o
+obj-$(CONFIG_MACH_UNIVERSAL_C210)      += mach-universal_c210.o
+obj-$(CONFIG_MACH_NURI)                        += mach-nuri.o
+obj-$(CONFIG_MACH_ORIGEN)              += mach-origen.o
+
+obj-$(CONFIG_MACH_SMDK4212)            += mach-smdk4x12.o
+obj-$(CONFIG_MACH_SMDK4412)            += mach-smdk4x12.o
+
+# device support
+
+obj-$(CONFIG_ARCH_EXYNOS4)             += dev-audio.o
+obj-$(CONFIG_EXYNOS4_DEV_AHCI)         += dev-ahci.o
+obj-$(CONFIG_EXYNOS4_DEV_PD)           += dev-pd.o
+obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)       += dev-sysmmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DWMCI)                += dev-dwmci.o
+
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC)       += setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0)      += setup-fimd0.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C1)       += setup-i2c1.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C2)       += setup-i2c2.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C3)       += setup-i2c3.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C4)       += setup-i2c4.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C5)       += setup-i2c5.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C6)       += setup-i2c6.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C7)       += setup-i2c7.o
+obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)     += setup-keypad.o
+obj-$(CONFIG_EXYNOS4_SETUP_SDHCI)      += setup-sdhci.o
+obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)    += setup-usb-phy.o
diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
new file mode 100644 (file)
index 0000000..b9862e2
--- /dev/null
@@ -0,0 +1,2 @@
+   zreladdr-y  += 0x40008000
+params_phys-y  := 0x40000100
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
new file mode 100644 (file)
index 0000000..b9d5ef6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/mach-exynos4/clock-exynos4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4210 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos4-clock.h>
+
+static struct sleep_save exynos4210_clock_save[] = {
+       SAVE_ITEM(S5P_CLKSRC_IMAGE),
+       SAVE_ITEM(S5P_CLKSRC_LCD1),
+       SAVE_ITEM(S5P_CLKDIV_IMAGE),
+       SAVE_ITEM(S5P_CLKDIV_LCD1),
+       SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
+       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4210),
+       SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
+       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210),
+};
+
+static struct clksrc_clk *sysclks[] = {
+       /* nothing here yet */
+};
+
+static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
+}
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk            = {
+                       .name           = "sclk_sata",
+                       .id             = -1,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_mout_corebus,
+               .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .devname        = "exynos4-fb.1",
+                       .enable         = exynos4_clksrc_mask_lcd1_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
+       },
+};
+
+static struct clk init_clocks_off[] = {
+       {
+               .name           = "sataphy",
+               .id             = -1,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "sata",
+               .id             = -1,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "fimd",
+               .devname        = "exynos4-fb.1",
+               .enable         = exynos4_clk_ip_lcd1_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4210_clock_suspend(void)
+{
+       s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+
+       return 0;
+}
+
+static void exynos4210_clock_resume(void)
+{
+       s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+}
+
+#else
+#define exynos4210_clock_suspend NULL
+#define exynos4210_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4210_clock_syscore_ops = {
+       .suspend        = exynos4210_clock_suspend,
+       .resume         = exynos4210_clock_resume,
+};
+
+void __init exynos4210_register_clocks(void)
+{
+       int ptr;
+
+       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU;
+       clk_mout_mpll.reg_src.shift = 8;
+       clk_mout_mpll.reg_src.size = 1;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+       register_syscore_ops(&exynos4210_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
new file mode 100644 (file)
index 0000000..77d5dec
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * linux/arch/arm/mach-exynos4/clock-exynos4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4212 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos4-clock.h>
+
+static struct sleep_save exynos4212_clock_save[] = {
+       SAVE_ITEM(S5P_CLKSRC_IMAGE),
+       SAVE_ITEM(S5P_CLKDIV_IMAGE),
+       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212),
+       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212),
+};
+
+static struct clk *clk_src_mpll_user_list[] = {
+       [0] = &clk_fin_mpll,
+       [1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clk_src_mpll_user = {
+       .sources        = clk_src_mpll_user_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mpll_user_list),
+};
+
+static struct clksrc_clk clk_mout_mpll_user = {
+       .clk = {
+               .name           = "mout_mpll_user",
+       },
+       .sources        = &clk_src_mpll_user,
+       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_mpll_user,
+};
+
+static struct clksrc_clk clksrcs[] = {
+       /* nothing here yet */
+};
+
+static struct clk init_clocks_off[] = {
+       /* nothing here yet */
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4212_clock_suspend(void)
+{
+       s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+
+       return 0;
+}
+
+static void exynos4212_clock_resume(void)
+{
+       s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+}
+
+#else
+#define exynos4212_clock_suspend NULL
+#define exynos4212_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4212_clock_syscore_ops = {
+       .suspend        = exynos4212_clock_suspend,
+       .resume         = exynos4212_clock_resume,
+};
+
+void __init exynos4212_register_clocks(void)
+{
+       int ptr;
+
+       /* usbphy1 is removed */
+       clkset_group_list[4] = NULL;
+
+       /* mout_mpll_user is used */
+       clkset_group_list[6] = &clk_mout_mpll_user.clk;
+       clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
+
+       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC;
+       clk_mout_mpll.reg_src.shift = 12;
+       clk_mout_mpll.reg_src.size = 1;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+       register_syscore_ops(&exynos4212_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
new file mode 100644 (file)
index 0000000..2894f0a
--- /dev/null
@@ -0,0 +1,1491 @@
+/* linux/arch/arm/mach-exynos4/clock.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
+#include <mach/exynos4-clock.h>
+
+static struct sleep_save exynos4_clock_save[] = {
+       SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
+       SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
+       SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
+       SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
+       SAVE_ITEM(S5P_CLKSRC_TOP0),
+       SAVE_ITEM(S5P_CLKSRC_TOP1),
+       SAVE_ITEM(S5P_CLKSRC_CAM),
+       SAVE_ITEM(S5P_CLKSRC_TV),
+       SAVE_ITEM(S5P_CLKSRC_MFC),
+       SAVE_ITEM(S5P_CLKSRC_G3D),
+       SAVE_ITEM(S5P_CLKSRC_LCD0),
+       SAVE_ITEM(S5P_CLKSRC_MAUDIO),
+       SAVE_ITEM(S5P_CLKSRC_FSYS),
+       SAVE_ITEM(S5P_CLKSRC_PERIL0),
+       SAVE_ITEM(S5P_CLKSRC_PERIL1),
+       SAVE_ITEM(S5P_CLKDIV_CAM),
+       SAVE_ITEM(S5P_CLKDIV_TV),
+       SAVE_ITEM(S5P_CLKDIV_MFC),
+       SAVE_ITEM(S5P_CLKDIV_G3D),
+       SAVE_ITEM(S5P_CLKDIV_LCD0),
+       SAVE_ITEM(S5P_CLKDIV_MAUDIO),
+       SAVE_ITEM(S5P_CLKDIV_FSYS0),
+       SAVE_ITEM(S5P_CLKDIV_FSYS1),
+       SAVE_ITEM(S5P_CLKDIV_FSYS2),
+       SAVE_ITEM(S5P_CLKDIV_FSYS3),
+       SAVE_ITEM(S5P_CLKDIV_PERIL0),
+       SAVE_ITEM(S5P_CLKDIV_PERIL1),
+       SAVE_ITEM(S5P_CLKDIV_PERIL2),
+       SAVE_ITEM(S5P_CLKDIV_PERIL3),
+       SAVE_ITEM(S5P_CLKDIV_PERIL4),
+       SAVE_ITEM(S5P_CLKDIV_PERIL5),
+       SAVE_ITEM(S5P_CLKDIV_TOP),
+       SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
+       SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
+       SAVE_ITEM(S5P_CLKSRC_MASK_TV),
+       SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
+       SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
+       SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
+       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
+       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
+       SAVE_ITEM(S5P_CLKDIV2_RATIO),
+       SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
+       SAVE_ITEM(S5P_CLKGATE_IP_CAM),
+       SAVE_ITEM(S5P_CLKGATE_IP_TV),
+       SAVE_ITEM(S5P_CLKGATE_IP_MFC),
+       SAVE_ITEM(S5P_CLKGATE_IP_G3D),
+       SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
+       SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
+       SAVE_ITEM(S5P_CLKGATE_IP_GPS),
+       SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
+       SAVE_ITEM(S5P_CLKGATE_BLOCK),
+       SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
+       SAVE_ITEM(S5P_CLKSRC_DMC),
+       SAVE_ITEM(S5P_CLKDIV_DMC0),
+       SAVE_ITEM(S5P_CLKDIV_DMC1),
+       SAVE_ITEM(S5P_CLKGATE_IP_DMC),
+       SAVE_ITEM(S5P_CLKSRC_CPU),
+       SAVE_ITEM(S5P_CLKDIV_CPU),
+       SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
+       SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
+       SAVE_ITEM(S5P_CLKGATE_IP_CPU),
+};
+
+struct clk clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
+       .rate           = 27000000,
+};
+
+struct clk clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
+};
+
+struct clk clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
+       .rate           = 27000000,
+};
+
+struct clk clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
+};
+
+static struct clk dummy_apb_pclk = {
+       .name           = "apb_pclk",
+       .id             = -1,
+};
+
+static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
+}
+
+static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
+}
+
+int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
+}
+
+int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
+}
+
+static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
+}
+
+static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
+}
+
+static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
+}
+
+/* Core list of CMU_CPU side */
+
+static struct clksrc_clk clk_mout_apll = {
+       .clk    = {
+               .name           = "mout_apll",
+       },
+       .sources        = &clk_src_apll,
+       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+struct clksrc_clk clk_sclk_apll = {
+       .clk    = {
+               .name           = "sclk_apll",
+               .parent         = &clk_mout_apll.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
+};
+
+struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_mpll = {
+       .clk = {
+               .name           = "mout_mpll",
+       },
+       .sources        = &clk_src_mpll,
+
+       /* reg_src will be added in each SoCs' clock */
+};
+
+static struct clk *clkset_moutcore_list[] = {
+       [0] = &clk_mout_apll.clk,
+       [1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_moutcore = {
+       .sources        = clkset_moutcore_list,
+       .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
+};
+
+static struct clksrc_clk clk_moutcore = {
+       .clk    = {
+               .name           = "moutcore",
+       },
+       .sources        = &clkset_moutcore,
+       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk clk_coreclk = {
+       .clk    = {
+               .name           = "core_clk",
+               .parent         = &clk_moutcore.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_armclk = {
+       .clk    = {
+               .name           = "armclk",
+               .parent         = &clk_coreclk.clk,
+       },
+};
+
+static struct clksrc_clk clk_aclk_corem0 = {
+       .clk    = {
+               .name           = "aclk_corem0",
+               .parent         = &clk_coreclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_cores = {
+       .clk    = {
+               .name           = "aclk_cores",
+               .parent         = &clk_coreclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_corem1 = {
+       .clk    = {
+               .name           = "aclk_corem1",
+               .parent         = &clk_coreclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_periphclk = {
+       .clk    = {
+               .name           = "periphclk",
+               .parent         = &clk_coreclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
+};
+
+/* Core list of CMU_CORE side */
+
+struct clk *clkset_corebus_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+struct clksrc_sources clkset_mout_corebus = {
+       .sources        = clkset_corebus_list,
+       .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
+};
+
+static struct clksrc_clk clk_mout_corebus = {
+       .clk    = {
+               .name           = "mout_corebus",
+       },
+       .sources        = &clkset_mout_corebus,
+       .reg_src        = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk clk_sclk_dmc = {
+       .clk    = {
+               .name           = "sclk_dmc",
+               .parent         = &clk_mout_corebus.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_cored = {
+       .clk    = {
+               .name           = "aclk_cored",
+               .parent         = &clk_sclk_dmc.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_corep = {
+       .clk    = {
+               .name           = "aclk_corep",
+               .parent         = &clk_aclk_cored.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_acp = {
+       .clk    = {
+               .name           = "aclk_acp",
+               .parent         = &clk_mout_corebus.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_pclk_acp = {
+       .clk    = {
+               .name           = "pclk_acp",
+               .parent         = &clk_aclk_acp.clk,
+       },
+       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *clkset_aclk_top_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+struct clksrc_sources clkset_aclk = {
+       .sources        = clkset_aclk_top_list,
+       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
+};
+
+static struct clksrc_clk clk_aclk_200 = {
+       .clk    = {
+               .name           = "aclk_200",
+       },
+       .sources        = &clkset_aclk,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
+       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_aclk_100 = {
+       .clk    = {
+               .name           = "aclk_100",
+       },
+       .sources        = &clkset_aclk,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
+       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_aclk_160 = {
+       .clk    = {
+               .name           = "aclk_160",
+       },
+       .sources        = &clkset_aclk,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
+       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
+};
+
+struct clksrc_clk clk_aclk_133 = {
+       .clk    = {
+               .name           = "aclk_133",
+       },
+       .sources        = &clkset_aclk,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
+       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
+};
+
+static struct clk *clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources clkset_vpllsrc = {
+       .sources        = clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .enable         = exynos4_clksrc_mask_top_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources        = &clkset_vpllsrc,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_sclk_vpll_list[] = {
+       [0] = &clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources clkset_sclk_vpll = {
+       .sources        = clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
+};
+
+struct clksrc_clk clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+       },
+       .sources        = &clkset_sclk_vpll,
+       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
+};
+
+static struct clk init_clocks_off[] = {
+       {
+               .name           = "timers",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1<<24),
+       }, {
+               .name           = "csis",
+               .devname        = "s5p-mipi-csis.0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "csis",
+               .devname        = "s5p-mipi-csis.1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.2",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "fimc",
+               .devname        = "exynos4-fimc.3",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "fimd",
+               .devname        = "exynos4-fb.0",
+               .enable         = exynos4_clk_ip_lcd0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.0",
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.1",
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.2",
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "hsmmc",
+               .devname        = "s3c-sdhci.3",
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "dwmmc",
+               .parent         = &clk_aclk_133.clk,
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "dac",
+               .devname        = "s5p-sdo",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "mixer",
+               .devname        = "s5p-mixer",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "vp",
+               .devname        = "s5p-mixer",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "hdmi",
+               .devname        = "exynos4-hdmi",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "hdmiphy",
+               .devname        = "exynos4-hdmi",
+               .enable         = exynos4_clk_hdmiphy_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "dacphy",
+               .devname        = "s5p-sdo",
+               .enable         = exynos4_clk_dac_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "dma",
+               .devname        = "dma-pl330.0",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "dma",
+               .devname        = "dma-pl330.1",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "adc",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "keypad",
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "rtc",
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "watchdog",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "usbhost",
+               .enable         = exynos4_clk_ip_fsys_ctrl ,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "otg",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "spi",
+               .devname        = "s3c64xx-spi.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 19),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 20),
+       }, {
+               .name           = "iis",
+               .devname        = "samsung-i2s.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 21),
+       }, {
+               .name           = "ac97",
+               .devname        = "samsung-ac97",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 27),
+       }, {
+               .name           = "fimg2d",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "mfc",
+               .devname        = "s5p-mfc",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.0",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.1",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.2",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.3",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.4",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.5",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.6",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-i2c.7",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-hdmiphy-i2c",
+               .parent         = &clk_aclk_100.clk,
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "SYSMMU_MDMA",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "SYSMMU_FIMC0",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "SYSMMU_FIMC1",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "SYSMMU_FIMC2",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "SYSMMU_FIMC3",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "SYSMMU_JPEG",
+               .enable         = exynos4_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "SYSMMU_FIMD0",
+               .enable         = exynos4_clk_ip_lcd0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_FIMD1",
+               .enable         = exynos4_clk_ip_lcd1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_PCIe",
+               .enable         = exynos4_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "SYSMMU_G2D",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "SYSMMU_ROTATOR",
+               .enable         = exynos4_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_TV",
+               .enable         = exynos4_clk_ip_tv_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "SYSMMU_MFC_L",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "SYSMMU_MFC_R",
+               .enable         = exynos4_clk_ip_mfc_ctrl,
+               .ctrlbit        = (1 << 2),
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.0",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.1",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.2",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.3",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.4",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "uart",
+               .devname        = "s5pv210-uart.5",
+               .enable         = exynos4_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 5),
+       }
+};
+
+struct clk *clkset_group_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_xusbxti,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources clkset_group = {
+       .sources        = clkset_group_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group_list),
+};
+
+static struct clk *clkset_mout_g2d0_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d0 = {
+       .sources        = clkset_mout_g2d0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
+};
+
+static struct clksrc_clk clk_mout_g2d0 = {
+       .clk    = {
+               .name           = "mout_g2d0",
+       },
+       .sources        = &clkset_mout_g2d0,
+       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d1 = {
+       .sources        = clkset_mout_g2d1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
+};
+
+static struct clksrc_clk clk_mout_g2d1 = {
+       .clk    = {
+               .name           = "mout_g2d1",
+       },
+       .sources        = &clkset_mout_g2d1,
+       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d_list[] = {
+       [0] = &clk_mout_g2d0.clk,
+       [1] = &clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d = {
+       .sources        = clkset_mout_g2d_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
+};
+
+static struct clk *clkset_mout_mfc0_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc0 = {
+       .sources        = clkset_mout_mfc0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc0_list),
+};
+
+static struct clksrc_clk clk_mout_mfc0 = {
+       .clk    = {
+               .name           = "mout_mfc0",
+       },
+       .sources        = &clkset_mout_mfc0,
+       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_mfc1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc1 = {
+       .sources        = clkset_mout_mfc1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc1_list),
+};
+
+static struct clksrc_clk clk_mout_mfc1 = {
+       .clk    = {
+               .name           = "mout_mfc1",
+       },
+       .sources        = &clkset_mout_mfc1,
+       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_mout_mfc_list[] = {
+       [0] = &clk_mout_mfc0.clk,
+       [1] = &clk_mout_mfc1.clk,
+};
+
+static struct clksrc_sources clkset_mout_mfc = {
+       .sources        = clkset_mout_mfc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
+};
+
+static struct clk *clkset_sclk_dac_list[] = {
+       [0] = &clk_sclk_vpll.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_dac = {
+       .sources        = clkset_sclk_dac_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk clk_sclk_dac = {
+       .clk            = {
+               .name           = "sclk_dac",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 8),
+       },
+       .sources = &clkset_sclk_dac,
+       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_sclk_pixel = {
+       .clk            = {
+               .name           = "sclk_pixel",
+               .parent = &clk_sclk_vpll.clk,
+       },
+       .reg_div = { .reg = S5P_CLKDIV_TV, .shift = 0, .size = 4 },
+};
+
+static struct clk *clkset_sclk_hdmi_list[] = {
+       [0] = &clk_sclk_pixel.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_hdmi = {
+       .sources        = clkset_sclk_hdmi_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk clk_sclk_hdmi = {
+       .clk            = {
+               .name           = "sclk_hdmi",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 0),
+       },
+       .sources = &clkset_sclk_hdmi,
+       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_sclk_mixer_list[] = {
+       [0] = &clk_sclk_dac.clk,
+       [1] = &clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources clkset_sclk_mixer = {
+       .sources        = clkset_sclk_mixer_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
+};
+
+static struct clksrc_clk clk_sclk_mixer = {
+       .clk            = {
+               .name           = "sclk_mixer",
+               .enable         = exynos4_clksrc_mask_tv_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &clkset_sclk_mixer,
+       .reg_src = { .reg = S5P_CLKSRC_TV, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk *sclk_tv[] = {
+       &clk_sclk_dac,
+       &clk_sclk_pixel,
+       &clk_sclk_hdmi,
+       &clk_sclk_mixer,
+};
+
+static struct clksrc_clk clk_dout_mmc0 = {
+       .clk            = {
+               .name           = "dout_mmc0",
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc1 = {
+       .clk            = {
+               .name           = "dout_mmc1",
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc2 = {
+       .clk            = {
+               .name           = "dout_mmc2",
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc3 = {
+       .clk            = {
+               .name           = "dout_mmc3",
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc4 = {
+       .clk            = {
+               .name           = "dout_mmc4",
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "uclk1",
+                       .devname        = "s5pv210-uart.0",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .devname        = "s5pv210-uart.1",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .devname        = "s5pv210-uart.2",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .devname        = "s5pv210-uart.3",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_pwm",
+                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .devname        = "s5p-mipi-csis.0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .devname        = "s5p-mipi-csis.1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 28),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.0",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.1",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.2",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .devname        = "exynos4-fimc.3",
+                       .enable         = exynos4_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .devname        = "exynos4-fb.0",
+                       .enable         = exynos4_clksrc_mask_lcd0_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .devname        = "s3c64xx-spi.0",
+                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .devname        = "s3c64xx-spi.1",
+                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .devname        = "s3c64xx-spi.2",
+                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimg2d",
+               },
+               .sources = &clkset_mout_g2d,
+               .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mfc",
+                       .devname        = "s5p-mfc",
+               },
+               .sources = &clkset_mout_mfc,
+               .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .devname        = "s3c-sdhci.0",
+                       .parent         = &clk_dout_mmc0.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .devname        = "s3c-sdhci.1",
+                       .parent         = &clk_dout_mmc1.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .devname        = "s3c-sdhci.2",
+                       .parent         = &clk_dout_mmc2.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .devname        = "s3c-sdhci.3",
+                       .parent         = &clk_dout_mmc3.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_dwmmc",
+                       .parent         = &clk_dout_mmc4.clk,
+                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+       }
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_apll,
+       &clk_sclk_apll,
+       &clk_mout_epll,
+       &clk_mout_mpll,
+       &clk_moutcore,
+       &clk_coreclk,
+       &clk_armclk,
+       &clk_aclk_corem0,
+       &clk_aclk_cores,
+       &clk_aclk_corem1,
+       &clk_periphclk,
+       &clk_mout_corebus,
+       &clk_sclk_dmc,
+       &clk_aclk_cored,
+       &clk_aclk_corep,
+       &clk_aclk_acp,
+       &clk_pclk_acp,
+       &clk_vpllsrc,
+       &clk_sclk_vpll,
+       &clk_aclk_200,
+       &clk_aclk_100,
+       &clk_aclk_160,
+       &clk_aclk_133,
+       &clk_dout_mmc0,
+       &clk_dout_mmc1,
+       &clk_dout_mmc2,
+       &clk_dout_mmc3,
+       &clk_dout_mmc4,
+       &clk_mout_mfc0,
+       &clk_mout_mfc1,
+};
+
+static int xtal_rate;
+
+static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
+{
+       if (soc_is_exynos4210())
+               return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
+                                       pll_4508);
+       else if (soc_is_exynos4212() || soc_is_exynos4412())
+               return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
+       else
+               return 0;
+}
+
+static struct clk_ops exynos4_fout_apll_ops = {
+       .get_rate = exynos4_fout_apll_get_rate,
+};
+
+static u32 vpll_div[][8] = {
+       {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
+       { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
+};
+
+static unsigned long exynos4_vpll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int vpll_con0, vpll_con1 = 0;
+       unsigned int i;
+
+       /* Return if nothing changed */
+       if (clk->rate == rate)
+               return 0;
+
+       vpll_con0 = __raw_readl(S5P_VPLL_CON0);
+       vpll_con0 &= ~(0x1 << 27 |                                      \
+                       PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |       \
+                       PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |       \
+                       PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+       vpll_con1 = __raw_readl(S5P_VPLL_CON1);
+       vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |  \
+                       PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
+                       PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
+
+       for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
+               if (vpll_div[i][0] == rate) {
+                       vpll_con0 |= vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
+                       vpll_con0 |= vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
+                       vpll_con0 |= vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
+                       vpll_con1 |= vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
+                       vpll_con1 |= vpll_div[i][5] << PLL46XX_MFR_SHIFT;
+                       vpll_con1 |= vpll_div[i][6] << PLL46XX_MRR_SHIFT;
+                       vpll_con0 |= vpll_div[i][7] << 27;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(vpll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+                               __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(vpll_con0, S5P_VPLL_CON0);
+       __raw_writel(vpll_con1, S5P_VPLL_CON1);
+
+       /* Wait for VPLL lock */
+       while (!(__raw_readl(S5P_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
+               continue;
+
+       clk->rate = rate;
+       return 0;
+}
+
+static struct clk_ops exynos4_vpll_ops = {
+       .get_rate = exynos4_vpll_get_rate,
+       .set_rate = exynos4_vpll_set_rate,
+};
+
+void __init_or_cpufreq exynos4_setup_clocks(void)
+{
+       struct clk *xtal_clk;
+       unsigned long apll = 0;
+       unsigned long mpll = 0;
+       unsigned long epll = 0;
+       unsigned long vpll = 0;
+       unsigned long vpllsrc;
+       unsigned long xtal;
+       unsigned long armclk;
+       unsigned long sclk_dmc;
+       unsigned long aclk_200;
+       unsigned long aclk_100;
+       unsigned long aclk_160;
+       unsigned long aclk_133;
+       unsigned int ptr;
+
+       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+       xtal_clk = clk_get(NULL, "xtal");
+       BUG_ON(IS_ERR(xtal_clk));
+
+       xtal = clk_get_rate(xtal_clk);
+
+       xtal_rate = xtal;
+
+       clk_put(xtal_clk);
+
+       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+       if (soc_is_exynos4210()) {
+               apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
+                                       pll_4508);
+               mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
+                                       pll_4508);
+               epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
+                                       __raw_readl(S5P_EPLL_CON1), pll_4600);
+
+               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+               vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
+                                       __raw_readl(S5P_VPLL_CON1), pll_4650c);
+       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+               apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
+               mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
+               epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
+                                       __raw_readl(S5P_EPLL_CON1));
+
+               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+               vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
+                                       __raw_readl(S5P_VPLL_CON1));
+       } else {
+               /* nothing */
+       }
+
+       clk_fout_apll.ops = &exynos4_fout_apll_ops;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_fout_vpll.ops = &exynos4_vpll_ops;
+       clk_fout_vpll.rate = vpll;
+
+       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+                       apll, mpll, epll, vpll);
+
+       armclk = clk_get_rate(&clk_armclk.clk);
+       sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
+
+       aclk_200 = clk_get_rate(&clk_aclk_200.clk);
+       aclk_100 = clk_get_rate(&clk_aclk_100.clk);
+       aclk_160 = clk_get_rate(&clk_aclk_160.clk);
+       aclk_133 = clk_get_rate(&clk_aclk_133.clk);
+
+       printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
+                       armclk, sclk_dmc, aclk_200,
+                       aclk_100, aclk_160, aclk_133);
+
+       clk_f.rate = armclk;
+       clk_h.rate = sclk_dmc;
+       clk_p.rate = aclk_100;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+       &clk_sclk_hdmi27m,
+       &clk_sclk_hdmiphy,
+       &clk_sclk_usbphy0,
+       &clk_sclk_usbphy1,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos4_clock_suspend(void)
+{
+       s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+       return 0;
+}
+
+static void exynos4_clock_resume(void)
+{
+       s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+}
+
+#else
+#define exynos4_clock_suspend NULL
+#define exynos4_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4_clock_syscore_ops = {
+       .suspend        = exynos4_clock_suspend,
+       .resume         = exynos4_clock_resume,
+};
+
+void __init exynos4_register_clocks(void)
+{
+       int ptr;
+
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+               s3c_register_clksrc(sysclks[ptr], 1);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
+               s3c_register_clksrc(sclk_tv[ptr], 1);
+
+       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+       register_syscore_ops(&exynos4_clock_syscore_ops);
+       s3c24xx_register_clock(&dummy_apb_pclk);
+
+       s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c
new file mode 100644 (file)
index 0000000..90ec247
--- /dev/null
@@ -0,0 +1,298 @@
+/* linux/arch/arm/mach-exynos/cpu.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/sysdev.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/exynos4.h>
+#include <plat/adc-core.h>
+#include <plat/sdhci.h>
+#include <plat/fb-core.h>
+#include <plat/fimc-core.h>
+#include <plat/iic-core.h>
+#include <plat/reset.h>
+#include <plat/tv-core.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-pmu.h>
+
+unsigned int gic_bank_offset __read_mostly;
+
+extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
+                        unsigned int irq_start);
+extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
+
+/* Initial IO mappings */
+static struct map_desc exynos_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
+               .pfn            = __phys_to_pfn(EXYNOS_PA_SYSTIMER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_PMU,
+               .pfn            = __phys_to_pfn(EXYNOS_PA_PMU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
+               .pfn            = __phys_to_pfn(EXYNOS_PA_COMBINER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
+               .pfn            = __phys_to_pfn(EXYNOS_PA_GIC_CPU),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
+               .pfn            = __phys_to_pfn(EXYNOS_PA_GIC_DIST),
+               .length         = SZ_64K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_UART,
+               .pfn            = __phys_to_pfn(S3C_PA_UART),
+               .length         = SZ_512K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4_iodesc[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_CMU,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
+               .length         = SZ_128K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_COREPERI),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_L2CC,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_L2CC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO1,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO1),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO2,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO2),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO3,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO3),
+               .length         = SZ_256,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC0,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SROMC,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_HSPHY),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4_iodesc0[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static struct map_desc exynos4_iodesc1[] __initdata = {
+       {
+               .virtual        = (unsigned long)S5P_VA_SYSRAM,
+               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void exynos_idle(void)
+{
+       if (!need_resched())
+               cpu_do_idle();
+
+       local_irq_enable();
+}
+
+static void exynos4_sw_reset(void)
+{
+       __raw_writel(0x1, S5P_SWRESET);
+}
+
+/*
+ * exynos_map_io
+ *
+ * register the standard cpu IO areas
+ */
+void __init exynos4_map_io(void)
+{
+       iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
+       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+
+       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
+               iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
+       else
+               iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
+
+       /* initialize device information early */
+       exynos4_default_sdhci0();
+       exynos4_default_sdhci1();
+       exynos4_default_sdhci2();
+       exynos4_default_sdhci3();
+
+       s3c_adc_setname("samsung-adc-v3");
+
+       s3c_fimc_setname(0, "exynos4-fimc");
+       s3c_fimc_setname(1, "exynos4-fimc");
+       s3c_fimc_setname(2, "exynos4-fimc");
+       s3c_fimc_setname(3, "exynos4-fimc");
+
+       /* The I2C bus controllers are directly compatible with s3c2440 */
+       s3c_i2c0_setname("s3c2440-i2c");
+       s3c_i2c1_setname("s3c2440-i2c");
+       s3c_i2c2_setname("s3c2440-i2c");
+
+       s5p_fb_setname(0, "exynos4-fb");
+       s5p_hdmi_setname("exynos4-hdmi");
+}
+
+void __init exynos4_init_clocks(int xtal)
+{
+       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+       s3c24xx_register_baseclocks(xtal);
+       s5p_register_clocks(xtal);
+
+       if (soc_is_exynos4210())
+               exynos4210_register_clocks();
+       else if (soc_is_exynos4212() || soc_is_exynos4412())
+               exynos4212_register_clocks();
+
+       exynos4_register_clocks();
+       exynos4_setup_clocks();
+}
+
+static void exynos4_gic_irq_fix_base(struct irq_data *d)
+{
+       struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+
+       gic_data->cpu_base = S5P_VA_GIC_CPU +
+                           (gic_bank_offset * smp_processor_id());
+
+       gic_data->dist_base = S5P_VA_GIC_DIST +
+                           (gic_bank_offset * smp_processor_id());
+}
+
+void __init exynos4_init_irq(void)
+{
+       int irq;
+
+       gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
+
+       gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
+       gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base;
+       gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
+       gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base;
+
+       for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+
+               combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+                               COMBINER_IRQ(irq, 0));
+               combiner_cascade_irq(irq, IRQ_SPI(irq));
+       }
+
+       /* The parameters of s5p_init_irq() are for VIC init.
+        * Theses parameters should be NULL and 0 because EXYNOS4
+        * uses GIC instead of VIC.
+        */
+       s5p_init_irq(NULL, 0);
+}
+
+struct sysdev_class exynos4_sysclass = {
+       .name   = "exynos4-core",
+};
+
+static struct sys_device exynos4_sysdev = {
+       .cls    = &exynos4_sysclass,
+};
+
+static int __init exynos4_core_init(void)
+{
+       return sysdev_class_register(&exynos4_sysclass);
+}
+core_initcall(exynos4_core_init);
+
+#ifdef CONFIG_CACHE_L2X0
+static int __init exynos4_l2x0_cache_init(void)
+{
+       /* TAG, Data Latency Control: 2cycle */
+       __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+
+       if (soc_is_exynos4210())
+               __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+       else if (soc_is_exynos4212() || soc_is_exynos4412())
+               __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+
+       /* L2X0 Prefetch Control */
+       __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+
+       /* L2X0 Power Control */
+       __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+                    S5P_VA_L2CC + L2X0_POWER_CTRL);
+
+       l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
+
+       return 0;
+}
+
+early_initcall(exynos4_l2x0_cache_init);
+#endif
+
+int __init exynos_init(void)
+{
+       printk(KERN_INFO "EXYNOS: Initializing architecture\n");
+
+       /* set idle function */
+       pm_idle = exynos_idle;
+
+       /* set sw_reset function */
+       if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+               s5p_reset_hook = exynos4_sw_reset;
+
+       return sysdev_register(&exynos4_sysdev);
+}
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
new file mode 100644 (file)
index 0000000..4ebb382
--- /dev/null
@@ -0,0 +1,92 @@
+/* linux/arch/arm/mach-exynos4/cpuidle.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/proc-fns.h>
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+                       struct cpuidle_driver *drv,
+                             int index);
+
+static struct cpuidle_state exynos4_cpuidle_set[] = {
+       [0] = {
+               .enter                  = exynos4_enter_idle,
+               .exit_latency           = 1,
+               .target_residency       = 100000,
+               .flags                  = CPUIDLE_FLAG_TIME_VALID,
+               .name                   = "IDLE",
+               .desc                   = "ARM clock gating(WFI)",
+       },
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
+
+static struct cpuidle_driver exynos4_idle_driver = {
+       .name           = "exynos4_idle",
+       .owner          = THIS_MODULE,
+};
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv,
+                             int index)
+{
+       struct timeval before, after;
+       int idle_time;
+
+       local_irq_disable();
+       do_gettimeofday(&before);
+
+       cpu_do_idle();
+
+       do_gettimeofday(&after);
+       local_irq_enable();
+       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+                   (after.tv_usec - before.tv_usec);
+
+       dev->last_residency = idle_time;
+       return index;
+}
+
+static int __init exynos4_init_cpuidle(void)
+{
+       int i, max_cpuidle_state, cpu_id;
+       struct cpuidle_device *device;
+       struct cpuidle_driver *drv = &exynos4_idle_driver;
+
+       /* Setup cpuidle driver */
+       drv->state_count = (sizeof(exynos4_cpuidle_set) /
+                                      sizeof(struct cpuidle_state));
+       max_cpuidle_state = drv->state_count;
+       for (i = 0; i < max_cpuidle_state; i++) {
+               memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
+                               sizeof(struct cpuidle_state));
+       }
+       cpuidle_register_driver(&exynos4_idle_driver);
+
+       for_each_cpu(cpu_id, cpu_online_mask) {
+               device = &per_cpu(exynos4_cpuidle_device, cpu_id);
+               device->cpu = cpu_id;
+
+               device->state_count = drv->state_count;
+
+               if (cpuidle_register_device(device)) {
+                       printk(KERN_ERR "CPUidle register device failed\n,");
+                       return -EIO;
+               }
+       }
+       return 0;
+}
+device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos/dev-ahci.c b/arch/arm/mach-exynos/dev-ahci.c
new file mode 100644 (file)
index 0000000..f57a3de
--- /dev/null
@@ -0,0 +1,263 @@
+/* linux/arch/arm/mach-exynos4/dev-ahci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - AHCI support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/ahci_platform.h>
+
+#include <plat/cpu.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-pmu.h>
+
+/* PHY Control Register */
+#define SATA_CTRL0             0x0
+/* PHY Link Control Register */
+#define SATA_CTRL1             0x4
+/* PHY Status Register */
+#define SATA_PHY_STATUS                0x8
+
+#define SATA_CTRL0_RX_DATA_VALID(x)    (x << 27)
+#define SATA_CTRL0_SPEED_MODE          (1 << 26)
+#define SATA_CTRL0_M_PHY_CAL           (1 << 19)
+#define SATA_CTRL0_PHY_CMU_RST_N       (1 << 10)
+#define SATA_CTRL0_M_PHY_LN_RST_N      (1 << 9)
+#define SATA_CTRL0_PHY_POR_N           (1 << 8)
+
+#define SATA_CTRL1_RST_PMALIVE_N       (1 << 8)
+#define SATA_CTRL1_RST_RXOOB_N         (1 << 7)
+#define SATA_CTRL1_RST_RX_N            (1 << 6)
+#define SATA_CTRL1_RST_TX_N            (1 << 5)
+
+#define SATA_PHY_STATUS_CMU_OK         (1 << 18)
+#define SATA_PHY_STATUS_LANE_OK                (1 << 16)
+
+#define LANE0          0x200
+#define COM_LANE       0xA00
+
+#define HOST_PORTS_IMPL        0xC
+#define SCLK_SATA_FREQ (67 * MHZ)
+
+static void __iomem *phy_base, *phy_ctrl;
+
+struct phy_reg {
+       u8      reg;
+       u8      val;
+};
+
+/* SATA PHY setup */
+static const struct phy_reg exynos4_sataphy_cmu[] = {
+       { 0x00, 0x06 }, { 0x02, 0x80 }, { 0x22, 0xa0 }, { 0x23, 0x42 },
+       { 0x2e, 0x04 }, { 0x2f, 0x50 }, { 0x30, 0x70 }, { 0x31, 0x02 },
+       { 0x32, 0x25 }, { 0x33, 0x40 }, { 0x34, 0x01 }, { 0x35, 0x40 },
+       { 0x61, 0x2e }, { 0x63, 0x5e }, { 0x65, 0x42 }, { 0x66, 0xd1 },
+       { 0x67, 0x20 }, { 0x68, 0x28 }, { 0x69, 0x78 }, { 0x6a, 0x04 },
+       { 0x6b, 0xc8 }, { 0x6c, 0x06 },
+};
+
+static const struct phy_reg exynos4_sataphy_lane[] = {
+       { 0x00, 0x02 }, { 0x05, 0x10 }, { 0x06, 0x84 }, { 0x07, 0x04 },
+       { 0x08, 0xe0 }, { 0x10, 0x23 }, { 0x13, 0x05 }, { 0x14, 0x30 },
+       { 0x15, 0x00 }, { 0x17, 0x70 }, { 0x18, 0xf2 }, { 0x19, 0x1e },
+       { 0x1a, 0x18 }, { 0x1b, 0x0d }, { 0x1c, 0x08 }, { 0x50, 0x60 },
+       { 0x51, 0x0f },
+};
+
+static const struct phy_reg exynos4_sataphy_comlane[] = {
+       { 0x01, 0x20 }, { 0x03, 0x40 }, { 0x04, 0x3c }, { 0x05, 0x7d },
+       { 0x06, 0x1d }, { 0x07, 0xcf }, { 0x08, 0x05 }, { 0x09, 0x63 },
+       { 0x0a, 0x29 }, { 0x0b, 0xc4 }, { 0x0c, 0x01 }, { 0x0d, 0x03 },
+       { 0x0e, 0x28 }, { 0x0f, 0x98 }, { 0x10, 0x19 }, { 0x13, 0x80 },
+       { 0x14, 0xf0 }, { 0x15, 0xd0 }, { 0x39, 0xa0 }, { 0x3a, 0xa0 },
+       { 0x3b, 0xa0 }, { 0x3c, 0xa0 }, { 0x3d, 0xa0 }, { 0x3e, 0xa0 },
+       { 0x3f, 0xa0 }, { 0x40, 0x42 }, { 0x42, 0x80 }, { 0x43, 0x58 },
+       { 0x45, 0x44 }, { 0x46, 0x5c }, { 0x47, 0x86 }, { 0x48, 0x8d },
+       { 0x49, 0xd0 }, { 0x4a, 0x09 }, { 0x4b, 0x90 }, { 0x4c, 0x07 },
+       { 0x4d, 0x40 }, { 0x51, 0x20 }, { 0x52, 0x32 }, { 0x7f, 0xd8 },
+       { 0x80, 0x1a }, { 0x81, 0xff }, { 0x82, 0x11 }, { 0x83, 0x00 },
+       { 0x87, 0xf0 }, { 0x87, 0xff }, { 0x87, 0xff }, { 0x87, 0xff },
+       { 0x87, 0xff }, { 0x8c, 0x1c }, { 0x8d, 0xc2 }, { 0x8e, 0xc3 },
+       { 0x8f, 0x3f }, { 0x90, 0x0a }, { 0x96, 0xf8 },
+};
+
+static int wait_for_phy_ready(void __iomem *reg, unsigned long bit)
+{
+       unsigned long timeout;
+
+       /* wait for maximum of 3 sec */
+       timeout = jiffies + msecs_to_jiffies(3000);
+       while (!(__raw_readl(reg) & bit)) {
+               if (time_after(jiffies, timeout))
+                       return -1;
+               cpu_relax();
+       }
+       return 0;
+}
+
+static int ahci_phy_init(void __iomem *mmio)
+{
+       int i, ctrl0;
+
+       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_cmu); i++)
+               __raw_writeb(exynos4_sataphy_cmu[i].val,
+               phy_base + (exynos4_sataphy_cmu[i].reg * 4));
+
+       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_lane); i++)
+               __raw_writeb(exynos4_sataphy_lane[i].val,
+               phy_base + (LANE0 + exynos4_sataphy_lane[i].reg) * 4);
+
+       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_comlane); i++)
+               __raw_writeb(exynos4_sataphy_comlane[i].val,
+               phy_base + (COM_LANE + exynos4_sataphy_comlane[i].reg) * 4);
+
+       __raw_writeb(0x07, phy_base);
+
+       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+       ctrl0 |= SATA_CTRL0_PHY_CMU_RST_N;
+       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+       if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
+                               SATA_PHY_STATUS_CMU_OK) < 0) {
+               printk(KERN_ERR "PHY CMU not ready\n");
+               return -EBUSY;
+       }
+
+       __raw_writeb(0x03, phy_base + (COM_LANE * 4));
+
+       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+       ctrl0 |= SATA_CTRL0_M_PHY_LN_RST_N;
+       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+       if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
+                               SATA_PHY_STATUS_LANE_OK) < 0) {
+               printk(KERN_ERR "PHY LANE not ready\n");
+               return -EBUSY;
+       }
+
+       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+       ctrl0 |= SATA_CTRL0_M_PHY_CAL;
+       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+       return 0;
+}
+
+static int exynos4_ahci_init(struct device *dev, void __iomem *mmio)
+{
+       struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata;
+       int val, ret;
+
+       phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K);
+       if (!phy_base) {
+               dev_err(dev, "failed to allocate memory for SATA PHY\n");
+               return -ENOMEM;
+       }
+
+       phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16);
+       if (!phy_ctrl) {
+               dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
+               ret = -ENOMEM;
+               goto err1;
+       }
+
+       clk_sata = clk_get(dev, "sata");
+       if (IS_ERR(clk_sata)) {
+               dev_err(dev, "failed to get sata clock\n");
+               ret = PTR_ERR(clk_sata);
+               clk_sata = NULL;
+               goto err2;
+
+       }
+       clk_enable(clk_sata);
+
+       clk_sataphy = clk_get(dev, "sataphy");
+       if (IS_ERR(clk_sataphy)) {
+               dev_err(dev, "failed to get sataphy clock\n");
+               ret = PTR_ERR(clk_sataphy);
+               clk_sataphy = NULL;
+               goto err3;
+       }
+       clk_enable(clk_sataphy);
+
+       clk_sclk_sata = clk_get(dev, "sclk_sata");
+       if (IS_ERR(clk_sclk_sata)) {
+               dev_err(dev, "failed to get sclk_sata\n");
+               ret = PTR_ERR(clk_sclk_sata);
+               clk_sclk_sata = NULL;
+               goto err4;
+       }
+       clk_enable(clk_sclk_sata);
+       clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
+
+       __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL);
+
+       /* Enable PHY link control */
+       val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N |
+                       SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N;
+       __raw_writel(val, phy_ctrl + SATA_CTRL1);
+
+       /* Set communication speed as 3Gbps and enable PHY power */
+       val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE |
+                       SATA_CTRL0_PHY_POR_N;
+       __raw_writel(val, phy_ctrl + SATA_CTRL0);
+
+       /* Port0 is available */
+       __raw_writel(0x1, mmio + HOST_PORTS_IMPL);
+
+       return ahci_phy_init(mmio);
+
+err4:
+       clk_disable(clk_sataphy);
+       clk_put(clk_sataphy);
+err3:
+       clk_disable(clk_sata);
+       clk_put(clk_sata);
+err2:
+       iounmap(phy_ctrl);
+err1:
+       iounmap(phy_base);
+
+       return ret;
+}
+
+static struct ahci_platform_data exynos4_ahci_pdata = {
+       .init = exynos4_ahci_init,
+};
+
+static struct resource exynos4_ahci_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_SATA,
+               .end    = EXYNOS4_PA_SATA + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_SATA,
+               .end    = IRQ_SATA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 exynos4_ahci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_ahci = {
+       .name           = "ahci",
+       .id             = -1,
+       .resource       = exynos4_ahci_resource,
+       .num_resources  = ARRAY_SIZE(exynos4_ahci_resource),
+       .dev            = {
+               .platform_data          = &exynos4_ahci_pdata,
+               .dma_mask               = &exynos4_ahci_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
diff --git a/arch/arm/mach-exynos/dev-audio.c b/arch/arm/mach-exynos/dev-audio.c
new file mode 100644 (file)
index 0000000..5a9f9c2
--- /dev/null
@@ -0,0 +1,369 @@
+/* linux/arch/arm/mach-exynos4/dev-audio.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <mach/regs-audss.h>
+
+static const char *rclksrc[] = {
+       [0] = "busclk",
+       [1] = "i2sclk",
+};
+
+static int exynos4_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
+               break;
+       case 1:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
+               break;
+       case 2:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
+               break;
+       default:
+               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata i2sv5_pdata = {
+       .cfg_gpio = exynos4_cfg_i2s,
+       .type = {
+               .i2s = {
+                       .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+                                        | QUIRK_NEED_RSTCLR,
+                       .src_clk = rclksrc,
+                       .idma_addr = EXYNOS4_AUDSS_INT_MEM,
+               },
+       },
+};
+
+static struct resource exynos4_i2s0_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_I2S0,
+               .end    = EXYNOS4_PA_I2S0 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_I2S0_TX,
+               .end    = DMACH_I2S0_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_I2S0_RX,
+               .end    = DMACH_I2S0_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start  = DMACH_I2S0S_TX,
+               .end    = DMACH_I2S0S_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_i2s0 = {
+       .name = "samsung-i2s",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
+       .resource = exynos4_i2s0_resource,
+       .dev = {
+               .platform_data = &i2sv5_pdata,
+       },
+};
+
+static const char *rclksrc_v3[] = {
+       [0] = "sclk_i2s",
+       [1] = "no_such_clock",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+       .cfg_gpio = exynos4_cfg_i2s,
+       .type = {
+               .i2s = {
+                       .quirks = QUIRK_NO_MUXPSR,
+                       .src_clk = rclksrc_v3,
+               },
+       },
+};
+
+static struct resource exynos4_i2s1_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_I2S1,
+               .end    = EXYNOS4_PA_I2S1 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_I2S1_TX,
+               .end    = DMACH_I2S1_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_I2S1_RX,
+               .end    = DMACH_I2S1_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_i2s1 = {
+       .name = "samsung-i2s",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
+       .resource = exynos4_i2s1_resource,
+       .dev = {
+               .platform_data = &i2sv3_pdata,
+       },
+};
+
+static struct resource exynos4_i2s2_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_I2S2,
+               .end    = EXYNOS4_PA_I2S2 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_I2S2_TX,
+               .end    = DMACH_I2S2_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_I2S2_RX,
+               .end    = DMACH_I2S2_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_i2s2 = {
+       .name = "samsung-i2s",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
+       .resource = exynos4_i2s2_resource,
+       .dev = {
+               .platform_data = &i2sv3_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
+               break;
+       case 1:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
+               break;
+       case 2:
+               s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
+               break;
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+       .cfg_gpio = exynos4_pcm_cfg_gpio,
+};
+
+static struct resource exynos4_pcm0_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_PCM0,
+               .end    = EXYNOS4_PA_PCM0 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_PCM0_TX,
+               .end    = DMACH_PCM0_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_PCM0_RX,
+               .end    = DMACH_PCM0_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_pcm0 = {
+       .name = "samsung-pcm",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
+       .resource = exynos4_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource exynos4_pcm1_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_PCM1,
+               .end    = EXYNOS4_PA_PCM1 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_PCM1_TX,
+               .end    = DMACH_PCM1_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_PCM1_RX,
+               .end    = DMACH_PCM1_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_pcm1 = {
+       .name = "samsung-pcm",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
+       .resource = exynos4_pcm1_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource exynos4_pcm2_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_PCM2,
+               .end    = EXYNOS4_PA_PCM2 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_PCM2_TX,
+               .end    = DMACH_PCM2_TX,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_PCM2_RX,
+               .end    = DMACH_PCM2_RX,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device exynos4_device_pcm2 = {
+       .name = "samsung-pcm",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
+       .resource = exynos4_pcm2_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+/* AC97 Controller platform devices */
+
+static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
+{
+       return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource exynos4_ac97_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_AC97,
+               .end    = EXYNOS4_PA_AC97 + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_AC97_PCMOUT,
+               .end    = DMACH_AC97_PCMOUT,
+               .flags  = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start  = DMACH_AC97_PCMIN,
+               .end    = DMACH_AC97_PCMIN,
+               .flags  = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start  = DMACH_AC97_MICIN,
+               .end    = DMACH_AC97_MICIN,
+               .flags  = IORESOURCE_DMA,
+       },
+       [4] = {
+               .start  = IRQ_AC97,
+               .end    = IRQ_AC97,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+       .cfg_gpio = exynos4_ac97_cfg_gpio,
+};
+
+static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_ac97 = {
+       .name = "samsung-ac97",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
+       .resource = exynos4_ac97_resource,
+       .dev = {
+               .platform_data = &s3c_ac97_pdata,
+               .dma_mask = &exynos4_ac97_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+/* S/PDIF Controller platform_device */
+
+static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
+
+       return 0;
+}
+
+static struct resource exynos4_spdif_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_SPDIF,
+               .end    = EXYNOS4_PA_SPDIF + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_SPDIF,
+               .end    = DMACH_SPDIF,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+       .cfg_gpio = exynos4_spdif_cfg_gpio,
+};
+
+static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_spdif = {
+       .name = "samsung-spdif",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
+       .resource = exynos4_spdif_resource,
+       .dev = {
+               .platform_data = &samsung_spdif_pdata,
+               .dma_mask = &exynos4_spdif_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
diff --git a/arch/arm/mach-exynos/dev-dwmci.c b/arch/arm/mach-exynos/dev-dwmci.c
new file mode 100644 (file)
index 0000000..b025db4
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * linux/arch/arm/mach-exynos4/dev-dwmci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Platform device for Synopsys DesignWare Mobile Storage IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/dw_mmc.h>
+
+#include <plat/devs.h>
+
+#include <mach/map.h>
+
+static int exynos4_dwmci_get_bus_wd(u32 slot_id)
+{
+       return 4;
+}
+
+static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+       return 0;
+}
+
+static struct resource exynos4_dwmci_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_DWMCI,
+               .end    = EXYNOS4_PA_DWMCI + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_DWMCI,
+               .end    = IRQ_DWMCI,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+static struct dw_mci_board exynos4_dwci_pdata = {
+       .num_slots                      = 1,
+       .quirks                         = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+       .bus_hz                         = 80 * 1000 * 1000,
+       .detect_delay_ms        = 200,
+       .init                           = exynos4_dwmci_init,
+       .get_bus_wd                     = exynos4_dwmci_get_bus_wd,
+};
+
+static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_dwmci = {
+       .name           = "dw_mmc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
+       .resource       = exynos4_dwmci_resource,
+       .dev            = {
+               .dma_mask               = &exynos4_dwmci_dmamask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data  = &exynos4_dwci_pdata,
+       },
+};
+
+void __init exynos4_dwmci_set_platdata(struct dw_mci_board *pd)
+{
+       struct dw_mci_board *npd;
+
+       npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+                       &exynos4_device_dwmci);
+
+       if (!npd->init)
+               npd->init = exynos4_dwmci_init;
+       if (!npd->get_bus_wd)
+               npd->get_bus_wd = exynos4_dwmci_get_bus_wd;
+}
diff --git a/arch/arm/mach-exynos/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c
new file mode 100644 (file)
index 0000000..3273f25
--- /dev/null
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-exynos4/dev-pd.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Power Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/regs-pmu.h>
+
+#include <plat/pd.h>
+
+static int exynos4_pd_enable(struct device *dev)
+{
+       struct samsung_pd_info *pdata =  dev->platform_data;
+       u32 timeout;
+
+       __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
+
+       /* Wait max 1ms */
+       timeout = 10;
+       while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
+               != S5P_INT_LOCAL_PWR_EN) {
+               if (timeout == 0) {
+                       printk(KERN_ERR "Power domain %s enable failed.\n",
+                               dev_name(dev));
+                       return -ETIMEDOUT;
+               }
+               timeout--;
+               udelay(100);
+       }
+
+       return 0;
+}
+
+static int exynos4_pd_disable(struct device *dev)
+{
+       struct samsung_pd_info *pdata =  dev->platform_data;
+       u32 timeout;
+
+       __raw_writel(0, pdata->base);
+
+       /* Wait max 1ms */
+       timeout = 10;
+       while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
+               if (timeout == 0) {
+                       printk(KERN_ERR "Power domain %s disable failed.\n",
+                               dev_name(dev));
+                       return -ETIMEDOUT;
+               }
+               timeout--;
+               udelay(100);
+       }
+
+       return 0;
+}
+
+struct platform_device exynos4_device_pd[] = {
+       {
+               .name           = "samsung-pd",
+               .id             = 0,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_MFC_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 1,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_G3D_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 2,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_LCD0_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 3,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_LCD1_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 4,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_TV_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 5,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_CAM_CONF,
+                       },
+               },
+       }, {
+               .name           = "samsung-pd",
+               .id             = 6,
+               .dev = {
+                       .platform_data = &(struct samsung_pd_info) {
+                               .enable         = exynos4_pd_enable,
+                               .disable        = exynos4_pd_disable,
+                               .base           = S5P_PMU_GPS_CONF,
+                       },
+               },
+       },
+};
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
new file mode 100644 (file)
index 0000000..781563f
--- /dev/null
@@ -0,0 +1,233 @@
+/* linux/arch/arm/mach-exynos4/dev-sysmmu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - System MMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/export.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/sysmmu.h>
+#include <plat/s5p-clock.h>
+
+/* These names must be equal to the clock names in mach-exynos4/clock.c */
+const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
+       "SYSMMU_MDMA"   ,
+       "SYSMMU_SSS"    ,
+       "SYSMMU_FIMC0"  ,
+       "SYSMMU_FIMC1"  ,
+       "SYSMMU_FIMC2"  ,
+       "SYSMMU_FIMC3"  ,
+       "SYSMMU_JPEG"   ,
+       "SYSMMU_FIMD0"  ,
+       "SYSMMU_FIMD1"  ,
+       "SYSMMU_PCIe"   ,
+       "SYSMMU_G2D"    ,
+       "SYSMMU_ROTATOR",
+       "SYSMMU_MDMA2"  ,
+       "SYSMMU_TV"     ,
+       "SYSMMU_MFC_L"  ,
+       "SYSMMU_MFC_R"  ,
+};
+
+static struct resource exynos4_sysmmu_resource[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_SYSMMU_MDMA,
+               .end    = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_SYSMMU_MDMA0_0,
+               .end    = IRQ_SYSMMU_MDMA0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = EXYNOS4_PA_SYSMMU_SSS,
+               .end    = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [3] = {
+               .start  = IRQ_SYSMMU_SSS_0,
+               .end    = IRQ_SYSMMU_SSS_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [4] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMC0,
+               .end    = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [5] = {
+               .start  = IRQ_SYSMMU_FIMC0_0,
+               .end    = IRQ_SYSMMU_FIMC0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [6] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMC1,
+               .end    = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [7] = {
+               .start  = IRQ_SYSMMU_FIMC1_0,
+               .end    = IRQ_SYSMMU_FIMC1_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [8] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMC2,
+               .end    = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [9] = {
+               .start  = IRQ_SYSMMU_FIMC2_0,
+               .end    = IRQ_SYSMMU_FIMC2_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [10] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMC3,
+               .end    = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [11] = {
+               .start  = IRQ_SYSMMU_FIMC3_0,
+               .end    = IRQ_SYSMMU_FIMC3_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [12] = {
+               .start  = EXYNOS4_PA_SYSMMU_JPEG,
+               .end    = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [13] = {
+               .start  = IRQ_SYSMMU_JPEG_0,
+               .end    = IRQ_SYSMMU_JPEG_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [14] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMD0,
+               .end    = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [15] = {
+               .start  = IRQ_SYSMMU_LCD0_M0_0,
+               .end    = IRQ_SYSMMU_LCD0_M0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [16] = {
+               .start  = EXYNOS4_PA_SYSMMU_FIMD1,
+               .end    = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [17] = {
+               .start  = IRQ_SYSMMU_LCD1_M1_0,
+               .end    = IRQ_SYSMMU_LCD1_M1_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [18] = {
+               .start  = EXYNOS4_PA_SYSMMU_PCIe,
+               .end    = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [19] = {
+               .start  = IRQ_SYSMMU_PCIE_0,
+               .end    = IRQ_SYSMMU_PCIE_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [20] = {
+               .start  = EXYNOS4_PA_SYSMMU_G2D,
+               .end    = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [21] = {
+               .start  = IRQ_SYSMMU_2D_0,
+               .end    = IRQ_SYSMMU_2D_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [22] = {
+               .start  = EXYNOS4_PA_SYSMMU_ROTATOR,
+               .end    = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [23] = {
+               .start  = IRQ_SYSMMU_ROTATOR_0,
+               .end    = IRQ_SYSMMU_ROTATOR_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [24] = {
+               .start  = EXYNOS4_PA_SYSMMU_MDMA2,
+               .end    = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [25] = {
+               .start  = IRQ_SYSMMU_MDMA1_0,
+               .end    = IRQ_SYSMMU_MDMA1_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [26] = {
+               .start  = EXYNOS4_PA_SYSMMU_TV,
+               .end    = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [27] = {
+               .start  = IRQ_SYSMMU_TV_M0_0,
+               .end    = IRQ_SYSMMU_TV_M0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [28] = {
+               .start  = EXYNOS4_PA_SYSMMU_MFC_L,
+               .end    = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [29] = {
+               .start  = IRQ_SYSMMU_MFC_M0_0,
+               .end    = IRQ_SYSMMU_MFC_M0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [30] = {
+               .start  = EXYNOS4_PA_SYSMMU_MFC_R,
+               .end    = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [31] = {
+               .start  = IRQ_SYSMMU_MFC_M1_0,
+               .end    = IRQ_SYSMMU_MFC_M1_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device exynos4_device_sysmmu = {
+       .name           = "s5p-sysmmu",
+       .id             = 32,
+       .num_resources  = ARRAY_SIZE(exynos4_sysmmu_resource),
+       .resource       = exynos4_sysmmu_resource,
+};
+EXPORT_SYMBOL(exynos4_device_sysmmu);
+
+static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
+void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
+{
+       sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
+       if (IS_ERR(sysmmu_clk[ips]))
+               sysmmu_clk[ips] = NULL;
+       else
+               clk_put(sysmmu_clk[ips]);
+}
+
+void sysmmu_clk_enable(sysmmu_ips ips)
+{
+       if (sysmmu_clk[ips])
+               clk_enable(sysmmu_clk[ips]);
+}
+
+void sysmmu_clk_disable(sysmmu_ips ips)
+{
+       if (sysmmu_clk[ips])
+               clk_disable(sysmmu_clk[ips]);
+}
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
new file mode 100644 (file)
index 0000000..9667c61
--- /dev/null
@@ -0,0 +1,250 @@
+/* linux/arch/arm/mach-exynos4/dma.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl330.h>
+
+#include <asm/irq.h>
+#include <plat/devs.h>
+#include <plat/irqs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/dma.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+struct dma_pl330_peri pdma0_peri[28] = {
+       {
+               .peri_id = (u8)DMACH_PCM0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_PCM0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_PCM2_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_PCM2_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_MSM_REQ0,
+       }, {
+               .peri_id = (u8)DMACH_MSM_REQ2,
+       }, {
+               .peri_id = (u8)DMACH_SPI0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SPI0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SPI2_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SPI2_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_I2S0S_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_I2S0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_I2S0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART2_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART2_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART4_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART4_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS2_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS2_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS4_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS4_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_AC97_MICIN,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_AC97_PCMIN,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_AC97_PCMOUT,
+               .rqtype = MEMTODEV,
+       },
+};
+
+struct dma_pl330_platdata exynos4_pdma0_pdata = {
+       .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
+       .peri = pdma0_peri,
+};
+
+struct amba_device exynos4_device_pdma0 = {
+       .dev = {
+               .init_name = "dma-pl330.0",
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &exynos4_pdma0_pdata,
+       },
+       .res = {
+               .start = EXYNOS4_PA_PDMA0,
+               .end = EXYNOS4_PA_PDMA0 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_PDMA0, NO_IRQ},
+       .periphid = 0x00041330,
+};
+
+struct dma_pl330_peri pdma1_peri[25] = {
+       {
+               .peri_id = (u8)DMACH_PCM0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_PCM0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_PCM1_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_PCM1_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_MSM_REQ1,
+       }, {
+               .peri_id = (u8)DMACH_MSM_REQ3,
+       }, {
+               .peri_id = (u8)DMACH_SPI1_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SPI1_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_I2S0S_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_I2S0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_I2S0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_I2S1_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_I2S1_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART0_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART0_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART1_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART1_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_UART3_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_UART3_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS1_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS1_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS3_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS3_TX,
+               .rqtype = MEMTODEV,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS5_RX,
+               .rqtype = DEVTOMEM,
+       }, {
+               .peri_id = (u8)DMACH_SLIMBUS5_TX,
+               .rqtype = MEMTODEV,
+       },
+};
+
+struct dma_pl330_platdata exynos4_pdma1_pdata = {
+       .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
+       .peri = pdma1_peri,
+};
+
+struct amba_device exynos4_device_pdma1 = {
+       .dev = {
+               .init_name = "dma-pl330.1",
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &exynos4_pdma1_pdata,
+       },
+       .res = {
+               .start = EXYNOS4_PA_PDMA1,
+               .end = EXYNOS4_PA_PDMA1 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_PDMA1, NO_IRQ},
+       .periphid = 0x00041330,
+};
+
+static int __init exynos4_dma_init(void)
+{
+       amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+       amba_device_register(&exynos4_device_pdma1, &iomem_resource);
+
+       return 0;
+}
+arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos/headsmp.S b/arch/arm/mach-exynos/headsmp.S
new file mode 100644 (file)
index 0000000..3cdeb36
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  linux/arch/arm/mach-exynos4/headsmp.S
+ *
+ *  Cloned from linux/arch/arm/mach-realview/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+       __CPUINIT
+
+/*
+ * exynos4 specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(exynos4_secondary_startup)
+       mrc     p15, 0, r0, c0, c0, 5
+       and     r0, r0, #15
+       adr     r4, 1f
+       ldmia   r4, {r5, r6}
+       sub     r4, r4, r5
+       add     r6, r6, r4
+pen:   ldr     r7, [r6]
+       cmp     r7, r0
+       bne     pen
+
+       /*
+        * we've been released from the holding pen: secondary_stack
+        * should now contain the SVC stack for this core
+        */
+       b       secondary_startup
+
+1:     .long   .
+       .long   pen_release
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
new file mode 100644 (file)
index 0000000..da70e7e
--- /dev/null
@@ -0,0 +1,133 @@
+/* linux arch/arm/mach-exynos4/hotplug.c
+ *
+ *  Cloned from linux/arch/arm/mach-realview/hotplug.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-pmu.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+       unsigned int v;
+
+       flush_cache_all();
+       asm volatile(
+       "       mcr     p15, 0, %1, c7, c5, 0\n"
+       "       mcr     p15, 0, %1, c7, c10, 4\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %3\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+         : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "mrc    p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       orr     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+         : "=&r" (v)
+         : "Ir" (CR_C), "Ir" (0x40)
+         : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+       for (;;) {
+
+               /* make cpu1 to be turned off at next WFI command */
+               if (cpu == 1)
+                       __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION);
+
+               /*
+                * here's the WFI
+                */
+               asm(".word      0xe320f003\n"
+                   :
+                   :
+                   : "memory", "cc");
+
+               if (pen_release == cpu_logical_map(cpu)) {
+                       /*
+                        * OK, proper wakeup, we're done
+                        */
+                       break;
+               }
+
+               /*
+                * Getting here, means that we have come out of WFI without
+                * having been woken up - this shouldn't happen
+                *
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
+                */
+               (*spurious)++;
+       }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+       return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+       int spurious = 0;
+
+       /*
+        * we're ready for shutdown now, so do it
+        */
+       cpu_enter_lowpower();
+       platform_do_lowpower(cpu, &spurious);
+
+       /*
+        * bring this CPU back into the world of cache
+        * coherency, and then restore interrupts
+        */
+       cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+       /*
+        * we don't allow CPU 0 to be shutdown (it is still too special
+        * e.g. clock tick interrupts)
+        */
+       return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-exynos/include/mach/debug-macro.S b/arch/arm/mach-exynos/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..6cacf16
--- /dev/null
@@ -0,0 +1,35 @@
+/* linux/arch/arm/mach-exynos4/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+
+       /* note, for the boot process to work we have to keep the UART
+        * virtual address aligned to an 1MiB boundary for the L1
+        * mapping the head code makes. We keep the UART virtual address
+        * aligned and add in the offset when we load the value here.
+        */
+
+       .macro addruart, rp, rv, tmp
+               ldr     \rp, = S3C_PA_UART
+               ldr     \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+               add     \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+               add     \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+#endif
+       .endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-exynos/include/mach/dma.h b/arch/arm/mach-exynos/include/mach/dma.h
new file mode 100644 (file)
index 0000000..201842a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ *     Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common DMA API driver for PL330 */
+#include <plat/dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos/include/mach/dwmci.h b/arch/arm/mach-exynos/include/mach/dwmci.h
new file mode 100644 (file)
index 0000000..7ce6574
--- /dev/null
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-exynos4/include/mach/dwmci.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Synopsys DesignWare Mobile Storage for EXYNOS4210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_DWMCI_H
+#define __ASM_ARM_ARCH_DWMCI_H __FILE__
+
+#include <linux/mmc/dw_mmc.h>
+
+extern void exynos4_dwmci_set_platdata(struct dw_mci_board *pd);
+
+#endif /* __ASM_ARM_ARCH_DWMCI_H */
diff --git a/arch/arm/mach-exynos/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..f5e9fd8
--- /dev/null
@@ -0,0 +1,91 @@
+/* arch/arm/mach-exynos4/include/mach/entry-macro.S
+ *
+ * Cloned from arch/arm/mach-realview/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for EXYNOS4 platforms
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/hardware/gic.h>
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  get_irqnr_preamble, base, tmp
+               mov     \tmp, #0
+
+               mrc     p15, 0, \base, c0, c0, 5
+               and     \base, \base, #3
+               cmp     \base, #0
+               beq     1f
+
+               ldr     \tmp, =gic_bank_offset
+               ldr     \tmp, [\tmp]
+               cmp     \base, #1
+               beq     1f
+
+               cmp     \base, #2
+               addeq   \tmp, \tmp, \tmp
+               addne   \tmp, \tmp, \tmp, LSL #1
+
+1:             ldr     \base, =gic_cpu_base_addr
+               ldr     \base, [\base]
+               add     \base, \base, \tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
+               /*
+                * The interrupt numbering scheme is defined in the
+                * interrupt controller spec.  To wit:
+                *
+                * Interrupts 0-15 are IPI
+                * 16-28 are reserved
+                * 29-31 are local.  We allow 30 to be used for the watchdog.
+                * 32-1020 are global
+                * 1021-1022 are reserved
+                * 1023 is "spurious" (no interrupt)
+                *
+                * For now, we ignore all local interrupts so only return an interrupt if it's
+                * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+                *
+                * A simple read from the controller will tell us the number of the highest
+                 * priority enabled interrupt.  We then just need to check whether it is in the
+                * valid range for an IRQ (30-1020 inclusive).
+                */
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+
+               ldr     \tmp, =1021
+
+               bic     \irqnr, \irqstat, #0x1c00
+
+               cmp     \irqnr, #15
+               cmpcc   \irqnr, \irqnr
+               cmpne   \irqnr, \tmp
+               cmpcs   \irqnr, \irqnr
+               addne   \irqnr, \irqnr, #32
+
+               .endm
+
+               /* We assume that irqstat (the raw value of the IRQ acknowledge
+                * register) is preserved from the macro above.
+                * If there is an IPI, we immediately signal end of interrupt on the
+                * controller, since this requires the original irqstat value which
+                * we won't easily be able to recreate later.
+                */
+
+               .macro test_for_ipi, irqnr, irqstat, base, tmp
+               bic     \irqnr, \irqstat, #0x1c00
+               cmp     \irqnr, #16
+               strcc   \irqstat, [\base, #GIC_CPU_EOI]
+               cmpcs   \irqnr, \irqnr
+               .endm
diff --git a/arch/arm/mach-exynos/include/mach/exynos4-clock.h b/arch/arm/mach-exynos/include/mach/exynos4-clock.h
new file mode 100644 (file)
index 0000000..a07fcbf
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for exynos4 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clk clk_sclk_hdmi27m;
+extern struct clk clk_sclk_usbphy0;
+extern struct clk clk_sclk_usbphy1;
+extern struct clk clk_sclk_hdmiphy;
+
+extern struct clksrc_clk clk_sclk_apll;
+extern struct clksrc_clk clk_mout_mpll;
+extern struct clksrc_clk clk_aclk_133;
+extern struct clksrc_clk clk_mout_epll;
+extern struct clksrc_clk clk_sclk_vpll;
+
+extern struct clk *clkset_corebus_list[];
+extern struct clksrc_sources clkset_mout_corebus;
+
+extern struct clk *clkset_aclk_top_list[];
+extern struct clksrc_sources clkset_aclk;
+
+extern struct clk *clkset_group_list[];
+extern struct clksrc_sources clkset_group;
+
+extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..80523ca
--- /dev/null
@@ -0,0 +1,149 @@
+/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
+
+/* GPIO bank sizes */
+#define EXYNOS4_GPIO_A0_NR     (8)
+#define EXYNOS4_GPIO_A1_NR     (6)
+#define EXYNOS4_GPIO_B_NR      (8)
+#define EXYNOS4_GPIO_C0_NR     (5)
+#define EXYNOS4_GPIO_C1_NR     (5)
+#define EXYNOS4_GPIO_D0_NR     (4)
+#define EXYNOS4_GPIO_D1_NR     (4)
+#define EXYNOS4_GPIO_E0_NR     (5)
+#define EXYNOS4_GPIO_E1_NR     (8)
+#define EXYNOS4_GPIO_E2_NR     (6)
+#define EXYNOS4_GPIO_E3_NR     (8)
+#define EXYNOS4_GPIO_E4_NR     (8)
+#define EXYNOS4_GPIO_F0_NR     (8)
+#define EXYNOS4_GPIO_F1_NR     (8)
+#define EXYNOS4_GPIO_F2_NR     (8)
+#define EXYNOS4_GPIO_F3_NR     (6)
+#define EXYNOS4_GPIO_J0_NR     (8)
+#define EXYNOS4_GPIO_J1_NR     (5)
+#define EXYNOS4_GPIO_K0_NR     (7)
+#define EXYNOS4_GPIO_K1_NR     (7)
+#define EXYNOS4_GPIO_K2_NR     (7)
+#define EXYNOS4_GPIO_K3_NR     (7)
+#define EXYNOS4_GPIO_L0_NR     (8)
+#define EXYNOS4_GPIO_L1_NR     (3)
+#define EXYNOS4_GPIO_L2_NR     (8)
+#define EXYNOS4_GPIO_X0_NR     (8)
+#define EXYNOS4_GPIO_X1_NR     (8)
+#define EXYNOS4_GPIO_X2_NR     (8)
+#define EXYNOS4_GPIO_X3_NR     (8)
+#define EXYNOS4_GPIO_Y0_NR     (6)
+#define EXYNOS4_GPIO_Y1_NR     (4)
+#define EXYNOS4_GPIO_Y2_NR     (6)
+#define EXYNOS4_GPIO_Y3_NR     (8)
+#define EXYNOS4_GPIO_Y4_NR     (8)
+#define EXYNOS4_GPIO_Y5_NR     (8)
+#define EXYNOS4_GPIO_Y6_NR     (8)
+#define EXYNOS4_GPIO_Z_NR      (7)
+
+/* GPIO bank numbers */
+
+#define EXYNOS4_GPIO_NEXT(__gpio) \
+       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+       EXYNOS4_GPIO_A0_START   = 0,
+       EXYNOS4_GPIO_A1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
+       EXYNOS4_GPIO_B_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
+       EXYNOS4_GPIO_C0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
+       EXYNOS4_GPIO_C1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
+       EXYNOS4_GPIO_D0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
+       EXYNOS4_GPIO_D1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
+       EXYNOS4_GPIO_E0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
+       EXYNOS4_GPIO_E1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
+       EXYNOS4_GPIO_E2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
+       EXYNOS4_GPIO_E3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
+       EXYNOS4_GPIO_E4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
+       EXYNOS4_GPIO_F0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
+       EXYNOS4_GPIO_F1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
+       EXYNOS4_GPIO_F2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
+       EXYNOS4_GPIO_F3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
+       EXYNOS4_GPIO_J0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
+       EXYNOS4_GPIO_J1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
+       EXYNOS4_GPIO_K0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
+       EXYNOS4_GPIO_K1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
+       EXYNOS4_GPIO_K2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
+       EXYNOS4_GPIO_K3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
+       EXYNOS4_GPIO_L0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
+       EXYNOS4_GPIO_L1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
+       EXYNOS4_GPIO_L2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
+       EXYNOS4_GPIO_X0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
+       EXYNOS4_GPIO_X1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
+       EXYNOS4_GPIO_X2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
+       EXYNOS4_GPIO_X3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
+       EXYNOS4_GPIO_Y0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
+       EXYNOS4_GPIO_Y1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
+       EXYNOS4_GPIO_Y2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
+       EXYNOS4_GPIO_Y3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
+       EXYNOS4_GPIO_Y4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
+       EXYNOS4_GPIO_Y5_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
+       EXYNOS4_GPIO_Y6_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
+       EXYNOS4_GPIO_Z_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
+};
+
+/* EXYNOS4 GPIO number definitions */
+#define EXYNOS4_GPA0(_nr)      (EXYNOS4_GPIO_A0_START + (_nr))
+#define EXYNOS4_GPA1(_nr)      (EXYNOS4_GPIO_A1_START + (_nr))
+#define EXYNOS4_GPB(_nr)       (EXYNOS4_GPIO_B_START + (_nr))
+#define EXYNOS4_GPC0(_nr)      (EXYNOS4_GPIO_C0_START + (_nr))
+#define EXYNOS4_GPC1(_nr)      (EXYNOS4_GPIO_C1_START + (_nr))
+#define EXYNOS4_GPD0(_nr)      (EXYNOS4_GPIO_D0_START + (_nr))
+#define EXYNOS4_GPD1(_nr)      (EXYNOS4_GPIO_D1_START + (_nr))
+#define EXYNOS4_GPE0(_nr)      (EXYNOS4_GPIO_E0_START + (_nr))
+#define EXYNOS4_GPE1(_nr)      (EXYNOS4_GPIO_E1_START + (_nr))
+#define EXYNOS4_GPE2(_nr)      (EXYNOS4_GPIO_E2_START + (_nr))
+#define EXYNOS4_GPE3(_nr)      (EXYNOS4_GPIO_E3_START + (_nr))
+#define EXYNOS4_GPE4(_nr)      (EXYNOS4_GPIO_E4_START + (_nr))
+#define EXYNOS4_GPF0(_nr)      (EXYNOS4_GPIO_F0_START + (_nr))
+#define EXYNOS4_GPF1(_nr)      (EXYNOS4_GPIO_F1_START + (_nr))
+#define EXYNOS4_GPF2(_nr)      (EXYNOS4_GPIO_F2_START + (_nr))
+#define EXYNOS4_GPF3(_nr)      (EXYNOS4_GPIO_F3_START + (_nr))
+#define EXYNOS4_GPJ0(_nr)      (EXYNOS4_GPIO_J0_START + (_nr))
+#define EXYNOS4_GPJ1(_nr)      (EXYNOS4_GPIO_J1_START + (_nr))
+#define EXYNOS4_GPK0(_nr)      (EXYNOS4_GPIO_K0_START + (_nr))
+#define EXYNOS4_GPK1(_nr)      (EXYNOS4_GPIO_K1_START + (_nr))
+#define EXYNOS4_GPK2(_nr)      (EXYNOS4_GPIO_K2_START + (_nr))
+#define EXYNOS4_GPK3(_nr)      (EXYNOS4_GPIO_K3_START + (_nr))
+#define EXYNOS4_GPL0(_nr)      (EXYNOS4_GPIO_L0_START + (_nr))
+#define EXYNOS4_GPL1(_nr)      (EXYNOS4_GPIO_L1_START + (_nr))
+#define EXYNOS4_GPL2(_nr)      (EXYNOS4_GPIO_L2_START + (_nr))
+#define EXYNOS4_GPX0(_nr)      (EXYNOS4_GPIO_X0_START + (_nr))
+#define EXYNOS4_GPX1(_nr)      (EXYNOS4_GPIO_X1_START + (_nr))
+#define EXYNOS4_GPX2(_nr)      (EXYNOS4_GPIO_X2_START + (_nr))
+#define EXYNOS4_GPX3(_nr)      (EXYNOS4_GPIO_X3_START + (_nr))
+#define EXYNOS4_GPY0(_nr)      (EXYNOS4_GPIO_Y0_START + (_nr))
+#define EXYNOS4_GPY1(_nr)      (EXYNOS4_GPIO_Y1_START + (_nr))
+#define EXYNOS4_GPY2(_nr)      (EXYNOS4_GPIO_Y2_START + (_nr))
+#define EXYNOS4_GPY3(_nr)      (EXYNOS4_GPIO_Y3_START + (_nr))
+#define EXYNOS4_GPY4(_nr)      (EXYNOS4_GPIO_Y4_START + (_nr))
+#define EXYNOS4_GPY5(_nr)      (EXYNOS4_GPIO_Y5_START + (_nr))
+#define EXYNOS4_GPY6(_nr)      (EXYNOS4_GPIO_Y6_START + (_nr))
+#define EXYNOS4_GPZ(_nr)       (EXYNOS4_GPIO_Z_START + (_nr))
+
+/* the end of the EXYNOS4 specific gpios */
+#define EXYNOS4_GPIO_END       (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
+#define S3C_GPIO_END           EXYNOS4_GPIO_END
+
+/* define the number of gpios we need to the one after the GPZ() range */
+#define ARCH_NR_GPIOS          (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) +       \
+                                CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-exynos/include/mach/hardware.h b/arch/arm/mach-exynos/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..5109eb2
--- /dev/null
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-exynos/include/mach/io.h b/arch/arm/mach-exynos/include/mach/io.h
new file mode 100644 (file)
index 0000000..d5478d2
--- /dev/null
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-exynos4/include/mach/io.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Default IO routines for EXYNOS4
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H __FILE__
+
+/* No current ISA/PCI bus support. */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..dfd4b7e
--- /dev/null
@@ -0,0 +1,169 @@
+/* linux/arch/arm/mach-exynos4/include/mach/irqs.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* PPI: Private Peripheral Interrupt */
+
+#define IRQ_PPI(x)             S5P_IRQ(x+16)
+
+#define IRQ_MCT_LOCALTIMER     IRQ_PPI(12)
+
+/* SPI: Shared Peripheral Interrupt */
+
+#define IRQ_SPI(x)             S5P_IRQ(x+32)
+
+#define IRQ_EINT0              IRQ_SPI(16)
+#define IRQ_EINT1              IRQ_SPI(17)
+#define IRQ_EINT2              IRQ_SPI(18)
+#define IRQ_EINT3              IRQ_SPI(19)
+#define IRQ_EINT4              IRQ_SPI(20)
+#define IRQ_EINT5              IRQ_SPI(21)
+#define IRQ_EINT6              IRQ_SPI(22)
+#define IRQ_EINT7              IRQ_SPI(23)
+#define IRQ_EINT8              IRQ_SPI(24)
+#define IRQ_EINT9              IRQ_SPI(25)
+#define IRQ_EINT10             IRQ_SPI(26)
+#define IRQ_EINT11             IRQ_SPI(27)
+#define IRQ_EINT12             IRQ_SPI(28)
+#define IRQ_EINT13             IRQ_SPI(29)
+#define IRQ_EINT14             IRQ_SPI(30)
+#define IRQ_EINT15             IRQ_SPI(31)
+#define IRQ_EINT16_31          IRQ_SPI(32)
+
+#define IRQ_PDMA0              IRQ_SPI(35)
+#define IRQ_PDMA1              IRQ_SPI(36)
+#define IRQ_TIMER0_VIC         IRQ_SPI(37)
+#define IRQ_TIMER1_VIC         IRQ_SPI(38)
+#define IRQ_TIMER2_VIC         IRQ_SPI(39)
+#define IRQ_TIMER3_VIC         IRQ_SPI(40)
+#define IRQ_TIMER4_VIC         IRQ_SPI(41)
+#define IRQ_MCT_L0             IRQ_SPI(42)
+#define IRQ_WDT                        IRQ_SPI(43)
+#define IRQ_RTC_ALARM          IRQ_SPI(44)
+#define IRQ_RTC_TIC            IRQ_SPI(45)
+#define IRQ_GPIO_XB            IRQ_SPI(46)
+#define IRQ_GPIO_XA            IRQ_SPI(47)
+#define IRQ_MCT_L1             IRQ_SPI(48)
+
+#define IRQ_UART0              IRQ_SPI(52)
+#define IRQ_UART1              IRQ_SPI(53)
+#define IRQ_UART2              IRQ_SPI(54)
+#define IRQ_UART3              IRQ_SPI(55)
+#define IRQ_UART4              IRQ_SPI(56)
+#define IRQ_MCT_G0             IRQ_SPI(57)
+#define IRQ_IIC                        IRQ_SPI(58)
+#define IRQ_IIC1               IRQ_SPI(59)
+#define IRQ_IIC2               IRQ_SPI(60)
+#define IRQ_IIC3               IRQ_SPI(61)
+#define IRQ_IIC4               IRQ_SPI(62)
+#define IRQ_IIC5               IRQ_SPI(63)
+#define IRQ_IIC6               IRQ_SPI(64)
+#define IRQ_IIC7               IRQ_SPI(65)
+
+#define IRQ_USB_HOST           IRQ_SPI(70)
+#define IRQ_USB_HSOTG          IRQ_SPI(71)
+#define IRQ_MODEM_IF           IRQ_SPI(72)
+#define IRQ_HSMMC0             IRQ_SPI(73)
+#define IRQ_HSMMC1             IRQ_SPI(74)
+#define IRQ_HSMMC2             IRQ_SPI(75)
+#define IRQ_HSMMC3             IRQ_SPI(76)
+#define IRQ_DWMCI              IRQ_SPI(77)
+
+#define IRQ_MIPI_CSIS0         IRQ_SPI(78)
+#define IRQ_MIPI_CSIS1         IRQ_SPI(80)
+
+#define IRQ_ONENAND_AUDI       IRQ_SPI(82)
+#define IRQ_ROTATOR            IRQ_SPI(83)
+#define IRQ_FIMC0              IRQ_SPI(84)
+#define IRQ_FIMC1              IRQ_SPI(85)
+#define IRQ_FIMC2              IRQ_SPI(86)
+#define IRQ_FIMC3              IRQ_SPI(87)
+#define IRQ_JPEG               IRQ_SPI(88)
+#define IRQ_2D                 IRQ_SPI(89)
+#define IRQ_PCIE               IRQ_SPI(90)
+
+#define IRQ_MIXER              IRQ_SPI(91)
+#define IRQ_HDMI               IRQ_SPI(92)
+#define IRQ_IIC_HDMIPHY                IRQ_SPI(93)
+#define IRQ_MFC                        IRQ_SPI(94)
+#define IRQ_SDO                        IRQ_SPI(95)
+
+#define IRQ_AUDIO_SS           IRQ_SPI(96)
+#define IRQ_I2S0               IRQ_SPI(97)
+#define IRQ_I2S1               IRQ_SPI(98)
+#define IRQ_I2S2               IRQ_SPI(99)
+#define IRQ_AC97               IRQ_SPI(100)
+
+#define IRQ_SPDIF              IRQ_SPI(104)
+#define IRQ_ADC0               IRQ_SPI(105)
+#define IRQ_PEN0               IRQ_SPI(106)
+#define IRQ_ADC1               IRQ_SPI(107)
+#define IRQ_PEN1               IRQ_SPI(108)
+#define IRQ_KEYPAD             IRQ_SPI(109)
+#define IRQ_PMU                        IRQ_SPI(110)
+#define IRQ_GPS                        IRQ_SPI(111)
+#define IRQ_INTFEEDCTRL_SSS    IRQ_SPI(112)
+#define IRQ_SLIMBUS            IRQ_SPI(113)
+
+#define IRQ_TSI                        IRQ_SPI(115)
+#define IRQ_SATA               IRQ_SPI(116)
+
+#define MAX_IRQ_IN_COMBINER    8
+#define COMBINER_GROUP(x)      ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
+#define COMBINER_IRQ(x, y)     (COMBINER_GROUP(x) + y)
+
+#define IRQ_SYSMMU_MDMA0_0     COMBINER_IRQ(4, 0)
+#define IRQ_SYSMMU_SSS_0       COMBINER_IRQ(4, 1)
+#define IRQ_SYSMMU_FIMC0_0     COMBINER_IRQ(4, 2)
+#define IRQ_SYSMMU_FIMC1_0     COMBINER_IRQ(4, 3)
+#define IRQ_SYSMMU_FIMC2_0     COMBINER_IRQ(4, 4)
+#define IRQ_SYSMMU_FIMC3_0     COMBINER_IRQ(4, 5)
+#define IRQ_SYSMMU_JPEG_0      COMBINER_IRQ(4, 6)
+#define IRQ_SYSMMU_2D_0                COMBINER_IRQ(4, 7)
+
+#define IRQ_SYSMMU_ROTATOR_0   COMBINER_IRQ(5, 0)
+#define IRQ_SYSMMU_MDMA1_0     COMBINER_IRQ(5, 1)
+#define IRQ_SYSMMU_LCD0_M0_0   COMBINER_IRQ(5, 2)
+#define IRQ_SYSMMU_LCD1_M1_0   COMBINER_IRQ(5, 3)
+#define IRQ_SYSMMU_TV_M0_0     COMBINER_IRQ(5, 4)
+#define IRQ_SYSMMU_MFC_M0_0    COMBINER_IRQ(5, 5)
+#define IRQ_SYSMMU_MFC_M1_0    COMBINER_IRQ(5, 6)
+#define IRQ_SYSMMU_PCIE_0      COMBINER_IRQ(5, 7)
+
+#define IRQ_FIMD0_FIFO         COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC                COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM       COMBINER_IRQ(11, 2)
+
+#define MAX_COMBINER_NR                16
+
+#define IRQ_ADC                        IRQ_ADC0
+#define IRQ_TC                 IRQ_PEN0
+
+#define S5P_IRQ_EINT_BASE      COMBINER_IRQ(MAX_COMBINER_NR, 0)
+
+#define S5P_EINT_BASE1         (S5P_IRQ_EINT_BASE + 0)
+#define S5P_EINT_BASE2         (S5P_IRQ_EINT_BASE + 16)
+
+/* optional GPIO interrupts */
+#define S5P_GPIOINT_BASE       (S5P_IRQ_EINT_BASE + 32)
+#define IRQ_GPIO1_NR_GROUPS    16
+#define IRQ_GPIO2_NR_GROUPS    9
+#define IRQ_GPIO_END           (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
+
+/* Set the default NR_IRQS */
+#define NR_IRQS                        (IRQ_GPIO_END + 64)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
new file mode 100644 (file)
index 0000000..058541d
--- /dev/null
@@ -0,0 +1,197 @@
+/* linux/arch/arm/mach-exynos/include/mach/map.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS4 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+
+/*
+ * EXYNOS4 UART offset is 0x10000 but the older S5P SoCs are 0x400.
+ * So need to define it, and here is to avoid redefinition warning.
+ */
+#define S3C_UART_OFFSET                        (0x10000)
+
+#include <plat/map-s5p.h>
+
+#define EXYNOS4_PA_SYSRAM0             0x02025000
+#define EXYNOS4_PA_SYSRAM1             0x02020000
+
+#define EXYNOS4_PA_FIMC0               0x11800000
+#define EXYNOS4_PA_FIMC1               0x11810000
+#define EXYNOS4_PA_FIMC2               0x11820000
+#define EXYNOS4_PA_FIMC3               0x11830000
+
+#define EXYNOS4_PA_I2S0                        0x03830000
+#define EXYNOS4_PA_I2S1                        0xE3100000
+#define EXYNOS4_PA_I2S2                        0xE2A00000
+
+#define EXYNOS4_PA_PCM0                        0x03840000
+#define EXYNOS4_PA_PCM1                        0x13980000
+#define EXYNOS4_PA_PCM2                        0x13990000
+
+#define EXYNOS4_PA_SROM_BANK(x)                (0x04000000 + ((x) * 0x01000000))
+
+#define EXYNOS4_PA_ONENAND             0x0C000000
+#define EXYNOS4_PA_ONENAND_DMA         0x0C600000
+
+#define EXYNOS4_PA_CHIPID              0x10000000
+
+#define EXYNOS4_PA_SYSCON              0x10010000
+#define EXYNOS4_PA_PMU                 0x10020000
+#define EXYNOS4_PA_CMU                 0x10030000
+
+#define EXYNOS4_PA_SYSTIMER            0x10050000
+#define EXYNOS4_PA_WATCHDOG            0x10060000
+#define EXYNOS4_PA_RTC                 0x10070000
+
+#define EXYNOS4_PA_KEYPAD              0x100A0000
+
+#define EXYNOS4_PA_DMC0                        0x10400000
+
+#define EXYNOS4_PA_COMBINER            0x10440000
+
+#define EXYNOS4_PA_GIC_CPU             0x10480000
+#define EXYNOS4_PA_GIC_DIST            0x10490000
+
+#define EXYNOS4_PA_COREPERI            0x10500000
+#define EXYNOS4_PA_TWD                 0x10500600
+#define EXYNOS4_PA_L2CC                        0x10502000
+
+#define EXYNOS4_PA_MDMA                        0x10810000
+#define EXYNOS4_PA_PDMA0               0x12680000
+#define EXYNOS4_PA_PDMA1               0x12690000
+
+#define EXYNOS4_PA_SYSMMU_MDMA         0x10A40000
+#define EXYNOS4_PA_SYSMMU_SSS          0x10A50000
+#define EXYNOS4_PA_SYSMMU_FIMC0                0x11A20000
+#define EXYNOS4_PA_SYSMMU_FIMC1                0x11A30000
+#define EXYNOS4_PA_SYSMMU_FIMC2                0x11A40000
+#define EXYNOS4_PA_SYSMMU_FIMC3                0x11A50000
+#define EXYNOS4_PA_SYSMMU_JPEG         0x11A60000
+#define EXYNOS4_PA_SYSMMU_FIMD0                0x11E20000
+#define EXYNOS4_PA_SYSMMU_FIMD1                0x12220000
+#define EXYNOS4_PA_SYSMMU_PCIe         0x12620000
+#define EXYNOS4_PA_SYSMMU_G2D          0x12A20000
+#define EXYNOS4_PA_SYSMMU_ROTATOR      0x12A30000
+#define EXYNOS4_PA_SYSMMU_MDMA2                0x12A40000
+#define EXYNOS4_PA_SYSMMU_TV           0x12E20000
+#define EXYNOS4_PA_SYSMMU_MFC_L                0x13620000
+#define EXYNOS4_PA_SYSMMU_MFC_R                0x13630000
+
+#define EXYNOS4_PA_GPIO1               0x11400000
+#define EXYNOS4_PA_GPIO2               0x11000000
+#define EXYNOS4_PA_GPIO3               0x03860000
+
+#define EXYNOS4_PA_MIPI_CSIS0          0x11880000
+#define EXYNOS4_PA_MIPI_CSIS1          0x11890000
+
+#define EXYNOS4_PA_FIMD0               0x11C00000
+
+#define EXYNOS4_PA_HSMMC(x)            (0x12510000 + ((x) * 0x10000))
+#define EXYNOS4_PA_DWMCI               0x12550000
+
+#define EXYNOS4_PA_SATA                        0x12560000
+#define EXYNOS4_PA_SATAPHY             0x125D0000
+#define EXYNOS4_PA_SATAPHY_CTRL                0x126B0000
+
+#define EXYNOS4_PA_SROMC               0x12570000
+
+#define EXYNOS4_PA_EHCI                        0x12580000
+#define EXYNOS4_PA_HSPHY               0x125B0000
+#define EXYNOS4_PA_MFC                 0x13400000
+
+#define EXYNOS4_PA_UART                        0x13800000
+
+#define EXYNOS4_PA_VP                  0x12C00000
+#define EXYNOS4_PA_MIXER               0x12C10000
+#define EXYNOS4_PA_SDO                 0x12C20000
+#define EXYNOS4_PA_HDMI                        0x12D00000
+#define EXYNOS4_PA_IIC_HDMIPHY         0x138E0000
+
+#define EXYNOS4_PA_IIC(x)              (0x13860000 + ((x) * 0x10000))
+
+#define EXYNOS4_PA_ADC                 0x13910000
+#define EXYNOS4_PA_ADC1                        0x13911000
+
+#define EXYNOS4_PA_AC97                        0x139A0000
+
+#define EXYNOS4_PA_SPDIF               0x139B0000
+
+#define EXYNOS4_PA_TIMER               0x139D0000
+
+#define EXYNOS4_PA_SDRAM               0x40000000
+
+/* Compatibiltiy Defines */
+
+#define S3C_PA_HSMMC0                  EXYNOS4_PA_HSMMC(0)
+#define S3C_PA_HSMMC1                  EXYNOS4_PA_HSMMC(1)
+#define S3C_PA_HSMMC2                  EXYNOS4_PA_HSMMC(2)
+#define S3C_PA_HSMMC3                  EXYNOS4_PA_HSMMC(3)
+#define S3C_PA_IIC                     EXYNOS4_PA_IIC(0)
+#define S3C_PA_IIC1                    EXYNOS4_PA_IIC(1)
+#define S3C_PA_IIC2                    EXYNOS4_PA_IIC(2)
+#define S3C_PA_IIC3                    EXYNOS4_PA_IIC(3)
+#define S3C_PA_IIC4                    EXYNOS4_PA_IIC(4)
+#define S3C_PA_IIC5                    EXYNOS4_PA_IIC(5)
+#define S3C_PA_IIC6                    EXYNOS4_PA_IIC(6)
+#define S3C_PA_IIC7                    EXYNOS4_PA_IIC(7)
+#define S3C_PA_RTC                     EXYNOS4_PA_RTC
+#define S3C_PA_WDT                     EXYNOS4_PA_WATCHDOG
+#define S3C_PA_UART                    EXYNOS4_PA_UART
+
+#define S5P_PA_CHIPID                  EXYNOS4_PA_CHIPID
+#define S5P_PA_EHCI                    EXYNOS4_PA_EHCI
+#define S5P_PA_FIMC0                   EXYNOS4_PA_FIMC0
+#define S5P_PA_FIMC1                   EXYNOS4_PA_FIMC1
+#define S5P_PA_FIMC2                   EXYNOS4_PA_FIMC2
+#define S5P_PA_FIMC3                   EXYNOS4_PA_FIMC3
+#define S5P_PA_FIMD0                   EXYNOS4_PA_FIMD0
+#define S5P_PA_HDMI                    EXYNOS4_PA_HDMI
+#define S5P_PA_IIC_HDMIPHY             EXYNOS4_PA_IIC_HDMIPHY
+#define S5P_PA_MFC                     EXYNOS4_PA_MFC
+#define S5P_PA_MIPI_CSIS0              EXYNOS4_PA_MIPI_CSIS0
+#define S5P_PA_MIPI_CSIS1              EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_MIXER                   EXYNOS4_PA_MIXER
+#define S5P_PA_ONENAND                 EXYNOS4_PA_ONENAND
+#define S5P_PA_ONENAND_DMA             EXYNOS4_PA_ONENAND_DMA
+#define S5P_PA_SDO                     EXYNOS4_PA_SDO
+#define S5P_PA_SDRAM                   EXYNOS4_PA_SDRAM
+#define S5P_PA_SROMC                   EXYNOS4_PA_SROMC
+#define S5P_PA_SYSCON                  EXYNOS4_PA_SYSCON
+#define S5P_PA_TIMER                   EXYNOS4_PA_TIMER
+#define S5P_PA_VP                      EXYNOS4_PA_VP
+
+#define SAMSUNG_PA_ADC                 EXYNOS4_PA_ADC
+#define SAMSUNG_PA_ADC1                        EXYNOS4_PA_ADC1
+#define SAMSUNG_PA_KEYPAD              EXYNOS4_PA_KEYPAD
+
+#define EXYNOS_PA_COMBINER             EXYNOS4_PA_COMBINER
+#define EXYNOS_PA_GIC_CPU              EXYNOS4_PA_GIC_CPU
+#define EXYNOS_PA_GIC_DIST             EXYNOS4_PA_GIC_DIST
+#define EXYNOS_PA_PMU                  EXYNOS4_PA_PMU
+#define EXYNOS_PA_SYSTIMER             EXYNOS4_PA_SYSTIMER
+
+/* Compatibility UART */
+
+#define S3C_VA_UARTx(x)                        (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
+#define S5P_PA_UART(x)                 (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
+#define S5P_PA_UART0                   S5P_PA_UART(0)
+#define S5P_PA_UART1                   S5P_PA_UART(1)
+#define S5P_PA_UART2                   S5P_PA_UART(2)
+#define S5P_PA_UART3                   S5P_PA_UART(3)
+#define S5P_PA_UART4                   S5P_PA_UART(4)
+
+#define S5P_SZ_UART                    SZ_256
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/include/mach/memory.h b/arch/arm/mach-exynos/include/mach/memory.h
new file mode 100644 (file)
index 0000000..374ef2c
--- /dev/null
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/memory.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H __FILE__
+
+#define PLAT_PHYS_OFFSET               UL(0x40000000)
+
+/* Maximum of 256MiB in one bank */
+#define MAX_PHYSMEM_BITS       32
+#define SECTION_SIZE_BITS      28
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h
new file mode 100644 (file)
index 0000000..9d8da51
--- /dev/null
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PM_CORE_H
+#define __ASM_ARCH_PM_CORE_H __FILE__
+
+#include <mach/regs-pmu.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+       unsigned int tmp;
+       tmp = __raw_readl(S5P_WAKEUP_MASK);
+       tmp &= ~(1 << 31);
+       __raw_writel(tmp, S5P_WAKEUP_MASK);
+
+       __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
+       __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+                                          struct pm_uart_save *save)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+       /* nothing here yet */
+}
+
+static inline void samsung_pm_saved_gpios(void)
+{
+       /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_PM_CORE_H */
diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h
new file mode 100644 (file)
index 0000000..632dd56
--- /dev/null
@@ -0,0 +1,32 @@
+/* linux/arch/arm/mach-exynos4/include/mach/pmu.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS4210 - PMU(Power Management Unit) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PMU_H
+#define __ASM_ARCH_PMU_H __FILE__
+
+#define PMU_TABLE_END  NULL
+
+enum sys_powerdown {
+       SYS_AFTR,
+       SYS_LPA,
+       SYS_SLEEP,
+       NUM_SYS_POWERDOWN,
+};
+
+struct exynos4_pmu_conf {
+       void __iomem *reg;
+       unsigned int val[NUM_SYS_POWERDOWN];
+};
+
+extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
+
+#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-audss.h b/arch/arm/mach-exynos/include/mach/regs-audss.h
new file mode 100644 (file)
index 0000000..ca5a8b6
--- /dev/null
@@ -0,0 +1,18 @@
+/* arch/arm/mach-exynos4/include/mach/regs-audss.h
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *             http://www.samsung.com
+ *
+ * Exynos4 Audio SubSystem clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_AUDSS_H
+#define __PLAT_REGS_AUDSS_H __FILE__
+
+#define EXYNOS4_AUDSS_INT_MEM  (0x03000000)
+
+#endif /* _PLAT_REGS_AUDSS_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..6c37ebe
--- /dev/null
@@ -0,0 +1,210 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <plat/cpu.h>
+#include <mach/map.h>
+
+#define S5P_CLKREG(x)                  (S5P_VA_CMU + (x))
+
+#define S5P_CLKDIV_LEFTBUS             S5P_CLKREG(0x04500)
+#define S5P_CLKDIV_STAT_LEFTBUS                S5P_CLKREG(0x04600)
+#define S5P_CLKGATE_IP_LEFTBUS         S5P_CLKREG(0x04800)
+
+#define S5P_CLKDIV_RIGHTBUS            S5P_CLKREG(0x08500)
+#define S5P_CLKDIV_STAT_RIGHTBUS       S5P_CLKREG(0x08600)
+#define S5P_CLKGATE_IP_RIGHTBUS                S5P_CLKREG(0x08800)
+
+#define S5P_EPLL_LOCK                  S5P_CLKREG(0x0C010)
+#define S5P_VPLL_LOCK                  S5P_CLKREG(0x0C020)
+
+#define S5P_EPLL_CON0                  S5P_CLKREG(0x0C110)
+#define S5P_EPLL_CON1                  S5P_CLKREG(0x0C114)
+#define S5P_VPLL_CON0                  S5P_CLKREG(0x0C120)
+#define S5P_VPLL_CON1                  S5P_CLKREG(0x0C124)
+
+#define S5P_CLKSRC_TOP0                        S5P_CLKREG(0x0C210)
+#define S5P_CLKSRC_TOP1                        S5P_CLKREG(0x0C214)
+#define S5P_CLKSRC_CAM                 S5P_CLKREG(0x0C220)
+#define S5P_CLKSRC_TV                  S5P_CLKREG(0x0C224)
+#define S5P_CLKSRC_MFC                 S5P_CLKREG(0x0C228)
+#define S5P_CLKSRC_G3D                 S5P_CLKREG(0x0C22C)
+#define S5P_CLKSRC_IMAGE               S5P_CLKREG(0x0C230)
+#define S5P_CLKSRC_LCD0                        S5P_CLKREG(0x0C234)
+#define S5P_CLKSRC_MAUDIO              S5P_CLKREG(0x0C23C)
+#define S5P_CLKSRC_FSYS                        S5P_CLKREG(0x0C240)
+#define S5P_CLKSRC_PERIL0              S5P_CLKREG(0x0C250)
+#define S5P_CLKSRC_PERIL1              S5P_CLKREG(0x0C254)
+
+#define S5P_CLKSRC_MASK_TOP            S5P_CLKREG(0x0C310)
+#define S5P_CLKSRC_MASK_CAM            S5P_CLKREG(0x0C320)
+#define S5P_CLKSRC_MASK_TV             S5P_CLKREG(0x0C324)
+#define S5P_CLKSRC_MASK_LCD0           S5P_CLKREG(0x0C334)
+#define S5P_CLKSRC_MASK_MAUDIO         S5P_CLKREG(0x0C33C)
+#define S5P_CLKSRC_MASK_FSYS           S5P_CLKREG(0x0C340)
+#define S5P_CLKSRC_MASK_PERIL0         S5P_CLKREG(0x0C350)
+#define S5P_CLKSRC_MASK_PERIL1         S5P_CLKREG(0x0C354)
+
+#define S5P_CLKDIV_TOP                 S5P_CLKREG(0x0C510)
+#define S5P_CLKDIV_CAM                 S5P_CLKREG(0x0C520)
+#define S5P_CLKDIV_TV                  S5P_CLKREG(0x0C524)
+#define S5P_CLKDIV_MFC                 S5P_CLKREG(0x0C528)
+#define S5P_CLKDIV_G3D                 S5P_CLKREG(0x0C52C)
+#define S5P_CLKDIV_IMAGE               S5P_CLKREG(0x0C530)
+#define S5P_CLKDIV_LCD0                        S5P_CLKREG(0x0C534)
+#define S5P_CLKDIV_MAUDIO              S5P_CLKREG(0x0C53C)
+#define S5P_CLKDIV_FSYS0               S5P_CLKREG(0x0C540)
+#define S5P_CLKDIV_FSYS1               S5P_CLKREG(0x0C544)
+#define S5P_CLKDIV_FSYS2               S5P_CLKREG(0x0C548)
+#define S5P_CLKDIV_FSYS3               S5P_CLKREG(0x0C54C)
+#define S5P_CLKDIV_PERIL0              S5P_CLKREG(0x0C550)
+#define S5P_CLKDIV_PERIL1              S5P_CLKREG(0x0C554)
+#define S5P_CLKDIV_PERIL2              S5P_CLKREG(0x0C558)
+#define S5P_CLKDIV_PERIL3              S5P_CLKREG(0x0C55C)
+#define S5P_CLKDIV_PERIL4              S5P_CLKREG(0x0C560)
+#define S5P_CLKDIV_PERIL5              S5P_CLKREG(0x0C564)
+#define S5P_CLKDIV2_RATIO              S5P_CLKREG(0x0C580)
+
+#define S5P_CLKDIV_STAT_TOP            S5P_CLKREG(0x0C610)
+
+#define S5P_CLKGATE_SCLKCAM            S5P_CLKREG(0x0C820)
+#define S5P_CLKGATE_IP_CAM             S5P_CLKREG(0x0C920)
+#define S5P_CLKGATE_IP_TV              S5P_CLKREG(0x0C924)
+#define S5P_CLKGATE_IP_MFC             S5P_CLKREG(0x0C928)
+#define S5P_CLKGATE_IP_G3D             S5P_CLKREG(0x0C92C)
+#define S5P_CLKGATE_IP_IMAGE           (soc_is_exynos4210() ? \
+                                       S5P_CLKREG(0x0C930) : \
+                                       S5P_CLKREG(0x04930))
+#define S5P_CLKGATE_IP_IMAGE_4210      S5P_CLKREG(0x0C930)
+#define S5P_CLKGATE_IP_IMAGE_4212      S5P_CLKREG(0x04930)
+#define S5P_CLKGATE_IP_LCD0            S5P_CLKREG(0x0C934)
+#define S5P_CLKGATE_IP_FSYS            S5P_CLKREG(0x0C940)
+#define S5P_CLKGATE_IP_GPS             S5P_CLKREG(0x0C94C)
+#define S5P_CLKGATE_IP_PERIL           S5P_CLKREG(0x0C950)
+#define S5P_CLKGATE_IP_PERIR           (soc_is_exynos4210() ? \
+                                       S5P_CLKREG(0x0C960) : \
+                                       S5P_CLKREG(0x08960))
+#define S5P_CLKGATE_IP_PERIR_4210      S5P_CLKREG(0x0C960)
+#define S5P_CLKGATE_IP_PERIR_4212      S5P_CLKREG(0x08960)
+#define S5P_CLKGATE_BLOCK              S5P_CLKREG(0x0C970)
+
+#define S5P_CLKSRC_MASK_DMC            S5P_CLKREG(0x10300)
+#define S5P_CLKSRC_DMC                 S5P_CLKREG(0x10200)
+#define S5P_CLKDIV_DMC0                        S5P_CLKREG(0x10500)
+#define S5P_CLKDIV_DMC1                        S5P_CLKREG(0x10504)
+#define S5P_CLKDIV_STAT_DMC0           S5P_CLKREG(0x10600)
+#define S5P_CLKGATE_IP_DMC             S5P_CLKREG(0x10900)
+
+#define S5P_APLL_LOCK                  S5P_CLKREG(0x14000)
+#define S5P_MPLL_LOCK                  (soc_is_exynos4210() ? \
+                                       S5P_CLKREG(0x14004) :  \
+                                       S5P_CLKREG(0x10008))
+#define S5P_APLL_CON0                  S5P_CLKREG(0x14100)
+#define S5P_APLL_CON1                  S5P_CLKREG(0x14104)
+#define S5P_MPLL_CON0                  (soc_is_exynos4210() ? \
+                                       S5P_CLKREG(0x14108) : \
+                                       S5P_CLKREG(0x10108))
+#define S5P_MPLL_CON1                  (soc_is_exynos4210() ? \
+                                       S5P_CLKREG(0x1410C) : \
+                                       S5P_CLKREG(0x1010C))
+
+#define S5P_CLKSRC_CPU                 S5P_CLKREG(0x14200)
+#define S5P_CLKMUX_STATCPU             S5P_CLKREG(0x14400)
+
+#define S5P_CLKDIV_CPU                 S5P_CLKREG(0x14500)
+#define S5P_CLKDIV_CPU1                        S5P_CLKREG(0x14504)
+#define S5P_CLKDIV_STATCPU             S5P_CLKREG(0x14600)
+#define S5P_CLKDIV_STATCPU1            S5P_CLKREG(0x14604)
+
+#define S5P_CLKGATE_SCLKCPU            S5P_CLKREG(0x14800)
+#define S5P_CLKGATE_IP_CPU             S5P_CLKREG(0x14900)
+
+#define S5P_APLL_LOCKTIME              (0x1C20)        /* 300us */
+
+#define S5P_APLLCON0_ENABLE_SHIFT      (31)
+#define S5P_APLLCON0_LOCKED_SHIFT      (29)
+#define S5P_APLL_VAL_1000              ((250 << 16) | (6 << 8) | 1)
+#define S5P_APLL_VAL_800               ((200 << 16) | (6 << 8) | 1)
+
+#define S5P_EPLLCON0_ENABLE_SHIFT      (31)
+#define S5P_EPLLCON0_LOCKED_SHIFT      (29)
+
+#define S5P_VPLLCON0_ENABLE_SHIFT      (31)
+#define S5P_VPLLCON0_LOCKED_SHIFT      (29)
+
+#define S5P_CLKSRC_CPU_MUXCORE_SHIFT   (16)
+#define S5P_CLKMUX_STATCPU_MUXCORE_MASK        (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
+
+#define S5P_CLKDIV_CPU0_CORE_SHIFT     (0)
+#define S5P_CLKDIV_CPU0_CORE_MASK      (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
+#define S5P_CLKDIV_CPU0_COREM0_SHIFT   (4)
+#define S5P_CLKDIV_CPU0_COREM0_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
+#define S5P_CLKDIV_CPU0_COREM1_SHIFT   (8)
+#define S5P_CLKDIV_CPU0_COREM1_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
+#define S5P_CLKDIV_CPU0_PERIPH_SHIFT   (12)
+#define S5P_CLKDIV_CPU0_PERIPH_MASK    (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
+#define S5P_CLKDIV_CPU0_ATB_SHIFT      (16)
+#define S5P_CLKDIV_CPU0_ATB_MASK       (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
+#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT  (20)
+#define S5P_CLKDIV_CPU0_PCLKDBG_MASK   (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
+#define S5P_CLKDIV_CPU0_APLL_SHIFT     (24)
+#define S5P_CLKDIV_CPU0_APLL_MASK      (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
+
+#define S5P_CLKDIV_DMC0_ACP_SHIFT      (0)
+#define S5P_CLKDIV_DMC0_ACP_MASK       (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
+#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT  (4)
+#define S5P_CLKDIV_DMC0_ACPPCLK_MASK   (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
+#define S5P_CLKDIV_DMC0_DPHY_SHIFT     (8)
+#define S5P_CLKDIV_DMC0_DPHY_MASK      (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
+#define S5P_CLKDIV_DMC0_DMC_SHIFT      (12)
+#define S5P_CLKDIV_DMC0_DMC_MASK       (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
+#define S5P_CLKDIV_DMC0_DMCD_SHIFT     (16)
+#define S5P_CLKDIV_DMC0_DMCD_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
+#define S5P_CLKDIV_DMC0_DMCP_SHIFT     (20)
+#define S5P_CLKDIV_DMC0_DMCP_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
+#define S5P_CLKDIV_DMC0_COPY2_SHIFT    (24)
+#define S5P_CLKDIV_DMC0_COPY2_MASK     (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
+#define S5P_CLKDIV_DMC0_CORETI_SHIFT   (28)
+#define S5P_CLKDIV_DMC0_CORETI_MASK    (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
+
+#define S5P_CLKDIV_TOP_ACLK200_SHIFT   (0)
+#define S5P_CLKDIV_TOP_ACLK200_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK100_SHIFT   (4)
+#define S5P_CLKDIV_TOP_ACLK100_MASK    (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK160_SHIFT   (8)
+#define S5P_CLKDIV_TOP_ACLK160_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
+#define S5P_CLKDIV_TOP_ACLK133_SHIFT   (12)
+#define S5P_CLKDIV_TOP_ACLK133_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
+#define S5P_CLKDIV_TOP_ONENAND_SHIFT   (16)
+#define S5P_CLKDIV_TOP_ONENAND_MASK    (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
+
+#define S5P_CLKDIV_BUS_GDLR_SHIFT      (0)
+#define S5P_CLKDIV_BUS_GDLR_MASK       (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
+#define S5P_CLKDIV_BUS_GPLR_SHIFT      (4)
+#define S5P_CLKDIV_BUS_GPLR_MASK       (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
+
+/* Only for EXYNOS4210 */
+
+#define S5P_CLKSRC_LCD1                        S5P_CLKREG(0x0C238)
+#define S5P_CLKSRC_MASK_LCD1           S5P_CLKREG(0x0C338)
+#define S5P_CLKDIV_LCD1                        S5P_CLKREG(0x0C538)
+#define S5P_CLKGATE_IP_LCD1            S5P_CLKREG(0x0C938)
+
+/* Compatibility defines and inclusion */
+
+#include <mach/regs-pmu.h>
+
+#define S5P_EPLL_CON                   S5P_EPLL_CON0
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h
new file mode 100644 (file)
index 0000000..1401b21
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - GPIO (including EINT) register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#define EXYNOS4_EINT40CON              (S5P_VA_GPIO2 + 0xE00)
+#define S5P_EINT_CON(x)                        (EXYNOS4_EINT40CON + ((x) * 0x4))
+
+#define EXYNOS4_EINT40FLTCON0          (S5P_VA_GPIO2 + 0xE80)
+#define S5P_EINT_FLTCON(x)             (EXYNOS4_EINT40FLTCON0 + ((x) * 0x4))
+
+#define EXYNOS4_EINT40MASK             (S5P_VA_GPIO2 + 0xF00)
+#define S5P_EINT_MASK(x)               (EXYNOS4_EINT40MASK + ((x) * 0x4))
+
+#define EXYNOS4_EINT40PEND             (S5P_VA_GPIO2 + 0xF40)
+#define S5P_EINT_PEND(x)               (EXYNOS4_EINT40PEND + ((x) * 0x4))
+
+#define EINT_REG_NR(x)                 (EINT_OFFSET(x) >> 3)
+
+#define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
+
+#define EINT_MODE                      S3C_GPIO_SFN(0xf)
+
+#define EINT_GPIO_0(x)                 EXYNOS4_GPX0(x)
+#define EINT_GPIO_1(x)                 EXYNOS4_GPX1(x)
+#define EINT_GPIO_2(x)                 EXYNOS4_GPX2(x)
+#define EINT_GPIO_3(x)                 EXYNOS4_GPX3(x)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-irq.h b/arch/arm/mach-exynos/include/mach/regs-irq.h
new file mode 100644 (file)
index 0000000..9c7b4bf
--- /dev/null
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/gic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-mct.h b/arch/arm/mach-exynos/include/mach/regs-mct.h
new file mode 100644 (file)
index 0000000..80dd02a
--- /dev/null
@@ -0,0 +1,53 @@
+/* arch/arm/mach-exynos4/include/mach/regs-mct.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 MCT configutation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_MCT_H
+#define __ASM_ARCH_REGS_MCT_H __FILE__
+
+#include <mach/map.h>
+
+#define EXYNOS4_MCTREG(x)              (S5P_VA_SYSTIMER + (x))
+
+#define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
+#define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
+#define EXYNOS4_MCT_G_CNT_WSTAT                EXYNOS4_MCTREG(0x110)
+
+#define EXYNOS4_MCT_G_COMP0_L          EXYNOS4_MCTREG(0x200)
+#define EXYNOS4_MCT_G_COMP0_U          EXYNOS4_MCTREG(0x204)
+#define EXYNOS4_MCT_G_COMP0_ADD_INCR   EXYNOS4_MCTREG(0x208)
+
+#define EXYNOS4_MCT_G_TCON             EXYNOS4_MCTREG(0x240)
+
+#define EXYNOS4_MCT_G_INT_CSTAT                EXYNOS4_MCTREG(0x244)
+#define EXYNOS4_MCT_G_INT_ENB          EXYNOS4_MCTREG(0x248)
+#define EXYNOS4_MCT_G_WSTAT            EXYNOS4_MCTREG(0x24C)
+
+#define _EXYNOS4_MCT_L_BASE            EXYNOS4_MCTREG(0x300)
+#define EXYNOS4_MCT_L_BASE(x)          (_EXYNOS4_MCT_L_BASE + (0x100 * x))
+#define EXYNOS4_MCT_L_MASK             (0xffffff00)
+
+#define MCT_L_TCNTB_OFFSET             (0x00)
+#define MCT_L_ICNTB_OFFSET             (0x08)
+#define MCT_L_TCON_OFFSET              (0x20)
+#define MCT_L_INT_CSTAT_OFFSET         (0x30)
+#define MCT_L_INT_ENB_OFFSET           (0x34)
+#define MCT_L_WSTAT_OFFSET             (0x40)
+
+#define MCT_G_TCON_START               (1 << 8)
+#define MCT_G_TCON_COMP0_AUTO_INC      (1 << 1)
+#define MCT_G_TCON_COMP0_ENABLE                (1 << 0)
+
+#define MCT_L_TCON_INTERVAL_MODE       (1 << 2)
+#define MCT_L_TCON_INT_START           (1 << 1)
+#define MCT_L_TCON_TIMER_START         (1 << 0)
+
+#endif /* __ASM_ARCH_REGS_MCT_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-mem.h b/arch/arm/mach-exynos/include/mach/regs-mem.h
new file mode 100644 (file)
index 0000000..0368b5a
--- /dev/null
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - SROMC and DMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_MEM_H
+#define __ASM_ARCH_REGS_MEM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_DMC0_MEMCON_OFFSET         0x04
+
+#define S5P_DMC0_MEMTYPE_SHIFT         8
+#define S5P_DMC0_MEMTYPE_MASK          0xF
+
+#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
new file mode 100644 (file)
index 0000000..4fff8e9
--- /dev/null
@@ -0,0 +1,220 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_H
+#define __ASM_ARCH_REGS_PMU_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_PMUREG(x)                          (S5P_VA_PMU + (x))
+
+#define S5P_CENTRAL_SEQ_CONFIGURATION          S5P_PMUREG(0x0200)
+
+#define S5P_CENTRAL_LOWPWR_CFG                 (1 << 16)
+
+#define S5P_CENTRAL_SEQ_OPTION                 S5P_PMUREG(0x0208)
+
+#define S5P_USE_STANDBY_WFI0                   (1 << 16)
+#define S5P_USE_STANDBY_WFI1                   (1 << 17)
+#define S5P_USE_STANDBYWFI_ISP_ARM             (1 << 18)
+#define S5P_USE_STANDBY_WFE0                   (1 << 24)
+#define S5P_USE_STANDBY_WFE1                   (1 << 25)
+#define S5P_USE_STANDBYWFE_ISP_ARM             (1 << 26)
+
+#define S5P_SWRESET                            S5P_PMUREG(0x0400)
+
+#define S5P_WAKEUP_STAT                                S5P_PMUREG(0x0600)
+#define S5P_EINT_WAKEUP_MASK                   S5P_PMUREG(0x0604)
+#define S5P_WAKEUP_MASK                                S5P_PMUREG(0x0608)
+
+#define S5P_HDMI_PHY_CONTROL                   S5P_PMUREG(0x0700)
+#define S5P_HDMI_PHY_ENABLE                    (1 << 0)
+
+#define S5P_DAC_PHY_CONTROL                    S5P_PMUREG(0x070C)
+#define S5P_DAC_PHY_ENABLE                     (1 << 0)
+
+#define S5P_MIPI_DPHY_CONTROL(n)               S5P_PMUREG(0x0710 + (n) * 4)
+#define S5P_MIPI_DPHY_ENABLE                   (1 << 0)
+#define S5P_MIPI_DPHY_SRESETN                  (1 << 1)
+#define S5P_MIPI_DPHY_MRESETN                  (1 << 2)
+
+#define S5P_INFORM0                            S5P_PMUREG(0x0800)
+#define S5P_INFORM1                            S5P_PMUREG(0x0804)
+#define S5P_INFORM2                            S5P_PMUREG(0x0808)
+#define S5P_INFORM3                            S5P_PMUREG(0x080C)
+#define S5P_INFORM4                            S5P_PMUREG(0x0810)
+#define S5P_INFORM5                            S5P_PMUREG(0x0814)
+#define S5P_INFORM6                            S5P_PMUREG(0x0818)
+#define S5P_INFORM7                            S5P_PMUREG(0x081C)
+
+#define S5P_ARM_CORE0_LOWPWR                   S5P_PMUREG(0x1000)
+#define S5P_DIS_IRQ_CORE0                      S5P_PMUREG(0x1004)
+#define S5P_DIS_IRQ_CENTRAL0                   S5P_PMUREG(0x1008)
+#define S5P_ARM_CORE1_LOWPWR                   S5P_PMUREG(0x1010)
+#define S5P_DIS_IRQ_CORE1                      S5P_PMUREG(0x1014)
+#define S5P_DIS_IRQ_CENTRAL1                   S5P_PMUREG(0x1018)
+#define S5P_ARM_COMMON_LOWPWR                  S5P_PMUREG(0x1080)
+#define S5P_L2_0_LOWPWR                                S5P_PMUREG(0x10C0)
+#define S5P_L2_1_LOWPWR                                S5P_PMUREG(0x10C4)
+#define S5P_CMU_ACLKSTOP_LOWPWR                        S5P_PMUREG(0x1100)
+#define S5P_CMU_SCLKSTOP_LOWPWR                        S5P_PMUREG(0x1104)
+#define S5P_CMU_RESET_LOWPWR                   S5P_PMUREG(0x110C)
+#define S5P_APLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1120)
+#define S5P_MPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1124)
+#define S5P_VPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1128)
+#define S5P_EPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x112C)
+#define S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR       S5P_PMUREG(0x1138)
+#define S5P_CMU_RESET_GPSALIVE_LOWPWR          S5P_PMUREG(0x113C)
+#define S5P_CMU_CLKSTOP_CAM_LOWPWR             S5P_PMUREG(0x1140)
+#define S5P_CMU_CLKSTOP_TV_LOWPWR              S5P_PMUREG(0x1144)
+#define S5P_CMU_CLKSTOP_MFC_LOWPWR             S5P_PMUREG(0x1148)
+#define S5P_CMU_CLKSTOP_G3D_LOWPWR             S5P_PMUREG(0x114C)
+#define S5P_CMU_CLKSTOP_LCD0_LOWPWR            S5P_PMUREG(0x1150)
+#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR          S5P_PMUREG(0x1158)
+#define S5P_CMU_CLKSTOP_GPS_LOWPWR             S5P_PMUREG(0x115C)
+#define S5P_CMU_RESET_CAM_LOWPWR               S5P_PMUREG(0x1160)
+#define S5P_CMU_RESET_TV_LOWPWR                        S5P_PMUREG(0x1164)
+#define S5P_CMU_RESET_MFC_LOWPWR               S5P_PMUREG(0x1168)
+#define S5P_CMU_RESET_G3D_LOWPWR               S5P_PMUREG(0x116C)
+#define S5P_CMU_RESET_LCD0_LOWPWR              S5P_PMUREG(0x1170)
+#define S5P_CMU_RESET_MAUDIO_LOWPWR            S5P_PMUREG(0x1178)
+#define S5P_CMU_RESET_GPS_LOWPWR               S5P_PMUREG(0x117C)
+#define S5P_TOP_BUS_LOWPWR                     S5P_PMUREG(0x1180)
+#define S5P_TOP_RETENTION_LOWPWR               S5P_PMUREG(0x1184)
+#define S5P_TOP_PWR_LOWPWR                     S5P_PMUREG(0x1188)
+#define S5P_LOGIC_RESET_LOWPWR                 S5P_PMUREG(0x11A0)
+#define S5P_ONENAND_MEM_LOWPWR                 S5P_PMUREG(0x11C0)
+#define S5P_G2D_ACP_MEM_LOWPWR                 S5P_PMUREG(0x11C8)
+#define S5P_USBOTG_MEM_LOWPWR                  S5P_PMUREG(0x11CC)
+#define S5P_HSMMC_MEM_LOWPWR                   S5P_PMUREG(0x11D0)
+#define S5P_CSSYS_MEM_LOWPWR                   S5P_PMUREG(0x11D4)
+#define S5P_SECSS_MEM_LOWPWR                   S5P_PMUREG(0x11D8)
+#define S5P_PAD_RETENTION_DRAM_LOWPWR          S5P_PMUREG(0x1200)
+#define S5P_PAD_RETENTION_MAUDIO_LOWPWR                S5P_PMUREG(0x1204)
+#define S5P_PAD_RETENTION_GPIO_LOWPWR          S5P_PMUREG(0x1220)
+#define S5P_PAD_RETENTION_UART_LOWPWR          S5P_PMUREG(0x1224)
+#define S5P_PAD_RETENTION_MMCA_LOWPWR          S5P_PMUREG(0x1228)
+#define S5P_PAD_RETENTION_MMCB_LOWPWR          S5P_PMUREG(0x122C)
+#define S5P_PAD_RETENTION_EBIA_LOWPWR          S5P_PMUREG(0x1230)
+#define S5P_PAD_RETENTION_EBIB_LOWPWR          S5P_PMUREG(0x1234)
+#define S5P_PAD_RETENTION_ISOLATION_LOWPWR     S5P_PMUREG(0x1240)
+#define S5P_PAD_RETENTION_ALV_SEL_LOWPWR       S5P_PMUREG(0x1260)
+#define S5P_XUSBXTI_LOWPWR                     S5P_PMUREG(0x1280)
+#define S5P_XXTI_LOWPWR                                S5P_PMUREG(0x1284)
+#define S5P_EXT_REGULATOR_LOWPWR               S5P_PMUREG(0x12C0)
+#define S5P_GPIO_MODE_LOWPWR                   S5P_PMUREG(0x1300)
+#define S5P_GPIO_MODE_MAUDIO_LOWPWR            S5P_PMUREG(0x1340)
+#define S5P_CAM_LOWPWR                         S5P_PMUREG(0x1380)
+#define S5P_TV_LOWPWR                          S5P_PMUREG(0x1384)
+#define S5P_MFC_LOWPWR                         S5P_PMUREG(0x1388)
+#define S5P_G3D_LOWPWR                         S5P_PMUREG(0x138C)
+#define S5P_LCD0_LOWPWR                                S5P_PMUREG(0x1390)
+#define S5P_MAUDIO_LOWPWR                      S5P_PMUREG(0x1398)
+#define S5P_GPS_LOWPWR                         S5P_PMUREG(0x139C)
+#define S5P_GPS_ALIVE_LOWPWR                   S5P_PMUREG(0x13A0)
+
+#define S5P_ARM_CORE0_CONFIGURATION            S5P_PMUREG(0x2000)
+#define S5P_ARM_CORE0_OPTION                   S5P_PMUREG(0x2008)
+#define S5P_ARM_CORE1_CONFIGURATION            S5P_PMUREG(0x2080)
+#define S5P_ARM_CORE1_STATUS                   S5P_PMUREG(0x2084)
+#define S5P_ARM_CORE1_OPTION                   S5P_PMUREG(0x2088)
+
+#define S5P_ARM_COMMON_OPTION                  S5P_PMUREG(0x2408)
+#define S5P_TOP_PWR_OPTION                     S5P_PMUREG(0x2C48)
+#define S5P_CAM_OPTION                         S5P_PMUREG(0x3C08)
+#define S5P_TV_OPTION                          S5P_PMUREG(0x3C28)
+#define S5P_MFC_OPTION                         S5P_PMUREG(0x3C48)
+#define S5P_G3D_OPTION                         S5P_PMUREG(0x3C68)
+#define S5P_LCD0_OPTION                                S5P_PMUREG(0x3C88)
+#define S5P_LCD1_OPTION                                S5P_PMUREG(0x3CA8)
+#define S5P_MAUDIO_OPTION                      S5P_PMUREG(0x3CC8)
+#define S5P_GPS_OPTION                         S5P_PMUREG(0x3CE8)
+#define S5P_GPS_ALIVE_OPTION                   S5P_PMUREG(0x3D08)
+
+#define S5P_PAD_RET_MAUDIO_OPTION              S5P_PMUREG(0x3028)
+#define S5P_PAD_RET_GPIO_OPTION                        S5P_PMUREG(0x3108)
+#define S5P_PAD_RET_UART_OPTION                        S5P_PMUREG(0x3128)
+#define S5P_PAD_RET_MMCA_OPTION                        S5P_PMUREG(0x3148)
+#define S5P_PAD_RET_MMCB_OPTION                        S5P_PMUREG(0x3168)
+#define S5P_PAD_RET_EBIA_OPTION                        S5P_PMUREG(0x3188)
+#define S5P_PAD_RET_EBIB_OPTION                        S5P_PMUREG(0x31A8)
+
+#define S5P_PMU_CAM_CONF                       S5P_PMUREG(0x3C00)
+#define S5P_PMU_TV_CONF                                S5P_PMUREG(0x3C20)
+#define S5P_PMU_MFC_CONF                       S5P_PMUREG(0x3C40)
+#define S5P_PMU_G3D_CONF                       S5P_PMUREG(0x3C60)
+#define S5P_PMU_LCD0_CONF                      S5P_PMUREG(0x3C80)
+#define S5P_PMU_GPS_CONF                       S5P_PMUREG(0x3CE0)
+
+#define S5P_PMU_SATA_PHY_CONTROL_EN            0x1
+#define S5P_CORE_LOCAL_PWR_EN                  0x3
+#define S5P_INT_LOCAL_PWR_EN                   0x7
+
+#define S5P_CHECK_SLEEP                                0x00000BAD
+
+/* Only for EXYNOS4210 */
+#define S5P_USBHOST_PHY_CONTROL                S5P_PMUREG(0x0708)
+#define S5P_USBHOST_PHY_ENABLE         (1 << 0)
+
+#define S5P_PMU_SATA_PHY_CONTROL       S5P_PMUREG(0x0720)
+
+#define S5P_CMU_CLKSTOP_LCD1_LOWPWR    S5P_PMUREG(0x1154)
+#define S5P_CMU_RESET_LCD1_LOWPWR      S5P_PMUREG(0x1174)
+#define S5P_MODIMIF_MEM_LOWPWR         S5P_PMUREG(0x11C4)
+#define S5P_PCIE_MEM_LOWPWR            S5P_PMUREG(0x11E0)
+#define S5P_SATA_MEM_LOWPWR            S5P_PMUREG(0x11E4)
+#define S5P_LCD1_LOWPWR                        S5P_PMUREG(0x1394)
+
+#define S5P_PMU_LCD1_CONF              S5P_PMUREG(0x3CA0)
+
+/* Only for EXYNOS4212 */
+#define S5P_ISP_ARM_LOWPWR                     S5P_PMUREG(0x1050)
+#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR       S5P_PMUREG(0x1054)
+#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR     S5P_PMUREG(0x1058)
+#define S5P_CMU_ACLKSTOP_COREBLK_LOWPWR                S5P_PMUREG(0x1110)
+#define S5P_CMU_SCLKSTOP_COREBLK_LOWPWR                S5P_PMUREG(0x1114)
+#define S5P_CMU_RESET_COREBLK_LOWPWR           S5P_PMUREG(0x111C)
+#define S5P_MPLLUSER_SYSCLK_LOWPWR             S5P_PMUREG(0x1130)
+#define S5P_CMU_CLKSTOP_ISP_LOWPWR             S5P_PMUREG(0x1154)
+#define S5P_CMU_RESET_ISP_LOWPWR               S5P_PMUREG(0x1174)
+#define S5P_TOP_BUS_COREBLK_LOWPWR             S5P_PMUREG(0x1190)
+#define S5P_TOP_RETENTION_COREBLK_LOWPWR       S5P_PMUREG(0x1194)
+#define S5P_TOP_PWR_COREBLK_LOWPWR             S5P_PMUREG(0x1198)
+#define S5P_OSCCLK_GATE_LOWPWR                 S5P_PMUREG(0x11A4)
+#define S5P_LOGIC_RESET_COREBLK_LOWPWR         S5P_PMUREG(0x11B0)
+#define S5P_OSCCLK_GATE_COREBLK_LOWPWR         S5P_PMUREG(0x11B4)
+#define S5P_HSI_MEM_LOWPWR                     S5P_PMUREG(0x11C4)
+#define S5P_ROTATOR_MEM_LOWPWR                 S5P_PMUREG(0x11DC)
+#define S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR  S5P_PMUREG(0x123C)
+#define S5P_PAD_ISOLATION_COREBLK_LOWPWR       S5P_PMUREG(0x1250)
+#define S5P_GPIO_MODE_COREBLK_LOWPWR           S5P_PMUREG(0x1320)
+#define S5P_TOP_ASB_RESET_LOWPWR               S5P_PMUREG(0x1344)
+#define S5P_TOP_ASB_ISOLATION_LOWPWR           S5P_PMUREG(0x1348)
+#define S5P_ISP_LOWPWR                         S5P_PMUREG(0x1394)
+#define S5P_DRAM_FREQ_DOWN_LOWPWR              S5P_PMUREG(0x13B0)
+#define S5P_DDRPHY_DLLOFF_LOWPWR               S5P_PMUREG(0x13B4)
+#define S5P_CMU_SYSCLK_ISP_LOWPWR              S5P_PMUREG(0x13B8)
+#define S5P_CMU_SYSCLK_GPS_LOWPWR              S5P_PMUREG(0x13BC)
+#define S5P_LPDDR_PHY_DLL_LOCK_LOWPWR          S5P_PMUREG(0x13C0)
+
+#define S5P_ARM_L2_0_OPTION                    S5P_PMUREG(0x2608)
+#define S5P_ARM_L2_1_OPTION                    S5P_PMUREG(0x2628)
+#define S5P_ONENAND_MEM_OPTION                 S5P_PMUREG(0x2E08)
+#define S5P_HSI_MEM_OPTION                     S5P_PMUREG(0x2E28)
+#define S5P_G2D_ACP_MEM_OPTION                 S5P_PMUREG(0x2E48)
+#define S5P_USBOTG_MEM_OPTION                  S5P_PMUREG(0x2E68)
+#define S5P_HSMMC_MEM_OPTION                   S5P_PMUREG(0x2E88)
+#define S5P_CSSYS_MEM_OPTION                   S5P_PMUREG(0x2EA8)
+#define S5P_SECSS_MEM_OPTION                   S5P_PMUREG(0x2EC8)
+#define S5P_ROTATOR_MEM_OPTION                 S5P_PMUREG(0x2F48)
+
+#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
new file mode 100644 (file)
index 0000000..68ff6ad
--- /dev/null
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - System MMU register
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_SYSMMU_H
+#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
+
+#define S5P_MMU_CTRL                   0x000
+#define S5P_MMU_CFG                    0x004
+#define S5P_MMU_STATUS                 0x008
+#define S5P_MMU_FLUSH                  0x00C
+#define S5P_PT_BASE_ADDR               0x014
+#define S5P_INT_STATUS                 0x018
+#define S5P_INT_CLEAR                  0x01C
+#define S5P_PAGE_FAULT_ADDR            0x024
+#define S5P_AW_FAULT_ADDR              0x028
+#define S5P_AR_FAULT_ADDR              0x02C
+#define S5P_DEFAULT_SLAVE_ADDR         0x030
+
+#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
new file mode 100644 (file)
index 0000000..c337cf3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_REGS_USB_PHY_H
+#define __PLAT_S5P_REGS_USB_PHY_H
+
+#define EXYNOS4_HSOTG_PHYREG(x)                ((x) + S3C_VA_USB_HSPHY)
+
+#define EXYNOS4_PHYPWR                 EXYNOS4_HSOTG_PHYREG(0x00)
+#define PHY1_HSIC_NORMAL_MASK          (0xf << 9)
+#define PHY1_HSIC1_SLEEP               (1 << 12)
+#define PHY1_HSIC1_FORCE_SUSPEND       (1 << 11)
+#define PHY1_HSIC0_SLEEP               (1 << 10)
+#define PHY1_HSIC0_FORCE_SUSPEND       (1 << 9)
+
+#define PHY1_STD_NORMAL_MASK           (0x7 << 6)
+#define PHY1_STD_SLEEP                 (1 << 8)
+#define PHY1_STD_ANALOG_POWERDOWN      (1 << 7)
+#define PHY1_STD_FORCE_SUSPEND         (1 << 6)
+
+#define PHY0_NORMAL_MASK               (0x39 << 0)
+#define PHY0_SLEEP                     (1 << 5)
+#define PHY0_OTG_DISABLE               (1 << 4)
+#define PHY0_ANALOG_POWERDOWN          (1 << 3)
+#define PHY0_FORCE_SUSPEND             (1 << 0)
+
+#define EXYNOS4_PHYCLK                 EXYNOS4_HSOTG_PHYREG(0x04)
+#define PHY1_COMMON_ON_N               (1 << 7)
+#define PHY0_COMMON_ON_N               (1 << 4)
+#define PHY0_ID_PULLUP                 (1 << 2)
+#define CLKSEL_MASK                    (0x3 << 0)
+#define CLKSEL_SHIFT                   (0)
+#define CLKSEL_48M                     (0x0 << 0)
+#define CLKSEL_12M                     (0x2 << 0)
+#define CLKSEL_24M                     (0x3 << 0)
+
+#define EXYNOS4_RSTCON                 EXYNOS4_HSOTG_PHYREG(0x08)
+#define HOST_LINK_PORT_SWRST_MASK      (0xf << 6)
+#define HOST_LINK_PORT2_SWRST          (1 << 9)
+#define HOST_LINK_PORT1_SWRST          (1 << 8)
+#define HOST_LINK_PORT0_SWRST          (1 << 7)
+#define HOST_LINK_ALL_SWRST            (1 << 6)
+
+#define PHY1_SWRST_MASK                        (0x7 << 3)
+#define PHY1_HSIC_SWRST                        (1 << 5)
+#define PHY1_STD_SWRST                 (1 << 4)
+#define PHY1_ALL_SWRST                 (1 << 3)
+
+#define PHY0_SWRST_MASK                        (0x7 << 0)
+#define PHY0_PHYLINK_SWRST             (1 << 2)
+#define PHY0_HLINK_SWRST               (1 << 1)
+#define PHY0_SWRST                     (1 << 0)
+
+#define EXYNOS4_PHY1CON                        EXYNOS4_HSOTG_PHYREG(0x34)
+#define FPENABLEN                      (1 << 0)
+
+#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
new file mode 100644 (file)
index 0000000..6a5fbb5
--- /dev/null
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung sysmmu driver for EXYNOS4
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_SYSMMU_H
+#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
+
+enum exynos4_sysmmu_ips {
+       SYSMMU_MDMA,
+       SYSMMU_SSS,
+       SYSMMU_FIMC0,
+       SYSMMU_FIMC1,
+       SYSMMU_FIMC2,
+       SYSMMU_FIMC3,
+       SYSMMU_JPEG,
+       SYSMMU_FIMD0,
+       SYSMMU_FIMD1,
+       SYSMMU_PCIe,
+       SYSMMU_G2D,
+       SYSMMU_ROTATOR,
+       SYSMMU_MDMA2,
+       SYSMMU_TV,
+       SYSMMU_MFC_L,
+       SYSMMU_MFC_R,
+       EXYNOS4_SYSMMU_TOTAL_IPNUM,
+};
+
+#define S5P_SYSMMU_TOTAL_IPNUM         EXYNOS4_SYSMMU_TOTAL_IPNUM
+
+extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
+
+typedef enum exynos4_sysmmu_ips sysmmu_ips;
+
+void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
+void sysmmu_clk_enable(sysmmu_ips ips);
+void sysmmu_clk_disable(sysmmu_ips ips);
+
+#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h
new file mode 100644 (file)
index 0000000..5e3220c
--- /dev/null
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/system.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/system-reset.h>
+
+static void arch_idle(void)
+{
+       /* nothing here yet */
+}
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-exynos/include/mach/timex.h b/arch/arm/mach-exynos/include/mach/timex.h
new file mode 100644 (file)
index 0000000..6d13875
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-exynos4/include/mach/timex.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * EXYNOS4 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H __FILE__
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-exynos/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..21d97bc
--- /dev/null
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H __FILE__
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+       /* we do not need to do any cpu detection here at the moment. */
+
+       /*
+        * For preventing FIFO overrun or infinite loop of UART console,
+        * fifo_max should be the minimum fifo size of all of the UART channels
+        */
+       fifo_mask = S5PV210_UFSTAT_TXMASK;
+       fifo_max = 15 << S5PV210_UFSTAT_TXSHIFT;
+}
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-exynos/include/mach/vmalloc.h b/arch/arm/mach-exynos/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..284330e
--- /dev/null
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Based on arch/arm/mach-s5p6440/include/mach/vmalloc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * EXYNOS4 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H __FILE__
+
+#define VMALLOC_END    0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-exynos/init.c b/arch/arm/mach-exynos/init.c
new file mode 100644 (file)
index 0000000..a8a83e3
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-exynos4/init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
+       [0] = {
+               .name           = "uclk1",
+               .divisor        = 1,
+               .min_baud       = 0,
+               .max_baud       = 0,
+       },
+};
+
+/* uart registration process */
+void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       struct s3c2410_uartcfg *tcfg = cfg;
+       u32 ucnt;
+
+       for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+               if (!tcfg->clocks) {
+                       tcfg->has_fracval = 1;
+                       tcfg->clocks = exynos4_serial_clocks;
+                       tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
+               }
+               tcfg->flags |= NO_NEED_CHECK_CLKSRC;
+       }
+
+       s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-exynos/irq-combiner.c b/arch/arm/mach-exynos/irq-combiner.c
new file mode 100644 (file)
index 0000000..5a2758a
--- /dev/null
@@ -0,0 +1,124 @@
+/* linux/arch/arm/mach-exynos4/irq-combiner.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/common/gic.c
+ *
+ * IRQ COMBINER support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+
+#define COMBINER_ENABLE_SET    0x0
+#define COMBINER_ENABLE_CLEAR  0x4
+#define COMBINER_INT_STATUS    0xC
+
+static DEFINE_SPINLOCK(irq_controller_lock);
+
+struct combiner_chip_data {
+       unsigned int irq_offset;
+       unsigned int irq_mask;
+       void __iomem *base;
+};
+
+static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
+
+static inline void __iomem *combiner_base(struct irq_data *data)
+{
+       struct combiner_chip_data *combiner_data =
+               irq_data_get_irq_chip_data(data);
+
+       return combiner_data->base;
+}
+
+static void combiner_mask_irq(struct irq_data *data)
+{
+       u32 mask = 1 << (data->irq % 32);
+
+       __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
+}
+
+static void combiner_unmask_irq(struct irq_data *data)
+{
+       u32 mask = 1 << (data->irq % 32);
+
+       __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
+}
+
+static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+       struct combiner_chip_data *chip_data = irq_get_handler_data(irq);
+       struct irq_chip *chip = irq_get_chip(irq);
+       unsigned int cascade_irq, combiner_irq;
+       unsigned long status;
+
+       chained_irq_enter(chip, desc);
+
+       spin_lock(&irq_controller_lock);
+       status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
+       spin_unlock(&irq_controller_lock);
+       status &= chip_data->irq_mask;
+
+       if (status == 0)
+               goto out;
+
+       combiner_irq = __ffs(status);
+
+       cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
+       if (unlikely(cascade_irq >= NR_IRQS))
+               do_bad_IRQ(cascade_irq, desc);
+       else
+               generic_handle_irq(cascade_irq);
+
+ out:
+       chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip combiner_chip = {
+       .name           = "COMBINER",
+       .irq_mask       = combiner_mask_irq,
+       .irq_unmask     = combiner_unmask_irq,
+};
+
+void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
+{
+       if (combiner_nr >= MAX_COMBINER_NR)
+               BUG();
+       if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
+               BUG();
+       irq_set_chained_handler(irq, combiner_handle_cascade_irq);
+}
+
+void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
+                         unsigned int irq_start)
+{
+       unsigned int i;
+
+       if (combiner_nr >= MAX_COMBINER_NR)
+               BUG();
+
+       combiner_data[combiner_nr].base = base;
+       combiner_data[combiner_nr].irq_offset = irq_start;
+       combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
+
+       /* Disable all interrupts */
+
+       __raw_writel(combiner_data[combiner_nr].irq_mask,
+                    base + COMBINER_ENABLE_CLEAR);
+
+       /* Setup the Linux IRQ subsystem */
+
+       for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
+                               + MAX_IRQ_IN_COMBINER; i++) {
+               irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq);
+               irq_set_chip_data(i, &combiner_data[combiner_nr]);
+               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+       }
+}
diff --git a/arch/arm/mach-exynos/irq-eint.c b/arch/arm/mach-exynos/irq-eint.c
new file mode 100644 (file)
index 0000000..badb8c6
--- /dev/null
@@ -0,0 +1,237 @@
+/* linux/arch/arm/mach-exynos4/irq-eint.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ EINT support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+
+#include <plat/pm.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+
+#include <asm/mach/irq.h>
+
+static DEFINE_SPINLOCK(eint_lock);
+
+static unsigned int eint0_15_data[16];
+
+static unsigned int exynos4_get_irq_nr(unsigned int number)
+{
+       u32 ret = 0;
+
+       switch (number) {
+       case 0 ... 3:
+               ret = (number + IRQ_EINT0);
+               break;
+       case 4 ... 7:
+               ret = (number + (IRQ_EINT4 - 4));
+               break;
+       case 8 ... 15:
+               ret = (number + (IRQ_EINT8 - 8));
+               break;
+       default:
+               printk(KERN_ERR "number available : %d\n", number);
+       }
+
+       return ret;
+}
+
+static inline void exynos4_irq_eint_mask(struct irq_data *data)
+{
+       u32 mask;
+
+       spin_lock(&eint_lock);
+       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       mask |= eint_irq_to_bit(data->irq);
+       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       spin_unlock(&eint_lock);
+}
+
+static void exynos4_irq_eint_unmask(struct irq_data *data)
+{
+       u32 mask;
+
+       spin_lock(&eint_lock);
+       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       mask &= ~(eint_irq_to_bit(data->irq));
+       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+       spin_unlock(&eint_lock);
+}
+
+static inline void exynos4_irq_eint_ack(struct irq_data *data)
+{
+       __raw_writel(eint_irq_to_bit(data->irq),
+                    S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+}
+
+static void exynos4_irq_eint_maskack(struct irq_data *data)
+{
+       exynos4_irq_eint_mask(data);
+       exynos4_irq_eint_ack(data);
+}
+
+static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
+{
+       int offs = EINT_OFFSET(data->irq);
+       int shift;
+       u32 ctrl, mask;
+       u32 newvalue = 0;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+               break;
+
+       case IRQ_TYPE_EDGE_FALLING:
+               newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+               break;
+
+       case IRQ_TYPE_EDGE_BOTH:
+               newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+               break;
+
+       case IRQ_TYPE_LEVEL_LOW:
+               newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+               break;
+
+       case IRQ_TYPE_LEVEL_HIGH:
+               newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+               break;
+
+       default:
+               printk(KERN_ERR "No such irq type %d", type);
+               return -EINVAL;
+       }
+
+       shift = (offs & 0x7) * 4;
+       mask = 0x7 << shift;
+
+       spin_lock(&eint_lock);
+       ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+       ctrl &= ~mask;
+       ctrl |= newvalue << shift;
+       __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+       spin_unlock(&eint_lock);
+
+       switch (offs) {
+       case 0 ... 7:
+               s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+               break;
+       case 8 ... 15:
+               s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+               break;
+       case 16 ... 23:
+               s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+               break;
+       case 24 ... 31:
+               s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+               break;
+       default:
+               printk(KERN_ERR "No such irq number %d", offs);
+       }
+
+       return 0;
+}
+
+static struct irq_chip exynos4_irq_eint = {
+       .name           = "exynos4-eint",
+       .irq_mask       = exynos4_irq_eint_mask,
+       .irq_unmask     = exynos4_irq_eint_unmask,
+       .irq_mask_ack   = exynos4_irq_eint_maskack,
+       .irq_ack        = exynos4_irq_eint_ack,
+       .irq_set_type   = exynos4_irq_eint_set_type,
+#ifdef CONFIG_PM
+       .irq_set_wake   = s3c_irqext_wake,
+#endif
+};
+
+/* exynos4_irq_demux_eint
+ *
+ * This function demuxes the IRQ from from EINTs 16 to 31.
+ * It is designed to be inlined into the specific handler
+ * s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void exynos4_irq_demux_eint(unsigned int start)
+{
+       unsigned int irq;
+
+       u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
+       u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+
+       status &= ~mask;
+       status &= 0xff;
+
+       while (status) {
+               irq = fls(status) - 1;
+               generic_handle_irq(irq + start);
+               status &= ~(1 << irq);
+       }
+}
+
+static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_chip *chip = irq_get_chip(irq);
+       chained_irq_enter(chip, desc);
+       exynos4_irq_demux_eint(IRQ_EINT(16));
+       exynos4_irq_demux_eint(IRQ_EINT(24));
+       chained_irq_exit(chip, desc);
+}
+
+static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+{
+       u32 *irq_data = irq_get_handler_data(irq);
+       struct irq_chip *chip = irq_get_chip(irq);
+
+       chained_irq_enter(chip, desc);
+       chip->irq_mask(&desc->irq_data);
+
+       if (chip->irq_ack)
+               chip->irq_ack(&desc->irq_data);
+
+       generic_handle_irq(*irq_data);
+
+       chip->irq_unmask(&desc->irq_data);
+       chained_irq_exit(chip, desc);
+}
+
+int __init exynos4_init_irq_eint(void)
+{
+       int irq;
+
+       for (irq = 0 ; irq <= 31 ; irq++) {
+               irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
+                                        handle_level_irq);
+               set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
+       }
+
+       irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
+
+       for (irq = 0 ; irq <= 15 ; irq++) {
+               eint0_15_data[irq] = IRQ_EINT(irq);
+
+               irq_set_handler_data(exynos4_get_irq_nr(irq),
+                                    &eint0_15_data[irq]);
+               irq_set_chained_handler(exynos4_get_irq_nr(irq),
+                                       exynos4_irq_eint0_15);
+       }
+
+       return 0;
+}
+
+arch_initcall(exynos4_init_irq_eint);
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
new file mode 100644 (file)
index 0000000..f0ca6c1
--- /dev/null
@@ -0,0 +1,215 @@
+/* linux/arch/arm/mach-exynos4/mach-armlex4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/smsc911x.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define ARMLEX4210_UCON_DEFAULT        (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define ARMLEX4210_ULCON_DEFAULT       S3C2410_LCON_CS8
+
+#define ARMLEX4210_UFCON_DEFAULT       (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = ARMLEX4210_UCON_DEFAULT,
+               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
+               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = ARMLEX4210_UCON_DEFAULT,
+               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
+               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = ARMLEX4210_UCON_DEFAULT,
+               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
+               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = ARMLEX4210_UCON_DEFAULT,
+               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
+               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
+       },
+};
+
+static struct s3c_sdhci_platdata armlex4210_hsmmc0_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_PERMANENT,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = EXYNOS4_GPX2(5),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+       .max_width              = 4,
+};
+
+static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_PERMANENT,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+       .max_width              = 4,
+};
+
+static void __init armlex4210_sdhci_init(void)
+{
+       s3c_sdhci0_set_platdata(&armlex4210_hsmmc0_pdata);
+       s3c_sdhci2_set_platdata(&armlex4210_hsmmc2_pdata);
+       s3c_sdhci3_set_platdata(&armlex4210_hsmmc3_pdata);
+}
+
+static void __init armlex4210_wlan_init(void)
+{
+       /* enable */
+       s3c_gpio_cfgpin(EXYNOS4_GPX2(0), S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(EXYNOS4_GPX2(0), S3C_GPIO_PULL_UP);
+
+       /* reset */
+       s3c_gpio_cfgpin(EXYNOS4_GPX1(6), S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
+
+       /* wakeup */
+       s3c_gpio_cfgpin(EXYNOS4_GPX1(5), S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(EXYNOS4_GPX1(5), S3C_GPIO_PULL_UP);
+}
+
+static struct resource armlex4210_smsc911x_resources[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_SROM_BANK(3),
+               .end    = EXYNOS4_PA_SROM_BANK(3) + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT(27),
+               .end    = IRQ_EINT(27),
+               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+       },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device armlex4210_smsc911x = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(armlex4210_smsc911x_resources),
+       .resource       = armlex4210_smsc911x_resources,
+       .dev            = {
+               .platform_data  = &smsc9215_config,
+       },
+};
+
+static struct platform_device *armlex4210_devices[] __initdata = {
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &exynos4_device_sysmmu,
+       &samsung_asoc_dma,
+       &armlex4210_smsc911x,
+       &exynos4_device_ahci,
+};
+
+static void __init armlex4210_smsc911x_init(void)
+{
+       u32 cs1;
+
+       /* configure nCS1 width to 16 bits */
+       cs1 = __raw_readl(S5P_SROM_BW) &
+               ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+       cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+               (0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+               (1 << S5P_SROM_BW__ADDRMODE__SHIFT) |
+               (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+               S5P_SROM_BW__NCS1__SHIFT;
+       __raw_writel(cs1, S5P_SROM_BW);
+
+       /* set timing for nCS1 suitable for ethernet chip */
+       __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+                    (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+                    (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+                    (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+static void __init armlex4210_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(armlex4210_uartcfgs,
+                          ARRAY_SIZE(armlex4210_uartcfgs));
+}
+
+static void __init armlex4210_machine_init(void)
+{
+       armlex4210_smsc911x_init();
+
+       armlex4210_sdhci_init();
+
+       armlex4210_wlan_init();
+
+       platform_add_devices(armlex4210_devices,
+                            ARRAY_SIZE(armlex4210_devices));
+}
+
+MACHINE_START(ARMLEX4210, "ARMLEX4210")
+       /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = armlex4210_map_io,
+       .init_machine   = armlex4210_machine_init,
+       .timer          = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
new file mode 100644 (file)
index 0000000..236bbe1
--- /dev/null
@@ -0,0 +1,1339 @@
+/*
+ * linux/arch/arm/mach-exynos4/mach-nuri.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/power/max8903_charger.h>
+#include <linux/power/max17042_battery.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/mmc/host.h>
+#include <linux/fb.h>
+#include <linux/pwm_backlight.h>
+
+#include <video/platform_lcd.h>
+#include <media/m5mols.h>
+#include <media/s5p_fimc.h>
+#include <media/v4l2-mediabus.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/adc.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/sdhci.h>
+#include <plat/ehci.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/mfc.h>
+#include <plat/pd.h>
+#include <plat/fimc-core.h>
+#include <plat/camport.h>
+#include <plat/mipi_csis.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define NURI_UCON_DEFAULT      (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define NURI_ULCON_DEFAULT     S3C2410_LCON_CS8
+
+#define NURI_UFCON_DEFAULT     (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG256 |      \
+                                S5PV210_UFCON_RXTRIG256)
+
+enum fixed_regulator_id {
+       FIXED_REG_ID_MMC = 0,
+       FIXED_REG_ID_MAX8903,
+       FIXED_REG_ID_CAM_A28V,
+       FIXED_REG_ID_CAM_12V,
+};
+
+static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
+       {
+               .hwport         = 0,
+               .ucon           = NURI_UCON_DEFAULT,
+               .ulcon          = NURI_ULCON_DEFAULT,
+               .ufcon          = NURI_UFCON_DEFAULT,
+       },
+       {
+               .hwport         = 1,
+               .ucon           = NURI_UCON_DEFAULT,
+               .ulcon          = NURI_ULCON_DEFAULT,
+               .ufcon          = NURI_UFCON_DEFAULT,
+       },
+       {
+               .hwport         = 2,
+               .ucon           = NURI_UCON_DEFAULT,
+               .ulcon          = NURI_ULCON_DEFAULT,
+               .ufcon          = NURI_UFCON_DEFAULT,
+       },
+       {
+               .hwport         = 3,
+               .ucon           = NURI_UCON_DEFAULT,
+               .ulcon          = NURI_ULCON_DEFAULT,
+               .ufcon          = NURI_UFCON_DEFAULT,
+       },
+};
+
+/* eMMC */
+static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
+       .max_width              = 8,
+       .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                               MMC_CAP_DISABLE | MMC_CAP_ERASE),
+       .cd_type                = S3C_SDHCI_CD_PERMANENT,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply emmc_supplies[] = {
+       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+       REGULATOR_SUPPLY("vmmc", "dw_mmc"),
+};
+
+static struct regulator_init_data emmc_fixed_voltage_init_data = {
+       .constraints            = {
+               .name           = "VMEM_VDD_2.8V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(emmc_supplies),
+       .consumer_supplies      = emmc_supplies,
+};
+
+static struct fixed_voltage_config emmc_fixed_voltage_config = {
+       .supply_name            = "MASSMEMORY_EN (inverted)",
+       .microvolts             = 2800000,
+       .gpio                   = EXYNOS4_GPL1(1),
+       .enable_high            = false,
+       .init_data              = &emmc_fixed_voltage_init_data,
+};
+
+static struct platform_device emmc_fixed_voltage = {
+       .name                   = "reg-fixed-voltage",
+       .id                     = FIXED_REG_ID_MMC,
+       .dev                    = {
+               .platform_data  = &emmc_fixed_voltage_config,
+       },
+};
+
+/* SD */
+static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
+       .max_width              = 4,
+       .host_caps              = MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                               MMC_CAP_DISABLE,
+       .ext_cd_gpio            = EXYNOS4_GPX3(3),      /* XEINT_27 */
+       .ext_cd_gpio_invert     = 1,
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* WLAN */
+static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
+       .max_width              = 4,
+       .host_caps              = MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+       .cd_type                = S3C_SDHCI_CD_EXTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static void __init nuri_sdhci_init(void)
+{
+       s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
+       s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
+       s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
+}
+
+/* GPIO KEYS */
+static struct gpio_keys_button nuri_gpio_keys_tables[] = {
+       {
+               .code                   = KEY_VOLUMEUP,
+               .gpio                   = EXYNOS4_GPX2(0),      /* XEINT16 */
+               .desc                   = "gpio-keys: KEY_VOLUMEUP",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_VOLUMEDOWN,
+               .gpio                   = EXYNOS4_GPX2(1),      /* XEINT17 */
+               .desc                   = "gpio-keys: KEY_VOLUMEDOWN",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_POWER,
+               .gpio                   = EXYNOS4_GPX2(7),      /* XEINT23 */
+               .desc                   = "gpio-keys: KEY_POWER",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       },
+};
+
+static struct gpio_keys_platform_data nuri_gpio_keys_data = {
+       .buttons                = nuri_gpio_keys_tables,
+       .nbuttons               = ARRAY_SIZE(nuri_gpio_keys_tables),
+};
+
+static struct platform_device nuri_gpio_keys = {
+       .name                   = "gpio-keys",
+       .dev                    = {
+               .platform_data  = &nuri_gpio_keys_data,
+       },
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win nuri_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 64,
+               .right_margin   = 16,
+               .upper_margin   = 64,
+               .lower_margin   = 1,
+               .hsync_len      = 48,
+               .vsync_len      = 3,
+               .xres           = 1280,
+               .yres           = 800,
+               .refresh        = 60,
+       },
+       .max_bpp        = 24,
+       .default_bpp    = 16,
+       .virtual_x      = 1280,
+       .virtual_y      = 800,
+};
+
+static struct s3c_fb_platdata nuri_fb_pdata __initdata = {
+       .win[0]         = &nuri_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+                         VIDCON0_CLKSEL_LCD,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
+static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
+{
+       int gpio = EXYNOS4_GPE1(5);
+
+       gpio_request(gpio, "LVDS_nSHDN");
+       gpio_direction_output(gpio, power);
+       gpio_free(gpio);
+}
+
+static int nuri_bl_init(struct device *dev)
+{
+       int ret, gpio = EXYNOS4_GPE2(3);
+
+       ret = gpio_request(gpio, "LCD_LDO_EN");
+       if (!ret)
+               gpio_direction_output(gpio, 0);
+
+       return ret;
+}
+
+static int nuri_bl_notify(struct device *dev, int brightness)
+{
+       if (brightness < 1)
+               brightness = 0;
+
+       gpio_set_value(EXYNOS4_GPE2(3), 1);
+
+       return brightness;
+}
+
+static void nuri_bl_exit(struct device *dev)
+{
+       gpio_free(EXYNOS4_GPE2(3));
+}
+
+/* nuri pwm backlight */
+static struct platform_pwm_backlight_data nuri_backlight_data = {
+       .pwm_id                 = 0,
+       .pwm_period_ns          = 30000,
+       .max_brightness         = 100,
+       .dft_brightness         = 50,
+       .init                   = nuri_bl_init,
+       .notify                 = nuri_bl_notify,
+       .exit                   = nuri_bl_exit,
+};
+
+static struct platform_device nuri_backlight_device = {
+       .name                   = "pwm-backlight",
+       .id                     = -1,
+       .dev                    = {
+               .parent         = &s3c_device_timer[0].dev,
+               .platform_data  = &nuri_backlight_data,
+       },
+};
+
+static struct plat_lcd_data nuri_lcd_platform_data = {
+       .set_power              = nuri_lcd_power_on,
+};
+
+static struct platform_device nuri_lcd_device = {
+       .name                   = "platform-lcd",
+       .id                     = -1,
+       .dev                    = {
+               .platform_data  = &nuri_lcd_platform_data,
+       },
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+       /* Gyro, To be updated */
+};
+
+/* TSP */
+static u8 mxt_init_vals[] = {
+       /* MXT_GEN_COMMAND(6) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* MXT_GEN_POWER(7) */
+       0x20, 0xff, 0x32,
+       /* MXT_GEN_ACQUIRE(8) */
+       0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
+       /* MXT_TOUCH_MULTI(9) */
+       0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00,
+       /* MXT_TOUCH_KEYARRAY(15) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x00,
+       /* MXT_SPT_GPIOPWM(19) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* MXT_PROCI_GRIPFACE(20) */
+       0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
+       0x0f, 0x0a,
+       /* MXT_PROCG_NOISE(22) */
+       0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
+       0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
+       /* MXT_TOUCH_PROXIMITY(23) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       /* MXT_PROCI_ONETOUCH(24) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* MXT_SPT_SELFTEST(25) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       /* MXT_PROCI_TWOTOUCH(27) */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* MXT_SPT_CTECONFIG(28) */
+       0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
+};
+
+static struct mxt_platform_data mxt_platform_data = {
+       .config                 = mxt_init_vals,
+       .config_length          = ARRAY_SIZE(mxt_init_vals),
+
+       .x_line                 = 18,
+       .y_line                 = 11,
+       .x_size                 = 1024,
+       .y_size                 = 600,
+       .blen                   = 0x1,
+       .threshold              = 0x28,
+       .voltage                = 2800000,              /* 2.8V */
+       .orient                 = MXT_DIAGONAL_COUNTER,
+       .irqflags               = IRQF_TRIGGER_FALLING,
+};
+
+static struct s3c2410_platform_i2c i2c3_data __initdata = {
+       .flags          = 0,
+       .bus_num        = 3,
+       .slave_addr     = 0x10,
+       .frequency      = 400 * 1000,
+       .sda_delay      = 100,
+};
+
+static struct i2c_board_info i2c3_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
+               .platform_data  = &mxt_platform_data,
+               .irq            = IRQ_EINT(4),
+       },
+};
+
+static void __init nuri_tsp_init(void)
+{
+       int gpio;
+
+       /* TOUCH_INT: XEINT_4 */
+       gpio = EXYNOS4_GPX0(4);
+       gpio_request(gpio, "TOUCH_INT");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+}
+
+static struct regulator_consumer_supply __initdata max8997_ldo1_[] = {
+       REGULATOR_SUPPLY("vdd", "s5p-adc"), /* Used by CPU's ADC drv */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo3_[] = {
+       REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
+       REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
+       REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
+       REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo8_[] = {
+       REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */
+       REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo11_[] = {
+       REGULATOR_SUPPLY("vcc", "platform-lcd"), /* U804 LVDS */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo12_[] = {
+       REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo13_[] = {
+       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo14_[] = {
+       REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
+};
+static struct regulator_consumer_supply __initdata max8997_ldo15_[] = {
+       REGULATOR_SUPPLY("avdd", "3-004a"), /* Touch Screen */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo16_[] = {
+       REGULATOR_SUPPLY("d_sensor", "0-001f"), /* HDC803 */
+};
+static struct regulator_consumer_supply __initdata max8997_ldo18_[] = {
+       REGULATOR_SUPPLY("vdd", "3-004a"), /* Touch Screen */
+};
+static struct regulator_consumer_supply __initdata max8997_buck1_[] = {
+       REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply __initdata max8997_buck2_[] = {
+       REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply __initdata max8997_buck3_[] = {
+       REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
+};
+static struct regulator_consumer_supply __initdata max8997_buck4_[] = {
+       REGULATOR_SUPPLY("core", "0-001f"), /* HDC803 */
+};
+static struct regulator_consumer_supply __initdata max8997_buck6_[] = {
+       REGULATOR_SUPPLY("dig_28", "0-001f"), /* pin "7" of HDC803 */
+};
+static struct regulator_consumer_supply __initdata max8997_esafeout1_[] = {
+       REGULATOR_SUPPLY("usb_vbus", NULL), /* CPU's USB OTG */
+};
+static struct regulator_consumer_supply __initdata max8997_esafeout2_[] = {
+       REGULATOR_SUPPLY("usb_vbus", "modemctl"), /* VBUS of Modem */
+};
+
+static struct regulator_consumer_supply __initdata max8997_charger_[] = {
+       REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+};
+static struct regulator_consumer_supply __initdata max8997_chg_toff_[] = {
+       REGULATOR_SUPPLY("vinchg_stop", NULL), /* for jack interrupt handlers */
+};
+
+static struct regulator_consumer_supply __initdata max8997_32khz_ap_[] = {
+       REGULATOR_SUPPLY("gps_clk", "bcm4751"),
+       REGULATOR_SUPPLY("bt_clk", "bcm4330-b1"),
+       REGULATOR_SUPPLY("wifi_clk", "bcm433-b1"),
+};
+
+static struct regulator_init_data __initdata max8997_ldo1_data = {
+       .constraints    = {
+               .name           = "VADC_3.3V_C210",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo1_),
+       .consumer_supplies      = max8997_ldo1_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo2_data = {
+       .constraints    = {
+               .name           = "VALIVE_1.1V_C210",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo3_data = {
+       .constraints    = {
+               .name           = "VUSB_1.1V_C210",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo3_),
+       .consumer_supplies      = max8997_ldo3_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo4_data = {
+       .constraints    = {
+               .name           = "VMIPI_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo4_),
+       .consumer_supplies      = max8997_ldo4_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo5_data = {
+       .constraints    = {
+               .name           = "VHSIC_1.2V_C210",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo5_),
+       .consumer_supplies      = max8997_ldo5_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo6_data = {
+       .constraints    = {
+               .name           = "VCC_1.8V_PDA",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo7_data = {
+       .constraints    = {
+               .name           = "CAM_ISP_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo7_),
+       .consumer_supplies      = max8997_ldo7_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo8_data = {
+       .constraints    = {
+               .name           = "VUSB/VDAC_3.3V_C210",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo8_),
+       .consumer_supplies      = max8997_ldo8_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo9_data = {
+       .constraints    = {
+               .name           = "VCC_2.8V_PDA",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo10_data = {
+       .constraints    = {
+               .name           = "VPLL_1.1V_C210",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo11_data = {
+       .constraints    = {
+               .name           = "LVDS_VDD3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .boot_on        = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo11_),
+       .consumer_supplies      = max8997_ldo11_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo12_data = {
+       .constraints    = {
+               .name           = "VT_CAM_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo12_),
+       .consumer_supplies      = max8997_ldo12_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo13_data = {
+       .constraints    = {
+               .name           = "VTF_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo13_),
+       .consumer_supplies      = max8997_ldo13_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo14_data = {
+       .constraints    = {
+               .name           = "VCC_3.0V_MOTOR",
+               .min_uV         = 3000000,
+               .max_uV         = 3000000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo14_),
+       .consumer_supplies      = max8997_ldo14_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo15_data = {
+       .constraints    = {
+               .name           = "VTOUCH_ADVV2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo15_),
+       .consumer_supplies      = max8997_ldo15_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo16_data = {
+       .constraints    = {
+               .name           = "CAM_SENSOR_IO_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo16_),
+       .consumer_supplies      = max8997_ldo16_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo18_data = {
+       .constraints    = {
+               .name           = "VTOUCH_VDD2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo18_),
+       .consumer_supplies      = max8997_ldo18_,
+};
+
+static struct regulator_init_data __initdata max8997_ldo21_data = {
+       .constraints    = {
+               .name           = "VDDQ_M1M2_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_buck1_data = {
+       .constraints    = {
+               .name           = "VARM_1.2V_C210",
+               .min_uV         = 900000,
+               .max_uV         = 1350000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_buck1_),
+       .consumer_supplies = max8997_buck1_,
+};
+
+static struct regulator_init_data __initdata max8997_buck2_data = {
+       .constraints    = {
+               .name           = "VINT_1.1V_C210",
+               .min_uV         = 900000,
+               .max_uV         = 1100000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_buck2_),
+       .consumer_supplies = max8997_buck2_,
+};
+
+static struct regulator_init_data __initdata max8997_buck3_data = {
+       .constraints    = {
+               .name           = "VG3D_1.1V_C210",
+               .min_uV         = 900000,
+               .max_uV         = 1100000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                 REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_buck3_),
+       .consumer_supplies = max8997_buck3_,
+};
+
+static struct regulator_init_data __initdata max8997_buck4_data = {
+       .constraints    = {
+               .name           = "CAM_ISP_CORE_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_buck4_),
+       .consumer_supplies = max8997_buck4_,
+};
+
+static struct regulator_init_data __initdata max8997_buck5_data = {
+       .constraints    = {
+               .name           = "VMEM_1.2V_C210",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_buck6_data = {
+       .constraints    = {
+               .name           = "CAM_AF_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_buck6_),
+       .consumer_supplies = max8997_buck6_,
+};
+
+static struct regulator_init_data __initdata max8997_buck7_data = {
+       .constraints    = {
+               .name           = "VCC_SUB_2.0V",
+               .min_uV         = 2000000,
+               .max_uV         = 2000000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_32khz_ap_data = {
+       .constraints    = {
+               .name           = "32KHz AP",
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(max8997_32khz_ap_),
+       .consumer_supplies = max8997_32khz_ap_,
+};
+
+static struct regulator_init_data __initdata max8997_32khz_cp_data = {
+       .constraints    = {
+               .name           = "32KHz CP",
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_vichg_data = {
+       .constraints    = {
+               .name           = "VICHG",
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_esafeout1_data = {
+       .constraints    = {
+               .name           = "SAFEOUT1",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_esafeout1_),
+       .consumer_supplies      = max8997_esafeout1_,
+};
+
+static struct regulator_init_data __initdata max8997_esafeout2_data = {
+       .constraints    = {
+               .name           = "SAFEOUT2",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_esafeout2_),
+       .consumer_supplies      = max8997_esafeout2_,
+};
+
+static struct regulator_init_data __initdata max8997_charger_cv_data = {
+       .constraints    = {
+               .name           = "CHARGER_CV",
+               .min_uV         = 4200000,
+               .max_uV         = 4200000,
+               .apply_uV       = 1,
+       },
+};
+
+static struct regulator_init_data __initdata max8997_charger_data = {
+       .constraints    = {
+               .name           = "CHARGER",
+               .min_uA         = 200000,
+               .max_uA         = 950000,
+               .boot_on        = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+                               REGULATOR_CHANGE_CURRENT,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_charger_),
+       .consumer_supplies      = max8997_charger_,
+};
+
+static struct regulator_init_data __initdata max8997_charger_topoff_data = {
+       .constraints    = {
+               .name           = "CHARGER TOPOFF",
+               .min_uA         = 50000,
+               .max_uA         = 200000,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(max8997_chg_toff_),
+       .consumer_supplies      = max8997_chg_toff_,
+};
+
+static struct max8997_regulator_data __initdata nuri_max8997_regulators[] = {
+       { MAX8997_LDO1, &max8997_ldo1_data },
+       { MAX8997_LDO2, &max8997_ldo2_data },
+       { MAX8997_LDO3, &max8997_ldo3_data },
+       { MAX8997_LDO4, &max8997_ldo4_data },
+       { MAX8997_LDO5, &max8997_ldo5_data },
+       { MAX8997_LDO6, &max8997_ldo6_data },
+       { MAX8997_LDO7, &max8997_ldo7_data },
+       { MAX8997_LDO8, &max8997_ldo8_data },
+       { MAX8997_LDO9, &max8997_ldo9_data },
+       { MAX8997_LDO10, &max8997_ldo10_data },
+       { MAX8997_LDO11, &max8997_ldo11_data },
+       { MAX8997_LDO12, &max8997_ldo12_data },
+       { MAX8997_LDO13, &max8997_ldo13_data },
+       { MAX8997_LDO14, &max8997_ldo14_data },
+       { MAX8997_LDO15, &max8997_ldo15_data },
+       { MAX8997_LDO16, &max8997_ldo16_data },
+
+       { MAX8997_LDO18, &max8997_ldo18_data },
+       { MAX8997_LDO21, &max8997_ldo21_data },
+
+       { MAX8997_BUCK1, &max8997_buck1_data },
+       { MAX8997_BUCK2, &max8997_buck2_data },
+       { MAX8997_BUCK3, &max8997_buck3_data },
+       { MAX8997_BUCK4, &max8997_buck4_data },
+       { MAX8997_BUCK5, &max8997_buck5_data },
+       { MAX8997_BUCK6, &max8997_buck6_data },
+       { MAX8997_BUCK7, &max8997_buck7_data },
+
+       { MAX8997_EN32KHZ_AP, &max8997_32khz_ap_data },
+       { MAX8997_EN32KHZ_CP, &max8997_32khz_cp_data },
+
+       { MAX8997_ENVICHG, &max8997_vichg_data },
+       { MAX8997_ESAFEOUT1, &max8997_esafeout1_data },
+       { MAX8997_ESAFEOUT2, &max8997_esafeout2_data },
+       { MAX8997_CHARGER_CV, &max8997_charger_cv_data },
+       { MAX8997_CHARGER, &max8997_charger_data },
+       { MAX8997_CHARGER_TOPOFF, &max8997_charger_topoff_data },
+};
+
+static struct max8997_platform_data __initdata nuri_max8997_pdata = {
+       .wakeup                 = 1,
+
+       .num_regulators         = ARRAY_SIZE(nuri_max8997_regulators),
+       .regulators             = nuri_max8997_regulators,
+
+       .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
+       .buck2_gpiodvs = true,
+
+       .buck1_voltage[0] = 1350000, /* 1.35V */
+       .buck1_voltage[1] = 1300000, /* 1.3V */
+       .buck1_voltage[2] = 1250000, /* 1.25V */
+       .buck1_voltage[3] = 1200000, /* 1.2V */
+       .buck1_voltage[4] = 1150000, /* 1.15V */
+       .buck1_voltage[5] = 1100000, /* 1.1V */
+       .buck1_voltage[6] = 1000000, /* 1.0V */
+       .buck1_voltage[7] = 950000, /* 0.95V */
+
+       .buck2_voltage[0] = 1100000, /* 1.1V */
+       .buck2_voltage[1] = 1000000, /* 1.0V */
+       .buck2_voltage[2] = 950000, /* 0.95V */
+       .buck2_voltage[3] = 900000, /* 0.9V */
+       .buck2_voltage[4] = 1100000, /* 1.1V */
+       .buck2_voltage[5] = 1000000, /* 1.0V */
+       .buck2_voltage[6] = 950000, /* 0.95V */
+       .buck2_voltage[7] = 900000, /* 0.9V */
+
+       .buck5_voltage[0] = 1200000, /* 1.2V */
+       .buck5_voltage[1] = 1200000, /* 1.2V */
+       .buck5_voltage[2] = 1200000, /* 1.2V */
+       .buck5_voltage[3] = 1200000, /* 1.2V */
+       .buck5_voltage[4] = 1200000, /* 1.2V */
+       .buck5_voltage[5] = 1200000, /* 1.2V */
+       .buck5_voltage[6] = 1200000, /* 1.2V */
+       .buck5_voltage[7] = 1200000, /* 1.2V */
+};
+
+/* GPIO I2C 5 (PMIC) */
+enum { I2C5_MAX8997 };
+static struct i2c_board_info i2c5_devs[] __initdata = {
+       [I2C5_MAX8997] = {
+               I2C_BOARD_INFO("max8997", 0xCC >> 1),
+               .platform_data  = &nuri_max8997_pdata,
+       },
+};
+
+static struct max17042_platform_data nuri_battery_platform_data = {
+};
+
+/* GPIO I2C 9 (Fuel Gauge) */
+static struct i2c_gpio_platform_data i2c9_gpio_data = {
+       .sda_pin                = EXYNOS4_GPY4(0),      /* XM0ADDR_8 */
+       .scl_pin                = EXYNOS4_GPY4(1),      /* XM0ADDR_9 */
+};
+static struct platform_device i2c9_gpio = {
+       .name                   = "i2c-gpio",
+       .id                     = 9,
+       .dev                    = {
+               .platform_data  = &i2c9_gpio_data,
+       },
+};
+enum { I2C9_MAX17042};
+static struct i2c_board_info i2c9_devs[] __initdata = {
+       [I2C9_MAX17042] = {
+               I2C_BOARD_INFO("max17042", 0x36),
+               .platform_data = &nuri_battery_platform_data,
+       },
+};
+
+/* MAX8903 Secondary Charger */
+static struct regulator_consumer_supply supplies_max8903[] = {
+       REGULATOR_SUPPLY("vinchg2", "charger-manager.0"),
+};
+
+static struct regulator_init_data max8903_charger_en_data = {
+       .constraints = {
+               .name           = "VOUT_CHARGER",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .boot_on        = 1,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(supplies_max8903),
+       .consumer_supplies = supplies_max8903,
+};
+
+static struct fixed_voltage_config max8903_charger_en = {
+       .supply_name = "VOUT_CHARGER",
+       .microvolts = 5000000, /* Assume 5VDC */
+       .gpio = EXYNOS4_GPY4(5), /* TA_EN negaged */
+       .enable_high = 0, /* Enable = Low */
+       .enabled_at_boot = 1,
+       .init_data = &max8903_charger_en_data,
+};
+
+static struct platform_device max8903_fixed_reg_dev = {
+       .name = "reg-fixed-voltage",
+       .id = FIXED_REG_ID_MAX8903,
+       .dev = { .platform_data = &max8903_charger_en },
+};
+
+static struct max8903_pdata nuri_max8903 = {
+       /*
+        * cen: don't control with the driver, let it be
+        * controlled by regulator above
+        */
+       .dok = EXYNOS4_GPX1(4), /* TA_nCONNECTED */
+       /* uok, usus: not connected */
+       .chg = EXYNOS4_GPE2(0), /* TA_nCHG */
+       /* flt: vcc_1.8V_pda */
+       .dcm = EXYNOS4_GPL0(1), /* CURR_ADJ */
+
+       .dc_valid = true,
+       .usb_valid = false, /* USB is not wired to MAX8903 */
+};
+
+static struct platform_device nuri_max8903_device = {
+       .name                   = "max8903-charger",
+       .dev                    = {
+               .platform_data  = &nuri_max8903,
+       },
+};
+
+static void __init nuri_power_init(void)
+{
+       int gpio;
+       int irq_base = IRQ_GPIO_END + 1;
+       int ta_en = 0;
+
+       nuri_max8997_pdata.irq_base = irq_base;
+       irq_base += MAX8997_IRQ_NR;
+
+       gpio = EXYNOS4_GPX0(7);
+       gpio_request(gpio, "AP_PMIC_IRQ");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+       gpio = EXYNOS4_GPX2(3);
+       gpio_request(gpio, "FUEL_ALERT");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+       gpio = nuri_max8903.dok;
+       gpio_request(gpio, "TA_nCONNECTED");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       ta_en = gpio_get_value(gpio) ? 0 : 1;
+
+       gpio = nuri_max8903.chg;
+       gpio_request(gpio, "TA_nCHG");
+       gpio_direction_input(gpio);
+
+       gpio = nuri_max8903.dcm;
+       gpio_request(gpio, "CURR_ADJ");
+       gpio_direction_output(gpio, ta_en);
+}
+
+/* USB EHCI */
+static struct s5p_ehci_platdata nuri_ehci_pdata;
+
+static void __init nuri_ehci_init(void)
+{
+       struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
+
+       s5p_ehci_set_platdata(pdata);
+}
+
+/* CAMERA */
+static struct regulator_consumer_supply cam_vdda_supply[] = {
+       REGULATOR_SUPPLY("a_sensor", "0-001f"),
+};
+
+static struct regulator_init_data cam_vdda_reg_init_data = {
+       .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+       .num_consumer_supplies = ARRAY_SIZE(cam_vdda_supply),
+       .consumer_supplies = cam_vdda_supply,
+};
+
+static struct fixed_voltage_config cam_vdda_fixed_voltage_cfg = {
+       .supply_name    = "CAM_IO_EN",
+       .microvolts     = 2800000,
+       .gpio           = EXYNOS4_GPE2(1), /* CAM_IO_EN */
+       .enable_high    = 1,
+       .init_data      = &cam_vdda_reg_init_data,
+};
+
+static struct platform_device cam_vdda_fixed_rdev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_A28V,
+       .dev = { .platform_data = &cam_vdda_fixed_voltage_cfg },
+};
+
+static struct regulator_consumer_supply camera_8m_12v_supply =
+       REGULATOR_SUPPLY("dig_12", "0-001f");
+
+static struct regulator_init_data cam_8m_12v_reg_init_data = {
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &camera_8m_12v_supply,
+       .constraints = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS
+       },
+};
+
+static struct fixed_voltage_config cam_8m_12v_fixed_voltage_cfg = {
+       .supply_name    = "8M_1.2V",
+       .microvolts     = 1200000,
+       .gpio           = EXYNOS4_GPE2(5), /* 8M_1.2V_EN */
+       .enable_high    = 1,
+       .init_data      = &cam_8m_12v_reg_init_data,
+};
+
+static struct platform_device cam_8m_12v_fixed_rdev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_12V,
+       .dev = { .platform_data = &cam_8m_12v_fixed_voltage_cfg },
+};
+
+static struct s5p_platform_mipi_csis mipi_csis_platdata = {
+       .clk_rate       = 166000000UL,
+       .lanes          = 2,
+       .alignment      = 32,
+       .hs_settle      = 12,
+       .phy_enable     = s5p_csis_phy_enable,
+};
+
+#define GPIO_CAM_MEGA_RST      EXYNOS4_GPY3(7) /* ISP_RESET */
+#define GPIO_CAM_8M_ISP_INT    EXYNOS4_GPL2(5)
+
+static struct m5mols_platform_data m5mols_platdata = {
+       .gpio_reset = GPIO_CAM_MEGA_RST,
+};
+
+static struct i2c_board_info m5mols_board_info = {
+       I2C_BOARD_INFO("M5MOLS", 0x1F),
+       .platform_data  = &m5mols_platdata,
+};
+
+static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
+       {
+               .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+                                 V4L2_MBUS_VSYNC_ACTIVE_LOW,
+               .bus_type       = FIMC_MIPI_CSI2,
+               .board_info     = &m5mols_board_info,
+               .clk_frequency  = 24000000UL,
+               .csi_data_align = 32,
+       },
+};
+
+static struct s5p_platform_fimc fimc_md_platdata = {
+       .isp_info       = nuri_camera_sensors,
+       .num_clients    = ARRAY_SIZE(nuri_camera_sensors),
+};
+
+static struct gpio nuri_camera_gpios[] = {
+       { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,           "8M_ISP_INT"  },
+       { GPIO_CAM_MEGA_RST,    GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
+};
+
+static void nuri_camera_init(void)
+{
+       s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
+                        &s5p_device_mipi_csis0);
+       s3c_set_platdata(&fimc_md_platdata,  sizeof(fimc_md_platdata),
+                        &s5p_device_fimc_md);
+
+       if (gpio_request_array(nuri_camera_gpios,
+                              ARRAY_SIZE(nuri_camera_gpios))) {
+               pr_err("%s: GPIO request failed\n", __func__);
+               return;
+       }
+
+       m5mols_board_info.irq = s5p_register_gpio_interrupt(GPIO_CAM_8M_ISP_INT);
+       if (!IS_ERR_VALUE(m5mols_board_info.irq))
+               s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xF));
+       else
+               pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
+
+       /* Free GPIOs controlled directly by the sensor drivers. */
+       gpio_free(GPIO_CAM_MEGA_RST);
+
+       if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
+               pr_err("%s: Camera port A setup failed\n", __func__);
+               return;
+       }
+       /* Increase drive strength of the sensor clock output */
+       s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
+}
+
+static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
+       .frequency      = 400000U,
+       .sda_delay      = 200,
+};
+
+static struct platform_device *nuri_devices[] __initdata = {
+       /* Samsung Platform Devices */
+       &s3c_device_i2c5, /* PMIC should initialize first */
+       &s3c_device_i2c0,
+       &emmc_fixed_voltage,
+       &s5p_device_mipi_csis0,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc3,
+       &s5p_device_fimd0,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_wdt,
+       &s3c_device_timer[0],
+       &s5p_device_ehci,
+       &s3c_device_i2c3,
+       &i2c9_gpio,
+       &s3c_device_adc,
+       &s3c_device_rtc,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
+       &exynos4_device_pd[PD_MFC],
+       &exynos4_device_pd[PD_LCD0],
+       &exynos4_device_pd[PD_CAM],
+       &s5p_device_fimc_md,
+
+       /* NURI Devices */
+       &nuri_gpio_keys,
+       &nuri_lcd_device,
+       &nuri_backlight_device,
+       &max8903_fixed_reg_dev,
+       &nuri_max8903_device,
+       &cam_vdda_fixed_rdev,
+       &cam_8m_12v_fixed_rdev,
+};
+
+static void __init nuri_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
+}
+
+static void __init nuri_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
+static void __init nuri_machine_init(void)
+{
+       nuri_sdhci_init();
+       nuri_tsp_init();
+       nuri_power_init();
+
+       s3c_i2c0_set_platdata(&nuri_i2c0_platdata);
+       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+       s3c_i2c3_set_platdata(&i2c3_data);
+       i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
+       s3c_i2c5_set_platdata(NULL);
+       i2c5_devs[I2C5_MAX8997].irq = gpio_to_irq(EXYNOS4_GPX0(7));
+       i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
+       i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
+       i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
+
+       s5p_fimd0_set_platdata(&nuri_fb_pdata);
+
+       nuri_camera_init();
+
+       nuri_ehci_init();
+       clk_xusbxti.rate = 24000000;
+
+       /* Last */
+       platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
+       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+       s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+
+       s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+}
+
+MACHINE_START(NURI, "NURI")
+       /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = nuri_map_io,
+       .init_machine   = nuri_machine_init,
+       .timer          = &exynos4_timer,
+       .reserve        = &nuri_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
new file mode 100644 (file)
index 0000000..f80b563
--- /dev/null
@@ -0,0 +1,700 @@
+/* linux/arch/arm/mach-exynos4/mach-origen.c
+ *
+ * Copyright (c) 2011 Insignal Co., Ltd.
+ *             http://www.insignal.co.kr/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8997.h>
+#include <linux/lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <plat/ehci.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/backlight.h>
+#include <plat/pd.h>
+#include <plat/fb.h>
+#include <plat/mfc.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define ORIGEN_UCON_DEFAULT    (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define ORIGEN_ULCON_DEFAULT   S3C2410_LCON_CS8
+
+#define ORIGEN_UFCON_DEFAULT   (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = ORIGEN_UCON_DEFAULT,
+               .ulcon          = ORIGEN_ULCON_DEFAULT,
+               .ufcon          = ORIGEN_UFCON_DEFAULT,
+       },
+};
+
+static struct regulator_consumer_supply __initdata ldo3_consumer[] = {
+       REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
+       REGULATOR_SUPPLY("vdd", "exynos4-hdmi"), /* HDMI */
+       REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"), /* HDMI */
+};
+static struct regulator_consumer_supply __initdata ldo6_consumer[] = {
+       REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
+};
+static struct regulator_consumer_supply __initdata ldo7_consumer[] = {
+       REGULATOR_SUPPLY("avdd", "alc5625"), /* Realtek ALC5625 */
+};
+static struct regulator_consumer_supply __initdata ldo8_consumer[] = {
+       REGULATOR_SUPPLY("vdd", "s5p-adc"), /* ADC */
+       REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"), /* HDMI */
+};
+static struct regulator_consumer_supply __initdata ldo9_consumer[] = {
+       REGULATOR_SUPPLY("dvdd", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
+};
+static struct regulator_consumer_supply __initdata ldo11_consumer[] = {
+       REGULATOR_SUPPLY("dvdd", "alc5625"), /* Realtek ALC5625 */
+};
+static struct regulator_consumer_supply __initdata ldo14_consumer[] = {
+       REGULATOR_SUPPLY("avdd18", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
+};
+static struct regulator_consumer_supply __initdata ldo17_consumer[] = {
+       REGULATOR_SUPPLY("vdd33", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
+};
+static struct regulator_consumer_supply __initdata buck1_consumer[] = {
+       REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply __initdata buck2_consumer[] = {
+       REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
+};
+static struct regulator_consumer_supply __initdata buck3_consumer[] = {
+       REGULATOR_SUPPLY("vdd_g3d", "mali_drm"), /* G3D */
+};
+static struct regulator_consumer_supply __initdata buck7_consumer[] = {
+       REGULATOR_SUPPLY("vcc", "platform-lcd"), /* LCD */
+};
+
+static struct regulator_init_data __initdata max8997_ldo1_data = {
+       .constraints    = {
+               .name           = "VDD_ABB_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo2_data = {
+       .constraints    = {
+               .name           = "VDD_ALIVE_1.1V",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo3_data = {
+       .constraints    = {
+               .name           = "VMIPI_1.1V",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo3_consumer),
+       .consumer_supplies      = ldo3_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo4_data = {
+       .constraints    = {
+               .name           = "VDD_RTC_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo6_data = {
+       .constraints    = {
+               .name           = "VMIPI_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo6_consumer),
+       .consumer_supplies      = ldo6_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo7_data = {
+       .constraints    = {
+               .name           = "VDD_AUD_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo7_consumer),
+       .consumer_supplies      = ldo7_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo8_data = {
+       .constraints    = {
+               .name           = "VADC_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo8_consumer),
+       .consumer_supplies      = ldo8_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo9_data = {
+       .constraints    = {
+               .name           = "DVDD_SWB_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo9_consumer),
+       .consumer_supplies      = ldo9_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo10_data = {
+       .constraints    = {
+               .name           = "VDD_PLL_1.1V",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_ldo11_data = {
+       .constraints    = {
+               .name           = "VDD_AUD_3V",
+               .min_uV         = 3000000,
+               .max_uV         = 3000000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo11_consumer),
+       .consumer_supplies      = ldo11_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo14_data = {
+       .constraints    = {
+               .name           = "AVDD18_SWB_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo14_consumer),
+       .consumer_supplies      = ldo14_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo17_data = {
+       .constraints    = {
+               .name           = "VDD_SWB_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldo17_consumer),
+       .consumer_supplies      = ldo17_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo21_data = {
+       .constraints    = {
+               .name           = "VDD_MIF_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_buck1_data = {
+       .constraints    = {
+               .name           = "VDD_ARM_1.2V",
+               .min_uV         = 950000,
+               .max_uV         = 1350000,
+               .always_on      = 1,
+               .boot_on        = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(buck1_consumer),
+       .consumer_supplies      = buck1_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_buck2_data = {
+       .constraints    = {
+               .name           = "VDD_INT_1.1V",
+               .min_uV         = 900000,
+               .max_uV         = 1100000,
+               .always_on      = 1,
+               .boot_on        = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(buck2_consumer),
+       .consumer_supplies      = buck2_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_buck3_data = {
+       .constraints    = {
+               .name           = "VDD_G3D_1.1V",
+               .min_uV         = 900000,
+               .max_uV         = 1100000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                       REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(buck3_consumer),
+       .consumer_supplies      = buck3_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_buck5_data = {
+       .constraints    = {
+               .name           = "VDDQ_M1M2_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data __initdata max8997_buck7_data = {
+       .constraints    = {
+               .name           = "VDD_LCD_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .boot_on        = 1,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(buck7_consumer),
+       .consumer_supplies      = buck7_consumer,
+};
+
+static struct max8997_regulator_data __initdata origen_max8997_regulators[] = {
+       { MAX8997_LDO1,         &max8997_ldo1_data },
+       { MAX8997_LDO2,         &max8997_ldo2_data },
+       { MAX8997_LDO3,         &max8997_ldo3_data },
+       { MAX8997_LDO4,         &max8997_ldo4_data },
+       { MAX8997_LDO6,         &max8997_ldo6_data },
+       { MAX8997_LDO7,         &max8997_ldo7_data },
+       { MAX8997_LDO8,         &max8997_ldo8_data },
+       { MAX8997_LDO9,         &max8997_ldo9_data },
+       { MAX8997_LDO10,        &max8997_ldo10_data },
+       { MAX8997_LDO11,        &max8997_ldo11_data },
+       { MAX8997_LDO14,        &max8997_ldo14_data },
+       { MAX8997_LDO17,        &max8997_ldo17_data },
+       { MAX8997_LDO21,        &max8997_ldo21_data },
+       { MAX8997_BUCK1,        &max8997_buck1_data },
+       { MAX8997_BUCK2,        &max8997_buck2_data },
+       { MAX8997_BUCK3,        &max8997_buck3_data },
+       { MAX8997_BUCK5,        &max8997_buck5_data },
+       { MAX8997_BUCK7,        &max8997_buck7_data },
+};
+
+struct max8997_platform_data __initdata origen_max8997_pdata = {
+       .num_regulators = ARRAY_SIZE(origen_max8997_regulators),
+       .regulators     = origen_max8997_regulators,
+
+       .wakeup = true,
+       .buck1_gpiodvs  = false,
+       .buck2_gpiodvs  = false,
+       .buck5_gpiodvs  = false,
+       .irq_base       = IRQ_GPIO_END + 1,
+
+       .ignore_gpiodvs_side_effect = true,
+       .buck125_default_idx = 0x0,
+
+       .buck125_gpios[0]       = EXYNOS4_GPX0(0),
+       .buck125_gpios[1]       = EXYNOS4_GPX0(1),
+       .buck125_gpios[2]       = EXYNOS4_GPX0(2),
+
+       .buck1_voltage[0]       = 1350000,
+       .buck1_voltage[1]       = 1300000,
+       .buck1_voltage[2]       = 1250000,
+       .buck1_voltage[3]       = 1200000,
+       .buck1_voltage[4]       = 1150000,
+       .buck1_voltage[5]       = 1100000,
+       .buck1_voltage[6]       = 1000000,
+       .buck1_voltage[7]       = 950000,
+
+       .buck2_voltage[0]       = 1100000,
+       .buck2_voltage[1]       = 1100000,
+       .buck2_voltage[2]       = 1100000,
+       .buck2_voltage[3]       = 1100000,
+       .buck2_voltage[4]       = 1000000,
+       .buck2_voltage[5]       = 1000000,
+       .buck2_voltage[6]       = 1000000,
+       .buck2_voltage[7]       = 1000000,
+
+       .buck5_voltage[0]       = 1200000,
+       .buck5_voltage[1]       = 1200000,
+       .buck5_voltage[2]       = 1200000,
+       .buck5_voltage[3]       = 1200000,
+       .buck5_voltage[4]       = 1200000,
+       .buck5_voltage[5]       = 1200000,
+       .buck5_voltage[6]       = 1200000,
+       .buck5_voltage[7]       = 1200000,
+};
+
+/* I2C0 */
+static struct i2c_board_info i2c0_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("max8997", (0xCC >> 1)),
+               .platform_data  = &origen_max8997_pdata,
+               .irq            = IRQ_EINT(4),
+       },
+};
+
+static struct s3c_sdhci_platdata origen_hsmmc0_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* USB EHCI */
+static struct s5p_ehci_platdata origen_ehci_pdata;
+
+static void __init origen_ehci_init(void)
+{
+       struct s5p_ehci_platdata *pdata = &origen_ehci_pdata;
+
+       s5p_ehci_set_platdata(pdata);
+}
+
+static struct gpio_keys_button origen_gpio_keys_table[] = {
+       {
+               .code                   = KEY_MENU,
+               .gpio                   = EXYNOS4_GPX1(5),
+               .desc                   = "gpio-keys: KEY_MENU",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_HOME,
+               .gpio                   = EXYNOS4_GPX1(6),
+               .desc                   = "gpio-keys: KEY_HOME",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_BACK,
+               .gpio                   = EXYNOS4_GPX1(7),
+               .desc                   = "gpio-keys: KEY_BACK",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_UP,
+               .gpio                   = EXYNOS4_GPX2(0),
+               .desc                   = "gpio-keys: KEY_UP",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_DOWN,
+               .gpio                   = EXYNOS4_GPX2(1),
+               .desc                   = "gpio-keys: KEY_DOWN",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .wakeup                 = 1,
+               .debounce_interval      = 1,
+       },
+};
+
+static struct gpio_keys_platform_data origen_gpio_keys_data = {
+       .buttons        = origen_gpio_keys_table,
+       .nbuttons       = ARRAY_SIZE(origen_gpio_keys_table),
+};
+
+static struct platform_device origen_device_gpiokeys = {
+       .name           = "gpio-keys",
+       .dev            = {
+               .platform_data  = &origen_gpio_keys_data,
+       },
+};
+
+static void lcd_hv070wsa_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+       int ret;
+
+       if (power)
+               ret = gpio_request_one(EXYNOS4_GPE3(4),
+                                       GPIOF_OUT_INIT_HIGH, "GPE3_4");
+       else
+               ret = gpio_request_one(EXYNOS4_GPE3(4),
+                                       GPIOF_OUT_INIT_LOW, "GPE3_4");
+
+       gpio_free(EXYNOS4_GPE3(4));
+
+       if (ret)
+               pr_err("failed to request gpio for LCD power: %d\n", ret);
+}
+
+static struct plat_lcd_data origen_lcd_hv070wsa_data = {
+       .set_power = lcd_hv070wsa_set_power,
+};
+
+static struct platform_device origen_lcd_hv070wsa = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s5p_device_fimd0.dev,
+       .dev.platform_data      = &origen_lcd_hv070wsa_data,
+};
+
+static struct s3c_fb_pd_win origen_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 64,
+               .right_margin   = 16,
+               .upper_margin   = 64,
+               .lower_margin   = 16,
+               .hsync_len      = 48,
+               .vsync_len      = 3,
+               .xres           = 1024,
+               .yres           = 600,
+       },
+       .max_bpp                = 32,
+       .default_bpp            = 24,
+};
+
+static struct s3c_fb_platdata origen_lcd_pdata __initdata = {
+       .win[0]         = &origen_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
+static struct platform_device *origen_devices[] __initdata = {
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc0,
+       &s3c_device_i2c0,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &s5p_device_ehci,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc3,
+       &s5p_device_fimd0,
+       &s5p_device_hdmi,
+       &s5p_device_i2c_hdmiphy,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
+       &s5p_device_mixer,
+       &exynos4_device_pd[PD_LCD0],
+       &exynos4_device_pd[PD_TV],
+       &exynos4_device_pd[PD_G3D],
+       &exynos4_device_pd[PD_LCD1],
+       &exynos4_device_pd[PD_CAM],
+       &exynos4_device_pd[PD_GPS],
+       &exynos4_device_pd[PD_MFC],
+       &origen_device_gpiokeys,
+       &origen_lcd_hv070wsa,
+};
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info origen_bl_gpio_info = {
+       .no             = EXYNOS4_GPD0(0),
+       .func           = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data origen_bl_data = {
+       .pwm_id         = 0,
+       .pwm_period_ns  = 1000,
+};
+
+static void s5p_tv_setup(void)
+{
+       /* Direct HPD to HDMI chip */
+       gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
+       s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
+       s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
+}
+
+static void __init origen_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+}
+
+static void __init origen_power_init(void)
+{
+       gpio_request(EXYNOS4_GPX0(4), "PMIC_IRQ");
+       s3c_gpio_cfgpin(EXYNOS4_GPX0(4), S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(EXYNOS4_GPX0(4), S3C_GPIO_PULL_NONE);
+}
+
+static void __init origen_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
+static void __init origen_machine_init(void)
+{
+       origen_power_init();
+
+       s3c_i2c0_set_platdata(NULL);
+       i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+
+       /*
+        * Since sdhci instance 2 can contain a bootable media,
+        * sdhci instance 0 is registered after instance 2.
+        */
+       s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
+       s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);
+
+       origen_ehci_init();
+       clk_xusbxti.rate = 24000000;
+
+       s5p_tv_setup();
+       s5p_i2c_hdmiphy_set_platdata(NULL);
+
+       s5p_fimd0_set_platdata(&origen_lcd_pdata);
+
+       platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
+
+       s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+
+       s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
+       s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
+
+       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+
+       samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
+}
+
+MACHINE_START(ORIGEN, "ORIGEN")
+       /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = origen_map_io,
+       .init_machine   = origen_machine_init,
+       .timer          = &exynos4_timer,
+       .reserve        = &origen_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
new file mode 100644 (file)
index 0000000..fcf2e0e
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/arm/mach-exynos4/mach-smdk4x12.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/machine.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/backlight.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
+#include <plat/regs-serial.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK4X12_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = SMDK4X12_UCON_DEFAULT,
+               .ulcon          = SMDK4X12_ULCON_DEFAULT,
+               .ufcon          = SMDK4X12_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = SMDK4X12_UCON_DEFAULT,
+               .ulcon          = SMDK4X12_ULCON_DEFAULT,
+               .ufcon          = SMDK4X12_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = SMDK4X12_UCON_DEFAULT,
+               .ulcon          = SMDK4X12_ULCON_DEFAULT,
+               .ufcon          = SMDK4X12_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = SMDK4X12_UCON_DEFAULT,
+               .ulcon          = SMDK4X12_ULCON_DEFAULT,
+               .ufcon          = SMDK4X12_UFCON_DEFAULT,
+       },
+};
+
+static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply max8997_buck1 =
+       REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2 =
+       REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8997_buck3 =
+       REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data max8997_buck1_data = {
+       .constraints    = {
+               .name           = "VDD_ARM_SMDK4X12",
+               .min_uV         = 925000,
+               .max_uV         = 1350000,
+               .always_on      = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+       .constraints    = {
+               .name           = "VDD_INT_SMDK4X12",
+               .min_uV         = 950000,
+               .max_uV         = 1150000,
+               .always_on      = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+       .constraints    = {
+               .name           = "VDD_G3D_SMDK4X12",
+               .min_uV         = 950000,
+               .max_uV         = 1150000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                                 REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &max8997_buck3,
+};
+
+static struct max8997_regulator_data smdk4x12_max8997_regulators[] = {
+       { MAX8997_BUCK1, &max8997_buck1_data },
+       { MAX8997_BUCK2, &max8997_buck2_data },
+       { MAX8997_BUCK3, &max8997_buck3_data },
+};
+
+static struct max8997_platform_data smdk4x12_max8997_pdata = {
+       .num_regulators = ARRAY_SIZE(smdk4x12_max8997_regulators),
+       .regulators     = smdk4x12_max8997_regulators,
+
+       .buck1_voltage[0] = 1100000,    /* 1.1V */
+       .buck1_voltage[1] = 1100000,    /* 1.1V */
+       .buck1_voltage[2] = 1100000,    /* 1.1V */
+       .buck1_voltage[3] = 1100000,    /* 1.1V */
+       .buck1_voltage[4] = 1100000,    /* 1.1V */
+       .buck1_voltage[5] = 1100000,    /* 1.1V */
+       .buck1_voltage[6] = 1000000,    /* 1.0V */
+       .buck1_voltage[7] = 950000,     /* 0.95V */
+
+       .buck2_voltage[0] = 1100000,    /* 1.1V */
+       .buck2_voltage[1] = 1000000,    /* 1.0V */
+       .buck2_voltage[2] = 950000,     /* 0.95V */
+       .buck2_voltage[3] = 900000,     /* 0.9V */
+       .buck2_voltage[4] = 1100000,    /* 1.1V */
+       .buck2_voltage[5] = 1000000,    /* 1.0V */
+       .buck2_voltage[6] = 950000,     /* 0.95V */
+       .buck2_voltage[7] = 900000,     /* 0.9V */
+
+       .buck5_voltage[0] = 1100000,    /* 1.1V */
+       .buck5_voltage[1] = 1100000,    /* 1.1V */
+       .buck5_voltage[2] = 1100000,    /* 1.1V */
+       .buck5_voltage[3] = 1100000,    /* 1.1V */
+       .buck5_voltage[4] = 1100000,    /* 1.1V */
+       .buck5_voltage[5] = 1100000,    /* 1.1V */
+       .buck5_voltage[6] = 1100000,    /* 1.1V */
+       .buck5_voltage[7] = 1100000,    /* 1.1V */
+};
+
+static struct i2c_board_info smdk4x12_i2c_devs0[] __initdata = {
+       {
+               I2C_BOARD_INFO("max8997", 0x66),
+               .platform_data  = &smdk4x12_max8997_pdata,
+       }
+};
+
+static struct i2c_board_info smdk4x12_i2c_devs1[] __initdata = {
+       { I2C_BOARD_INFO("wm8994", 0x1a), }
+};
+
+static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = {
+       /* nothing here yet */
+};
+
+static struct i2c_board_info smdk4x12_i2c_devs7[] __initdata = {
+       /* nothing here yet */
+};
+
+static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = {
+       .no = EXYNOS4_GPD0(1),
+       .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk4x12_bl_data = {
+       .pwm_id = 1,
+       .pwm_period_ns  = 1000,
+};
+
+static uint32_t smdk4x12_keymap[] __initdata = {
+       /* KEY(row, col, keycode) */
+       KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B),
+       KEY(1, 3, KEY_E), KEY(1, 4, KEY_C)
+};
+
+static struct matrix_keymap_data smdk4x12_keymap_data __initdata = {
+       .keymap         = smdk4x12_keymap,
+       .keymap_size    = ARRAY_SIZE(smdk4x12_keymap),
+};
+
+static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = {
+       .keymap_data    = &smdk4x12_keymap_data,
+       .rows           = 2,
+       .cols           = 5,
+};
+
+static struct platform_device *smdk4x12_devices[] __initdata = {
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_i2c0,
+       &s3c_device_i2c1,
+       &s3c_device_i2c3,
+       &s3c_device_i2c7,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &samsung_device_keypad,
+};
+
+static void __init smdk4x12_map_io(void)
+{
+       clk_xusbxti.rate = 24000000;
+
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(clk_xusbxti.rate);
+       s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
+}
+
+static void __init smdk4x12_machine_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       i2c_register_board_info(0, smdk4x12_i2c_devs0,
+                               ARRAY_SIZE(smdk4x12_i2c_devs0));
+
+       s3c_i2c1_set_platdata(NULL);
+       i2c_register_board_info(1, smdk4x12_i2c_devs1,
+                               ARRAY_SIZE(smdk4x12_i2c_devs1));
+
+       s3c_i2c3_set_platdata(NULL);
+       i2c_register_board_info(3, smdk4x12_i2c_devs3,
+                               ARRAY_SIZE(smdk4x12_i2c_devs3));
+
+       s3c_i2c7_set_platdata(NULL);
+       i2c_register_board_info(7, smdk4x12_i2c_devs7,
+                               ARRAY_SIZE(smdk4x12_i2c_devs7));
+
+       samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);
+
+       samsung_keypad_set_platdata(&smdk4x12_keypad_data);
+
+       s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata);
+       s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata);
+
+       platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices));
+}
+
+MACHINE_START(SMDK4212, "SMDK4212")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = smdk4x12_map_io,
+       .init_machine   = smdk4x12_machine_init,
+       .timer          = &exynos4_timer,
+MACHINE_END
+
+MACHINE_START(SMDK4412, "SMDK4412")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = smdk4x12_map_io,
+       .init_machine   = smdk4x12_machine_init,
+       .timer          = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
new file mode 100644 (file)
index 0000000..cec2afa
--- /dev/null
@@ -0,0 +1,390 @@
+/* linux/arch/arm/mach-exynos4/mach-smdkv310.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/gpio-cfg.h>
+#include <plat/backlight.h>
+#include <plat/mfc.h>
+#include <plat/ehci.h>
+#include <plat/clock.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKV310_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = SMDKV310_UCON_DEFAULT,
+               .ulcon          = SMDKV310_ULCON_DEFAULT,
+               .ufcon          = SMDKV310_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = SMDKV310_UCON_DEFAULT,
+               .ulcon          = SMDKV310_ULCON_DEFAULT,
+               .ufcon          = SMDKV310_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = SMDKV310_UCON_DEFAULT,
+               .ulcon          = SMDKV310_ULCON_DEFAULT,
+               .ufcon          = SMDKV310_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = SMDKV310_UCON_DEFAULT,
+               .ulcon          = SMDKV310_ULCON_DEFAULT,
+               .ufcon          = SMDKV310_UFCON_DEFAULT,
+       },
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = EXYNOS4_GPK0(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_INTERNAL,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = EXYNOS4_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+                                  unsigned int power)
+{
+       if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+               gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+               gpio_free(EXYNOS4_GPD0(1));
+#endif
+               /* fire nRESET on power up */
+               gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+               gpio_direction_output(EXYNOS4_GPX0(6), 1);
+               mdelay(100);
+
+               gpio_set_value(EXYNOS4_GPX0(6), 0);
+               mdelay(10);
+
+               gpio_set_value(EXYNOS4_GPX0(6), 1);
+               mdelay(10);
+
+               gpio_free(EXYNOS4_GPX0(6));
+       } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+               gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+               gpio_free(EXYNOS4_GPD0(1));
+#endif
+       }
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+       .set_power              = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s5p_device_fimd0.dev,
+       .dev.platform_data      = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 13,
+               .right_margin   = 8,
+               .upper_margin   = 7,
+               .lower_margin   = 5,
+               .hsync_len      = 3,
+               .vsync_len      = 1,
+               .xres           = 800,
+               .yres           = 480,
+       },
+       .max_bpp                = 32,
+       .default_bpp            = 24,
+};
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+       .win[0]         = &smdkv310_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
+static struct resource smdkv310_smsc911x_resources[] = {
+       [0] = {
+               .start  = EXYNOS4_PA_SROM_BANK(1),
+               .end    = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT(5),
+               .end    = IRQ_EINT(5),
+               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+       },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkv310_smsc911x = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(smdkv310_smsc911x_resources),
+       .resource       = smdkv310_smsc911x_resources,
+       .dev            = {
+               .platform_data  = &smsc9215_config,
+       },
+};
+
+static uint32_t smdkv310_keymap[] __initdata = {
+       /* KEY(row, col, keycode) */
+       KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
+       KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
+       KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
+       KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
+};
+
+static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
+       .keymap         = smdkv310_keymap,
+       .keymap_size    = ARRAY_SIZE(smdkv310_keymap),
+};
+
+static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
+       .keymap_data    = &smdkv310_keymap_data,
+       .rows           = 2,
+       .cols           = 8,
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+       {I2C_BOARD_INFO("wm8994", 0x1a),},
+};
+
+/* USB EHCI */
+static struct s5p_ehci_platdata smdkv310_ehci_pdata;
+
+static void __init smdkv310_ehci_init(void)
+{
+       struct s5p_ehci_platdata *pdata = &smdkv310_ehci_pdata;
+
+       s5p_ehci_set_platdata(pdata);
+}
+
+static struct platform_device *smdkv310_devices[] __initdata = {
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_i2c1,
+       &s5p_device_i2c_hdmiphy,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &s5p_device_ehci,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc3,
+       &exynos4_device_ac97,
+       &exynos4_device_i2s0,
+       &samsung_device_keypad,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
+       &exynos4_device_pd[PD_MFC],
+       &exynos4_device_pd[PD_G3D],
+       &exynos4_device_pd[PD_LCD0],
+       &exynos4_device_pd[PD_LCD1],
+       &exynos4_device_pd[PD_CAM],
+       &exynos4_device_pd[PD_TV],
+       &exynos4_device_pd[PD_GPS],
+       &exynos4_device_spdif,
+       &exynos4_device_sysmmu,
+       &samsung_asoc_dma,
+       &samsung_asoc_idma,
+       &s5p_device_fimd0,
+       &smdkv310_lcd_lte480wv,
+       &smdkv310_smsc911x,
+       &exynos4_device_ahci,
+       &s5p_device_hdmi,
+       &s5p_device_mixer,
+};
+
+static void __init smdkv310_smsc911x_init(void)
+{
+       u32 cs1;
+
+       /* configure nCS1 width to 16 bits */
+       cs1 = __raw_readl(S5P_SROM_BW) &
+               ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+       cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+               (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+               (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+               S5P_SROM_BW__NCS1__SHIFT;
+       __raw_writel(cs1, S5P_SROM_BW);
+
+       /* set timing for nCS1 suitable for ethernet chip */
+       __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+                    (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+                    (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+                    (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+                    (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkv310_bl_gpio_info = {
+       .no = EXYNOS4_GPD0(1),
+       .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkv310_bl_data = {
+       .pwm_id = 1,
+       .pwm_period_ns  = 1000,
+};
+
+static void s5p_tv_setup(void)
+{
+       /* direct HPD to HDMI chip */
+       WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
+       s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
+       s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
+
+       /* setup dependencies between TV devices */
+       s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
+       s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
+}
+
+static void __init smdkv310_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
+}
+
+static void __init smdkv310_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
+static void __init smdkv310_machine_init(void)
+{
+       s3c_i2c1_set_platdata(NULL);
+       i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+       smdkv310_smsc911x_init();
+
+       s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
+       s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
+       s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
+       s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+
+       s5p_tv_setup();
+       s5p_i2c_hdmiphy_set_platdata(NULL);
+
+       samsung_keypad_set_platdata(&smdkv310_keypad_data);
+
+       samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
+       s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+
+       smdkv310_ehci_init();
+       clk_xusbxti.rate = 24000000;
+
+       platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+}
+
+MACHINE_START(SMDKV310, "SMDKV310")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = smdkv310_map_io,
+       .init_machine   = smdkv310_machine_init,
+       .timer          = &exynos4_timer,
+       .reserve        = &smdkv310_reserve,
+MACHINE_END
+
+MACHINE_START(SMDKC210, "SMDKC210")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = smdkv310_map_io,
+       .init_machine   = smdkv310_machine_init,
+       .timer          = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
new file mode 100644 (file)
index 0000000..a2a177f
--- /dev/null
@@ -0,0 +1,1064 @@
+/* linux/arch/arm/mach-exynos4/mach-universal_c210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/mfd/max8998.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/max8952.h>
+#include <linux/mmc/host.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/mcs.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+#include <plat/fb.h>
+#include <plat/mfc.h>
+#include <plat/sdhci.h>
+#include <plat/pd.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/fimc-core.h>
+#include <plat/camport.h>
+#include <plat/mipi_csis.h>
+
+#include <mach/map.h>
+
+#include <media/v4l2-mediabus.h>
+#include <media/s5p_fimc.h>
+#include <media/m5mols.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define UNIVERSAL_ULCON_DEFAULT        S3C2410_LCON_CS8
+
+#define UNIVERSAL_UFCON_DEFAULT        (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG256 |      \
+                                S5PV210_UFCON_RXTRIG256)
+
+static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .ucon           = UNIVERSAL_UCON_DEFAULT,
+               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
+               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .ucon           = UNIVERSAL_UCON_DEFAULT,
+               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
+               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .ucon           = UNIVERSAL_UCON_DEFAULT,
+               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
+               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .ucon           = UNIVERSAL_UCON_DEFAULT,
+               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
+               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
+       },
+};
+
+static struct regulator_consumer_supply max8952_consumer =
+       REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct max8952_platform_data universal_max8952_pdata __initdata = {
+       .gpio_vid0      = EXYNOS4_GPX0(3),
+       .gpio_vid1      = EXYNOS4_GPX0(4),
+       .gpio_en        = -1, /* Not controllable, set "Always High" */
+       .default_mode   = 0, /* vid0 = 0, vid1 = 0 */
+       .dvs_mode       = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
+       .sync_freq      = 0, /* default: fastest */
+       .ramp_speed     = 0, /* default: fastest */
+
+       .reg_data       = {
+               .constraints    = {
+                       .name           = "VARM_1.2V",
+                       .min_uV         = 770000,
+                       .max_uV         = 1400000,
+                       .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+                       .always_on      = 1,
+                       .boot_on        = 1,
+               },
+               .num_consumer_supplies  = 1,
+               .consumer_supplies      = &max8952_consumer,
+       },
+};
+
+static struct regulator_consumer_supply lp3974_buck1_consumer =
+       REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply lp3974_buck2_consumer =
+       REGULATOR_SUPPLY("vddg3d", NULL);
+
+static struct regulator_consumer_supply lp3974_buck3_consumer =
+       REGULATOR_SUPPLY("vdet", "s5p-sdo");
+
+static struct regulator_init_data lp3974_buck1_data = {
+       .constraints    = {
+               .name           = "VINT_1.1V",
+               .min_uV         = 750000,
+               .max_uV         = 1500000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                       REGULATOR_CHANGE_STATUS,
+               .boot_on        = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &lp3974_buck1_consumer,
+};
+
+static struct regulator_init_data lp3974_buck2_data = {
+       .constraints    = {
+               .name           = "VG3D_1.1V",
+               .min_uV         = 750000,
+               .max_uV         = 1500000,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+                       REGULATOR_CHANGE_STATUS,
+               .boot_on        = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &lp3974_buck2_consumer,
+};
+
+static struct regulator_init_data lp3974_buck3_data = {
+       .constraints    = {
+               .name           = "VCC_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &lp3974_buck3_consumer,
+};
+
+static struct regulator_init_data lp3974_buck4_data = {
+       .constraints    = {
+               .name           = "VMEM_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .apply_uV       = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_ldo2_data = {
+       .constraints    = {
+               .name           = "VALIVE_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_consumer_supply lp3974_ldo3_consumer[] = {
+       REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
+       REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+       REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"),
+};
+
+static struct regulator_init_data lp3974_ldo3_data = {
+       .constraints    = {
+               .name           = "VUSB+MIPI_1.1V",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo3_consumer),
+       .consumer_supplies = lp3974_ldo3_consumer,
+};
+
+static struct regulator_consumer_supply lp3974_ldo4_consumer[] = {
+       REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
+};
+
+static struct regulator_init_data lp3974_ldo4_data = {
+       .constraints    = {
+               .name           = "VADC_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo4_consumer),
+       .consumer_supplies = lp3974_ldo4_consumer,
+};
+
+static struct regulator_init_data lp3974_ldo5_data = {
+       .constraints    = {
+               .name           = "VTF_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_ldo6_data = {
+       .constraints    = {
+               .name           = "LDO6",
+               .min_uV         = 2000000,
+               .max_uV         = 2000000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_consumer_supply lp3974_ldo7_consumer[] = {
+       REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"),
+};
+
+static struct regulator_init_data lp3974_ldo7_data = {
+       .constraints    = {
+               .name           = "VLCD+VMIPI_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(lp3974_ldo7_consumer),
+       .consumer_supplies      = lp3974_ldo7_consumer,
+};
+
+static struct regulator_consumer_supply lp3974_ldo8_consumer[] = {
+       REGULATOR_SUPPLY("vdd33a_dac", "s5p-sdo"),
+};
+
+static struct regulator_init_data lp3974_ldo8_data = {
+       .constraints    = {
+               .name           = "VUSB+VDAC_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo8_consumer),
+       .consumer_supplies = lp3974_ldo8_consumer,
+};
+
+static struct regulator_init_data lp3974_ldo9_data = {
+       .constraints    = {
+               .name           = "VCC_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_ldo10_data = {
+       .constraints    = {
+               .name           = "VPLL_1.1V",
+               .min_uV         = 1100000,
+               .max_uV         = 1100000,
+               .boot_on        = 1,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_consumer_supply lp3974_ldo11_consumer =
+       REGULATOR_SUPPLY("dig_28", "0-001f");
+
+static struct regulator_init_data lp3974_ldo11_data = {
+       .constraints    = {
+               .name           = "CAM_AF_3.3V",
+               .min_uV         = 3300000,
+               .max_uV         = 3300000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &lp3974_ldo11_consumer,
+};
+
+static struct regulator_init_data lp3974_ldo12_data = {
+       .constraints    = {
+               .name           = "PS_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_ldo13_data = {
+       .constraints    = {
+               .name           = "VHIC_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_consumer_supply lp3974_ldo14_consumer =
+       REGULATOR_SUPPLY("dig_18", "0-001f");
+
+static struct regulator_init_data lp3974_ldo14_data = {
+       .constraints    = {
+               .name           = "CAM_I_HOST_1.8V",
+               .min_uV         = 1800000,
+               .max_uV         = 1800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &lp3974_ldo14_consumer,
+};
+
+
+static struct regulator_consumer_supply lp3974_ldo15_consumer =
+       REGULATOR_SUPPLY("dig_12", "0-001f");
+
+static struct regulator_init_data lp3974_ldo15_data = {
+       .constraints    = {
+               .name           = "CAM_S_DIG+FM33_CORE_1.2V",
+               .min_uV         = 1200000,
+               .max_uV         = 1200000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &lp3974_ldo15_consumer,
+};
+
+static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
+       REGULATOR_SUPPLY("a_sensor", "0-001f"),
+};
+
+static struct regulator_init_data lp3974_ldo16_data = {
+       .constraints    = {
+               .name           = "CAM_S_ANA_2.8V",
+               .min_uV         = 2800000,
+               .max_uV         = 2800000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(lp3974_ldo16_consumer),
+       .consumer_supplies      = lp3974_ldo16_consumer,
+};
+
+static struct regulator_init_data lp3974_ldo17_data = {
+       .constraints    = {
+               .name           = "VCC_3.0V_LCD",
+               .min_uV         = 3000000,
+               .max_uV         = 3000000,
+               .apply_uV       = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .boot_on        = 1,
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_32khz_ap_data = {
+       .constraints    = {
+               .name           = "32KHz AP",
+               .always_on      = 1,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_32khz_cp_data = {
+       .constraints    = {
+               .name           = "32KHz CP",
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_vichg_data = {
+       .constraints    = {
+               .name           = "VICHG",
+               .state_mem      = {
+                       .disabled       = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_esafeout1_data = {
+       .constraints    = {
+               .name           = "SAFEOUT1",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct regulator_init_data lp3974_esafeout2_data = {
+       .constraints    = {
+               .name           = "SAFEOUT2",
+               .boot_on        = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+               .state_mem      = {
+                       .enabled        = 1,
+               },
+       },
+};
+
+static struct max8998_regulator_data lp3974_regulators[] = {
+       { MAX8998_LDO2,  &lp3974_ldo2_data },
+       { MAX8998_LDO3,  &lp3974_ldo3_data },
+       { MAX8998_LDO4,  &lp3974_ldo4_data },
+       { MAX8998_LDO5,  &lp3974_ldo5_data },
+       { MAX8998_LDO6,  &lp3974_ldo6_data },
+       { MAX8998_LDO7,  &lp3974_ldo7_data },
+       { MAX8998_LDO8,  &lp3974_ldo8_data },
+       { MAX8998_LDO9,  &lp3974_ldo9_data },
+       { MAX8998_LDO10, &lp3974_ldo10_data },
+       { MAX8998_LDO11, &lp3974_ldo11_data },
+       { MAX8998_LDO12, &lp3974_ldo12_data },
+       { MAX8998_LDO13, &lp3974_ldo13_data },
+       { MAX8998_LDO14, &lp3974_ldo14_data },
+       { MAX8998_LDO15, &lp3974_ldo15_data },
+       { MAX8998_LDO16, &lp3974_ldo16_data },
+       { MAX8998_LDO17, &lp3974_ldo17_data },
+       { MAX8998_BUCK1, &lp3974_buck1_data },
+       { MAX8998_BUCK2, &lp3974_buck2_data },
+       { MAX8998_BUCK3, &lp3974_buck3_data },
+       { MAX8998_BUCK4, &lp3974_buck4_data },
+       { MAX8998_EN32KHZ_AP, &lp3974_32khz_ap_data },
+       { MAX8998_EN32KHZ_CP, &lp3974_32khz_cp_data },
+       { MAX8998_ENVICHG, &lp3974_vichg_data },
+       { MAX8998_ESAFEOUT1, &lp3974_esafeout1_data },
+       { MAX8998_ESAFEOUT2, &lp3974_esafeout2_data },
+};
+
+static struct max8998_platform_data universal_lp3974_pdata = {
+       .num_regulators         = ARRAY_SIZE(lp3974_regulators),
+       .regulators             = lp3974_regulators,
+       .buck1_voltage1         = 1100000,      /* INT */
+       .buck1_voltage2         = 1000000,
+       .buck1_voltage3         = 1100000,
+       .buck1_voltage4         = 1000000,
+       .buck1_set1             = EXYNOS4_GPX0(5),
+       .buck1_set2             = EXYNOS4_GPX0(6),
+       .buck2_voltage1         = 1200000,      /* G3D */
+       .buck2_voltage2         = 1100000,
+       .buck1_default_idx      = 0,
+       .buck2_set3             = EXYNOS4_GPE2(0),
+       .buck2_default_idx      = 0,
+       .wakeup                 = true,
+};
+
+
+enum fixed_regulator_id {
+       FIXED_REG_ID_MMC0,
+       FIXED_REG_ID_HDMI_5V,
+       FIXED_REG_ID_CAM_S_IF,
+       FIXED_REG_ID_CAM_I_CORE,
+       FIXED_REG_ID_CAM_VT_DIO,
+};
+
+static struct regulator_consumer_supply hdmi_fixed_consumer =
+       REGULATOR_SUPPLY("hdmi-en", "exynos4-hdmi");
+
+static struct regulator_init_data hdmi_fixed_voltage_init_data = {
+       .constraints            = {
+               .name           = "HDMI_5V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &hdmi_fixed_consumer,
+};
+
+static struct fixed_voltage_config hdmi_fixed_voltage_config = {
+       .supply_name            = "HDMI_EN1",
+       .microvolts             = 5000000,
+       .gpio                   = EXYNOS4_GPE0(1),
+       .enable_high            = true,
+       .init_data              = &hdmi_fixed_voltage_init_data,
+};
+
+static struct platform_device hdmi_fixed_voltage = {
+       .name                   = "reg-fixed-voltage",
+       .id                     = FIXED_REG_ID_HDMI_5V,
+       .dev                    = {
+               .platform_data  = &hdmi_fixed_voltage_config,
+       },
+};
+
+/* GPIO I2C 5 (PMIC) */
+static struct i2c_board_info i2c5_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("max8952", 0xC0 >> 1),
+               .platform_data  = &universal_max8952_pdata,
+       }, {
+               I2C_BOARD_INFO("lp3974", 0xCC >> 1),
+               .platform_data  = &universal_lp3974_pdata,
+       },
+};
+
+/* I2C3 (TSP) */
+static struct mxt_platform_data qt602240_platform_data = {
+       .x_line         = 19,
+       .y_line         = 11,
+       .x_size         = 800,
+       .y_size         = 480,
+       .blen           = 0x11,
+       .threshold      = 0x28,
+       .voltage        = 2800000,              /* 2.8V */
+       .orient         = MXT_DIAGONAL,
+};
+
+static struct i2c_board_info i2c3_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("qt602240_ts", 0x4a),
+               .platform_data = &qt602240_platform_data,
+       },
+};
+
+static void __init universal_tsp_init(void)
+{
+       int gpio;
+
+       /* TSP_LDO_ON: XMDMADDR_11 */
+       gpio = EXYNOS4_GPE2(3);
+       gpio_request(gpio, "TSP_LDO_ON");
+       gpio_direction_output(gpio, 1);
+       gpio_export(gpio, 0);
+
+       /* TSP_INT: XMDMADDR_7 */
+       gpio = EXYNOS4_GPE1(7);
+       gpio_request(gpio, "TSP_INT");
+
+       s5p_register_gpio_interrupt(gpio);
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+       i2c3_devs[0].irq = gpio_to_irq(gpio);
+}
+
+
+/* GPIO I2C 12 (3 Touchkey) */
+static uint32_t touchkey_keymap[] = {
+       /* MCS_KEY_MAP(value, keycode) */
+       MCS_KEY_MAP(0, KEY_MENU),               /* KEY_SEND */
+       MCS_KEY_MAP(1, KEY_BACK),               /* KEY_END */
+};
+
+static struct mcs_platform_data touchkey_data = {
+       .keymap         = touchkey_keymap,
+       .keymap_size    = ARRAY_SIZE(touchkey_keymap),
+       .key_maxval     = 2,
+};
+
+/* GPIO I2C 3_TOUCH 2.8V */
+#define I2C_GPIO_BUS_12                12
+static struct i2c_gpio_platform_data i2c_gpio12_data = {
+       .sda_pin        = EXYNOS4_GPE4(0),      /* XMDMDATA_8 */
+       .scl_pin        = EXYNOS4_GPE4(1),      /* XMDMDATA_9 */
+};
+
+static struct platform_device i2c_gpio12 = {
+       .name           = "i2c-gpio",
+       .id             = I2C_GPIO_BUS_12,
+       .dev            = {
+               .platform_data  = &i2c_gpio12_data,
+       },
+};
+
+static struct i2c_board_info i2c_gpio12_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("mcs5080_touchkey", 0x20),
+               .platform_data = &touchkey_data,
+       },
+};
+
+static void __init universal_touchkey_init(void)
+{
+       int gpio;
+
+       gpio = EXYNOS4_GPE3(7);                 /* XMDMDATA_7 */
+       gpio_request(gpio, "3_TOUCH_INT");
+       s5p_register_gpio_interrupt(gpio);
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       i2c_gpio12_devs[0].irq = gpio_to_irq(gpio);
+
+       gpio = EXYNOS4_GPE3(3);                 /* XMDMDATA_3 */
+       gpio_request(gpio, "3_TOUCH_EN");
+       gpio_direction_output(gpio, 1);
+}
+
+static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = {
+       .frequency      = 300 * 1000,
+       .sda_delay      = 200,
+};
+
+/* GPIO KEYS */
+static struct gpio_keys_button universal_gpio_keys_tables[] = {
+       {
+               .code                   = KEY_VOLUMEUP,
+               .gpio                   = EXYNOS4_GPX2(0),      /* XEINT16 */
+               .desc                   = "gpio-keys: KEY_VOLUMEUP",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_VOLUMEDOWN,
+               .gpio                   = EXYNOS4_GPX2(1),      /* XEINT17 */
+               .desc                   = "gpio-keys: KEY_VOLUMEDOWN",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_CONFIG,
+               .gpio                   = EXYNOS4_GPX2(2),      /* XEINT18 */
+               .desc                   = "gpio-keys: KEY_CONFIG",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_CAMERA,
+               .gpio                   = EXYNOS4_GPX2(3),      /* XEINT19 */
+               .desc                   = "gpio-keys: KEY_CAMERA",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_OK,
+               .gpio                   = EXYNOS4_GPX3(5),      /* XEINT29 */
+               .desc                   = "gpio-keys: KEY_OK",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       },
+};
+
+static struct gpio_keys_platform_data universal_gpio_keys_data = {
+       .buttons        = universal_gpio_keys_tables,
+       .nbuttons       = ARRAY_SIZE(universal_gpio_keys_tables),
+};
+
+static struct platform_device universal_gpio_keys = {
+       .name                   = "gpio-keys",
+       .dev                    = {
+               .platform_data  = &universal_gpio_keys_data,
+       },
+};
+
+/* eMMC */
+static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
+       .max_width              = 8,
+       .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                               MMC_CAP_DISABLE),
+       .cd_type                = S3C_SDHCI_CD_PERMANENT,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply mmc0_supplies[] = {
+       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
+static struct regulator_init_data mmc0_fixed_voltage_init_data = {
+       .constraints            = {
+               .name           = "VMEM_VDD_2.8V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(mmc0_supplies),
+       .consumer_supplies      = mmc0_supplies,
+};
+
+static struct fixed_voltage_config mmc0_fixed_voltage_config = {
+       .supply_name            = "MASSMEMORY_EN",
+       .microvolts             = 2800000,
+       .gpio                   = EXYNOS4_GPE1(3),
+       .enable_high            = true,
+       .init_data              = &mmc0_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc0_fixed_voltage = {
+       .name                   = "reg-fixed-voltage",
+       .id                     = FIXED_REG_ID_MMC0,
+       .dev                    = {
+               .platform_data  = &mmc0_fixed_voltage_config,
+       },
+};
+
+/* SD */
+static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
+       .max_width              = 4,
+       .host_caps              = MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                               MMC_CAP_DISABLE,
+       .ext_cd_gpio            = EXYNOS4_GPX3(4),      /* XEINT_28 */
+       .ext_cd_gpio_invert     = 1,
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* WiFi */
+static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
+       .max_width              = 4,
+       .host_caps              = MMC_CAP_4_BIT_DATA |
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+                               MMC_CAP_DISABLE,
+       .cd_type                = S3C_SDHCI_CD_EXTERNAL,
+};
+
+static void __init universal_sdhci_init(void)
+{
+       s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
+       s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
+       s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
+}
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+       /* Gyro, To be updated */
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win universal_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 16,
+               .right_margin   = 16,
+               .upper_margin   = 2,
+               .lower_margin   = 28,
+               .hsync_len      = 2,
+               .vsync_len      = 1,
+               .xres           = 480,
+               .yres           = 800,
+               .refresh        = 55,
+       },
+       .max_bpp        = 32,
+       .default_bpp    = 16,
+};
+
+static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
+       .win[0]         = &universal_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+                         VIDCON0_CLKSEL_LCD,
+       .vidcon1        = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+                         | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
+};
+
+static struct regulator_consumer_supply cam_i_core_supply =
+       REGULATOR_SUPPLY("core", "0-001f");
+
+static struct regulator_init_data cam_i_core_reg_init_data = {
+       .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &cam_i_core_supply,
+};
+
+static struct fixed_voltage_config cam_i_core_fixed_voltage_cfg = {
+       .supply_name    = "CAM_I_CORE_1.2V",
+       .microvolts     = 1200000,
+       .gpio           = EXYNOS4_GPE2(2),      /* CAM_8M_CORE_EN */
+       .enable_high    = 1,
+       .init_data      = &cam_i_core_reg_init_data,
+};
+
+static struct platform_device cam_i_core_fixed_reg_dev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_I_CORE,
+       .dev = { .platform_data = &cam_i_core_fixed_voltage_cfg },
+};
+
+static struct regulator_consumer_supply cam_s_if_supply =
+       REGULATOR_SUPPLY("d_sensor", "0-001f");
+
+static struct regulator_init_data cam_s_if_reg_init_data = {
+       .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+       .num_consumer_supplies = 1,
+       .consumer_supplies = &cam_s_if_supply,
+};
+
+static struct fixed_voltage_config cam_s_if_fixed_voltage_cfg = {
+       .supply_name    = "CAM_S_IF_1.8V",
+       .microvolts     = 1800000,
+       .gpio           = EXYNOS4_GPE3(0),      /* CAM_PWR_EN1 */
+       .enable_high    = 1,
+       .init_data      = &cam_s_if_reg_init_data,
+};
+
+static struct platform_device cam_s_if_fixed_reg_dev = {
+       .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_S_IF,
+       .dev = { .platform_data = &cam_s_if_fixed_voltage_cfg },
+};
+
+static struct s5p_platform_mipi_csis mipi_csis_platdata = {
+       .clk_rate       = 166000000UL,
+       .lanes          = 2,
+       .alignment      = 32,
+       .hs_settle      = 12,
+       .phy_enable     = s5p_csis_phy_enable,
+};
+
+#define GPIO_CAM_LEVEL_EN(n)   EXYNOS4_GPE4(n + 3)
+#define GPIO_CAM_8M_ISP_INT    EXYNOS4_GPX1(5) /* XEINT_13 */
+#define GPIO_CAM_MEGA_nRST     EXYNOS4_GPE2(5)
+
+static int m5mols_set_power(struct device *dev, int on)
+{
+       gpio_set_value(GPIO_CAM_LEVEL_EN(1), !on);
+       gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
+       return 0;
+}
+
+static struct m5mols_platform_data m5mols_platdata = {
+       .gpio_reset     = GPIO_CAM_MEGA_nRST,
+       .reset_polarity = 0,
+       .set_power      = m5mols_set_power,
+};
+
+static struct i2c_board_info m5mols_board_info = {
+       I2C_BOARD_INFO("M5MOLS", 0x1F),
+       .platform_data = &m5mols_platdata,
+};
+
+static struct s5p_fimc_isp_info universal_camera_sensors[] = {
+       {
+               .mux_id         = 0,
+               .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+                                 V4L2_MBUS_VSYNC_ACTIVE_LOW,
+               .bus_type       = FIMC_MIPI_CSI2,
+               .board_info     = &m5mols_board_info,
+               .i2c_bus_num    = 0,
+               .clk_frequency  = 21600000UL,
+               .csi_data_align = 32,
+       },
+};
+
+static struct s5p_platform_fimc fimc_md_platdata = {
+       .isp_info       = universal_camera_sensors,
+       .num_clients    = ARRAY_SIZE(universal_camera_sensors),
+};
+
+static struct gpio universal_camera_gpios[] = {
+       { GPIO_CAM_LEVEL_EN(1), GPIOF_OUT_INIT_HIGH, "CAM_LVL_EN1" },
+       { GPIO_CAM_LEVEL_EN(2), GPIOF_OUT_INIT_LOW,  "CAM_LVL_EN2" },
+       { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,            "8M_ISP_INT"  },
+       { GPIO_CAM_MEGA_nRST,   GPIOF_OUT_INIT_LOW,  "CAM_8M_NRST" },
+};
+
+static void universal_camera_init(void)
+{
+       s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
+                        &s5p_device_mipi_csis0);
+       s3c_set_platdata(&fimc_md_platdata,  sizeof(fimc_md_platdata),
+                        &s5p_device_fimc_md);
+
+       if (gpio_request_array(universal_camera_gpios,
+                              ARRAY_SIZE(universal_camera_gpios))) {
+               pr_err("%s: GPIO request failed\n", __func__);
+               return;
+       }
+
+       if (!s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xf)))
+               m5mols_board_info.irq = gpio_to_irq(GPIO_CAM_8M_ISP_INT);
+       else
+               pr_err("Failed to configure 8M_ISP_INT GPIO\n");
+
+       /* Free GPIOs controlled directly by the sensor drivers. */
+       gpio_free(GPIO_CAM_MEGA_nRST);
+       gpio_free(GPIO_CAM_8M_ISP_INT);
+
+       if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
+               pr_err("Camera port A setup failed\n");
+}
+
+static struct platform_device *universal_devices[] __initdata = {
+       /* Samsung Platform Devices */
+       &s5p_device_mipi_csis0,
+       &s5p_device_fimc0,
+       &s5p_device_fimc1,
+       &s5p_device_fimc2,
+       &s5p_device_fimc3,
+       &mmc0_fixed_voltage,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_i2c0,
+       &s3c_device_i2c3,
+       &s3c_device_i2c5,
+       &s5p_device_i2c_hdmiphy,
+       &hdmi_fixed_voltage,
+       &exynos4_device_pd[PD_TV],
+       &s5p_device_hdmi,
+       &s5p_device_sdo,
+       &s5p_device_mixer,
+
+       /* Universal Devices */
+       &i2c_gpio12,
+       &universal_gpio_keys,
+       &s5p_device_onenand,
+       &s5p_device_fimd0,
+       &s5p_device_mfc,
+       &s5p_device_mfc_l,
+       &s5p_device_mfc_r,
+       &exynos4_device_pd[PD_MFC],
+       &exynos4_device_pd[PD_LCD0],
+       &exynos4_device_pd[PD_CAM],
+       &cam_i_core_fixed_reg_dev,
+       &cam_s_if_fixed_reg_dev,
+       &s5p_device_fimc_md,
+};
+
+static void __init universal_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
+}
+
+void s5p_tv_setup(void)
+{
+       /* direct HPD to HDMI chip */
+       gpio_request(EXYNOS4_GPX3(7), "hpd-plug");
+
+       gpio_direction_input(EXYNOS4_GPX3(7));
+       s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
+       s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
+
+       /* setup dependencies between TV devices */
+       s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
+       s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
+}
+
+static void __init universal_reserve(void)
+{
+       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
+}
+
+static void __init universal_machine_init(void)
+{
+       universal_sdhci_init();
+       s5p_tv_setup();
+
+       s3c_i2c0_set_platdata(&universal_i2c0_platdata);
+       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+       universal_tsp_init();
+       s3c_i2c3_set_platdata(NULL);
+       i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
+
+       s3c_i2c5_set_platdata(NULL);
+       s5p_i2c_hdmiphy_set_platdata(NULL);
+       i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
+
+       s5p_fimd0_set_platdata(&universal_lcd_pdata);
+
+       universal_touchkey_init();
+       i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
+                       ARRAY_SIZE(i2c_gpio12_devs));
+
+       universal_camera_init();
+
+       /* Last */
+       platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
+
+       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+       s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+
+       s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+       s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+}
+
+MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
+       /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+       .atag_offset    = 0x100,
+       .init_irq       = exynos4_init_irq,
+       .map_io         = universal_map_io,
+       .init_machine   = universal_machine_init,
+       .timer          = &exynos4_timer,
+       .reserve        = &universal_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
new file mode 100644 (file)
index 0000000..97343df
--- /dev/null
@@ -0,0 +1,471 @@
+/* linux/arch/arm/mach-exynos4/mct.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 MCT(Multi-Core Timer) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/percpu.h>
+
+#include <asm/hardware/gic.h>
+
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-mct.h>
+#include <asm/mach/time.h>
+
+enum {
+       MCT_INT_SPI,
+       MCT_INT_PPI
+};
+
+static unsigned long clk_cnt_per_tick;
+static unsigned long clk_rate;
+static unsigned int mct_int_type;
+
+struct mct_clock_event_device {
+       struct clock_event_device *evt;
+       void __iomem *base;
+       char name[10];
+};
+
+static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
+
+static void exynos4_mct_write(unsigned int value, void *addr)
+{
+       void __iomem *stat_addr;
+       u32 mask;
+       u32 i;
+
+       __raw_writel(value, addr);
+
+       if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) {
+               u32 base = (u32) addr & EXYNOS4_MCT_L_MASK;
+               switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) {
+               case (u32) MCT_L_TCON_OFFSET:
+                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+                       mask = 1 << 3;          /* L_TCON write status */
+                       break;
+               case (u32) MCT_L_ICNTB_OFFSET:
+                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+                       mask = 1 << 1;          /* L_ICNTB write status */
+                       break;
+               case (u32) MCT_L_TCNTB_OFFSET:
+                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+                       mask = 1 << 0;          /* L_TCNTB write status */
+                       break;
+               default:
+                       return;
+               }
+       } else {
+               switch ((u32) addr) {
+               case (u32) EXYNOS4_MCT_G_TCON:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 16;         /* G_TCON write status */
+                       break;
+               case (u32) EXYNOS4_MCT_G_COMP0_L:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 0;          /* G_COMP0_L write status */
+                       break;
+               case (u32) EXYNOS4_MCT_G_COMP0_U:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 1;          /* G_COMP0_U write status */
+                       break;
+               case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 2;          /* G_COMP0_ADD_INCR w status */
+                       break;
+               case (u32) EXYNOS4_MCT_G_CNT_L:
+                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+                       mask = 1 << 0;          /* G_CNT_L write status */
+                       break;
+               case (u32) EXYNOS4_MCT_G_CNT_U:
+                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+                       mask = 1 << 1;          /* G_CNT_U write status */
+                       break;
+               default:
+                       return;
+               }
+       }
+
+       /* Wait maximum 1 ms until written values are applied */
+       for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
+               if (__raw_readl(stat_addr) & mask) {
+                       __raw_writel(mask, stat_addr);
+                       return;
+               }
+
+       panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
+}
+
+/* Clocksource handling */
+static void exynos4_mct_frc_start(u32 hi, u32 lo)
+{
+       u32 reg;
+
+       exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
+       exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
+
+       reg = __raw_readl(EXYNOS4_MCT_G_TCON);
+       reg |= MCT_G_TCON_START;
+       exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
+}
+
+static cycle_t exynos4_frc_read(struct clocksource *cs)
+{
+       unsigned int lo, hi;
+       u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+
+       do {
+               hi = hi2;
+               lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
+               hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+       } while (hi != hi2);
+
+       return ((cycle_t)hi << 32) | lo;
+}
+
+static void exynos4_frc_resume(struct clocksource *cs)
+{
+       exynos4_mct_frc_start(0, 0);
+}
+
+struct clocksource mct_frc = {
+       .name           = "mct-frc",
+       .rating         = 400,
+       .read           = exynos4_frc_read,
+       .mask           = CLOCKSOURCE_MASK(64),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+       .resume         = exynos4_frc_resume,
+};
+
+static void __init exynos4_clocksource_init(void)
+{
+       exynos4_mct_frc_start(0, 0);
+
+       if (clocksource_register_hz(&mct_frc, clk_rate))
+               panic("%s: can't register clocksource\n", mct_frc.name);
+}
+
+static void exynos4_mct_comp0_stop(void)
+{
+       unsigned int tcon;
+
+       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+       tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
+
+       exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
+       exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
+}
+
+static void exynos4_mct_comp0_start(enum clock_event_mode mode,
+                                   unsigned long cycles)
+{
+       unsigned int tcon;
+       cycle_t comp_cycle;
+
+       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+
+       if (mode == CLOCK_EVT_MODE_PERIODIC) {
+               tcon |= MCT_G_TCON_COMP0_AUTO_INC;
+               exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
+       }
+
+       comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
+       exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
+       exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
+
+       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
+
+       tcon |= MCT_G_TCON_COMP0_ENABLE;
+       exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
+}
+
+static int exynos4_comp_set_next_event(unsigned long cycles,
+                                      struct clock_event_device *evt)
+{
+       exynos4_mct_comp0_start(evt->mode, cycles);
+
+       return 0;
+}
+
+static void exynos4_comp_set_mode(enum clock_event_mode mode,
+                                 struct clock_event_device *evt)
+{
+       exynos4_mct_comp0_stop();
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static struct clock_event_device mct_comp_device = {
+       .name           = "mct-comp",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .rating         = 250,
+       .set_next_event = exynos4_comp_set_next_event,
+       .set_mode       = exynos4_comp_set_mode,
+};
+
+static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction mct_comp_event_irq = {
+       .name           = "mct_comp_irq",
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = exynos4_mct_comp_isr,
+       .dev_id         = &mct_comp_device,
+};
+
+static void exynos4_clockevent_init(void)
+{
+       clk_cnt_per_tick = clk_rate / 2 / HZ;
+
+       clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
+       mct_comp_device.max_delta_ns =
+               clockevent_delta2ns(0xffffffff, &mct_comp_device);
+       mct_comp_device.min_delta_ns =
+               clockevent_delta2ns(0xf, &mct_comp_device);
+       mct_comp_device.cpumask = cpumask_of(0);
+       clockevents_register_device(&mct_comp_device);
+
+       setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+/* Clock event handling */
+static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
+{
+       unsigned long tmp;
+       unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
+       void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
+
+       tmp = __raw_readl(addr);
+       if (tmp & mask) {
+               tmp &= ~mask;
+               exynos4_mct_write(tmp, addr);
+       }
+}
+
+static void exynos4_mct_tick_start(unsigned long cycles,
+                                  struct mct_clock_event_device *mevt)
+{
+       unsigned long tmp;
+
+       exynos4_mct_tick_stop(mevt);
+
+       tmp = (1 << 31) | cycles;       /* MCT_L_UPDATE_ICNTB */
+
+       /* update interrupt count buffer */
+       exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
+
+       /* enable MCT tick interrupt */
+       exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
+
+       tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
+       tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
+              MCT_L_TCON_INTERVAL_MODE;
+       exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
+}
+
+static int exynos4_tick_set_next_event(unsigned long cycles,
+                                      struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
+
+       exynos4_mct_tick_start(cycles, mevt);
+
+       return 0;
+}
+
+static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
+                                        struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
+
+       exynos4_mct_tick_stop(mevt);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
+{
+       struct clock_event_device *evt = mevt->evt;
+
+       /*
+        * This is for supporting oneshot mode.
+        * Mct would generate interrupt periodically
+        * without explicit stopping.
+        */
+       if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
+               exynos4_mct_tick_stop(mevt);
+
+       /* Clear the MCT tick interrupt */
+       if (__raw_readl(mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
+               exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
+{
+       struct mct_clock_event_device *mevt = dev_id;
+       struct clock_event_device *evt = mevt->evt;
+
+       exynos4_mct_tick_clear(mevt);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction mct_tick0_event_irq = {
+       .name           = "mct_tick0_irq",
+       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
+       .handler        = exynos4_mct_tick_isr,
+};
+
+static struct irqaction mct_tick1_event_irq = {
+       .name           = "mct_tick1_irq",
+       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
+       .handler        = exynos4_mct_tick_isr,
+};
+
+static void exynos4_mct_tick_init(struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt;
+       unsigned int cpu = smp_processor_id();
+
+       mevt = this_cpu_ptr(&percpu_mct_tick);
+       mevt->evt = evt;
+
+       mevt->base = EXYNOS4_MCT_L_BASE(cpu);
+       sprintf(mevt->name, "mct_tick%d", cpu);
+
+       evt->name = mevt->name;
+       evt->cpumask = cpumask_of(cpu);
+       evt->set_next_event = exynos4_tick_set_next_event;
+       evt->set_mode = exynos4_tick_set_mode;
+       evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+       evt->rating = 450;
+
+       clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
+       evt->max_delta_ns =
+               clockevent_delta2ns(0x7fffffff, evt);
+       evt->min_delta_ns =
+               clockevent_delta2ns(0xf, evt);
+
+       clockevents_register_device(evt);
+
+       exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET);
+
+       if (mct_int_type == MCT_INT_SPI) {
+               if (cpu == 0) {
+                       mct_tick0_event_irq.dev_id = mevt;
+                       evt->irq = IRQ_MCT_L0;
+                       setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+               } else {
+                       mct_tick1_event_irq.dev_id = mevt;
+                       evt->irq = IRQ_MCT_L1;
+                       setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
+                       irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
+               }
+       } else {
+               enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0);
+       }
+}
+
+/* Setup the local clock events for a CPU */
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+       exynos4_mct_tick_init(evt);
+
+       return 0;
+}
+
+void local_timer_stop(struct clock_event_device *evt)
+{
+       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+       if (mct_int_type == MCT_INT_SPI)
+               disable_irq(evt->irq);
+       else
+               disable_percpu_irq(IRQ_MCT_LOCALTIMER);
+}
+#endif /* CONFIG_LOCAL_TIMERS */
+
+static void __init exynos4_timer_resources(void)
+{
+       struct clk *mct_clk;
+       mct_clk = clk_get(NULL, "xtal");
+
+       clk_rate = clk_get_rate(mct_clk);
+
+       if (mct_int_type == MCT_INT_PPI) {
+               int err;
+
+               err = request_percpu_irq(IRQ_MCT_LOCALTIMER,
+                                        exynos4_mct_tick_isr, "MCT",
+                                        &percpu_mct_tick);
+               WARN(err, "MCT: can't request IRQ %d (%d)\n",
+                    IRQ_MCT_LOCALTIMER, err);
+       }
+}
+
+static void __init exynos4_timer_init(void)
+{
+       if (soc_is_exynos4210())
+               mct_int_type = MCT_INT_SPI;
+       else
+               mct_int_type = MCT_INT_PPI;
+
+       exynos4_timer_resources();
+       exynos4_clocksource_init();
+       exynos4_clockevent_init();
+}
+
+struct sys_timer exynos4_timer = {
+       .init           = exynos4_timer_init,
+};
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
new file mode 100644 (file)
index 0000000..69ffb2f
--- /dev/null
@@ -0,0 +1,223 @@
+/* linux/arch/arm/mach-exynos4/platsmp.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+
+#include <plat/cpu.h>
+
+extern unsigned int gic_bank_offset;
+extern void exynos4_secondary_startup(void);
+
+#define CPU1_BOOT_REG          (samsung_rev() == EXYNOS4210_REV_1_1 ? \
+                               S5P_INFORM5 : S5P_VA_SYSRAM)
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+
+volatile int __cpuinitdata pen_release = -1;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+       pen_release = val;
+       smp_wmb();
+       __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+       outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+       return (void __iomem *)(S5P_VA_SCU);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __cpuinit exynos4_gic_secondary_init(void)
+{
+       void __iomem *dist_base = S5P_VA_GIC_DIST +
+                               (gic_bank_offset * smp_processor_id());
+       void __iomem *cpu_base = S5P_VA_GIC_CPU +
+                               (gic_bank_offset * smp_processor_id());
+       int i;
+
+       /*
+        * Deal with the banked PPI and SGI interrupts - disable all
+        * PPI interrupts, ensure all SGI interrupts are enabled.
+        */
+       __raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
+       __raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+
+       /*
+        * Set priority on PPI and SGI interrupts
+        */
+       for (i = 0; i < 32; i += 4)
+               __raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+
+       __raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK);
+       __raw_writel(1, cpu_base + GIC_CPU_CTRL);
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+       /*
+        * if any interrupts are already enabled for the primary
+        * core (e.g. timer irq), then they will not have been enabled
+        * for us: do so
+        */
+       exynos4_gic_secondary_init();
+
+       /*
+        * let the primary processor know we're out of the
+        * pen, then head off into the C entry point
+        */
+       write_pen_release(-1);
+
+       /*
+        * Synchronise with the boot thread.
+        */
+       spin_lock(&boot_lock);
+       spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+
+       /*
+        * Set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       spin_lock(&boot_lock);
+
+       /*
+        * The secondary processor is waiting to be released from
+        * the holding pen - release it, then wait for it to flag
+        * that it has been released by resetting pen_release.
+        *
+        * Note that "pen_release" is the hardware CPU ID, whereas
+        * "cpu" is Linux's internal ID.
+        */
+       write_pen_release(cpu_logical_map(cpu));
+
+       if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
+               __raw_writel(S5P_CORE_LOCAL_PWR_EN,
+                            S5P_ARM_CORE1_CONFIGURATION);
+
+               timeout = 10;
+
+               /* wait max 10 ms until cpu1 is on */
+               while ((__raw_readl(S5P_ARM_CORE1_STATUS)
+                       & S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) {
+                       if (timeout-- == 0)
+                               break;
+
+                       mdelay(1);
+               }
+
+               if (timeout == 0) {
+                       printk(KERN_ERR "cpu1 power enable failed");
+                       spin_unlock(&boot_lock);
+                       return -ETIMEDOUT;
+               }
+       }
+       /*
+        * Send the secondary CPU a soft interrupt, thereby causing
+        * the boot monitor to read the system wide flags register,
+        * and branch to the address found there.
+        */
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               smp_rmb();
+
+               __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
+                       CPU1_BOOT_REG);
+               gic_raise_softirq(cpumask_of(cpu), 1);
+
+               if (pen_release == -1)
+                       break;
+
+               udelay(10);
+       }
+
+       /*
+        * now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       spin_unlock(&boot_lock);
+
+       return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+
+void __init smp_init_cpus(void)
+{
+       void __iomem *scu_base = scu_base_addr();
+       unsigned int i, ncores;
+
+       ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+       /* sanity check */
+       if (ncores > nr_cpu_ids) {
+               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+                       ncores, nr_cpu_ids);
+               ncores = nr_cpu_ids;
+       }
+
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+
+       set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+       scu_enable(scu_base_addr());
+
+       /*
+        * Write the address of secondary startup into the
+        * system-wide flags register. The boot monitor waits
+        * until it receives a soft interrupt, and then the
+        * secondary CPU branches to this address.
+        */
+       __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
+                       CPU1_BOOT_REG);
+}
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
new file mode 100644 (file)
index 0000000..509a435
--- /dev/null
@@ -0,0 +1,428 @@
+/* linux/arch/arm/mach-exynos4/pm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4210 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+#include <plat/regs-srom.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+#include <mach/pm-core.h>
+#include <mach/pmu.h>
+
+static struct sleep_save exynos4_set_clksrc[] = {
+       { .reg = S5P_CLKSRC_MASK_TOP                    , .val = 0x00000001, },
+       { .reg = S5P_CLKSRC_MASK_CAM                    , .val = 0x11111111, },
+       { .reg = S5P_CLKSRC_MASK_TV                     , .val = 0x00000111, },
+       { .reg = S5P_CLKSRC_MASK_LCD0                   , .val = 0x00001111, },
+       { .reg = S5P_CLKSRC_MASK_MAUDIO                 , .val = 0x00000001, },
+       { .reg = S5P_CLKSRC_MASK_FSYS                   , .val = 0x01011111, },
+       { .reg = S5P_CLKSRC_MASK_PERIL0                 , .val = 0x01111111, },
+       { .reg = S5P_CLKSRC_MASK_PERIL1                 , .val = 0x01110111, },
+       { .reg = S5P_CLKSRC_MASK_DMC                    , .val = 0x00010000, },
+};
+
+static struct sleep_save exynos4210_set_clksrc[] = {
+       { .reg = S5P_CLKSRC_MASK_LCD1                   , .val = 0x00001111, },
+};
+
+static struct sleep_save exynos4_epll_save[] = {
+       SAVE_ITEM(S5P_EPLL_CON0),
+       SAVE_ITEM(S5P_EPLL_CON1),
+};
+
+static struct sleep_save exynos4_vpll_save[] = {
+       SAVE_ITEM(S5P_VPLL_CON0),
+       SAVE_ITEM(S5P_VPLL_CON1),
+};
+
+static struct sleep_save exynos4_core_save[] = {
+       /* GIC side */
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x014),
+       SAVE_ITEM(S5P_VA_GIC_CPU + 0x018),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
+
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
+
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
+       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
+
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
+       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
+
+       /* SROM side */
+       SAVE_ITEM(S5P_SROM_BW),
+       SAVE_ITEM(S5P_SROM_BC0),
+       SAVE_ITEM(S5P_SROM_BC1),
+       SAVE_ITEM(S5P_SROM_BC2),
+       SAVE_ITEM(S5P_SROM_BC3),
+};
+
+static struct sleep_save exynos4_l2cc_save[] = {
+       SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
+       SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
+       SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
+       SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
+       SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
+};
+
+/* For Cortex-A9 Diagnostic and Power control register */
+static unsigned int save_arm_register[2];
+
+static int exynos4_cpu_suspend(unsigned long arg)
+{
+       outer_flush_all();
+
+       /* issue the standby signal into the pm unit. */
+       cpu_do_idle();
+
+       /* we should never get past here */
+       panic("sleep resumed to originator?");
+}
+
+static void exynos4_pm_prepare(void)
+{
+       u32 tmp;
+
+       s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
+       s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
+       s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
+       s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
+
+       tmp = __raw_readl(S5P_INFORM1);
+
+       /* Set value of power down register for sleep mode */
+
+       exynos4_sys_powerdown_conf(SYS_SLEEP);
+       __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
+
+       /* ensure at least INFORM0 has the resume address */
+
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
+
+       /* Before enter central sequence mode, clock src register have to set */
+
+       s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
+
+       if (soc_is_exynos4210())
+               s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
+
+}
+
+static int exynos4_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = exynos4_pm_prepare;
+       pm_cpu_sleep = exynos4_cpu_suspend;
+
+       return 0;
+}
+
+/* This function copy from linux/arch/arm/kernel/smp_scu.c */
+
+void exynos4_scu_enable(void __iomem *scu_base)
+{
+       u32 scu_ctrl;
+
+       scu_ctrl = __raw_readl(scu_base);
+       /* already enabled? */
+       if (scu_ctrl & 1)
+               return;
+
+       scu_ctrl |= 1;
+       __raw_writel(scu_ctrl, scu_base);
+
+       /*
+        * Ensure that the data accessed by CPU0 before the SCU was
+        * initialised is visible to the other CPUs.
+        */
+       flush_cache_all();
+}
+
+static unsigned long pll_base_rate;
+
+static void exynos4_restore_pll(void)
+{
+       unsigned long pll_con, locktime, lockcnt;
+       unsigned long pll_in_rate;
+       unsigned int p_div, epll_wait = 0, vpll_wait = 0;
+
+       if (pll_base_rate == 0)
+               return;
+
+       pll_in_rate = pll_base_rate;
+
+       /* EPLL */
+       pll_con = exynos4_epll_save[0].val;
+
+       if (pll_con & (1 << 31)) {
+               pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT);
+               p_div = (pll_con >> PLL46XX_PDIV_SHIFT);
+
+               pll_in_rate /= 1000000;
+
+               locktime = (3000 / pll_in_rate) * p_div;
+               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
+
+               __raw_writel(lockcnt, S5P_EPLL_LOCK);
+
+               s3c_pm_do_restore_core(exynos4_epll_save,
+                                       ARRAY_SIZE(exynos4_epll_save));
+               epll_wait = 1;
+       }
+
+       pll_in_rate = pll_base_rate;
+
+       /* VPLL */
+       pll_con = exynos4_vpll_save[0].val;
+
+       if (pll_con & (1 << 31)) {
+               pll_in_rate /= 1000000;
+               /* 750us */
+               locktime = 750;
+               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
+
+               __raw_writel(lockcnt, S5P_VPLL_LOCK);
+
+               s3c_pm_do_restore_core(exynos4_vpll_save,
+                                       ARRAY_SIZE(exynos4_vpll_save));
+               vpll_wait = 1;
+       }
+
+       /* Wait PLL locking */
+
+       do {
+               if (epll_wait) {
+                       pll_con = __raw_readl(S5P_EPLL_CON0);
+                       if (pll_con & (1 << S5P_EPLLCON0_LOCKED_SHIFT))
+                               epll_wait = 0;
+               }
+
+               if (vpll_wait) {
+                       pll_con = __raw_readl(S5P_VPLL_CON0);
+                       if (pll_con & (1 << S5P_VPLLCON0_LOCKED_SHIFT))
+                               vpll_wait = 0;
+               }
+       } while (epll_wait || vpll_wait);
+}
+
+static struct sysdev_driver exynos4_pm_driver = {
+       .add            = exynos4_pm_add,
+};
+
+static __init int exynos4_pm_drvinit(void)
+{
+       struct clk *pll_base;
+       unsigned int tmp;
+
+       s3c_pm_init();
+
+       /* All wakeup disable */
+
+       tmp = __raw_readl(S5P_WAKEUP_MASK);
+       tmp |= ((0xFF << 8) | (0x1F << 1));
+       __raw_writel(tmp, S5P_WAKEUP_MASK);
+
+       pll_base = clk_get(NULL, "xtal");
+
+       if (!IS_ERR(pll_base)) {
+               pll_base_rate = clk_get_rate(pll_base);
+               clk_put(pll_base);
+       }
+
+       return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+}
+arch_initcall(exynos4_pm_drvinit);
+
+static int exynos4_pm_suspend(void)
+{
+       unsigned long tmp;
+
+       /* Setting Central Sequence Register for power down mode */
+
+       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+       tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
+       __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+
+       if (soc_is_exynos4212()) {
+               tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
+               tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM |
+                        S5P_USE_STANDBYWFE_ISP_ARM);
+               __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
+       }
+
+       /* Save Power control register */
+       asm ("mrc p15, 0, %0, c15, c0, 0"
+            : "=r" (tmp) : : "cc");
+       save_arm_register[0] = tmp;
+
+       /* Save Diagnostic register */
+       asm ("mrc p15, 0, %0, c15, c0, 1"
+            : "=r" (tmp) : : "cc");
+       save_arm_register[1] = tmp;
+
+       return 0;
+}
+
+static void exynos4_pm_resume(void)
+{
+       unsigned long tmp;
+
+       /*
+        * If PMU failed while entering sleep mode, WFI will be
+        * ignored by PMU and then exiting cpu_do_idle().
+        * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
+        * in this situation.
+        */
+       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+       if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
+               tmp |= S5P_CENTRAL_LOWPWR_CFG;
+               __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+               /* No need to perform below restore code */
+               goto early_wakeup;
+       }
+       /* Restore Power control register */
+       tmp = save_arm_register[0];
+       asm volatile ("mcr p15, 0, %0, c15, c0, 0"
+                     : : "r" (tmp)
+                     : "cc");
+
+       /* Restore Diagnostic register */
+       tmp = save_arm_register[1];
+       asm volatile ("mcr p15, 0, %0, c15, c0, 1"
+                     : : "r" (tmp)
+                     : "cc");
+
+       /* For release retention */
+
+       __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
+       __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
+
+       s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
+
+       exynos4_restore_pll();
+
+       exynos4_scu_enable(S5P_VA_SCU);
+
+#ifdef CONFIG_CACHE_L2X0
+       s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
+       outer_inv_all();
+       /* enable L2X0*/
+       writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
+#endif
+
+early_wakeup:
+       return;
+}
+
+static struct syscore_ops exynos4_pm_syscore_ops = {
+       .suspend        = exynos4_pm_suspend,
+       .resume         = exynos4_pm_resume,
+};
+
+static __init int exynos4_pm_syscore_init(void)
+{
+       register_syscore_ops(&exynos4_pm_syscore_ops);
+       return 0;
+}
+arch_initcall(exynos4_pm_syscore_init);
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
new file mode 100644 (file)
index 0000000..bba48f5
--- /dev/null
@@ -0,0 +1,230 @@
+/* linux/arch/arm/mach-exynos4/pmu.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS4210 - CPU PMU(Power Management Unit) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <mach/regs-clock.h>
+#include <mach/pmu.h>
+
+static struct exynos4_pmu_conf *exynos4_pmu_config;
+
+static struct exynos4_pmu_conf exynos4210_pmu_config[] = {
+       /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
+       { S5P_ARM_CORE0_LOWPWR,                 { 0x0, 0x0, 0x2 } },
+       { S5P_DIS_IRQ_CORE0,                    { 0x0, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_CENTRAL0,                 { 0x0, 0x0, 0x0 } },
+       { S5P_ARM_CORE1_LOWPWR,                 { 0x0, 0x0, 0x2 } },
+       { S5P_DIS_IRQ_CORE1,                    { 0x0, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_CENTRAL1,                 { 0x0, 0x0, 0x0 } },
+       { S5P_ARM_COMMON_LOWPWR,                { 0x0, 0x0, 0x2 } },
+       { S5P_L2_0_LOWPWR,                      { 0x2, 0x2, 0x3 } },
+       { S5P_L2_1_LOWPWR,                      { 0x2, 0x2, 0x3 } },
+       { S5P_CMU_ACLKSTOP_LOWPWR,              { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_SCLKSTOP_LOWPWR,              { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_LOWPWR,                 { 0x1, 0x1, 0x0 } },
+       { S5P_APLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_MPLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_VPLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_EPLL_SYSCLK_LOWPWR,               { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,     { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_GPSALIVE_LOWPWR,        { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_CAM_LOWPWR,           { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_TV_LOWPWR,            { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_MFC_LOWPWR,           { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_G3D_LOWPWR,           { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_LCD0_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_LCD1_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,        { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_CLKSTOP_GPS_LOWPWR,           { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_CAM_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_TV_LOWPWR,              { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_MFC_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_G3D_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_LCD0_LOWPWR,            { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_LCD1_LOWPWR,            { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_MAUDIO_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_GPS_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_TOP_BUS_LOWPWR,                   { 0x3, 0x0, 0x0 } },
+       { S5P_TOP_RETENTION_LOWPWR,             { 0x1, 0x0, 0x1 } },
+       { S5P_TOP_PWR_LOWPWR,                   { 0x3, 0x0, 0x3 } },
+       { S5P_LOGIC_RESET_LOWPWR,               { 0x1, 0x1, 0x0 } },
+       { S5P_ONENAND_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_MODIMIF_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_G2D_ACP_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_USBOTG_MEM_LOWPWR,                { 0x3, 0x0, 0x0 } },
+       { S5P_HSMMC_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_CSSYS_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_SECSS_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_PCIE_MEM_LOWPWR,                  { 0x3, 0x0, 0x0 } },
+       { S5P_SATA_MEM_LOWPWR,                  { 0x3, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_DRAM_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MAUDIO_LOWPWR,      { 0x1, 0x1, 0x0 } },
+       { S5P_PAD_RETENTION_GPIO_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_UART_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MMCA_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MMCB_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_EBIA_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_EBIB_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_ISOLATION_LOWPWR,   { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_ALV_SEL_LOWPWR,     { 0x1, 0x0, 0x0 } },
+       { S5P_XUSBXTI_LOWPWR,                   { 0x1, 0x1, 0x0 } },
+       { S5P_XXTI_LOWPWR,                      { 0x1, 0x1, 0x0 } },
+       { S5P_EXT_REGULATOR_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_GPIO_MODE_LOWPWR,                 { 0x1, 0x0, 0x0 } },
+       { S5P_GPIO_MODE_MAUDIO_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CAM_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_TV_LOWPWR,                        { 0x7, 0x0, 0x0 } },
+       { S5P_MFC_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_G3D_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_LCD0_LOWPWR,                      { 0x7, 0x0, 0x0 } },
+       { S5P_LCD1_LOWPWR,                      { 0x7, 0x0, 0x0 } },
+       { S5P_MAUDIO_LOWPWR,                    { 0x7, 0x7, 0x0 } },
+       { S5P_GPS_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_GPS_ALIVE_LOWPWR,                 { 0x7, 0x0, 0x0 } },
+       { PMU_TABLE_END,},
+};
+
+static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
+       { S5P_ARM_CORE0_LOWPWR,                 { 0x0, 0x0, 0x2 } },
+       { S5P_DIS_IRQ_CORE0,                    { 0x0, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_CENTRAL0,                 { 0x0, 0x0, 0x0 } },
+       { S5P_ARM_CORE1_LOWPWR,                 { 0x0, 0x0, 0x2 } },
+       { S5P_DIS_IRQ_CORE1,                    { 0x0, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_CENTRAL1,                 { 0x0, 0x0, 0x0 } },
+       { S5P_ISP_ARM_LOWPWR,                   { 0x1, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR,     { 0x0, 0x0, 0x0 } },
+       { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR,   { 0x0, 0x0, 0x0 } },
+       { S5P_ARM_COMMON_LOWPWR,                { 0x0, 0x0, 0x2 } },
+       { S5P_L2_0_LOWPWR,                      { 0x0, 0x0, 0x3 } },
+       /* XXX_OPTION register should be set other field */
+       { S5P_ARM_L2_0_OPTION,                  { 0x10, 0x10, 0x0 } },
+       { S5P_L2_1_LOWPWR,                      { 0x0, 0x0, 0x3 } },
+       { S5P_ARM_L2_1_OPTION,                  { 0x10, 0x10, 0x0 } },
+       { S5P_CMU_ACLKSTOP_LOWPWR,              { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_SCLKSTOP_LOWPWR,              { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_LOWPWR,                 { 0x1, 0x1, 0x0 } },
+       { S5P_DRAM_FREQ_DOWN_LOWPWR,            { 0x1, 0x1, 0x1 } },
+       { S5P_DDRPHY_DLLOFF_LOWPWR,             { 0x1, 0x1, 0x1 } },
+       { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR,        { 0x1, 0x1, 0x1 } },
+       { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR,      { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR,      { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_COREBLK_LOWPWR,         { 0x1, 0x1, 0x0 } },
+       { S5P_APLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_MPLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_VPLL_SYSCLK_LOWPWR,               { 0x1, 0x0, 0x0 } },
+       { S5P_EPLL_SYSCLK_LOWPWR,               { 0x1, 0x1, 0x0 } },
+       { S5P_MPLLUSER_SYSCLK_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,     { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_GPSALIVE_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_CAM_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_TV_LOWPWR,            { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_MFC_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_G3D_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_LCD0_LOWPWR,          { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_ISP_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_CLKSTOP_GPS_LOWPWR,           { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_CAM_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_TV_LOWPWR,              { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_MFC_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_G3D_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_LCD0_LOWPWR,            { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_ISP_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_RESET_MAUDIO_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_CMU_RESET_GPS_LOWPWR,             { 0x1, 0x0, 0x0 } },
+       { S5P_TOP_BUS_LOWPWR,                   { 0x3, 0x0, 0x0 } },
+       { S5P_TOP_RETENTION_LOWPWR,             { 0x1, 0x0, 0x1 } },
+       { S5P_TOP_PWR_LOWPWR,                   { 0x3, 0x0, 0x3 } },
+       { S5P_TOP_BUS_COREBLK_LOWPWR,           { 0x3, 0x0, 0x0 } },
+       { S5P_TOP_RETENTION_COREBLK_LOWPWR,     { 0x1, 0x0, 0x1 } },
+       { S5P_TOP_PWR_COREBLK_LOWPWR,           { 0x3, 0x0, 0x3 } },
+       { S5P_LOGIC_RESET_LOWPWR,               { 0x1, 0x1, 0x0 } },
+       { S5P_OSCCLK_GATE_LOWPWR,               { 0x1, 0x0, 0x1 } },
+       { S5P_LOGIC_RESET_COREBLK_LOWPWR,       { 0x1, 0x1, 0x0 } },
+       { S5P_OSCCLK_GATE_COREBLK_LOWPWR,       { 0x1, 0x0, 0x1 } },
+       { S5P_ONENAND_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_ONENAND_MEM_OPTION,               { 0x10, 0x10, 0x0 } },
+       { S5P_HSI_MEM_LOWPWR,                   { 0x3, 0x0, 0x0 } },
+       { S5P_HSI_MEM_OPTION,                   { 0x10, 0x10, 0x0 } },
+       { S5P_G2D_ACP_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_G2D_ACP_MEM_OPTION,               { 0x10, 0x10, 0x0 } },
+       { S5P_USBOTG_MEM_LOWPWR,                { 0x3, 0x0, 0x0 } },
+       { S5P_USBOTG_MEM_OPTION,                { 0x10, 0x10, 0x0 } },
+       { S5P_HSMMC_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_HSMMC_MEM_OPTION,                 { 0x10, 0x10, 0x0 } },
+       { S5P_CSSYS_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_CSSYS_MEM_OPTION,                 { 0x10, 0x10, 0x0 } },
+       { S5P_SECSS_MEM_LOWPWR,                 { 0x3, 0x0, 0x0 } },
+       { S5P_SECSS_MEM_OPTION,                 { 0x10, 0x10, 0x0 } },
+       { S5P_ROTATOR_MEM_LOWPWR,               { 0x3, 0x0, 0x0 } },
+       { S5P_ROTATOR_MEM_OPTION,               { 0x10, 0x10, 0x0 } },
+       { S5P_PAD_RETENTION_DRAM_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MAUDIO_LOWPWR,      { 0x1, 0x1, 0x0 } },
+       { S5P_PAD_RETENTION_GPIO_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_UART_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MMCA_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_MMCB_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_EBIA_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_EBIB_LOWPWR,        { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_ISOLATION_LOWPWR,   { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_ISOLATION_COREBLK_LOWPWR,     { 0x1, 0x0, 0x0 } },
+       { S5P_PAD_RETENTION_ALV_SEL_LOWPWR,     { 0x1, 0x0, 0x0 } },
+       { S5P_XUSBXTI_LOWPWR,                   { 0x1, 0x1, 0x0 } },
+       { S5P_XXTI_LOWPWR,                      { 0x1, 0x1, 0x0 } },
+       { S5P_EXT_REGULATOR_LOWPWR,             { 0x1, 0x1, 0x0 } },
+       { S5P_GPIO_MODE_LOWPWR,                 { 0x1, 0x0, 0x0 } },
+       { S5P_GPIO_MODE_COREBLK_LOWPWR,         { 0x1, 0x0, 0x0 } },
+       { S5P_GPIO_MODE_MAUDIO_LOWPWR,          { 0x1, 0x1, 0x0 } },
+       { S5P_TOP_ASB_RESET_LOWPWR,             { 0x1, 0x1, 0x1 } },
+       { S5P_TOP_ASB_ISOLATION_LOWPWR,         { 0x1, 0x0, 0x1 } },
+       { S5P_CAM_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_TV_LOWPWR,                        { 0x7, 0x0, 0x0 } },
+       { S5P_MFC_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_G3D_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_LCD0_LOWPWR,                      { 0x7, 0x0, 0x0 } },
+       { S5P_ISP_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_MAUDIO_LOWPWR,                    { 0x7, 0x7, 0x0 } },
+       { S5P_GPS_LOWPWR,                       { 0x7, 0x0, 0x0 } },
+       { S5P_GPS_ALIVE_LOWPWR,                 { 0x7, 0x0, 0x0 } },
+       { S5P_CMU_SYSCLK_ISP_LOWPWR,            { 0x1, 0x0, 0x0 } },
+       { S5P_CMU_SYSCLK_GPS_LOWPWR,            { 0x1, 0x0, 0x0 } },
+       { PMU_TABLE_END,},
+};
+
+void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
+{
+       unsigned int i;
+
+       for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++)
+               __raw_writel(exynos4_pmu_config[i].val[mode],
+                               exynos4_pmu_config[i].reg);
+}
+
+static int __init exynos4_pmu_init(void)
+{
+       exynos4_pmu_config = exynos4210_pmu_config;
+
+       if (soc_is_exynos4210()) {
+               exynos4_pmu_config = exynos4210_pmu_config;
+               pr_info("EXYNOS4210 PMU Initialize\n");
+       } else if (soc_is_exynos4212()) {
+               exynos4_pmu_config = exynos4212_pmu_config;
+               pr_info("EXYNOS4212 PMU Initialize\n");
+       } else {
+               pr_info("EXYNOS4: PMU not supported\n");
+       }
+
+       return 0;
+}
+arch_initcall(exynos4_pmu_init);
diff --git a/arch/arm/mach-exynos/setup-fimc.c b/arch/arm/mach-exynos/setup-fimc.c
new file mode 100644 (file)
index 0000000..6a45078
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * Exynos4 camera interface GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/camport.h>
+
+int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
+{
+       u32 gpio8, gpio5;
+       u32 sfn;
+       int ret;
+
+       switch (id) {
+       case S5P_CAMPORT_A:
+               gpio8 = EXYNOS4_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
+               gpio5 = EXYNOS4_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
+               sfn = S3C_GPIO_SFN(2);
+               break;
+
+       case S5P_CAMPORT_B:
+               gpio8 = EXYNOS4_GPE0(0); /* DATA[0:7] */
+               gpio5 = EXYNOS4_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
+               sfn = S3C_GPIO_SFN(3);
+               break;
+
+       default:
+               WARN(1, "Wrong camport id: %d\n", id);
+               return -EINVAL;
+       }
+
+       ret = s3c_gpio_cfgall_range(gpio8, 8, sfn, S3C_GPIO_PULL_UP);
+       if (ret)
+               return ret;
+
+       return s3c_gpio_cfgall_range(gpio5, 5, sfn, S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-fimd0.c b/arch/arm/mach-exynos/setup-fimd0.c
new file mode 100644 (file)
index 0000000..07a6dbe
--- /dev/null
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-exynos4/setup-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base Exynos4 FIMD 0 configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-fb-v4.h>
+
+#include <mach/map.h>
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+       unsigned int reg;
+
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
+
+       /*
+        * Set DISPLAY_CONTROL register for Display path selection.
+        *
+        * DISPLAY_CONTROL[1:0]
+        * ---------------------
+        *  00 | MIE
+        *  01 | MDINE
+        *  10 | FIMD : selected
+        *  11 | FIMD
+        */
+       reg = __raw_readl(S3C_VA_SYS + 0x0210);
+       reg |= (1 << 1);
+       __raw_writel(reg, S3C_VA_SYS + 0x0210);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c0.c b/arch/arm/mach-exynos/setup-i2c0.c
new file mode 100644 (file)
index 0000000..d395bd1
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c1.c b/arch/arm/mach-exynos/setup-i2c1.c
new file mode 100644 (file)
index 0000000..fd7235a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c1.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C1 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPD1(2), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c2.c b/arch/arm/mach-exynos/setup-i2c2.c
new file mode 100644 (file)
index 0000000..2694b19
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c2.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C2 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c2_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPA0(6), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c3.c b/arch/arm/mach-exynos/setup-i2c3.c
new file mode 100644 (file)
index 0000000..379bd30
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C3 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c3_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c4.c b/arch/arm/mach-exynos/setup-i2c4.c
new file mode 100644 (file)
index 0000000..9f3c048
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C4 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c4_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c5.c b/arch/arm/mach-exynos/setup-i2c5.c
new file mode 100644 (file)
index 0000000..77e1a1e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c5.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C5 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c5_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c6.c b/arch/arm/mach-exynos/setup-i2c6.c
new file mode 100644 (file)
index 0000000..284d12b
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C6 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c6_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
+                             S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c7.c b/arch/arm/mach-exynos/setup-i2c7.c
new file mode 100644 (file)
index 0000000..b7611ee
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C7 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c7_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-keypad.c b/arch/arm/mach-exynos/setup-keypad.c
new file mode 100644 (file)
index 0000000..7862bfb
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-exynos4/setup-keypad.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * GPIO configuration for Exynos4 KeyPad device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
+{
+       /* Keypads can be of various combinations, Just making sure */
+
+       if (rows > 8) {
+               /* Set all the necessary GPX2 pins: KP_ROW[0~7] */
+               s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), 8, S3C_GPIO_SFN(3),
+                                       S3C_GPIO_PULL_UP);
+
+               /* Set all the necessary GPX3 pins: KP_ROW[8~] */
+               s3c_gpio_cfgall_range(EXYNOS4_GPX3(0), (rows - 8),
+                                        S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+       } else {
+               /* Set all the necessary GPX2 pins: KP_ROW[x] */
+               s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), rows, S3C_GPIO_SFN(3),
+                                       S3C_GPIO_PULL_UP);
+       }
+
+       /* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
+       s3c_gpio_cfgrange_nopull(EXYNOS4_GPX1(0), cols, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-exynos/setup-sdhci-gpio.c b/arch/arm/mach-exynos/setup-sdhci-gpio.c
new file mode 100644 (file)
index 0000000..e8d08bf
--- /dev/null
@@ -0,0 +1,152 @@
+/* linux/arch/arm/mach-exynos4/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK0[0:1] pins to special-function 2 */
+       for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       switch (width) {
+       case 8:
+               for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+                       /* Data pin GPK1[3:6] to special-function 3 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       case 4:
+               for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
+                       /* Data pin GPK0[3:6] to special-function 2 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       default:
+               break;
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK1[0:1] pins to special-function 2 */
+       for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+               /* Data pin GPK1[3:6] to special-function 2 */
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK2[0:1] pins to special-function 2 */
+       for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       switch (width) {
+       case 8:
+               for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+                       /* Data pin GPK3[3:6] to special-function 3 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       case 4:
+               for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
+                       /* Data pin GPK2[3:6] to special-function 2 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       default:
+               break;
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK3[0:1] pins to special-function 2 */
+       for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+               /* Data pin GPK3[3:6] to special-function 2 */
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
diff --git a/arch/arm/mach-exynos/setup-sdhci.c b/arch/arm/mach-exynos/setup-sdhci.c
new file mode 100644 (file)
index 0000000..92937b4
--- /dev/null
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/setup-sdhci.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *exynos4_hsmmc_clksrcs[4] = {
+       [0] = NULL,
+       [1] = NULL,
+       [2] = "sclk_mmc",       /* mmc_bus */
+       [3] = NULL,
+};
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
new file mode 100644 (file)
index 0000000..39aca04
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-usb-phy.h>
+#include <plat/cpu.h>
+#include <plat/usb-phy.h>
+
+static int exynos4_usb_phy1_init(struct platform_device *pdev)
+{
+       struct clk *otg_clk;
+       struct clk *xusbxti_clk;
+       u32 phyclk;
+       u32 rstcon;
+       int err;
+
+       otg_clk = clk_get(&pdev->dev, "otg");
+       if (IS_ERR(otg_clk)) {
+               dev_err(&pdev->dev, "Failed to get otg clock\n");
+               return PTR_ERR(otg_clk);
+       }
+
+       err = clk_enable(otg_clk);
+       if (err) {
+               clk_put(otg_clk);
+               return err;
+       }
+
+       writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
+                       S5P_USBHOST_PHY_CONTROL);
+
+       /* set clock frequency for PLL */
+       phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
+
+       xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
+       if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
+               switch (clk_get_rate(xusbxti_clk)) {
+               case 12 * MHZ:
+                       phyclk |= CLKSEL_12M;
+                       break;
+               case 24 * MHZ:
+                       phyclk |= CLKSEL_24M;
+                       break;
+               default:
+               case 48 * MHZ:
+                       /* default reference clock */
+                       break;
+               }
+               clk_put(xusbxti_clk);
+       }
+
+       writel(phyclk, EXYNOS4_PHYCLK);
+
+       /* floating prevention logic: disable */
+       writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
+
+       /* set to normal HSIC 0 and 1 of PHY1 */
+       writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
+                       EXYNOS4_PHYPWR);
+
+       /* set to normal standard USB of PHY1 */
+       writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
+
+       /* reset all ports of both PHY and Link */
+       rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
+               PHY1_SWRST_MASK;
+       writel(rstcon, EXYNOS4_RSTCON);
+       udelay(10);
+
+       rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
+       writel(rstcon, EXYNOS4_RSTCON);
+       udelay(80);
+
+       clk_disable(otg_clk);
+       clk_put(otg_clk);
+
+       return 0;
+}
+
+static int exynos4_usb_phy1_exit(struct platform_device *pdev)
+{
+       struct clk *otg_clk;
+       int err;
+
+       otg_clk = clk_get(&pdev->dev, "otg");
+       if (IS_ERR(otg_clk)) {
+               dev_err(&pdev->dev, "Failed to get otg clock\n");
+               return PTR_ERR(otg_clk);
+       }
+
+       err = clk_enable(otg_clk);
+       if (err) {
+               clk_put(otg_clk);
+               return err;
+       }
+
+       writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
+                       EXYNOS4_PHYPWR);
+
+       writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
+                       S5P_USBHOST_PHY_CONTROL);
+
+       clk_disable(otg_clk);
+       clk_put(otg_clk);
+
+       return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_HOST)
+               return exynos4_usb_phy1_init(pdev);
+
+       return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_HOST)
+               return exynos4_usb_phy1_exit(pdev);
+
+       return -EINVAL;
+}
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
deleted file mode 100644 (file)
index 44013e0..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-# arch/arm/mach-exynos4/Kconfig
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-#              http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-# Configuration options for the EXYNOS4
-
-if ARCH_EXYNOS4
-
-config CPU_EXYNOS4210
-       bool
-       select SAMSUNG_DMADEV
-       select ARM_CPU_SUSPEND if PM
-       help
-         Enable EXYNOS4210 CPU support
-
-config SOC_EXYNOS4212
-       bool
-       help
-         Enable EXYNOS4212 SoC support
-
-config SOC_EXYNOS4412
-       bool
-       help
-         Enable EXYNOS4412 SoC support
-
-config EXYNOS4_MCT
-       bool
-       default y
-       help
-         Use MCT (Multi Core Timer) as kernel timers
-
-config EXYNOS4_DEV_AHCI
-       bool
-       help
-         Compile in platform device definitions for AHCI
-
-config EXYNOS4_SETUP_FIMD0
-       bool
-       help
-         Common setup code for FIMD0.
-
-config EXYNOS4_DEV_PD
-       bool
-       help
-         Compile in platform device definitions for Power Domain
-
-config EXYNOS4_DEV_SYSMMU
-       bool
-       help
-         Common setup code for SYSTEM MMU in EXYNOS4
-
-config EXYNOS4_DEV_DWMCI
-       bool
-       help
-         Compile in platform device definitions for DWMCI
-
-config EXYNOS4_SETUP_I2C1
-       bool
-       help
-         Common setup code for i2c bus 1.
-
-config EXYNOS4_SETUP_I2C2
-       bool
-       help
-         Common setup code for i2c bus 2.
-
-config EXYNOS4_SETUP_I2C3
-       bool
-       help
-         Common setup code for i2c bus 3.
-
-config EXYNOS4_SETUP_I2C4
-       bool
-       help
-         Common setup code for i2c bus 4.
-
-config EXYNOS4_SETUP_I2C5
-       bool
-       help
-         Common setup code for i2c bus 5.
-
-config EXYNOS4_SETUP_I2C6
-       bool
-       help
-         Common setup code for i2c bus 6.
-
-config EXYNOS4_SETUP_I2C7
-       bool
-       help
-         Common setup code for i2c bus 7.
-
-config EXYNOS4_SETUP_KEYPAD
-       bool
-       help
-         Common setup code for keypad.
-
-config EXYNOS4_SETUP_SDHCI
-       bool
-       select EXYNOS4_SETUP_SDHCI_GPIO
-       help
-         Internal helper functions for EXYNOS4 based SDHCI systems.
-
-config EXYNOS4_SETUP_SDHCI_GPIO
-       bool
-       help
-         Common setup code for SDHCI gpio.
-
-config EXYNOS4_SETUP_FIMC
-       bool
-       help
-         Common setup code for the camera interfaces.
-
-config EXYNOS4_SETUP_USB_PHY
-       bool
-       help
-         Common setup code for USB PHY controller
-
-# machine support
-
-menu "EXYNOS4 Machines"
-
-comment "EXYNOS4210 Boards"
-
-config MACH_SMDKC210
-       bool "SMDKC210"
-       select MACH_SMDKV310
-       help
-         Machine support for Samsung SMDKC210
-
-config MACH_SMDKV310
-       bool "SMDKV310"
-       select CPU_EXYNOS4210
-       select S5P_DEV_FIMD0
-       select S3C_DEV_RTC
-       select S3C_DEV_WDT
-       select S3C_DEV_I2C1
-       select S3C_DEV_HSMMC
-       select S3C_DEV_HSMMC1
-       select S3C_DEV_HSMMC2
-       select S3C_DEV_HSMMC3
-       select SAMSUNG_DEV_BACKLIGHT
-       select EXYNOS4_DEV_AHCI
-       select SAMSUNG_DEV_KEYPAD
-       select EXYNOS4_DEV_PD
-       select SAMSUNG_DEV_PWM
-       select EXYNOS4_DEV_SYSMMU
-       select EXYNOS4_SETUP_FIMD0
-       select EXYNOS4_SETUP_I2C1
-       select EXYNOS4_SETUP_KEYPAD
-       select EXYNOS4_SETUP_SDHCI
-       help
-         Machine support for Samsung SMDKV310
-
-config MACH_ARMLEX4210
-       bool "ARMLEX4210"
-       select CPU_EXYNOS4210
-       select S3C_DEV_RTC
-       select S3C_DEV_WDT
-       select S3C_DEV_HSMMC
-       select S3C_DEV_HSMMC2
-       select S3C_DEV_HSMMC3
-       select EXYNOS4_DEV_AHCI
-       select EXYNOS4_DEV_SYSMMU
-       select EXYNOS4_SETUP_SDHCI
-       help
-         Machine support for Samsung ARMLEX4210 based on EXYNOS4210
-
-config MACH_UNIVERSAL_C210
-       bool "Mobile UNIVERSAL_C210 Board"
-       select CPU_EXYNOS4210
-       select S5P_GPIO_INT
-       select S5P_DEV_FIMC0
-       select S5P_DEV_FIMC1
-       select S5P_DEV_FIMC2
-       select S5P_DEV_FIMC3
-       select S3C_DEV_HSMMC
-       select S3C_DEV_HSMMC2
-       select S3C_DEV_HSMMC3
-       select S3C_DEV_I2C1
-       select S3C_DEV_I2C3
-       select S3C_DEV_I2C5
-       select S5P_DEV_MFC
-       select S5P_DEV_ONENAND
-       select EXYNOS4_DEV_PD
-       select EXYNOS4_SETUP_I2C1
-       select EXYNOS4_SETUP_I2C3
-       select EXYNOS4_SETUP_I2C5
-       select EXYNOS4_SETUP_SDHCI
-       help
-         Machine support for Samsung Mobile Universal S5PC210 Reference
-         Board.
-
-config MACH_NURI
-       bool "Mobile NURI Board"
-       select CPU_EXYNOS4210
-       select S3C_DEV_WDT
-       select S3C_DEV_HSMMC
-       select S3C_DEV_HSMMC2
-       select S3C_DEV_HSMMC3
-       select S3C_DEV_I2C1
-       select S3C_DEV_I2C3
-       select S3C_DEV_I2C5
-       select S5P_DEV_MFC
-       select S5P_DEV_USB_EHCI
-       select EXYNOS4_DEV_PD
-       select EXYNOS4_SETUP_I2C1
-       select EXYNOS4_SETUP_I2C3
-       select EXYNOS4_SETUP_I2C5
-       select EXYNOS4_SETUP_SDHCI
-       select EXYNOS4_SETUP_USB_PHY
-       select SAMSUNG_DEV_PWM
-       select SAMSUNG_DEV_ADC
-       help
-         Machine support for Samsung Mobile NURI Board.
-
-config MACH_ORIGEN
-       bool "ORIGEN"
-       select CPU_EXYNOS4210
-       select S3C_DEV_RTC
-       select S3C_DEV_WDT
-       select S3C_DEV_HSMMC2
-       select EXYNOS4_SETUP_SDHCI
-       help
-         Machine support for ORIGEN based on Samsung EXYNOS4210
-
-comment "EXYNOS4212 Boards"
-
-config MACH_SMDK4212
-       bool "SMDK4212"
-       select SOC_EXYNOS4212
-       select S3C_DEV_HSMMC2
-       select S3C_DEV_HSMMC3
-       select S3C_DEV_I2C1
-       select S3C_DEV_I2C3
-       select S3C_DEV_I2C7
-       select S3C_DEV_RTC
-       select S3C_DEV_WDT
-       select SAMSUNG_DEV_BACKLIGHT
-       select SAMSUNG_DEV_KEYPAD
-       select SAMSUNG_DEV_PWM
-       select EXYNOS4_SETUP_I2C1
-       select EXYNOS4_SETUP_I2C3
-       select EXYNOS4_SETUP_I2C7
-       select EXYNOS4_SETUP_KEYPAD
-       select EXYNOS4_SETUP_SDHCI
-       help
-         Machine support for Samsung SMDK4212
-
-comment "EXYNOS4412 Boards"
-
-config MACH_SMDK4412
-       bool "SMDK4412"
-       select SOC_EXYNOS4412
-       select MACH_SMDK4212
-       help
-         Machine support for Samsung SMDK4412
-
-endmenu
-
-comment "Configuration for HSMMC bus width"
-
-menu "Use 8-bit bus width"
-
-config EXYNOS4_SDHCI_CH0_8BIT
-       bool "Channel 0 with 8-bit bus"
-       help
-         Support HSMMC Channel 0 8-bit bus.
-         If selected, Channel 1 is disabled.
-
-config EXYNOS4_SDHCI_CH2_8BIT
-       bool "Channel 2 with 8-bit bus"
-       help
-         Support HSMMC Channel 2 8-bit bus.
-         If selected, Channel 3 is disabled.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
deleted file mode 100644 (file)
index c9b2e1f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-# arch/arm/mach-exynos4/Makefile
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-#              http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-obj-y                          :=
-obj-m                          :=
-obj-n                          :=
-obj-                           :=
-
-# Core support for EXYNOS4 system
-
-obj-$(CONFIG_ARCH_EXYNOS4)     += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_ARCH_EXYNOS4)     += setup-i2c0.o irq-eint.o dma.o pmu.o
-obj-$(CONFIG_CPU_EXYNOS4210)   += clock-exynos4210.o
-obj-$(CONFIG_SOC_EXYNOS4212)   += clock-exynos4212.o
-obj-$(CONFIG_PM)               += pm.o sleep.o
-obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
-
-obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
-
-obj-$(CONFIG_EXYNOS4_MCT)      += mct.o
-
-obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
-
-# machine support
-
-obj-$(CONFIG_MACH_SMDKC210)            += mach-smdkv310.o
-obj-$(CONFIG_MACH_SMDKV310)            += mach-smdkv310.o
-obj-$(CONFIG_MACH_ARMLEX4210)          += mach-armlex4210.o
-obj-$(CONFIG_MACH_UNIVERSAL_C210)      += mach-universal_c210.o
-obj-$(CONFIG_MACH_NURI)                        += mach-nuri.o
-obj-$(CONFIG_MACH_ORIGEN)              += mach-origen.o
-
-obj-$(CONFIG_MACH_SMDK4212)            += mach-smdk4x12.o
-obj-$(CONFIG_MACH_SMDK4412)            += mach-smdk4x12.o
-
-# device support
-
-obj-y                                  += dev-audio.o
-obj-$(CONFIG_EXYNOS4_DEV_AHCI)         += dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_PD)           += dev-pd.o
-obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)       += dev-sysmmu.o
-obj-$(CONFIG_EXYNOS4_DEV_DWMCI)        += dev-dwmci.o
-
-obj-$(CONFIG_EXYNOS4_SETUP_FIMC)       += setup-fimc.o
-obj-$(CONFIG_EXYNOS4_SETUP_FIMD0)      += setup-fimd0.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C1)       += setup-i2c1.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C2)       += setup-i2c2.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C3)       += setup-i2c3.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C4)       += setup-i2c4.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C5)       += setup-i2c5.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C6)       += setup-i2c6.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C7)       += setup-i2c7.o
-obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)     += setup-keypad.o
-obj-$(CONFIG_EXYNOS4_SETUP_SDHCI)      += setup-sdhci.o
-obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
-
-obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)    += setup-usb-phy.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot
deleted file mode 100644 (file)
index b9862e2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-   zreladdr-y  += 0x40008000
-params_phys-y  := 0x40000100
diff --git a/arch/arm/mach-exynos4/clock-exynos4210.c b/arch/arm/mach-exynos4/clock-exynos4210.c
deleted file mode 100644 (file)
index b9d5ef6..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/clock-exynos4210.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4210 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/exynos4.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/exynos4-clock.h>
-
-static struct sleep_save exynos4210_clock_save[] = {
-       SAVE_ITEM(S5P_CLKSRC_IMAGE),
-       SAVE_ITEM(S5P_CLKSRC_LCD1),
-       SAVE_ITEM(S5P_CLKDIV_IMAGE),
-       SAVE_ITEM(S5P_CLKDIV_LCD1),
-       SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
-       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4210),
-       SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4210),
-};
-
-static struct clksrc_clk *sysclks[] = {
-       /* nothing here yet */
-};
-
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk            = {
-                       .name           = "sclk_sata",
-                       .id             = -1,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_mout_corebus,
-               .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimd",
-                       .devname        = "exynos4-fb.1",
-                       .enable         = exynos4_clksrc_mask_lcd1_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
-       },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "sataphy",
-               .id             = -1,
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "sata",
-               .id             = -1,
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "fimd",
-               .devname        = "exynos4-fb.1",
-               .enable         = exynos4_clk_ip_lcd1_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4210_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-
-       return 0;
-}
-
-static void exynos4210_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-}
-
-#else
-#define exynos4210_clock_suspend NULL
-#define exynos4210_clock_resume NULL
-#endif
-
-struct syscore_ops exynos4210_clock_syscore_ops = {
-       .suspend        = exynos4210_clock_suspend,
-       .resume         = exynos4210_clock_resume,
-};
-
-void __init exynos4210_register_clocks(void)
-{
-       int ptr;
-
-       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_CPU;
-       clk_mout_mpll.reg_src.shift = 8;
-       clk_mout_mpll.reg_src.size = 1;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       register_syscore_ops(&exynos4210_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos4/clock-exynos4212.c b/arch/arm/mach-exynos4/clock-exynos4212.c
deleted file mode 100644 (file)
index 77d5dec..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/clock-exynos4212.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4212 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/exynos4.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/exynos4-clock.h>
-
-static struct sleep_save exynos4212_clock_save[] = {
-       SAVE_ITEM(S5P_CLKSRC_IMAGE),
-       SAVE_ITEM(S5P_CLKDIV_IMAGE),
-       SAVE_ITEM(S5P_CLKGATE_IP_IMAGE_4212),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIR_4212),
-};
-
-static struct clk *clk_src_mpll_user_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clk_src_mpll_user = {
-       .sources        = clk_src_mpll_user_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_mpll_user_list),
-};
-
-static struct clksrc_clk clk_mout_mpll_user = {
-       .clk = {
-               .name           = "mout_mpll_user",
-       },
-       .sources        = &clk_src_mpll_user,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 24, .size = 1 },
-};
-
-static struct clksrc_clk *sysclks[] = {
-       &clk_mout_mpll_user,
-};
-
-static struct clksrc_clk clksrcs[] = {
-       /* nothing here yet */
-};
-
-static struct clk init_clocks_off[] = {
-       /* nothing here yet */
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4212_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-
-       return 0;
-}
-
-static void exynos4212_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-}
-
-#else
-#define exynos4212_clock_suspend NULL
-#define exynos4212_clock_resume NULL
-#endif
-
-struct syscore_ops exynos4212_clock_syscore_ops = {
-       .suspend        = exynos4212_clock_suspend,
-       .resume         = exynos4212_clock_resume,
-};
-
-void __init exynos4212_register_clocks(void)
-{
-       int ptr;
-
-       /* usbphy1 is removed */
-       clkset_group_list[4] = NULL;
-
-       /* mout_mpll_user is used */
-       clkset_group_list[6] = &clk_mout_mpll_user.clk;
-       clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
-
-       clk_mout_mpll.reg_src.reg = S5P_CLKSRC_DMC;
-       clk_mout_mpll.reg_src.shift = 12;
-       clk_mout_mpll.reg_src.size = 1;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       register_syscore_ops(&exynos4212_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
deleted file mode 100644 (file)
index e21952d..0000000
+++ /dev/null
@@ -1,1296 +0,0 @@
-/* linux/arch/arm/mach-exynos4/clock.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/exynos4.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-#include <mach/exynos4-clock.h>
-
-static struct sleep_save exynos4_clock_save[] = {
-       SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
-       SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
-       SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
-       SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
-       SAVE_ITEM(S5P_CLKSRC_TOP0),
-       SAVE_ITEM(S5P_CLKSRC_TOP1),
-       SAVE_ITEM(S5P_CLKSRC_CAM),
-       SAVE_ITEM(S5P_CLKSRC_TV),
-       SAVE_ITEM(S5P_CLKSRC_MFC),
-       SAVE_ITEM(S5P_CLKSRC_G3D),
-       SAVE_ITEM(S5P_CLKSRC_LCD0),
-       SAVE_ITEM(S5P_CLKSRC_MAUDIO),
-       SAVE_ITEM(S5P_CLKSRC_FSYS),
-       SAVE_ITEM(S5P_CLKSRC_PERIL0),
-       SAVE_ITEM(S5P_CLKSRC_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV_CAM),
-       SAVE_ITEM(S5P_CLKDIV_TV),
-       SAVE_ITEM(S5P_CLKDIV_MFC),
-       SAVE_ITEM(S5P_CLKDIV_G3D),
-       SAVE_ITEM(S5P_CLKDIV_LCD0),
-       SAVE_ITEM(S5P_CLKDIV_MAUDIO),
-       SAVE_ITEM(S5P_CLKDIV_FSYS0),
-       SAVE_ITEM(S5P_CLKDIV_FSYS1),
-       SAVE_ITEM(S5P_CLKDIV_FSYS2),
-       SAVE_ITEM(S5P_CLKDIV_FSYS3),
-       SAVE_ITEM(S5P_CLKDIV_PERIL0),
-       SAVE_ITEM(S5P_CLKDIV_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV_PERIL2),
-       SAVE_ITEM(S5P_CLKDIV_PERIL3),
-       SAVE_ITEM(S5P_CLKDIV_PERIL4),
-       SAVE_ITEM(S5P_CLKDIV_PERIL5),
-       SAVE_ITEM(S5P_CLKDIV_TOP),
-       SAVE_ITEM(S5P_CLKSRC_MASK_TOP),
-       SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
-       SAVE_ITEM(S5P_CLKSRC_MASK_TV),
-       SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
-       SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
-       SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
-       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
-       SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
-       SAVE_ITEM(S5P_CLKDIV2_RATIO),
-       SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
-       SAVE_ITEM(S5P_CLKGATE_IP_CAM),
-       SAVE_ITEM(S5P_CLKGATE_IP_TV),
-       SAVE_ITEM(S5P_CLKGATE_IP_MFC),
-       SAVE_ITEM(S5P_CLKGATE_IP_G3D),
-       SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
-       SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
-       SAVE_ITEM(S5P_CLKGATE_IP_GPS),
-       SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
-       SAVE_ITEM(S5P_CLKGATE_BLOCK),
-       SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
-       SAVE_ITEM(S5P_CLKSRC_DMC),
-       SAVE_ITEM(S5P_CLKDIV_DMC0),
-       SAVE_ITEM(S5P_CLKDIV_DMC1),
-       SAVE_ITEM(S5P_CLKGATE_IP_DMC),
-       SAVE_ITEM(S5P_CLKSRC_CPU),
-       SAVE_ITEM(S5P_CLKDIV_CPU),
-       SAVE_ITEM(S5P_CLKDIV_CPU + 0x4),
-       SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
-       SAVE_ITEM(S5P_CLKGATE_IP_CPU),
-};
-
-struct clk clk_sclk_hdmi27m = {
-       .name           = "sclk_hdmi27m",
-       .rate           = 27000000,
-};
-
-struct clk clk_sclk_hdmiphy = {
-       .name           = "sclk_hdmiphy",
-};
-
-struct clk clk_sclk_usbphy0 = {
-       .name           = "sclk_usbphy0",
-       .rate           = 27000000,
-};
-
-struct clk clk_sclk_usbphy1 = {
-       .name           = "sclk_usbphy1",
-};
-
-static struct clk dummy_apb_pclk = {
-       .name           = "apb_pclk",
-       .id             = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
-}
-
-int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
-}
-
-int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-       },
-       .sources        = &clk_src_apll,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-struct clksrc_clk clk_sclk_apll = {
-       .clk    = {
-               .name           = "sclk_apll",
-               .parent         = &clk_mout_apll.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-       },
-       .sources        = &clk_src_epll,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
-       },
-       .sources        = &clk_src_mpll,
-
-       /* reg_src will be added in each SoCs' clock */
-};
-
-static struct clk *clkset_moutcore_list[] = {
-       [0] = &clk_mout_apll.clk,
-       [1] = &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_moutcore = {
-       .sources        = clkset_moutcore_list,
-       .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
-};
-
-static struct clksrc_clk clk_moutcore = {
-       .clk    = {
-               .name           = "moutcore",
-       },
-       .sources        = &clkset_moutcore,
-       .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk clk_coreclk = {
-       .clk    = {
-               .name           = "core_clk",
-               .parent         = &clk_moutcore.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_armclk = {
-       .clk    = {
-               .name           = "armclk",
-               .parent         = &clk_coreclk.clk,
-       },
-};
-
-static struct clksrc_clk clk_aclk_corem0 = {
-       .clk    = {
-               .name           = "aclk_corem0",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cores = {
-       .clk    = {
-               .name           = "aclk_cores",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corem1 = {
-       .clk    = {
-               .name           = "aclk_corem1",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk clk_periphclk = {
-       .clk    = {
-               .name           = "periphclk",
-               .parent         = &clk_coreclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-struct clk *clkset_corebus_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-struct clksrc_sources clkset_mout_corebus = {
-       .sources        = clkset_corebus_list,
-       .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
-};
-
-static struct clksrc_clk clk_mout_corebus = {
-       .clk    = {
-               .name           = "mout_corebus",
-       },
-       .sources        = &clkset_mout_corebus,
-       .reg_src        = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_sclk_dmc = {
-       .clk    = {
-               .name           = "sclk_dmc",
-               .parent         = &clk_mout_corebus.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cored = {
-       .clk    = {
-               .name           = "aclk_cored",
-               .parent         = &clk_sclk_dmc.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corep = {
-       .clk    = {
-               .name           = "aclk_corep",
-               .parent         = &clk_aclk_cored.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_acp = {
-       .clk    = {
-               .name           = "aclk_acp",
-               .parent         = &clk_mout_corebus.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_pclk_acp = {
-       .clk    = {
-               .name           = "pclk_acp",
-               .parent         = &clk_aclk_acp.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-struct clk *clkset_aclk_top_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-struct clksrc_sources clkset_aclk = {
-       .sources        = clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
-static struct clksrc_clk clk_aclk_200 = {
-       .clk    = {
-               .name           = "aclk_200",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_100 = {
-       .clk    = {
-               .name           = "aclk_100",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk clk_aclk_160 = {
-       .clk    = {
-               .name           = "aclk_160",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-struct clksrc_clk clk_aclk_133 = {
-       .clk    = {
-               .name           = "aclk_133",
-       },
-       .sources        = &clkset_aclk,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
-       .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *clkset_vpllsrc_list[] = {
-       [0] = &clk_fin_vpll,
-       [1] = &clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources clkset_vpllsrc = {
-       .sources        = clkset_vpllsrc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk clk_vpllsrc = {
-       .clk    = {
-               .name           = "vpll_src",
-               .enable         = exynos4_clksrc_mask_top_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources        = &clkset_vpllsrc,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_sclk_vpll_list[] = {
-       [0] = &clk_vpllsrc.clk,
-       [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources clkset_sclk_vpll = {
-       .sources        = clkset_sclk_vpll_list,
-       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
-};
-
-struct clksrc_clk clk_sclk_vpll = {
-       .clk    = {
-               .name           = "sclk_vpll",
-       },
-       .sources        = &clkset_sclk_vpll,
-       .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "timers",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1<<24),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.2",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "fimd",
-               .devname        = "exynos4-fb.0",
-               .enable         = exynos4_clk_ip_lcd0_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.0",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.1",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.2",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "s3c-sdhci.3",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "dwmmc",
-               .parent         = &clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "dma",
-               .devname        = "s3c-pl330.0",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "dma",
-               .devname        = "s3c-pl330.1",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "adc",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "keypad",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "rtc",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "watchdog",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "usbhost",
-               .enable         = exynos4_clk_ip_fsys_ctrl ,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "otg",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 17),
-       }, {
-               .name           = "spi",
-               .devname        = "s3c64xx-spi.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 19),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 20),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "ac97",
-               .devname        = "samsung-ac97",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 27),
-       }, {
-               .name           = "fimg2d",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "mfc",
-               .devname        = "s5p-mfc",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.0",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.1",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.2",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.3",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.4",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.5",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.6",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.7",
-               .parent         = &clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "SYSMMU_MDMA",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "SYSMMU_FIMC0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "SYSMMU_FIMC1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "SYSMMU_FIMC2",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "SYSMMU_FIMC3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "SYSMMU_JPEG",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "SYSMMU_FIMD0",
-               .enable         = exynos4_clk_ip_lcd0_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_FIMD1",
-               .enable         = exynos4_clk_ip_lcd1_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_PCIe",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "SYSMMU_G2D",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "SYSMMU_ROTATOR",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_TV",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "SYSMMU_MFC_L",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "SYSMMU_MFC_R",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 2),
-       }
-};
-
-static struct clk init_clocks[] = {
-       {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.3",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.4",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.5",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 5),
-       }
-};
-
-struct clk *clkset_group_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = &clk_xusbxti,
-       [2] = &clk_sclk_hdmi27m,
-       [3] = &clk_sclk_usbphy0,
-       [4] = &clk_sclk_usbphy1,
-       [5] = &clk_sclk_hdmiphy,
-       [6] = &clk_mout_mpll.clk,
-       [7] = &clk_mout_epll.clk,
-       [8] = &clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources clkset_group = {
-       .sources        = clkset_group_list,
-       .nr_sources     = ARRAY_SIZE(clkset_group_list),
-};
-
-static struct clk *clkset_mout_g2d0_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d0 = {
-       .sources        = clkset_mout_g2d0_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
-};
-
-static struct clksrc_clk clk_mout_g2d0 = {
-       .clk    = {
-               .name           = "mout_g2d0",
-       },
-       .sources        = &clkset_mout_g2d0,
-       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d1_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d1 = {
-       .sources        = clkset_mout_g2d1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
-};
-
-static struct clksrc_clk clk_mout_g2d1 = {
-       .clk    = {
-               .name           = "mout_g2d1",
-       },
-       .sources        = &clkset_mout_g2d1,
-       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d_list[] = {
-       [0] = &clk_mout_g2d0.clk,
-       [1] = &clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d = {
-       .sources        = clkset_mout_g2d_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
-};
-
-static struct clk *clkset_mout_mfc0_list[] = {
-       [0] = &clk_mout_mpll.clk,
-       [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc0 = {
-       .sources        = clkset_mout_mfc0_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc0_list),
-};
-
-static struct clksrc_clk clk_mout_mfc0 = {
-       .clk    = {
-               .name           = "mout_mfc0",
-       },
-       .sources        = &clkset_mout_mfc0,
-       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_mout_mfc1_list[] = {
-       [0] = &clk_mout_epll.clk,
-       [1] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc1 = {
-       .sources        = clkset_mout_mfc1_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc1_list),
-};
-
-static struct clksrc_clk clk_mout_mfc1 = {
-       .clk    = {
-               .name           = "mout_mfc1",
-       },
-       .sources        = &clkset_mout_mfc1,
-       .reg_src        = { .reg = S5P_CLKSRC_MFC, .shift = 4, .size = 1 },
-};
-
-static struct clk *clkset_mout_mfc_list[] = {
-       [0] = &clk_mout_mfc0.clk,
-       [1] = &clk_mout_mfc1.clk,
-};
-
-static struct clksrc_sources clkset_mout_mfc = {
-       .sources        = clkset_mout_mfc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_mout_mfc_list),
-};
-
-static struct clksrc_clk clk_dout_mmc0 = {
-       .clk            = {
-               .name           = "dout_mmc0",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc1 = {
-       .clk            = {
-               .name           = "dout_mmc1",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc2 = {
-       .clk            = {
-               .name           = "dout_mmc2",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc3 = {
-       .clk            = {
-               .name           = "dout_mmc3",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc4 = {
-       .clk            = {
-               .name           = "dout_mmc4",
-       },
-       .sources = &clkset_group,
-       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
-       .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "uclk1",
-                       .devname        = "s5pv210-uart.0",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "uclk1",
-                       .devname        = "s5pv210-uart.1",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 4),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "uclk1",
-                       .devname        = "s5pv210-uart.2",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 8),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "uclk1",
-                       .devname        = "s5pv210-uart.3",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 12),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_pwm",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 28),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_cam0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_cam1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 20),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 4),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.2",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 8),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.3",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 12),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimd",
-                       .devname        = "exynos4-fb.0",
-                       .enable         = exynos4_clksrc_mask_lcd0_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_spi",
-                       .devname        = "s3c64xx-spi.0",
-                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_spi",
-                       .devname        = "s3c64xx-spi.1",
-                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
-                       .ctrlbit        = (1 << 20),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_spi",
-                       .devname        = "s3c64xx-spi.2",
-                       .enable         = exynos4_clksrc_mask_peril1_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &clkset_group,
-               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
-               .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimg2d",
-               },
-               .sources = &clkset_mout_g2d,
-               .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mfc",
-                       .devname        = "s5p-mfc",
-               },
-               .sources = &clkset_mout_mfc,
-               .reg_src = { .reg = S5P_CLKSRC_MFC, .shift = 8, .size = 1 },
-               .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mmc",
-                       .devname        = "s3c-sdhci.0",
-                       .parent         = &clk_dout_mmc0.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mmc",
-                       .devname        = "s3c-sdhci.1",
-                       .parent         = &clk_dout_mmc1.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 4),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mmc",
-                       .devname        = "s3c-sdhci.2",
-                       .parent         = &clk_dout_mmc2.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 8),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_mmc",
-                       .devname        = "s3c-sdhci.3",
-                       .parent         = &clk_dout_mmc3.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 12),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_dwmmc",
-                       .parent         = &clk_dout_mmc4.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
-       }
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *sysclks[] = {
-       &clk_mout_apll,
-       &clk_sclk_apll,
-       &clk_mout_epll,
-       &clk_mout_mpll,
-       &clk_moutcore,
-       &clk_coreclk,
-       &clk_armclk,
-       &clk_aclk_corem0,
-       &clk_aclk_cores,
-       &clk_aclk_corem1,
-       &clk_periphclk,
-       &clk_mout_corebus,
-       &clk_sclk_dmc,
-       &clk_aclk_cored,
-       &clk_aclk_corep,
-       &clk_aclk_acp,
-       &clk_pclk_acp,
-       &clk_vpllsrc,
-       &clk_sclk_vpll,
-       &clk_aclk_200,
-       &clk_aclk_100,
-       &clk_aclk_160,
-       &clk_aclk_133,
-       &clk_dout_mmc0,
-       &clk_dout_mmc1,
-       &clk_dout_mmc2,
-       &clk_dout_mmc3,
-       &clk_dout_mmc4,
-       &clk_mout_mfc0,
-       &clk_mout_mfc1,
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
-       if (soc_is_exynos4210())
-               return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0),
-                                       pll_4508);
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               return s5p_get_pll35xx(xtal_rate, __raw_readl(S5P_APLL_CON0));
-       else
-               return 0;
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
-       .get_rate = exynos4_fout_apll_get_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long apll = 0;
-       unsigned long mpll = 0;
-       unsigned long epll = 0;
-       unsigned long vpll = 0;
-       unsigned long vpllsrc;
-       unsigned long xtal;
-       unsigned long armclk;
-       unsigned long sclk_dmc;
-       unsigned long aclk_200;
-       unsigned long aclk_100;
-       unsigned long aclk_160;
-       unsigned long aclk_133;
-       unsigned int ptr;
-
-       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-       xtal_clk = clk_get(NULL, "xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-
-       xtal_rate = xtal;
-
-       clk_put(xtal_clk);
-
-       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-       if (soc_is_exynos4210()) {
-               apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0),
-                                       pll_4508);
-               mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0),
-                                       pll_4508);
-               epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
-                                       __raw_readl(S5P_EPLL_CON1), pll_4600);
-
-               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
-               vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
-                                       __raw_readl(S5P_VPLL_CON1), pll_4650c);
-       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
-               apll = s5p_get_pll35xx(xtal, __raw_readl(S5P_APLL_CON0));
-               mpll = s5p_get_pll35xx(xtal, __raw_readl(S5P_MPLL_CON0));
-               epll = s5p_get_pll36xx(xtal, __raw_readl(S5P_EPLL_CON0),
-                                       __raw_readl(S5P_EPLL_CON1));
-
-               vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
-               vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
-                                       __raw_readl(S5P_VPLL_CON1));
-       } else {
-               /* nothing */
-       }
-
-       clk_fout_apll.ops = &exynos4_fout_apll_ops;
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_vpll.rate = vpll;
-
-       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
-                       apll, mpll, epll, vpll);
-
-       armclk = clk_get_rate(&clk_armclk.clk);
-       sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
-
-       aclk_200 = clk_get_rate(&clk_aclk_200.clk);
-       aclk_100 = clk_get_rate(&clk_aclk_100.clk);
-       aclk_160 = clk_get_rate(&clk_aclk_160.clk);
-       aclk_133 = clk_get_rate(&clk_aclk_133.clk);
-
-       printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
-                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
-                       armclk, sclk_dmc, aclk_200,
-                       aclk_100, aclk_160, aclk_133);
-
-       clk_f.rate = armclk;
-       clk_h.rate = sclk_dmc;
-       clk_p.rate = aclk_100;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-               s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks[] __initdata = {
-       /* Nothing here yet */
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-       return 0;
-}
-
-static void exynos4_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-}
-
-#else
-#define exynos4_clock_suspend NULL
-#define exynos4_clock_resume NULL
-#endif
-
-struct syscore_ops exynos4_clock_syscore_ops = {
-       .suspend        = exynos4_clock_suspend,
-       .resume         = exynos4_clock_resume,
-};
-
-void __init exynos4_register_clocks(void)
-{
-       int ptr;
-
-       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-<<<<<<< HEAD
-       register_syscore_ops(&exynos4_clock_syscore_ops);
-=======
-       s3c24xx_register_clock(&dummy_apb_pclk);
-
->>>>>>> 4598fc2c94b68740e0269db03c98a1e7ad5af773
-       s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
deleted file mode 100644 (file)
index a348434..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/* linux/arch/arm/mach-exynos4/cpu.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/sched.h>
-#include <linux/sysdev.h>
-
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/proc-fns.h>
-#include <asm/hardware/cache-l2x0.h>
-#include <asm/hardware/gic.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/devs.h>
-#include <plat/exynos4.h>
-#include <plat/adc-core.h>
-#include <plat/sdhci.h>
-#include <plat/fb-core.h>
-#include <plat/fimc-core.h>
-#include <plat/iic-core.h>
-#include <plat/reset.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-pmu.h>
-
-unsigned int gic_bank_offset __read_mostly;
-
-extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
-                        unsigned int irq_start);
-extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
-
-/* Initial IO mappings */
-static struct map_desc exynos4_iodesc[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_CMU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_CMU),
-               .length         = SZ_128K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_PMU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_PMU),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_COMBINER_BASE,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_COMBINER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_COREPERI_BASE,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_COREPERI),
-               .length         = SZ_8K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_L2CC,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_L2CC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO1,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO1),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO2,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO2),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO3,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GPIO3),
-               .length         = SZ_256,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_DMC0,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_DMC0),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_UART,
-               .pfn            = __phys_to_pfn(S3C_PA_UART),
-               .length         = SZ_512K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SROMC,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SROMC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_HSPHY),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_CPU,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_GIC_DIST,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
-               .length         = SZ_64K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4_iodesc0[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static struct map_desc exynos4_iodesc1[] __initdata = {
-       {
-               .virtual        = (unsigned long)S5P_VA_SYSRAM,
-               .pfn            = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       },
-};
-
-static void exynos4_idle(void)
-{
-       if (!need_resched())
-               cpu_do_idle();
-
-       local_irq_enable();
-}
-
-static void exynos4_sw_reset(void)
-{
-       __raw_writel(0x1, S5P_SWRESET);
-}
-
-/*
- * exynos4_map_io
- *
- * register the standard cpu IO areas
- */
-void __init exynos4_map_io(void)
-{
-       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-
-       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
-               iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
-       else
-               iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
-
-       /* initialize device information early */
-       exynos4_default_sdhci0();
-       exynos4_default_sdhci1();
-       exynos4_default_sdhci2();
-       exynos4_default_sdhci3();
-
-       s3c_adc_setname("samsung-adc-v3");
-
-       s3c_fimc_setname(0, "exynos4-fimc");
-       s3c_fimc_setname(1, "exynos4-fimc");
-       s3c_fimc_setname(2, "exynos4-fimc");
-       s3c_fimc_setname(3, "exynos4-fimc");
-
-       /* The I2C bus controllers are directly compatible with s3c2440 */
-       s3c_i2c0_setname("s3c2440-i2c");
-       s3c_i2c1_setname("s3c2440-i2c");
-       s3c_i2c2_setname("s3c2440-i2c");
-
-       s5p_fb_setname(0, "exynos4-fb");
-}
-
-void __init exynos4_init_clocks(int xtal)
-{
-       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
-       s3c24xx_register_baseclocks(xtal);
-       s5p_register_clocks(xtal);
-
-       if (soc_is_exynos4210())
-               exynos4210_register_clocks();
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               exynos4212_register_clocks();
-
-       exynos4_register_clocks();
-       exynos4_setup_clocks();
-}
-
-static void exynos4_gic_irq_fix_base(struct irq_data *d)
-{
-       struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
-
-       gic_data->cpu_base = S5P_VA_GIC_CPU +
-                           (gic_bank_offset * smp_processor_id());
-
-       gic_data->dist_base = S5P_VA_GIC_DIST +
-                           (gic_bank_offset * smp_processor_id());
-}
-
-void __init exynos4_init_irq(void)
-{
-       int irq;
-
-       gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
-
-       gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
-       gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base;
-       gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
-       gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base;
-
-       for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
-
-               combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
-                               COMBINER_IRQ(irq, 0));
-               combiner_cascade_irq(irq, IRQ_SPI(irq));
-       }
-
-       /* The parameters of s5p_init_irq() are for VIC init.
-        * Theses parameters should be NULL and 0 because EXYNOS4
-        * uses GIC instead of VIC.
-        */
-       s5p_init_irq(NULL, 0);
-}
-
-struct sysdev_class exynos4_sysclass = {
-       .name   = "exynos4-core",
-};
-
-static struct sys_device exynos4_sysdev = {
-       .cls    = &exynos4_sysclass,
-};
-
-static int __init exynos4_core_init(void)
-{
-       return sysdev_class_register(&exynos4_sysclass);
-}
-
-core_initcall(exynos4_core_init);
-
-#ifdef CONFIG_CACHE_L2X0
-static int __init exynos4_l2x0_cache_init(void)
-{
-       /* TAG, Data Latency Control: 2cycle */
-       __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
-
-       if (soc_is_exynos4210())
-               __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
-
-       /* L2X0 Prefetch Control */
-       __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
-
-       /* L2X0 Power Control */
-       __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
-                    S5P_VA_L2CC + L2X0_POWER_CTRL);
-
-       l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
-
-       return 0;
-}
-
-early_initcall(exynos4_l2x0_cache_init);
-#endif
-
-int __init exynos4_init(void)
-{
-       printk(KERN_INFO "EXYNOS4: Initializing architecture\n");
-
-       /* set idle function */
-       pm_idle = exynos4_idle;
-
-       /* set sw_reset function */
-       s5p_reset_hook = exynos4_sw_reset;
-
-       return sysdev_register(&exynos4_sysdev);
-}
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
deleted file mode 100644 (file)
index bf7e96f..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* linux/arch/arm/mach-exynos4/cpuidle.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/cpuidle.h>
-#include <linux/io.h>
-
-#include <asm/proc-fns.h>
-
-static int exynos4_enter_idle(struct cpuidle_device *dev,
-                             struct cpuidle_state *state);
-
-static struct cpuidle_state exynos4_cpuidle_set[] = {
-       [0] = {
-               .enter                  = exynos4_enter_idle,
-               .exit_latency           = 1,
-               .target_residency       = 100000,
-               .flags                  = CPUIDLE_FLAG_TIME_VALID,
-               .name                   = "IDLE",
-               .desc                   = "ARM clock gating(WFI)",
-       },
-};
-
-static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
-
-static struct cpuidle_driver exynos4_idle_driver = {
-       .name           = "exynos4_idle",
-       .owner          = THIS_MODULE,
-};
-
-static int exynos4_enter_idle(struct cpuidle_device *dev,
-                             struct cpuidle_state *state)
-{
-       struct timeval before, after;
-       int idle_time;
-
-       local_irq_disable();
-       do_gettimeofday(&before);
-
-       cpu_do_idle();
-
-       do_gettimeofday(&after);
-       local_irq_enable();
-       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
-                   (after.tv_usec - before.tv_usec);
-
-       return idle_time;
-}
-
-static int __init exynos4_init_cpuidle(void)
-{
-       int i, max_cpuidle_state, cpu_id;
-       struct cpuidle_device *device;
-
-       cpuidle_register_driver(&exynos4_idle_driver);
-
-       for_each_cpu(cpu_id, cpu_online_mask) {
-               device = &per_cpu(exynos4_cpuidle_device, cpu_id);
-               device->cpu = cpu_id;
-
-               device->state_count = (sizeof(exynos4_cpuidle_set) /
-                                              sizeof(struct cpuidle_state));
-
-               max_cpuidle_state = device->state_count;
-
-               for (i = 0; i < max_cpuidle_state; i++) {
-                       memcpy(&device->states[i], &exynos4_cpuidle_set[i],
-                                       sizeof(struct cpuidle_state));
-               }
-
-               if (cpuidle_register_device(device)) {
-                       printk(KERN_ERR "CPUidle register device failed\n,");
-                       return -EIO;
-               }
-       }
-       return 0;
-}
-device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos4/dev-ahci.c b/arch/arm/mach-exynos4/dev-ahci.c
deleted file mode 100644 (file)
index f57a3de..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-ahci.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - AHCI support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/ahci_platform.h>
-
-#include <plat/cpu.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/regs-pmu.h>
-
-/* PHY Control Register */
-#define SATA_CTRL0             0x0
-/* PHY Link Control Register */
-#define SATA_CTRL1             0x4
-/* PHY Status Register */
-#define SATA_PHY_STATUS                0x8
-
-#define SATA_CTRL0_RX_DATA_VALID(x)    (x << 27)
-#define SATA_CTRL0_SPEED_MODE          (1 << 26)
-#define SATA_CTRL0_M_PHY_CAL           (1 << 19)
-#define SATA_CTRL0_PHY_CMU_RST_N       (1 << 10)
-#define SATA_CTRL0_M_PHY_LN_RST_N      (1 << 9)
-#define SATA_CTRL0_PHY_POR_N           (1 << 8)
-
-#define SATA_CTRL1_RST_PMALIVE_N       (1 << 8)
-#define SATA_CTRL1_RST_RXOOB_N         (1 << 7)
-#define SATA_CTRL1_RST_RX_N            (1 << 6)
-#define SATA_CTRL1_RST_TX_N            (1 << 5)
-
-#define SATA_PHY_STATUS_CMU_OK         (1 << 18)
-#define SATA_PHY_STATUS_LANE_OK                (1 << 16)
-
-#define LANE0          0x200
-#define COM_LANE       0xA00
-
-#define HOST_PORTS_IMPL        0xC
-#define SCLK_SATA_FREQ (67 * MHZ)
-
-static void __iomem *phy_base, *phy_ctrl;
-
-struct phy_reg {
-       u8      reg;
-       u8      val;
-};
-
-/* SATA PHY setup */
-static const struct phy_reg exynos4_sataphy_cmu[] = {
-       { 0x00, 0x06 }, { 0x02, 0x80 }, { 0x22, 0xa0 }, { 0x23, 0x42 },
-       { 0x2e, 0x04 }, { 0x2f, 0x50 }, { 0x30, 0x70 }, { 0x31, 0x02 },
-       { 0x32, 0x25 }, { 0x33, 0x40 }, { 0x34, 0x01 }, { 0x35, 0x40 },
-       { 0x61, 0x2e }, { 0x63, 0x5e }, { 0x65, 0x42 }, { 0x66, 0xd1 },
-       { 0x67, 0x20 }, { 0x68, 0x28 }, { 0x69, 0x78 }, { 0x6a, 0x04 },
-       { 0x6b, 0xc8 }, { 0x6c, 0x06 },
-};
-
-static const struct phy_reg exynos4_sataphy_lane[] = {
-       { 0x00, 0x02 }, { 0x05, 0x10 }, { 0x06, 0x84 }, { 0x07, 0x04 },
-       { 0x08, 0xe0 }, { 0x10, 0x23 }, { 0x13, 0x05 }, { 0x14, 0x30 },
-       { 0x15, 0x00 }, { 0x17, 0x70 }, { 0x18, 0xf2 }, { 0x19, 0x1e },
-       { 0x1a, 0x18 }, { 0x1b, 0x0d }, { 0x1c, 0x08 }, { 0x50, 0x60 },
-       { 0x51, 0x0f },
-};
-
-static const struct phy_reg exynos4_sataphy_comlane[] = {
-       { 0x01, 0x20 }, { 0x03, 0x40 }, { 0x04, 0x3c }, { 0x05, 0x7d },
-       { 0x06, 0x1d }, { 0x07, 0xcf }, { 0x08, 0x05 }, { 0x09, 0x63 },
-       { 0x0a, 0x29 }, { 0x0b, 0xc4 }, { 0x0c, 0x01 }, { 0x0d, 0x03 },
-       { 0x0e, 0x28 }, { 0x0f, 0x98 }, { 0x10, 0x19 }, { 0x13, 0x80 },
-       { 0x14, 0xf0 }, { 0x15, 0xd0 }, { 0x39, 0xa0 }, { 0x3a, 0xa0 },
-       { 0x3b, 0xa0 }, { 0x3c, 0xa0 }, { 0x3d, 0xa0 }, { 0x3e, 0xa0 },
-       { 0x3f, 0xa0 }, { 0x40, 0x42 }, { 0x42, 0x80 }, { 0x43, 0x58 },
-       { 0x45, 0x44 }, { 0x46, 0x5c }, { 0x47, 0x86 }, { 0x48, 0x8d },
-       { 0x49, 0xd0 }, { 0x4a, 0x09 }, { 0x4b, 0x90 }, { 0x4c, 0x07 },
-       { 0x4d, 0x40 }, { 0x51, 0x20 }, { 0x52, 0x32 }, { 0x7f, 0xd8 },
-       { 0x80, 0x1a }, { 0x81, 0xff }, { 0x82, 0x11 }, { 0x83, 0x00 },
-       { 0x87, 0xf0 }, { 0x87, 0xff }, { 0x87, 0xff }, { 0x87, 0xff },
-       { 0x87, 0xff }, { 0x8c, 0x1c }, { 0x8d, 0xc2 }, { 0x8e, 0xc3 },
-       { 0x8f, 0x3f }, { 0x90, 0x0a }, { 0x96, 0xf8 },
-};
-
-static int wait_for_phy_ready(void __iomem *reg, unsigned long bit)
-{
-       unsigned long timeout;
-
-       /* wait for maximum of 3 sec */
-       timeout = jiffies + msecs_to_jiffies(3000);
-       while (!(__raw_readl(reg) & bit)) {
-               if (time_after(jiffies, timeout))
-                       return -1;
-               cpu_relax();
-       }
-       return 0;
-}
-
-static int ahci_phy_init(void __iomem *mmio)
-{
-       int i, ctrl0;
-
-       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_cmu); i++)
-               __raw_writeb(exynos4_sataphy_cmu[i].val,
-               phy_base + (exynos4_sataphy_cmu[i].reg * 4));
-
-       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_lane); i++)
-               __raw_writeb(exynos4_sataphy_lane[i].val,
-               phy_base + (LANE0 + exynos4_sataphy_lane[i].reg) * 4);
-
-       for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_comlane); i++)
-               __raw_writeb(exynos4_sataphy_comlane[i].val,
-               phy_base + (COM_LANE + exynos4_sataphy_comlane[i].reg) * 4);
-
-       __raw_writeb(0x07, phy_base);
-
-       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-       ctrl0 |= SATA_CTRL0_PHY_CMU_RST_N;
-       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-       if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
-                               SATA_PHY_STATUS_CMU_OK) < 0) {
-               printk(KERN_ERR "PHY CMU not ready\n");
-               return -EBUSY;
-       }
-
-       __raw_writeb(0x03, phy_base + (COM_LANE * 4));
-
-       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-       ctrl0 |= SATA_CTRL0_M_PHY_LN_RST_N;
-       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-       if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
-                               SATA_PHY_STATUS_LANE_OK) < 0) {
-               printk(KERN_ERR "PHY LANE not ready\n");
-               return -EBUSY;
-       }
-
-       ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-       ctrl0 |= SATA_CTRL0_M_PHY_CAL;
-       __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-       return 0;
-}
-
-static int exynos4_ahci_init(struct device *dev, void __iomem *mmio)
-{
-       struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata;
-       int val, ret;
-
-       phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K);
-       if (!phy_base) {
-               dev_err(dev, "failed to allocate memory for SATA PHY\n");
-               return -ENOMEM;
-       }
-
-       phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16);
-       if (!phy_ctrl) {
-               dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
-               ret = -ENOMEM;
-               goto err1;
-       }
-
-       clk_sata = clk_get(dev, "sata");
-       if (IS_ERR(clk_sata)) {
-               dev_err(dev, "failed to get sata clock\n");
-               ret = PTR_ERR(clk_sata);
-               clk_sata = NULL;
-               goto err2;
-
-       }
-       clk_enable(clk_sata);
-
-       clk_sataphy = clk_get(dev, "sataphy");
-       if (IS_ERR(clk_sataphy)) {
-               dev_err(dev, "failed to get sataphy clock\n");
-               ret = PTR_ERR(clk_sataphy);
-               clk_sataphy = NULL;
-               goto err3;
-       }
-       clk_enable(clk_sataphy);
-
-       clk_sclk_sata = clk_get(dev, "sclk_sata");
-       if (IS_ERR(clk_sclk_sata)) {
-               dev_err(dev, "failed to get sclk_sata\n");
-               ret = PTR_ERR(clk_sclk_sata);
-               clk_sclk_sata = NULL;
-               goto err4;
-       }
-       clk_enable(clk_sclk_sata);
-       clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
-
-       __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL);
-
-       /* Enable PHY link control */
-       val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N |
-                       SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N;
-       __raw_writel(val, phy_ctrl + SATA_CTRL1);
-
-       /* Set communication speed as 3Gbps and enable PHY power */
-       val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE |
-                       SATA_CTRL0_PHY_POR_N;
-       __raw_writel(val, phy_ctrl + SATA_CTRL0);
-
-       /* Port0 is available */
-       __raw_writel(0x1, mmio + HOST_PORTS_IMPL);
-
-       return ahci_phy_init(mmio);
-
-err4:
-       clk_disable(clk_sataphy);
-       clk_put(clk_sataphy);
-err3:
-       clk_disable(clk_sata);
-       clk_put(clk_sata);
-err2:
-       iounmap(phy_ctrl);
-err1:
-       iounmap(phy_base);
-
-       return ret;
-}
-
-static struct ahci_platform_data exynos4_ahci_pdata = {
-       .init = exynos4_ahci_init,
-};
-
-static struct resource exynos4_ahci_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_SATA,
-               .end    = EXYNOS4_PA_SATA + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_SATA,
-               .end    = IRQ_SATA,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 exynos4_ahci_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ahci = {
-       .name           = "ahci",
-       .id             = -1,
-       .resource       = exynos4_ahci_resource,
-       .num_resources  = ARRAY_SIZE(exynos4_ahci_resource),
-       .dev            = {
-               .platform_data          = &exynos4_ahci_pdata,
-               .dma_mask               = &exynos4_ahci_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c
deleted file mode 100644 (file)
index 5a9f9c2..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-audio.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-#include <mach/regs-audss.h>
-
-static const char *rclksrc[] = {
-       [0] = "busclk",
-       [1] = "i2sclk",
-};
-
-static int exynos4_cfg_i2s(struct platform_device *pdev)
-{
-       /* configure GPIO for i2s port */
-       switch (pdev->id) {
-       case 0:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
-               break;
-       case 1:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
-               break;
-       case 2:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
-               break;
-       default:
-               printk(KERN_ERR "Invalid Device %d\n", pdev->id);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct s3c_audio_pdata i2sv5_pdata = {
-       .cfg_gpio = exynos4_cfg_i2s,
-       .type = {
-               .i2s = {
-                       .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
-                                        | QUIRK_NEED_RSTCLR,
-                       .src_clk = rclksrc,
-                       .idma_addr = EXYNOS4_AUDSS_INT_MEM,
-               },
-       },
-};
-
-static struct resource exynos4_i2s0_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_I2S0,
-               .end    = EXYNOS4_PA_I2S0 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_I2S0_TX,
-               .end    = DMACH_I2S0_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_I2S0_RX,
-               .end    = DMACH_I2S0_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start  = DMACH_I2S0S_TX,
-               .end    = DMACH_I2S0S_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_i2s0 = {
-       .name = "samsung-i2s",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
-       .resource = exynos4_i2s0_resource,
-       .dev = {
-               .platform_data = &i2sv5_pdata,
-       },
-};
-
-static const char *rclksrc_v3[] = {
-       [0] = "sclk_i2s",
-       [1] = "no_such_clock",
-};
-
-static struct s3c_audio_pdata i2sv3_pdata = {
-       .cfg_gpio = exynos4_cfg_i2s,
-       .type = {
-               .i2s = {
-                       .quirks = QUIRK_NO_MUXPSR,
-                       .src_clk = rclksrc_v3,
-               },
-       },
-};
-
-static struct resource exynos4_i2s1_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_I2S1,
-               .end    = EXYNOS4_PA_I2S1 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_I2S1_TX,
-               .end    = DMACH_I2S1_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_I2S1_RX,
-               .end    = DMACH_I2S1_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_i2s1 = {
-       .name = "samsung-i2s",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
-       .resource = exynos4_i2s1_resource,
-       .dev = {
-               .platform_data = &i2sv3_pdata,
-       },
-};
-
-static struct resource exynos4_i2s2_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_I2S2,
-               .end    = EXYNOS4_PA_I2S2 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_I2S2_TX,
-               .end    = DMACH_I2S2_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_I2S2_RX,
-               .end    = DMACH_I2S2_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_i2s2 = {
-       .name = "samsung-i2s",
-       .id = 2,
-       .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
-       .resource = exynos4_i2s2_resource,
-       .dev = {
-               .platform_data = &i2sv3_pdata,
-       },
-};
-
-/* PCM Controller platform_devices */
-
-static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
-{
-       switch (pdev->id) {
-       case 0:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
-               break;
-       case 1:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
-               break;
-       case 2:
-               s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
-               break;
-       default:
-               printk(KERN_DEBUG "Invalid PCM Controller number!");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
-       .cfg_gpio = exynos4_pcm_cfg_gpio,
-};
-
-static struct resource exynos4_pcm0_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_PCM0,
-               .end    = EXYNOS4_PA_PCM0 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_PCM0_TX,
-               .end    = DMACH_PCM0_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_PCM0_RX,
-               .end    = DMACH_PCM0_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_pcm0 = {
-       .name = "samsung-pcm",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
-       .resource = exynos4_pcm0_resource,
-       .dev = {
-               .platform_data = &s3c_pcm_pdata,
-       },
-};
-
-static struct resource exynos4_pcm1_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_PCM1,
-               .end    = EXYNOS4_PA_PCM1 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_PCM1_TX,
-               .end    = DMACH_PCM1_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_PCM1_RX,
-               .end    = DMACH_PCM1_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_pcm1 = {
-       .name = "samsung-pcm",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
-       .resource = exynos4_pcm1_resource,
-       .dev = {
-               .platform_data = &s3c_pcm_pdata,
-       },
-};
-
-static struct resource exynos4_pcm2_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_PCM2,
-               .end    = EXYNOS4_PA_PCM2 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_PCM2_TX,
-               .end    = DMACH_PCM2_TX,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_PCM2_RX,
-               .end    = DMACH_PCM2_RX,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device exynos4_device_pcm2 = {
-       .name = "samsung-pcm",
-       .id = 2,
-       .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
-       .resource = exynos4_pcm2_resource,
-       .dev = {
-               .platform_data = &s3c_pcm_pdata,
-       },
-};
-
-/* AC97 Controller platform devices */
-
-static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
-{
-       return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
-}
-
-static struct resource exynos4_ac97_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_AC97,
-               .end    = EXYNOS4_PA_AC97 + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_AC97_PCMOUT,
-               .end    = DMACH_AC97_PCMOUT,
-               .flags  = IORESOURCE_DMA,
-       },
-       [2] = {
-               .start  = DMACH_AC97_PCMIN,
-               .end    = DMACH_AC97_PCMIN,
-               .flags  = IORESOURCE_DMA,
-       },
-       [3] = {
-               .start  = DMACH_AC97_MICIN,
-               .end    = DMACH_AC97_MICIN,
-               .flags  = IORESOURCE_DMA,
-       },
-       [4] = {
-               .start  = IRQ_AC97,
-               .end    = IRQ_AC97,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct s3c_audio_pdata s3c_ac97_pdata = {
-       .cfg_gpio = exynos4_ac97_cfg_gpio,
-};
-
-static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ac97 = {
-       .name = "samsung-ac97",
-       .id = -1,
-       .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
-       .resource = exynos4_ac97_resource,
-       .dev = {
-               .platform_data = &s3c_ac97_pdata,
-               .dma_mask = &exynos4_ac97_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-/* S/PDIF Controller platform_device */
-
-static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
-{
-       s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
-
-       return 0;
-}
-
-static struct resource exynos4_spdif_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_SPDIF,
-               .end    = EXYNOS4_PA_SPDIF + 0x100 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = DMACH_SPDIF,
-               .end    = DMACH_SPDIF,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-static struct s3c_audio_pdata samsung_spdif_pdata = {
-       .cfg_gpio = exynos4_spdif_cfg_gpio,
-};
-
-static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_spdif = {
-       .name = "samsung-spdif",
-       .id = -1,
-       .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
-       .resource = exynos4_spdif_resource,
-       .dev = {
-               .platform_data = &samsung_spdif_pdata,
-               .dma_mask = &exynos4_spdif_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-exynos4/dev-dwmci.c
deleted file mode 100644 (file)
index b025db4..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/dev-dwmci.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Platform device for Synopsys DesignWare Mobile Storage IP
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/mmc/dw_mmc.h>
-
-#include <plat/devs.h>
-
-#include <mach/map.h>
-
-static int exynos4_dwmci_get_bus_wd(u32 slot_id)
-{
-       return 4;
-}
-
-static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
-{
-       return 0;
-}
-
-static struct resource exynos4_dwmci_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_DWMCI,
-               .end    = EXYNOS4_PA_DWMCI + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_DWMCI,
-               .end    = IRQ_DWMCI,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static struct dw_mci_board exynos4_dwci_pdata = {
-       .num_slots                      = 1,
-       .quirks                         = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
-       .bus_hz                         = 80 * 1000 * 1000,
-       .detect_delay_ms        = 200,
-       .init                           = exynos4_dwmci_init,
-       .get_bus_wd                     = exynos4_dwmci_get_bus_wd,
-};
-
-static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_dwmci = {
-       .name           = "dw_mmc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
-       .resource       = exynos4_dwmci_resource,
-       .dev            = {
-               .dma_mask               = &exynos4_dwmci_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-               .platform_data  = &exynos4_dwci_pdata,
-       },
-};
-
-void __init exynos4_dwmci_set_platdata(struct dw_mci_board *pd)
-{
-       struct dw_mci_board *npd;
-
-       npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
-                       &exynos4_device_dwmci);
-
-       if (!npd->init)
-               npd->init = exynos4_dwmci_init;
-       if (!npd->get_bus_wd)
-               npd->get_bus_wd = exynos4_dwmci_get_bus_wd;
-}
diff --git a/arch/arm/mach-exynos4/dev-pd.c b/arch/arm/mach-exynos4/dev-pd.c
deleted file mode 100644 (file)
index 3273f25..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-pd.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Power Domain support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-
-#include <mach/regs-pmu.h>
-
-#include <plat/pd.h>
-
-static int exynos4_pd_enable(struct device *dev)
-{
-       struct samsung_pd_info *pdata =  dev->platform_data;
-       u32 timeout;
-
-       __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
-
-       /* Wait max 1ms */
-       timeout = 10;
-       while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
-               != S5P_INT_LOCAL_PWR_EN) {
-               if (timeout == 0) {
-                       printk(KERN_ERR "Power domain %s enable failed.\n",
-                               dev_name(dev));
-                       return -ETIMEDOUT;
-               }
-               timeout--;
-               udelay(100);
-       }
-
-       return 0;
-}
-
-static int exynos4_pd_disable(struct device *dev)
-{
-       struct samsung_pd_info *pdata =  dev->platform_data;
-       u32 timeout;
-
-       __raw_writel(0, pdata->base);
-
-       /* Wait max 1ms */
-       timeout = 10;
-       while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
-               if (timeout == 0) {
-                       printk(KERN_ERR "Power domain %s disable failed.\n",
-                               dev_name(dev));
-                       return -ETIMEDOUT;
-               }
-               timeout--;
-               udelay(100);
-       }
-
-       return 0;
-}
-
-struct platform_device exynos4_device_pd[] = {
-       {
-               .name           = "samsung-pd",
-               .id             = 0,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_MFC_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 1,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_G3D_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 2,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_LCD0_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 3,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_LCD1_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 4,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_TV_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 5,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_CAM_CONF,
-                       },
-               },
-       }, {
-               .name           = "samsung-pd",
-               .id             = 6,
-               .dev = {
-                       .platform_data = &(struct samsung_pd_info) {
-                               .enable         = exynos4_pd_enable,
-                               .disable        = exynos4_pd_disable,
-                               .base           = S5P_PMU_GPS_CONF,
-                       },
-               },
-       },
-};
diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos4/dev-sysmmu.c
deleted file mode 100644 (file)
index 3b7cae0..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-sysmmu.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - System MMU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/sysmmu.h>
-#include <plat/s5p-clock.h>
-
-/* These names must be equal to the clock names in mach-exynos4/clock.c */
-const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
-       "SYSMMU_MDMA"   ,
-       "SYSMMU_SSS"    ,
-       "SYSMMU_FIMC0"  ,
-       "SYSMMU_FIMC1"  ,
-       "SYSMMU_FIMC2"  ,
-       "SYSMMU_FIMC3"  ,
-       "SYSMMU_JPEG"   ,
-       "SYSMMU_FIMD0"  ,
-       "SYSMMU_FIMD1"  ,
-       "SYSMMU_PCIe"   ,
-       "SYSMMU_G2D"    ,
-       "SYSMMU_ROTATOR",
-       "SYSMMU_MDMA2"  ,
-       "SYSMMU_TV"     ,
-       "SYSMMU_MFC_L"  ,
-       "SYSMMU_MFC_R"  ,
-};
-
-static struct resource exynos4_sysmmu_resource[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_SYSMMU_MDMA,
-               .end    = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_SYSMMU_MDMA0_0,
-               .end    = IRQ_SYSMMU_MDMA0_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = EXYNOS4_PA_SYSMMU_SSS,
-               .end    = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [3] = {
-               .start  = IRQ_SYSMMU_SSS_0,
-               .end    = IRQ_SYSMMU_SSS_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [4] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMC0,
-               .end    = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [5] = {
-               .start  = IRQ_SYSMMU_FIMC0_0,
-               .end    = IRQ_SYSMMU_FIMC0_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [6] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMC1,
-               .end    = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [7] = {
-               .start  = IRQ_SYSMMU_FIMC1_0,
-               .end    = IRQ_SYSMMU_FIMC1_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [8] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMC2,
-               .end    = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [9] = {
-               .start  = IRQ_SYSMMU_FIMC2_0,
-               .end    = IRQ_SYSMMU_FIMC2_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [10] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMC3,
-               .end    = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [11] = {
-               .start  = IRQ_SYSMMU_FIMC3_0,
-               .end    = IRQ_SYSMMU_FIMC3_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [12] = {
-               .start  = EXYNOS4_PA_SYSMMU_JPEG,
-               .end    = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [13] = {
-               .start  = IRQ_SYSMMU_JPEG_0,
-               .end    = IRQ_SYSMMU_JPEG_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [14] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMD0,
-               .end    = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [15] = {
-               .start  = IRQ_SYSMMU_LCD0_M0_0,
-               .end    = IRQ_SYSMMU_LCD0_M0_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [16] = {
-               .start  = EXYNOS4_PA_SYSMMU_FIMD1,
-               .end    = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [17] = {
-               .start  = IRQ_SYSMMU_LCD1_M1_0,
-               .end    = IRQ_SYSMMU_LCD1_M1_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [18] = {
-               .start  = EXYNOS4_PA_SYSMMU_PCIe,
-               .end    = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [19] = {
-               .start  = IRQ_SYSMMU_PCIE_0,
-               .end    = IRQ_SYSMMU_PCIE_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [20] = {
-               .start  = EXYNOS4_PA_SYSMMU_G2D,
-               .end    = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [21] = {
-               .start  = IRQ_SYSMMU_2D_0,
-               .end    = IRQ_SYSMMU_2D_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [22] = {
-               .start  = EXYNOS4_PA_SYSMMU_ROTATOR,
-               .end    = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [23] = {
-               .start  = IRQ_SYSMMU_ROTATOR_0,
-               .end    = IRQ_SYSMMU_ROTATOR_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [24] = {
-               .start  = EXYNOS4_PA_SYSMMU_MDMA2,
-               .end    = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [25] = {
-               .start  = IRQ_SYSMMU_MDMA1_0,
-               .end    = IRQ_SYSMMU_MDMA1_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [26] = {
-               .start  = EXYNOS4_PA_SYSMMU_TV,
-               .end    = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [27] = {
-               .start  = IRQ_SYSMMU_TV_M0_0,
-               .end    = IRQ_SYSMMU_TV_M0_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [28] = {
-               .start  = EXYNOS4_PA_SYSMMU_MFC_L,
-               .end    = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [29] = {
-               .start  = IRQ_SYSMMU_MFC_M0_0,
-               .end    = IRQ_SYSMMU_MFC_M0_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [30] = {
-               .start  = EXYNOS4_PA_SYSMMU_MFC_R,
-               .end    = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [31] = {
-               .start  = IRQ_SYSMMU_MFC_M1_0,
-               .end    = IRQ_SYSMMU_MFC_M1_0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device exynos4_device_sysmmu = {
-       .name           = "s5p-sysmmu",
-       .id             = 32,
-       .num_resources  = ARRAY_SIZE(exynos4_sysmmu_resource),
-       .resource       = exynos4_sysmmu_resource,
-};
-EXPORT_SYMBOL(exynos4_device_sysmmu);
-
-static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
-{
-       sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
-       if (IS_ERR(sysmmu_clk[ips]))
-               sysmmu_clk[ips] = NULL;
-       else
-               clk_put(sysmmu_clk[ips]);
-}
-
-void sysmmu_clk_enable(sysmmu_ips ips)
-{
-       if (sysmmu_clk[ips])
-               clk_enable(sysmmu_clk[ips]);
-}
-
-void sysmmu_clk_disable(sysmmu_ips ips)
-{
-       if (sysmmu_clk[ips])
-               clk_disable(sysmmu_clk[ips]);
-}
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
deleted file mode 100644 (file)
index d57d662..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dma.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/pl330.h>
-
-#include <asm/irq.h>
-#include <plat/devs.h>
-#include <plat/irqs.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/dma.h>
-
-static u64 dma_dmamask = DMA_BIT_MASK(32);
-
-struct dma_pl330_peri pdma0_peri[28] = {
-       {
-               .peri_id = (u8)DMACH_PCM0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_PCM0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_PCM2_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_PCM2_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_MSM_REQ0,
-       }, {
-               .peri_id = (u8)DMACH_MSM_REQ2,
-       }, {
-               .peri_id = (u8)DMACH_SPI0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SPI0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SPI2_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SPI2_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_I2S0S_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_I2S0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_I2S0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART2_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART2_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART4_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART4_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS2_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS2_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS4_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS4_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_AC97_MICIN,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_AC97_PCMIN,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_AC97_PCMOUT,
-               .rqtype = MEMTODEV,
-       },
-};
-
-struct dma_pl330_platdata exynos4_pdma0_pdata = {
-       .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
-       .peri = pdma0_peri,
-};
-
-struct amba_device exynos4_device_pdma0 = {
-       .dev = {
-               .init_name = "dma-pl330.0",
-               .dma_mask = &dma_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = &exynos4_pdma0_pdata,
-       },
-       .res = {
-               .start = EXYNOS4_PA_PDMA0,
-               .end = EXYNOS4_PA_PDMA0 + SZ_4K,
-               .flags = IORESOURCE_MEM,
-       },
-       .irq = {IRQ_PDMA0, NO_IRQ},
-       .periphid = 0x00041330,
-};
-
-struct dma_pl330_peri pdma1_peri[25] = {
-       {
-               .peri_id = (u8)DMACH_PCM0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_PCM0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_PCM1_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_PCM1_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_MSM_REQ1,
-       }, {
-               .peri_id = (u8)DMACH_MSM_REQ3,
-       }, {
-               .peri_id = (u8)DMACH_SPI1_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SPI1_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_I2S0S_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_I2S0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_I2S0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_I2S1_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_I2S1_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART0_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART0_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART1_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART1_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_UART3_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_UART3_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS1_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS1_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS3_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS3_TX,
-               .rqtype = MEMTODEV,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS5_RX,
-               .rqtype = DEVTOMEM,
-       }, {
-               .peri_id = (u8)DMACH_SLIMBUS5_TX,
-               .rqtype = MEMTODEV,
-       },
-};
-
-struct dma_pl330_platdata exynos4_pdma1_pdata = {
-       .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
-       .peri = pdma1_peri,
-};
-
-struct amba_device exynos4_device_pdma1 = {
-       .dev = {
-               .init_name = "dma-pl330.1",
-               .dma_mask = &dma_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = &exynos4_pdma1_pdata,
-       },
-       .res = {
-               .start = EXYNOS4_PA_PDMA1,
-               .end = EXYNOS4_PA_PDMA1 + SZ_4K,
-               .flags = IORESOURCE_MEM,
-       },
-       .irq = {IRQ_PDMA1, NO_IRQ},
-       .periphid = 0x00041330,
-};
-
-static int __init exynos4_dma_init(void)
-{
-       amba_device_register(&exynos4_device_pdma0, &iomem_resource);
-
-       return 0;
-}
-arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos4/headsmp.S b/arch/arm/mach-exynos4/headsmp.S
deleted file mode 100644 (file)
index 3cdeb36..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  linux/arch/arm/mach-exynos4/headsmp.S
- *
- *  Cloned from linux/arch/arm/mach-realview/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-       __CPUINIT
-
-/*
- * exynos4 specific entry point for secondary CPUs.  This provides
- * a "holding pen" into which all secondary cores are held until we're
- * ready for them to initialise.
- */
-ENTRY(exynos4_secondary_startup)
-       mrc     p15, 0, r0, c0, c0, 5
-       and     r0, r0, #15
-       adr     r4, 1f
-       ldmia   r4, {r5, r6}
-       sub     r4, r4, r5
-       add     r6, r6, r4
-pen:   ldr     r7, [r6]
-       cmp     r7, r0
-       bne     pen
-
-       /*
-        * we've been released from the holding pen: secondary_stack
-        * should now contain the SVC stack for this core
-        */
-       b       secondary_startup
-
-1:     .long   .
-       .long   pen_release
diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c
deleted file mode 100644 (file)
index da70e7e..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* linux arch/arm/mach-exynos4/hotplug.c
- *
- *  Cloned from linux/arch/arm/mach-realview/hotplug.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-
-#include <mach/regs-pmu.h>
-
-extern volatile int pen_release;
-
-static inline void cpu_enter_lowpower(void)
-{
-       unsigned int v;
-
-       flush_cache_all();
-       asm volatile(
-       "       mcr     p15, 0, %1, c7, c5, 0\n"
-       "       mcr     p15, 0, %1, c7, c10, 4\n"
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, %3\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-         : "=&r" (v)
-         : "r" (0), "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile(
-       "mrc    p15, 0, %0, c1, c0, 0\n"
-       "       orr     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       orr     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-         : "=&r" (v)
-         : "Ir" (CR_C), "Ir" (0x40)
-         : "cc");
-}
-
-static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
-{
-       for (;;) {
-
-               /* make cpu1 to be turned off at next WFI command */
-               if (cpu == 1)
-                       __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION);
-
-               /*
-                * here's the WFI
-                */
-               asm(".word      0xe320f003\n"
-                   :
-                   :
-                   : "memory", "cc");
-
-               if (pen_release == cpu_logical_map(cpu)) {
-                       /*
-                        * OK, proper wakeup, we're done
-                        */
-                       break;
-               }
-
-               /*
-                * Getting here, means that we have come out of WFI without
-                * having been woken up - this shouldn't happen
-                *
-                * Just note it happening - when we're woken, we can report
-                * its occurrence.
-                */
-               (*spurious)++;
-       }
-}
-
-int platform_cpu_kill(unsigned int cpu)
-{
-       return 1;
-}
-
-/*
- * platform-specific code to shutdown a CPU
- *
- * Called with IRQs disabled
- */
-void platform_cpu_die(unsigned int cpu)
-{
-       int spurious = 0;
-
-       /*
-        * we're ready for shutdown now, so do it
-        */
-       cpu_enter_lowpower();
-       platform_do_lowpower(cpu, &spurious);
-
-       /*
-        * bring this CPU back into the world of cache
-        * coherency, and then restore interrupts
-        */
-       cpu_leave_lowpower();
-
-       if (spurious)
-               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
-}
-
-int platform_cpu_disable(unsigned int cpu)
-{
-       /*
-        * we don't allow CPU 0 to be shutdown (it is still too special
-        * e.g. clock tick interrupts)
-        */
-       return cpu == 0 ? -EPERM : 0;
-}
diff --git a/arch/arm/mach-exynos4/include/mach/clkdev.h b/arch/arm/mach-exynos4/include/mach/clkdev.h
deleted file mode 100644 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#endif
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos4/include/mach/debug-macro.S
deleted file mode 100644 (file)
index 6cacf16..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/debug-macro.S
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.S
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* pull in the relevant register and map files. */
-
-#include <mach/map.h>
-
-       /* note, for the boot process to work we have to keep the UART
-        * virtual address aligned to an 1MiB boundary for the L1
-        * mapping the head code makes. We keep the UART virtual address
-        * aligned and add in the offset when we load the value here.
-        */
-
-       .macro addruart, rp, rv, tmp
-               ldr     \rp, = S3C_PA_UART
-               ldr     \rv, = S3C_VA_UART
-#if CONFIG_DEBUG_S3C_UART != 0
-               add     \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
-               add     \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
-#endif
-       .endm
-
-#define fifo_full fifo_full_s5pv210
-#define fifo_level fifo_level_s5pv210
-
-#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h
deleted file mode 100644 (file)
index 201842a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MACH_DMA_H
-#define __MACH_DMA_H
-
-/* This platform uses the common DMA API driver for PL330 */
-#include <plat/dma-pl330.h>
-
-#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos4/include/mach/dwmci.h b/arch/arm/mach-exynos4/include/mach/dwmci.h
deleted file mode 100644 (file)
index 7ce6574..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/dwmci.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Synopsys DesignWare Mobile Storage for EXYNOS4210
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARM_ARCH_DWMCI_H
-#define __ASM_ARM_ARCH_DWMCI_H __FILE__
-
-#include <linux/mmc/dw_mmc.h>
-
-extern void exynos4_dwmci_set_platdata(struct dw_mci_board *pd);
-
-#endif /* __ASM_ARM_ARCH_DWMCI_H */
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
deleted file mode 100644 (file)
index f5e9fd8..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* arch/arm/mach-exynos4/include/mach/entry-macro.S
- *
- * Cloned from arch/arm/mach-realview/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for EXYNOS4 platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
-*/
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/hardware/gic.h>
-
-               .macro  disable_fiq
-               .endm
-
-               .macro  get_irqnr_preamble, base, tmp
-               mov     \tmp, #0
-
-               mrc     p15, 0, \base, c0, c0, 5
-               and     \base, \base, #3
-               cmp     \base, #0
-               beq     1f
-
-               ldr     \tmp, =gic_bank_offset
-               ldr     \tmp, [\tmp]
-               cmp     \base, #1
-               beq     1f
-
-               cmp     \base, #2
-               addeq   \tmp, \tmp, \tmp
-               addne   \tmp, \tmp, \tmp, LSL #1
-
-1:             ldr     \base, =gic_cpu_base_addr
-               ldr     \base, [\base]
-               add     \base, \base, \tmp
-               .endm
-
-               .macro  arch_ret_to_user, tmp1, tmp2
-               .endm
-
-               /*
-                * The interrupt numbering scheme is defined in the
-                * interrupt controller spec.  To wit:
-                *
-                * Interrupts 0-15 are IPI
-                * 16-28 are reserved
-                * 29-31 are local.  We allow 30 to be used for the watchdog.
-                * 32-1020 are global
-                * 1021-1022 are reserved
-                * 1023 is "spurious" (no interrupt)
-                *
-                * For now, we ignore all local interrupts so only return an interrupt if it's
-                * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
-                *
-                * A simple read from the controller will tell us the number of the highest
-                 * priority enabled interrupt.  We then just need to check whether it is in the
-                * valid range for an IRQ (30-1020 inclusive).
-                */
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
-               ldr     \tmp, =1021
-
-               bic     \irqnr, \irqstat, #0x1c00
-
-               cmp     \irqnr, #15
-               cmpcc   \irqnr, \irqnr
-               cmpne   \irqnr, \tmp
-               cmpcs   \irqnr, \irqnr
-               addne   \irqnr, \irqnr, #32
-
-               .endm
-
-               /* We assume that irqstat (the raw value of the IRQ acknowledge
-                * register) is preserved from the macro above.
-                * If there is an IPI, we immediately signal end of interrupt on the
-                * controller, since this requires the original irqstat value which
-                * we won't easily be able to recreate later.
-                */
-
-               .macro test_for_ipi, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               cmp     \irqnr, #16
-               strcc   \irqstat, [\base, #GIC_CPU_EOI]
-               cmpcs   \irqnr, \irqnr
-               .endm
diff --git a/arch/arm/mach-exynos4/include/mach/exynos4-clock.h b/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
deleted file mode 100644 (file)
index a07fcbf..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/include/mach/exynos4-clock.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for exynos4 clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_CLOCK_H
-#define __ASM_ARCH_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-extern struct clk clk_sclk_hdmi27m;
-extern struct clk clk_sclk_usbphy0;
-extern struct clk clk_sclk_usbphy1;
-extern struct clk clk_sclk_hdmiphy;
-
-extern struct clksrc_clk clk_sclk_apll;
-extern struct clksrc_clk clk_mout_mpll;
-extern struct clksrc_clk clk_aclk_133;
-extern struct clksrc_clk clk_mout_epll;
-extern struct clksrc_clk clk_sclk_vpll;
-
-extern struct clk *clkset_corebus_list[];
-extern struct clksrc_sources clkset_mout_corebus;
-
-extern struct clk *clkset_aclk_top_list[];
-extern struct clksrc_sources clkset_aclk;
-
-extern struct clk *clkset_group_list[];
-extern struct clksrc_sources clkset_group;
-
-extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
-
-#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos4/include/mach/gpio.h
deleted file mode 100644 (file)
index 80523ca..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H __FILE__
-
-/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
-
-/* GPIO bank sizes */
-#define EXYNOS4_GPIO_A0_NR     (8)
-#define EXYNOS4_GPIO_A1_NR     (6)
-#define EXYNOS4_GPIO_B_NR      (8)
-#define EXYNOS4_GPIO_C0_NR     (5)
-#define EXYNOS4_GPIO_C1_NR     (5)
-#define EXYNOS4_GPIO_D0_NR     (4)
-#define EXYNOS4_GPIO_D1_NR     (4)
-#define EXYNOS4_GPIO_E0_NR     (5)
-#define EXYNOS4_GPIO_E1_NR     (8)
-#define EXYNOS4_GPIO_E2_NR     (6)
-#define EXYNOS4_GPIO_E3_NR     (8)
-#define EXYNOS4_GPIO_E4_NR     (8)
-#define EXYNOS4_GPIO_F0_NR     (8)
-#define EXYNOS4_GPIO_F1_NR     (8)
-#define EXYNOS4_GPIO_F2_NR     (8)
-#define EXYNOS4_GPIO_F3_NR     (6)
-#define EXYNOS4_GPIO_J0_NR     (8)
-#define EXYNOS4_GPIO_J1_NR     (5)
-#define EXYNOS4_GPIO_K0_NR     (7)
-#define EXYNOS4_GPIO_K1_NR     (7)
-#define EXYNOS4_GPIO_K2_NR     (7)
-#define EXYNOS4_GPIO_K3_NR     (7)
-#define EXYNOS4_GPIO_L0_NR     (8)
-#define EXYNOS4_GPIO_L1_NR     (3)
-#define EXYNOS4_GPIO_L2_NR     (8)
-#define EXYNOS4_GPIO_X0_NR     (8)
-#define EXYNOS4_GPIO_X1_NR     (8)
-#define EXYNOS4_GPIO_X2_NR     (8)
-#define EXYNOS4_GPIO_X3_NR     (8)
-#define EXYNOS4_GPIO_Y0_NR     (6)
-#define EXYNOS4_GPIO_Y1_NR     (4)
-#define EXYNOS4_GPIO_Y2_NR     (6)
-#define EXYNOS4_GPIO_Y3_NR     (8)
-#define EXYNOS4_GPIO_Y4_NR     (8)
-#define EXYNOS4_GPIO_Y5_NR     (8)
-#define EXYNOS4_GPIO_Y6_NR     (8)
-#define EXYNOS4_GPIO_Z_NR      (7)
-
-/* GPIO bank numbers */
-
-#define EXYNOS4_GPIO_NEXT(__gpio) \
-       ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s5p_gpio_number {
-       EXYNOS4_GPIO_A0_START   = 0,
-       EXYNOS4_GPIO_A1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
-       EXYNOS4_GPIO_B_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
-       EXYNOS4_GPIO_C0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
-       EXYNOS4_GPIO_C1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
-       EXYNOS4_GPIO_D0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
-       EXYNOS4_GPIO_D1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
-       EXYNOS4_GPIO_E0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
-       EXYNOS4_GPIO_E1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
-       EXYNOS4_GPIO_E2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
-       EXYNOS4_GPIO_E3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
-       EXYNOS4_GPIO_E4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
-       EXYNOS4_GPIO_F0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
-       EXYNOS4_GPIO_F1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
-       EXYNOS4_GPIO_F2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
-       EXYNOS4_GPIO_F3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
-       EXYNOS4_GPIO_J0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
-       EXYNOS4_GPIO_J1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
-       EXYNOS4_GPIO_K0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
-       EXYNOS4_GPIO_K1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
-       EXYNOS4_GPIO_K2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
-       EXYNOS4_GPIO_K3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
-       EXYNOS4_GPIO_L0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
-       EXYNOS4_GPIO_L1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
-       EXYNOS4_GPIO_L2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
-       EXYNOS4_GPIO_X0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
-       EXYNOS4_GPIO_X1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
-       EXYNOS4_GPIO_X2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
-       EXYNOS4_GPIO_X3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
-       EXYNOS4_GPIO_Y0_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
-       EXYNOS4_GPIO_Y1_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
-       EXYNOS4_GPIO_Y2_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
-       EXYNOS4_GPIO_Y3_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
-       EXYNOS4_GPIO_Y4_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
-       EXYNOS4_GPIO_Y5_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
-       EXYNOS4_GPIO_Y6_START   = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
-       EXYNOS4_GPIO_Z_START    = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
-};
-
-/* EXYNOS4 GPIO number definitions */
-#define EXYNOS4_GPA0(_nr)      (EXYNOS4_GPIO_A0_START + (_nr))
-#define EXYNOS4_GPA1(_nr)      (EXYNOS4_GPIO_A1_START + (_nr))
-#define EXYNOS4_GPB(_nr)       (EXYNOS4_GPIO_B_START + (_nr))
-#define EXYNOS4_GPC0(_nr)      (EXYNOS4_GPIO_C0_START + (_nr))
-#define EXYNOS4_GPC1(_nr)      (EXYNOS4_GPIO_C1_START + (_nr))
-#define EXYNOS4_GPD0(_nr)      (EXYNOS4_GPIO_D0_START + (_nr))
-#define EXYNOS4_GPD1(_nr)      (EXYNOS4_GPIO_D1_START + (_nr))
-#define EXYNOS4_GPE0(_nr)      (EXYNOS4_GPIO_E0_START + (_nr))
-#define EXYNOS4_GPE1(_nr)      (EXYNOS4_GPIO_E1_START + (_nr))
-#define EXYNOS4_GPE2(_nr)      (EXYNOS4_GPIO_E2_START + (_nr))
-#define EXYNOS4_GPE3(_nr)      (EXYNOS4_GPIO_E3_START + (_nr))
-#define EXYNOS4_GPE4(_nr)      (EXYNOS4_GPIO_E4_START + (_nr))
-#define EXYNOS4_GPF0(_nr)      (EXYNOS4_GPIO_F0_START + (_nr))
-#define EXYNOS4_GPF1(_nr)      (EXYNOS4_GPIO_F1_START + (_nr))
-#define EXYNOS4_GPF2(_nr)      (EXYNOS4_GPIO_F2_START + (_nr))
-#define EXYNOS4_GPF3(_nr)      (EXYNOS4_GPIO_F3_START + (_nr))
-#define EXYNOS4_GPJ0(_nr)      (EXYNOS4_GPIO_J0_START + (_nr))
-#define EXYNOS4_GPJ1(_nr)      (EXYNOS4_GPIO_J1_START + (_nr))
-#define EXYNOS4_GPK0(_nr)      (EXYNOS4_GPIO_K0_START + (_nr))
-#define EXYNOS4_GPK1(_nr)      (EXYNOS4_GPIO_K1_START + (_nr))
-#define EXYNOS4_GPK2(_nr)      (EXYNOS4_GPIO_K2_START + (_nr))
-#define EXYNOS4_GPK3(_nr)      (EXYNOS4_GPIO_K3_START + (_nr))
-#define EXYNOS4_GPL0(_nr)      (EXYNOS4_GPIO_L0_START + (_nr))
-#define EXYNOS4_GPL1(_nr)      (EXYNOS4_GPIO_L1_START + (_nr))
-#define EXYNOS4_GPL2(_nr)      (EXYNOS4_GPIO_L2_START + (_nr))
-#define EXYNOS4_GPX0(_nr)      (EXYNOS4_GPIO_X0_START + (_nr))
-#define EXYNOS4_GPX1(_nr)      (EXYNOS4_GPIO_X1_START + (_nr))
-#define EXYNOS4_GPX2(_nr)      (EXYNOS4_GPIO_X2_START + (_nr))
-#define EXYNOS4_GPX3(_nr)      (EXYNOS4_GPIO_X3_START + (_nr))
-#define EXYNOS4_GPY0(_nr)      (EXYNOS4_GPIO_Y0_START + (_nr))
-#define EXYNOS4_GPY1(_nr)      (EXYNOS4_GPIO_Y1_START + (_nr))
-#define EXYNOS4_GPY2(_nr)      (EXYNOS4_GPIO_Y2_START + (_nr))
-#define EXYNOS4_GPY3(_nr)      (EXYNOS4_GPIO_Y3_START + (_nr))
-#define EXYNOS4_GPY4(_nr)      (EXYNOS4_GPIO_Y4_START + (_nr))
-#define EXYNOS4_GPY5(_nr)      (EXYNOS4_GPIO_Y5_START + (_nr))
-#define EXYNOS4_GPY6(_nr)      (EXYNOS4_GPIO_Y6_START + (_nr))
-#define EXYNOS4_GPZ(_nr)       (EXYNOS4_GPIO_Z_START + (_nr))
-
-/* the end of the EXYNOS4 specific gpios */
-#define EXYNOS4_GPIO_END       (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
-#define S3C_GPIO_END           EXYNOS4_GPIO_END
-
-/* define the number of gpios we need to the one after the GPZ() range */
-#define ARCH_NR_GPIOS          (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) +       \
-                                CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-
-#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/hardware.h b/arch/arm/mach-exynos4/include/mach/hardware.h
deleted file mode 100644 (file)
index 5109eb2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Hardware support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H __FILE__
-
-/* currently nothing here, placeholder */
-
-#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-exynos4/include/mach/io.h b/arch/arm/mach-exynos4/include/mach/io.h
deleted file mode 100644 (file)
index d5478d2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/io.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
- *
- * Based on arch/arm/mach-s5p6442/include/mach/io.h
- *
- * Default IO routines for EXYNOS4
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H __FILE__
-
-/* No current ISA/PCI bus support. */
-#define __io(a)                __typesafe_io(a)
-#define __mem_pci(a)   (a)
-
-#define IO_SPACE_LIMIT (0xFFFFFFFF)
-
-#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
deleted file mode 100644 (file)
index 2d3f6bc..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/irqs.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - IRQ definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-#include <plat/irqs.h>
-
-/* PPI: Private Peripheral Interrupt */
-
-#define IRQ_PPI(x)             S5P_IRQ(x+16)
-
-#define IRQ_MCT_LOCALTIMER     IRQ_PPI(12)
-
-/* SPI: Shared Peripheral Interrupt */
-
-#define IRQ_SPI(x)             S5P_IRQ(x+32)
-
-#define IRQ_EINT0              IRQ_SPI(16)
-#define IRQ_EINT1              IRQ_SPI(17)
-#define IRQ_EINT2              IRQ_SPI(18)
-#define IRQ_EINT3              IRQ_SPI(19)
-#define IRQ_EINT4              IRQ_SPI(20)
-#define IRQ_EINT5              IRQ_SPI(21)
-#define IRQ_EINT6              IRQ_SPI(22)
-#define IRQ_EINT7              IRQ_SPI(23)
-#define IRQ_EINT8              IRQ_SPI(24)
-#define IRQ_EINT9              IRQ_SPI(25)
-#define IRQ_EINT10             IRQ_SPI(26)
-#define IRQ_EINT11             IRQ_SPI(27)
-#define IRQ_EINT12             IRQ_SPI(28)
-#define IRQ_EINT13             IRQ_SPI(29)
-#define IRQ_EINT14             IRQ_SPI(30)
-#define IRQ_EINT15             IRQ_SPI(31)
-#define IRQ_EINT16_31          IRQ_SPI(32)
-
-#define IRQ_PDMA0              IRQ_SPI(35)
-#define IRQ_PDMA1              IRQ_SPI(36)
-#define IRQ_TIMER0_VIC         IRQ_SPI(37)
-#define IRQ_TIMER1_VIC         IRQ_SPI(38)
-#define IRQ_TIMER2_VIC         IRQ_SPI(39)
-#define IRQ_TIMER3_VIC         IRQ_SPI(40)
-#define IRQ_TIMER4_VIC         IRQ_SPI(41)
-#define IRQ_MCT_L0             IRQ_SPI(42)
-#define IRQ_WDT                        IRQ_SPI(43)
-#define IRQ_RTC_ALARM          IRQ_SPI(44)
-#define IRQ_RTC_TIC            IRQ_SPI(45)
-#define IRQ_GPIO_XB            IRQ_SPI(46)
-#define IRQ_GPIO_XA            IRQ_SPI(47)
-#define IRQ_MCT_L1             IRQ_SPI(48)
-
-#define IRQ_UART0              IRQ_SPI(52)
-#define IRQ_UART1              IRQ_SPI(53)
-#define IRQ_UART2              IRQ_SPI(54)
-#define IRQ_UART3              IRQ_SPI(55)
-#define IRQ_UART4              IRQ_SPI(56)
-#define IRQ_MCT_G0             IRQ_SPI(57)
-#define IRQ_IIC                        IRQ_SPI(58)
-#define IRQ_IIC1               IRQ_SPI(59)
-#define IRQ_IIC2               IRQ_SPI(60)
-#define IRQ_IIC3               IRQ_SPI(61)
-#define IRQ_IIC4               IRQ_SPI(62)
-#define IRQ_IIC5               IRQ_SPI(63)
-#define IRQ_IIC6               IRQ_SPI(64)
-#define IRQ_IIC7               IRQ_SPI(65)
-
-#define IRQ_USB_HOST           IRQ_SPI(70)
-#define IRQ_USB_HSOTG          IRQ_SPI(71)
-#define IRQ_MODEM_IF           IRQ_SPI(72)
-#define IRQ_HSMMC0             IRQ_SPI(73)
-#define IRQ_HSMMC1             IRQ_SPI(74)
-#define IRQ_HSMMC2             IRQ_SPI(75)
-#define IRQ_HSMMC3             IRQ_SPI(76)
-#define IRQ_DWMCI              IRQ_SPI(77)
-
-#define IRQ_MIPI_CSIS0         IRQ_SPI(78)
-#define IRQ_MIPI_CSIS1         IRQ_SPI(80)
-
-#define IRQ_ONENAND_AUDI       IRQ_SPI(82)
-#define IRQ_ROTATOR            IRQ_SPI(83)
-#define IRQ_FIMC0              IRQ_SPI(84)
-#define IRQ_FIMC1              IRQ_SPI(85)
-#define IRQ_FIMC2              IRQ_SPI(86)
-#define IRQ_FIMC3              IRQ_SPI(87)
-#define IRQ_JPEG               IRQ_SPI(88)
-#define IRQ_2D                 IRQ_SPI(89)
-#define IRQ_PCIE               IRQ_SPI(90)
-
-#define IRQ_MFC                        IRQ_SPI(94)
-
-#define IRQ_AUDIO_SS           IRQ_SPI(96)
-#define IRQ_I2S0               IRQ_SPI(97)
-#define IRQ_I2S1               IRQ_SPI(98)
-#define IRQ_I2S2               IRQ_SPI(99)
-#define IRQ_AC97               IRQ_SPI(100)
-
-#define IRQ_SPDIF              IRQ_SPI(104)
-#define IRQ_ADC0               IRQ_SPI(105)
-#define IRQ_PEN0               IRQ_SPI(106)
-#define IRQ_ADC1               IRQ_SPI(107)
-#define IRQ_PEN1               IRQ_SPI(108)
-#define IRQ_KEYPAD             IRQ_SPI(109)
-#define IRQ_PMU                        IRQ_SPI(110)
-#define IRQ_GPS                        IRQ_SPI(111)
-#define IRQ_INTFEEDCTRL_SSS    IRQ_SPI(112)
-#define IRQ_SLIMBUS            IRQ_SPI(113)
-
-#define IRQ_TSI                        IRQ_SPI(115)
-#define IRQ_SATA               IRQ_SPI(116)
-
-#define MAX_IRQ_IN_COMBINER    8
-#define COMBINER_GROUP(x)      ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
-#define COMBINER_IRQ(x, y)     (COMBINER_GROUP(x) + y)
-
-#define IRQ_SYSMMU_MDMA0_0     COMBINER_IRQ(4, 0)
-#define IRQ_SYSMMU_SSS_0       COMBINER_IRQ(4, 1)
-#define IRQ_SYSMMU_FIMC0_0     COMBINER_IRQ(4, 2)
-#define IRQ_SYSMMU_FIMC1_0     COMBINER_IRQ(4, 3)
-#define IRQ_SYSMMU_FIMC2_0     COMBINER_IRQ(4, 4)
-#define IRQ_SYSMMU_FIMC3_0     COMBINER_IRQ(4, 5)
-#define IRQ_SYSMMU_JPEG_0      COMBINER_IRQ(4, 6)
-#define IRQ_SYSMMU_2D_0                COMBINER_IRQ(4, 7)
-
-#define IRQ_SYSMMU_ROTATOR_0   COMBINER_IRQ(5, 0)
-#define IRQ_SYSMMU_MDMA1_0     COMBINER_IRQ(5, 1)
-#define IRQ_SYSMMU_LCD0_M0_0   COMBINER_IRQ(5, 2)
-#define IRQ_SYSMMU_LCD1_M1_0   COMBINER_IRQ(5, 3)
-#define IRQ_SYSMMU_TV_M0_0     COMBINER_IRQ(5, 4)
-#define IRQ_SYSMMU_MFC_M0_0    COMBINER_IRQ(5, 5)
-#define IRQ_SYSMMU_MFC_M1_0    COMBINER_IRQ(5, 6)
-#define IRQ_SYSMMU_PCIE_0      COMBINER_IRQ(5, 7)
-
-#define IRQ_FIMD0_FIFO         COMBINER_IRQ(11, 0)
-#define IRQ_FIMD0_VSYNC                COMBINER_IRQ(11, 1)
-#define IRQ_FIMD0_SYSTEM       COMBINER_IRQ(11, 2)
-
-#define MAX_COMBINER_NR                16
-
-#define IRQ_ADC                        IRQ_ADC0
-#define IRQ_TC                 IRQ_PEN0
-
-#define S5P_IRQ_EINT_BASE      COMBINER_IRQ(MAX_COMBINER_NR, 0)
-
-#define S5P_EINT_BASE1         (S5P_IRQ_EINT_BASE + 0)
-#define S5P_EINT_BASE2         (S5P_IRQ_EINT_BASE + 16)
-
-/* optional GPIO interrupts */
-#define S5P_GPIOINT_BASE       (S5P_IRQ_EINT_BASE + 32)
-#define IRQ_GPIO1_NR_GROUPS    16
-#define IRQ_GPIO2_NR_GROUPS    9
-#define IRQ_GPIO_END           (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
-
-/* Set the default NR_IRQS */
-#define NR_IRQS                        (IRQ_GPIO_END + 64)
-
-#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
deleted file mode 100644 (file)
index 9f97eb8..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/map.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * EXYNOS4 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-
-/*
- * EXYNOS4 UART offset is 0x10000 but the older S5P SoCs are 0x400.
- * So need to define it, and here is to avoid redefinition warning.
- */
-#define S3C_UART_OFFSET                        (0x10000)
-
-#include <plat/map-s5p.h>
-
-#define EXYNOS4_PA_SYSRAM0             0x02025000
-#define EXYNOS4_PA_SYSRAM1             0x02020000
-
-#define EXYNOS4_PA_FIMC0               0x11800000
-#define EXYNOS4_PA_FIMC1               0x11810000
-#define EXYNOS4_PA_FIMC2               0x11820000
-#define EXYNOS4_PA_FIMC3               0x11830000
-
-#define EXYNOS4_PA_I2S0                        0x03830000
-#define EXYNOS4_PA_I2S1                        0xE3100000
-#define EXYNOS4_PA_I2S2                        0xE2A00000
-
-#define EXYNOS4_PA_PCM0                        0x03840000
-#define EXYNOS4_PA_PCM1                        0x13980000
-#define EXYNOS4_PA_PCM2                        0x13990000
-
-#define EXYNOS4_PA_SROM_BANK(x)                (0x04000000 + ((x) * 0x01000000))
-
-#define EXYNOS4_PA_ONENAND             0x0C000000
-#define EXYNOS4_PA_ONENAND_DMA         0x0C600000
-
-#define EXYNOS4_PA_CHIPID              0x10000000
-
-#define EXYNOS4_PA_SYSCON              0x10010000
-#define EXYNOS4_PA_PMU                 0x10020000
-#define EXYNOS4_PA_CMU                 0x10030000
-
-#define EXYNOS4_PA_SYSTIMER            0x10050000
-#define EXYNOS4_PA_WATCHDOG            0x10060000
-#define EXYNOS4_PA_RTC                 0x10070000
-
-#define EXYNOS4_PA_KEYPAD              0x100A0000
-
-#define EXYNOS4_PA_DMC0                        0x10400000
-
-#define EXYNOS4_PA_COMBINER            0x10440000
-
-#define EXYNOS4_PA_GIC_CPU             0x10480000
-#define EXYNOS4_PA_GIC_DIST            0x10490000
-
-#define EXYNOS4_PA_COREPERI            0x10500000
-#define EXYNOS4_PA_TWD                 0x10500600
-#define EXYNOS4_PA_L2CC                        0x10502000
-
-#define EXYNOS4_PA_MDMA                        0x10810000
-#define EXYNOS4_PA_PDMA0               0x12680000
-#define EXYNOS4_PA_PDMA1               0x12690000
-
-#define EXYNOS4_PA_SYSMMU_MDMA         0x10A40000
-#define EXYNOS4_PA_SYSMMU_SSS          0x10A50000
-#define EXYNOS4_PA_SYSMMU_FIMC0                0x11A20000
-#define EXYNOS4_PA_SYSMMU_FIMC1                0x11A30000
-#define EXYNOS4_PA_SYSMMU_FIMC2                0x11A40000
-#define EXYNOS4_PA_SYSMMU_FIMC3                0x11A50000
-#define EXYNOS4_PA_SYSMMU_JPEG         0x11A60000
-#define EXYNOS4_PA_SYSMMU_FIMD0                0x11E20000
-#define EXYNOS4_PA_SYSMMU_FIMD1                0x12220000
-#define EXYNOS4_PA_SYSMMU_PCIe         0x12620000
-#define EXYNOS4_PA_SYSMMU_G2D          0x12A20000
-#define EXYNOS4_PA_SYSMMU_ROTATOR      0x12A30000
-#define EXYNOS4_PA_SYSMMU_MDMA2                0x12A40000
-#define EXYNOS4_PA_SYSMMU_TV           0x12E20000
-#define EXYNOS4_PA_SYSMMU_MFC_L                0x13620000
-#define EXYNOS4_PA_SYSMMU_MFC_R                0x13630000
-
-#define EXYNOS4_PA_GPIO1               0x11400000
-#define EXYNOS4_PA_GPIO2               0x11000000
-#define EXYNOS4_PA_GPIO3               0x03860000
-
-#define EXYNOS4_PA_MIPI_CSIS0          0x11880000
-#define EXYNOS4_PA_MIPI_CSIS1          0x11890000
-
-#define EXYNOS4_PA_FIMD0               0x11C00000
-
-#define EXYNOS4_PA_HSMMC(x)            (0x12510000 + ((x) * 0x10000))
-#define EXYNOS4_PA_DWMCI               0x12550000
-
-#define EXYNOS4_PA_SATA                        0x12560000
-#define EXYNOS4_PA_SATAPHY             0x125D0000
-#define EXYNOS4_PA_SATAPHY_CTRL                0x126B0000
-
-#define EXYNOS4_PA_SROMC               0x12570000
-
-#define EXYNOS4_PA_EHCI                        0x12580000
-#define EXYNOS4_PA_HSPHY               0x125B0000
-#define EXYNOS4_PA_MFC                 0x13400000
-
-#define EXYNOS4_PA_UART                        0x13800000
-
-#define EXYNOS4_PA_IIC(x)              (0x13860000 + ((x) * 0x10000))
-
-#define EXYNOS4_PA_ADC                 0x13910000
-#define EXYNOS4_PA_ADC1                        0x13911000
-
-#define EXYNOS4_PA_AC97                        0x139A0000
-
-#define EXYNOS4_PA_SPDIF               0x139B0000
-
-#define EXYNOS4_PA_TIMER               0x139D0000
-
-#define EXYNOS4_PA_SDRAM               0x40000000
-
-/* Compatibiltiy Defines */
-
-#define S3C_PA_HSMMC0                  EXYNOS4_PA_HSMMC(0)
-#define S3C_PA_HSMMC1                  EXYNOS4_PA_HSMMC(1)
-#define S3C_PA_HSMMC2                  EXYNOS4_PA_HSMMC(2)
-#define S3C_PA_HSMMC3                  EXYNOS4_PA_HSMMC(3)
-#define S3C_PA_IIC                     EXYNOS4_PA_IIC(0)
-#define S3C_PA_IIC1                    EXYNOS4_PA_IIC(1)
-#define S3C_PA_IIC2                    EXYNOS4_PA_IIC(2)
-#define S3C_PA_IIC3                    EXYNOS4_PA_IIC(3)
-#define S3C_PA_IIC4                    EXYNOS4_PA_IIC(4)
-#define S3C_PA_IIC5                    EXYNOS4_PA_IIC(5)
-#define S3C_PA_IIC6                    EXYNOS4_PA_IIC(6)
-#define S3C_PA_IIC7                    EXYNOS4_PA_IIC(7)
-#define SAMSUNG_PA_ADC                 EXYNOS4_PA_ADC
-#define SAMSUNG_PA_ADC1                        EXYNOS4_PA_ADC1
-#define S3C_PA_RTC                     EXYNOS4_PA_RTC
-#define S3C_PA_WDT                     EXYNOS4_PA_WATCHDOG
-
-#define S5P_PA_CHIPID                  EXYNOS4_PA_CHIPID
-#define S5P_PA_FIMC0                   EXYNOS4_PA_FIMC0
-#define S5P_PA_FIMC1                   EXYNOS4_PA_FIMC1
-#define S5P_PA_FIMC2                   EXYNOS4_PA_FIMC2
-#define S5P_PA_FIMC3                   EXYNOS4_PA_FIMC3
-#define S5P_PA_MIPI_CSIS0              EXYNOS4_PA_MIPI_CSIS0
-#define S5P_PA_MIPI_CSIS1              EXYNOS4_PA_MIPI_CSIS1
-#define S5P_PA_FIMD0                   EXYNOS4_PA_FIMD0
-#define S5P_PA_ONENAND                 EXYNOS4_PA_ONENAND
-#define S5P_PA_ONENAND_DMA             EXYNOS4_PA_ONENAND_DMA
-#define S5P_PA_SDRAM                   EXYNOS4_PA_SDRAM
-#define S5P_PA_SROMC                   EXYNOS4_PA_SROMC
-#define S5P_PA_MFC                     EXYNOS4_PA_MFC
-#define S5P_PA_SYSCON                  EXYNOS4_PA_SYSCON
-#define S5P_PA_TIMER                   EXYNOS4_PA_TIMER
-#define S5P_PA_EHCI                    EXYNOS4_PA_EHCI
-
-#define SAMSUNG_PA_KEYPAD              EXYNOS4_PA_KEYPAD
-
-/* UART */
-
-#define S3C_PA_UART                    EXYNOS4_PA_UART
-
-#define S5P_PA_UART(x)                 (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
-#define S5P_PA_UART0                   S5P_PA_UART(0)
-#define S5P_PA_UART1                   S5P_PA_UART(1)
-#define S5P_PA_UART2                   S5P_PA_UART(2)
-#define S5P_PA_UART3                   S5P_PA_UART(3)
-#define S5P_PA_UART4                   S5P_PA_UART(4)
-
-#define S5P_SZ_UART                    SZ_256
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos4/include/mach/memory.h b/arch/arm/mach-exynos4/include/mach/memory.h
deleted file mode 100644 (file)
index 374ef2c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/memory.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Memory definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H __FILE__
-
-#define PLAT_PHYS_OFFSET               UL(0x40000000)
-
-/* Maximum of 256MiB in one bank */
-#define MAX_PHYSMEM_BITS       32
-#define SECTION_SIZE_BITS      28
-
-#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-exynos4/include/mach/pm-core.h b/arch/arm/mach-exynos4/include/mach/pm-core.h
deleted file mode 100644 (file)
index 1df3b81..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#include <mach/regs-pmu.h>
-
-static inline void s3c_pm_debug_init_uart(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_prepare_irqs(void)
-{
-       unsigned int tmp;
-       tmp = __raw_readl(S5P_WAKEUP_MASK);
-       tmp &= ~(1 << 31);
-       __raw_writel(tmp, S5P_WAKEUP_MASK);
-
-       __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
-       __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
-}
-
-static inline void s3c_pm_arch_stop_clocks(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_show_resume_irqs(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_arch_update_uart(void __iomem *regs,
-                                          struct pm_uart_save *save)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_restored_gpios(void)
-{
-       /* nothing here yet */
-}
-
-static inline void s3c_pm_saved_gpios(void)
-{
-       /* nothing here yet */
-}
diff --git a/arch/arm/mach-exynos4/include/mach/pmu.h b/arch/arm/mach-exynos4/include/mach/pmu.h
deleted file mode 100644 (file)
index a952904..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pmu.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * EXYNOS4210 - PMU(Power Management Unit) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_PMU_H
-#define __ASM_ARCH_PMU_H __FILE__
-
-enum sys_powerdown {
-       SYS_AFTR,
-       SYS_LPA,
-       SYS_SLEEP,
-       NUM_SYS_POWERDOWN,
-};
-
-extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
-
-#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/pwm-clock.h b/arch/arm/mach-exynos4/include/mach/pwm-clock.h
deleted file mode 100644 (file)
index 8e12090..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pwm-clock.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
- *
- * EXYNOS4 - pwm clock and timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_PWMCLK_H
-#define __ASM_ARCH_PWMCLK_H __FILE__
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
-
-#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-audss.h b/arch/arm/mach-exynos4/include/mach/regs-audss.h
deleted file mode 100644 (file)
index ca5a8b6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/mach-exynos4/include/mach/regs-audss.h
- *
- * Copyright (c) 2011 Samsung Electronics
- *             http://www.samsung.com
- *
- * Exynos4 Audio SubSystem clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_REGS_AUDSS_H
-#define __PLAT_REGS_AUDSS_H __FILE__
-
-#define EXYNOS4_AUDSS_INT_MEM  (0x03000000)
-
-#endif /* _PLAT_REGS_AUDSS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
deleted file mode 100644 (file)
index 6c37ebe..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-clock.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_CLOCK_H
-#define __ASM_ARCH_REGS_CLOCK_H __FILE__
-
-#include <plat/cpu.h>
-#include <mach/map.h>
-
-#define S5P_CLKREG(x)                  (S5P_VA_CMU + (x))
-
-#define S5P_CLKDIV_LEFTBUS             S5P_CLKREG(0x04500)
-#define S5P_CLKDIV_STAT_LEFTBUS                S5P_CLKREG(0x04600)
-#define S5P_CLKGATE_IP_LEFTBUS         S5P_CLKREG(0x04800)
-
-#define S5P_CLKDIV_RIGHTBUS            S5P_CLKREG(0x08500)
-#define S5P_CLKDIV_STAT_RIGHTBUS       S5P_CLKREG(0x08600)
-#define S5P_CLKGATE_IP_RIGHTBUS                S5P_CLKREG(0x08800)
-
-#define S5P_EPLL_LOCK                  S5P_CLKREG(0x0C010)
-#define S5P_VPLL_LOCK                  S5P_CLKREG(0x0C020)
-
-#define S5P_EPLL_CON0                  S5P_CLKREG(0x0C110)
-#define S5P_EPLL_CON1                  S5P_CLKREG(0x0C114)
-#define S5P_VPLL_CON0                  S5P_CLKREG(0x0C120)
-#define S5P_VPLL_CON1                  S5P_CLKREG(0x0C124)
-
-#define S5P_CLKSRC_TOP0                        S5P_CLKREG(0x0C210)
-#define S5P_CLKSRC_TOP1                        S5P_CLKREG(0x0C214)
-#define S5P_CLKSRC_CAM                 S5P_CLKREG(0x0C220)
-#define S5P_CLKSRC_TV                  S5P_CLKREG(0x0C224)
-#define S5P_CLKSRC_MFC                 S5P_CLKREG(0x0C228)
-#define S5P_CLKSRC_G3D                 S5P_CLKREG(0x0C22C)
-#define S5P_CLKSRC_IMAGE               S5P_CLKREG(0x0C230)
-#define S5P_CLKSRC_LCD0                        S5P_CLKREG(0x0C234)
-#define S5P_CLKSRC_MAUDIO              S5P_CLKREG(0x0C23C)
-#define S5P_CLKSRC_FSYS                        S5P_CLKREG(0x0C240)
-#define S5P_CLKSRC_PERIL0              S5P_CLKREG(0x0C250)
-#define S5P_CLKSRC_PERIL1              S5P_CLKREG(0x0C254)
-
-#define S5P_CLKSRC_MASK_TOP            S5P_CLKREG(0x0C310)
-#define S5P_CLKSRC_MASK_CAM            S5P_CLKREG(0x0C320)
-#define S5P_CLKSRC_MASK_TV             S5P_CLKREG(0x0C324)
-#define S5P_CLKSRC_MASK_LCD0           S5P_CLKREG(0x0C334)
-#define S5P_CLKSRC_MASK_MAUDIO         S5P_CLKREG(0x0C33C)
-#define S5P_CLKSRC_MASK_FSYS           S5P_CLKREG(0x0C340)
-#define S5P_CLKSRC_MASK_PERIL0         S5P_CLKREG(0x0C350)
-#define S5P_CLKSRC_MASK_PERIL1         S5P_CLKREG(0x0C354)
-
-#define S5P_CLKDIV_TOP                 S5P_CLKREG(0x0C510)
-#define S5P_CLKDIV_CAM                 S5P_CLKREG(0x0C520)
-#define S5P_CLKDIV_TV                  S5P_CLKREG(0x0C524)
-#define S5P_CLKDIV_MFC                 S5P_CLKREG(0x0C528)
-#define S5P_CLKDIV_G3D                 S5P_CLKREG(0x0C52C)
-#define S5P_CLKDIV_IMAGE               S5P_CLKREG(0x0C530)
-#define S5P_CLKDIV_LCD0                        S5P_CLKREG(0x0C534)
-#define S5P_CLKDIV_MAUDIO              S5P_CLKREG(0x0C53C)
-#define S5P_CLKDIV_FSYS0               S5P_CLKREG(0x0C540)
-#define S5P_CLKDIV_FSYS1               S5P_CLKREG(0x0C544)
-#define S5P_CLKDIV_FSYS2               S5P_CLKREG(0x0C548)
-#define S5P_CLKDIV_FSYS3               S5P_CLKREG(0x0C54C)
-#define S5P_CLKDIV_PERIL0              S5P_CLKREG(0x0C550)
-#define S5P_CLKDIV_PERIL1              S5P_CLKREG(0x0C554)
-#define S5P_CLKDIV_PERIL2              S5P_CLKREG(0x0C558)
-#define S5P_CLKDIV_PERIL3              S5P_CLKREG(0x0C55C)
-#define S5P_CLKDIV_PERIL4              S5P_CLKREG(0x0C560)
-#define S5P_CLKDIV_PERIL5              S5P_CLKREG(0x0C564)
-#define S5P_CLKDIV2_RATIO              S5P_CLKREG(0x0C580)
-
-#define S5P_CLKDIV_STAT_TOP            S5P_CLKREG(0x0C610)
-
-#define S5P_CLKGATE_SCLKCAM            S5P_CLKREG(0x0C820)
-#define S5P_CLKGATE_IP_CAM             S5P_CLKREG(0x0C920)
-#define S5P_CLKGATE_IP_TV              S5P_CLKREG(0x0C924)
-#define S5P_CLKGATE_IP_MFC             S5P_CLKREG(0x0C928)
-#define S5P_CLKGATE_IP_G3D             S5P_CLKREG(0x0C92C)
-#define S5P_CLKGATE_IP_IMAGE           (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x0C930) : \
-                                       S5P_CLKREG(0x04930))
-#define S5P_CLKGATE_IP_IMAGE_4210      S5P_CLKREG(0x0C930)
-#define S5P_CLKGATE_IP_IMAGE_4212      S5P_CLKREG(0x04930)
-#define S5P_CLKGATE_IP_LCD0            S5P_CLKREG(0x0C934)
-#define S5P_CLKGATE_IP_FSYS            S5P_CLKREG(0x0C940)
-#define S5P_CLKGATE_IP_GPS             S5P_CLKREG(0x0C94C)
-#define S5P_CLKGATE_IP_PERIL           S5P_CLKREG(0x0C950)
-#define S5P_CLKGATE_IP_PERIR           (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x0C960) : \
-                                       S5P_CLKREG(0x08960))
-#define S5P_CLKGATE_IP_PERIR_4210      S5P_CLKREG(0x0C960)
-#define S5P_CLKGATE_IP_PERIR_4212      S5P_CLKREG(0x08960)
-#define S5P_CLKGATE_BLOCK              S5P_CLKREG(0x0C970)
-
-#define S5P_CLKSRC_MASK_DMC            S5P_CLKREG(0x10300)
-#define S5P_CLKSRC_DMC                 S5P_CLKREG(0x10200)
-#define S5P_CLKDIV_DMC0                        S5P_CLKREG(0x10500)
-#define S5P_CLKDIV_DMC1                        S5P_CLKREG(0x10504)
-#define S5P_CLKDIV_STAT_DMC0           S5P_CLKREG(0x10600)
-#define S5P_CLKGATE_IP_DMC             S5P_CLKREG(0x10900)
-
-#define S5P_APLL_LOCK                  S5P_CLKREG(0x14000)
-#define S5P_MPLL_LOCK                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x14004) :  \
-                                       S5P_CLKREG(0x10008))
-#define S5P_APLL_CON0                  S5P_CLKREG(0x14100)
-#define S5P_APLL_CON1                  S5P_CLKREG(0x14104)
-#define S5P_MPLL_CON0                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x14108) : \
-                                       S5P_CLKREG(0x10108))
-#define S5P_MPLL_CON1                  (soc_is_exynos4210() ? \
-                                       S5P_CLKREG(0x1410C) : \
-                                       S5P_CLKREG(0x1010C))
-
-#define S5P_CLKSRC_CPU                 S5P_CLKREG(0x14200)
-#define S5P_CLKMUX_STATCPU             S5P_CLKREG(0x14400)
-
-#define S5P_CLKDIV_CPU                 S5P_CLKREG(0x14500)
-#define S5P_CLKDIV_CPU1                        S5P_CLKREG(0x14504)
-#define S5P_CLKDIV_STATCPU             S5P_CLKREG(0x14600)
-#define S5P_CLKDIV_STATCPU1            S5P_CLKREG(0x14604)
-
-#define S5P_CLKGATE_SCLKCPU            S5P_CLKREG(0x14800)
-#define S5P_CLKGATE_IP_CPU             S5P_CLKREG(0x14900)
-
-#define S5P_APLL_LOCKTIME              (0x1C20)        /* 300us */
-
-#define S5P_APLLCON0_ENABLE_SHIFT      (31)
-#define S5P_APLLCON0_LOCKED_SHIFT      (29)
-#define S5P_APLL_VAL_1000              ((250 << 16) | (6 << 8) | 1)
-#define S5P_APLL_VAL_800               ((200 << 16) | (6 << 8) | 1)
-
-#define S5P_EPLLCON0_ENABLE_SHIFT      (31)
-#define S5P_EPLLCON0_LOCKED_SHIFT      (29)
-
-#define S5P_VPLLCON0_ENABLE_SHIFT      (31)
-#define S5P_VPLLCON0_LOCKED_SHIFT      (29)
-
-#define S5P_CLKSRC_CPU_MUXCORE_SHIFT   (16)
-#define S5P_CLKMUX_STATCPU_MUXCORE_MASK        (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
-
-#define S5P_CLKDIV_CPU0_CORE_SHIFT     (0)
-#define S5P_CLKDIV_CPU0_CORE_MASK      (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM0_SHIFT   (4)
-#define S5P_CLKDIV_CPU0_COREM0_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM1_SHIFT   (8)
-#define S5P_CLKDIV_CPU0_COREM1_MASK    (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
-#define S5P_CLKDIV_CPU0_PERIPH_SHIFT   (12)
-#define S5P_CLKDIV_CPU0_PERIPH_MASK    (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
-#define S5P_CLKDIV_CPU0_ATB_SHIFT      (16)
-#define S5P_CLKDIV_CPU0_ATB_MASK       (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
-#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT  (20)
-#define S5P_CLKDIV_CPU0_PCLKDBG_MASK   (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
-#define S5P_CLKDIV_CPU0_APLL_SHIFT     (24)
-#define S5P_CLKDIV_CPU0_APLL_MASK      (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
-
-#define S5P_CLKDIV_DMC0_ACP_SHIFT      (0)
-#define S5P_CLKDIV_DMC0_ACP_MASK       (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
-#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT  (4)
-#define S5P_CLKDIV_DMC0_ACPPCLK_MASK   (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
-#define S5P_CLKDIV_DMC0_DPHY_SHIFT     (8)
-#define S5P_CLKDIV_DMC0_DPHY_MASK      (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
-#define S5P_CLKDIV_DMC0_DMC_SHIFT      (12)
-#define S5P_CLKDIV_DMC0_DMC_MASK       (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCD_SHIFT     (16)
-#define S5P_CLKDIV_DMC0_DMCD_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCP_SHIFT     (20)
-#define S5P_CLKDIV_DMC0_DMCP_MASK      (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
-#define S5P_CLKDIV_DMC0_COPY2_SHIFT    (24)
-#define S5P_CLKDIV_DMC0_COPY2_MASK     (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
-#define S5P_CLKDIV_DMC0_CORETI_SHIFT   (28)
-#define S5P_CLKDIV_DMC0_CORETI_MASK    (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
-
-#define S5P_CLKDIV_TOP_ACLK200_SHIFT   (0)
-#define S5P_CLKDIV_TOP_ACLK200_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK100_SHIFT   (4)
-#define S5P_CLKDIV_TOP_ACLK100_MASK    (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK160_SHIFT   (8)
-#define S5P_CLKDIV_TOP_ACLK160_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK133_SHIFT   (12)
-#define S5P_CLKDIV_TOP_ACLK133_MASK    (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
-#define S5P_CLKDIV_TOP_ONENAND_SHIFT   (16)
-#define S5P_CLKDIV_TOP_ONENAND_MASK    (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
-
-#define S5P_CLKDIV_BUS_GDLR_SHIFT      (0)
-#define S5P_CLKDIV_BUS_GDLR_MASK       (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
-#define S5P_CLKDIV_BUS_GPLR_SHIFT      (4)
-#define S5P_CLKDIV_BUS_GPLR_MASK       (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
-
-/* Only for EXYNOS4210 */
-
-#define S5P_CLKSRC_LCD1                        S5P_CLKREG(0x0C238)
-#define S5P_CLKSRC_MASK_LCD1           S5P_CLKREG(0x0C338)
-#define S5P_CLKDIV_LCD1                        S5P_CLKREG(0x0C538)
-#define S5P_CLKGATE_IP_LCD1            S5P_CLKREG(0x0C938)
-
-/* Compatibility defines and inclusion */
-
-#include <mach/regs-pmu.h>
-
-#define S5P_EPLL_CON                   S5P_EPLL_CON0
-
-#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-gpio.h b/arch/arm/mach-exynos4/include/mach/regs-gpio.h
deleted file mode 100644 (file)
index 1401b21..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - GPIO (including EINT) register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_GPIO_H
-#define __ASM_ARCH_REGS_GPIO_H __FILE__
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#define EXYNOS4_EINT40CON              (S5P_VA_GPIO2 + 0xE00)
-#define S5P_EINT_CON(x)                        (EXYNOS4_EINT40CON + ((x) * 0x4))
-
-#define EXYNOS4_EINT40FLTCON0          (S5P_VA_GPIO2 + 0xE80)
-#define S5P_EINT_FLTCON(x)             (EXYNOS4_EINT40FLTCON0 + ((x) * 0x4))
-
-#define EXYNOS4_EINT40MASK             (S5P_VA_GPIO2 + 0xF00)
-#define S5P_EINT_MASK(x)               (EXYNOS4_EINT40MASK + ((x) * 0x4))
-
-#define EXYNOS4_EINT40PEND             (S5P_VA_GPIO2 + 0xF40)
-#define S5P_EINT_PEND(x)               (EXYNOS4_EINT40PEND + ((x) * 0x4))
-
-#define EINT_REG_NR(x)                 (EINT_OFFSET(x) >> 3)
-
-#define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
-
-#define EINT_MODE                      S3C_GPIO_SFN(0xf)
-
-#define EINT_GPIO_0(x)                 EXYNOS4_GPX0(x)
-#define EINT_GPIO_1(x)                 EXYNOS4_GPX1(x)
-#define EINT_GPIO_2(x)                 EXYNOS4_GPX2(x)
-#define EINT_GPIO_3(x)                 EXYNOS4_GPX3(x)
-
-#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-irq.h b/arch/arm/mach-exynos4/include/mach/regs-irq.h
deleted file mode 100644 (file)
index 9c7b4bf..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - IRQ register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_IRQ_H
-#define __ASM_ARCH_REGS_IRQ_H __FILE__
-
-#include <asm/hardware/gic.h>
-#include <mach/map.h>
-
-#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos4/include/mach/regs-mct.h
deleted file mode 100644 (file)
index 80dd02a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* arch/arm/mach-exynos4/include/mach/regs-mct.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 MCT configutation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_MCT_H
-#define __ASM_ARCH_REGS_MCT_H __FILE__
-
-#include <mach/map.h>
-
-#define EXYNOS4_MCTREG(x)              (S5P_VA_SYSTIMER + (x))
-
-#define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
-#define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
-#define EXYNOS4_MCT_G_CNT_WSTAT                EXYNOS4_MCTREG(0x110)
-
-#define EXYNOS4_MCT_G_COMP0_L          EXYNOS4_MCTREG(0x200)
-#define EXYNOS4_MCT_G_COMP0_U          EXYNOS4_MCTREG(0x204)
-#define EXYNOS4_MCT_G_COMP0_ADD_INCR   EXYNOS4_MCTREG(0x208)
-
-#define EXYNOS4_MCT_G_TCON             EXYNOS4_MCTREG(0x240)
-
-#define EXYNOS4_MCT_G_INT_CSTAT                EXYNOS4_MCTREG(0x244)
-#define EXYNOS4_MCT_G_INT_ENB          EXYNOS4_MCTREG(0x248)
-#define EXYNOS4_MCT_G_WSTAT            EXYNOS4_MCTREG(0x24C)
-
-#define _EXYNOS4_MCT_L_BASE            EXYNOS4_MCTREG(0x300)
-#define EXYNOS4_MCT_L_BASE(x)          (_EXYNOS4_MCT_L_BASE + (0x100 * x))
-#define EXYNOS4_MCT_L_MASK             (0xffffff00)
-
-#define MCT_L_TCNTB_OFFSET             (0x00)
-#define MCT_L_ICNTB_OFFSET             (0x08)
-#define MCT_L_TCON_OFFSET              (0x20)
-#define MCT_L_INT_CSTAT_OFFSET         (0x30)
-#define MCT_L_INT_ENB_OFFSET           (0x34)
-#define MCT_L_WSTAT_OFFSET             (0x40)
-
-#define MCT_G_TCON_START               (1 << 8)
-#define MCT_G_TCON_COMP0_AUTO_INC      (1 << 1)
-#define MCT_G_TCON_COMP0_ENABLE                (1 << 0)
-
-#define MCT_L_TCON_INTERVAL_MODE       (1 << 2)
-#define MCT_L_TCON_INT_START           (1 << 1)
-#define MCT_L_TCON_TIMER_START         (1 << 0)
-
-#endif /* __ASM_ARCH_REGS_MCT_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mem.h b/arch/arm/mach-exynos4/include/mach/regs-mem.h
deleted file mode 100644 (file)
index 0368b5a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-mem.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - SROMC and DMC register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_MEM_H
-#define __ASM_ARCH_REGS_MEM_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_DMC0_MEMCON_OFFSET         0x04
-
-#define S5P_DMC0_MEMTYPE_SHIFT         8
-#define S5P_DMC0_MEMTYPE_MASK          0xF
-
-#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
deleted file mode 100644 (file)
index cdf9b47..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Power management unit definition
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_PMU_H
-#define __ASM_ARCH_REGS_PMU_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_PMUREG(x)                          (S5P_VA_PMU + (x))
-
-#define S5P_CENTRAL_SEQ_CONFIGURATION          S5P_PMUREG(0x0200)
-
-#define S5P_CENTRAL_LOWPWR_CFG                 (1 << 16)
-
-#define S5P_CENTRAL_SEQ_OPTION                 S5P_PMUREG(0x0208)
-
-#define S5P_USE_STANDBY_WFI0                   (1 << 16)
-#define S5P_USE_STANDBY_WFI1                   (1 << 17)
-#define S5P_USE_STANDBY_WFE0                   (1 << 24)
-#define S5P_USE_STANDBY_WFE1                   (1 << 25)
-#define S5P_USE_MASK                           ((0x3 << 16) | (0x3 << 24))
-
-#define S5P_SWRESET                            S5P_PMUREG(0x0400)
-
-#define S5P_WAKEUP_STAT                                S5P_PMUREG(0x0600)
-#define S5P_EINT_WAKEUP_MASK                   S5P_PMUREG(0x0604)
-#define S5P_WAKEUP_MASK                                S5P_PMUREG(0x0608)
-
-#define S5P_USBHOST_PHY_CONTROL                        S5P_PMUREG(0x0708)
-#define S5P_USBHOST_PHY_ENABLE                 (1 << 0)
-
-#define S5P_MIPI_DPHY_CONTROL(n)               S5P_PMUREG(0x0710 + (n) * 4)
-#define S5P_MIPI_DPHY_ENABLE                   (1 << 0)
-#define S5P_MIPI_DPHY_SRESETN                  (1 << 1)
-#define S5P_MIPI_DPHY_MRESETN                  (1 << 2)
-
-#define S5P_PMU_SATA_PHY_CONTROL               S5P_PMUREG(0x0720)
-#define S5P_INFORM0                            S5P_PMUREG(0x0800)
-#define S5P_INFORM1                            S5P_PMUREG(0x0804)
-#define S5P_INFORM2                            S5P_PMUREG(0x0808)
-#define S5P_INFORM3                            S5P_PMUREG(0x080C)
-#define S5P_INFORM4                            S5P_PMUREG(0x0810)
-#define S5P_INFORM5                            S5P_PMUREG(0x0814)
-#define S5P_INFORM6                            S5P_PMUREG(0x0818)
-#define S5P_INFORM7                            S5P_PMUREG(0x081C)
-
-#define S5P_ARM_CORE0_LOWPWR                   S5P_PMUREG(0x1000)
-#define S5P_DIS_IRQ_CORE0                      S5P_PMUREG(0x1004)
-#define S5P_DIS_IRQ_CENTRAL0                   S5P_PMUREG(0x1008)
-#define S5P_ARM_CORE1_LOWPWR                   S5P_PMUREG(0x1010)
-#define S5P_DIS_IRQ_CORE1                      S5P_PMUREG(0x1014)
-#define S5P_DIS_IRQ_CENTRAL1                   S5P_PMUREG(0x1018)
-#define S5P_ARM_COMMON_LOWPWR                  S5P_PMUREG(0x1080)
-#define S5P_L2_0_LOWPWR                                S5P_PMUREG(0x10C0)
-#define S5P_L2_1_LOWPWR                                S5P_PMUREG(0x10C4)
-#define S5P_CMU_ACLKSTOP_LOWPWR                        S5P_PMUREG(0x1100)
-#define S5P_CMU_SCLKSTOP_LOWPWR                        S5P_PMUREG(0x1104)
-#define S5P_CMU_RESET_LOWPWR                   S5P_PMUREG(0x110C)
-#define S5P_APLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1120)
-#define S5P_MPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1124)
-#define S5P_VPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x1128)
-#define S5P_EPLL_SYSCLK_LOWPWR                 S5P_PMUREG(0x112C)
-#define S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR       S5P_PMUREG(0x1138)
-#define S5P_CMU_RESET_GPSALIVE_LOWPWR          S5P_PMUREG(0x113C)
-#define S5P_CMU_CLKSTOP_CAM_LOWPWR             S5P_PMUREG(0x1140)
-#define S5P_CMU_CLKSTOP_TV_LOWPWR              S5P_PMUREG(0x1144)
-#define S5P_CMU_CLKSTOP_MFC_LOWPWR             S5P_PMUREG(0x1148)
-#define S5P_CMU_CLKSTOP_G3D_LOWPWR             S5P_PMUREG(0x114C)
-#define S5P_CMU_CLKSTOP_LCD0_LOWPWR            S5P_PMUREG(0x1150)
-#define S5P_CMU_CLKSTOP_LCD1_LOWPWR            S5P_PMUREG(0x1154)
-#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR          S5P_PMUREG(0x1158)
-#define S5P_CMU_CLKSTOP_GPS_LOWPWR             S5P_PMUREG(0x115C)
-#define S5P_CMU_RESET_CAM_LOWPWR               S5P_PMUREG(0x1160)
-#define S5P_CMU_RESET_TV_LOWPWR                        S5P_PMUREG(0x1164)
-#define S5P_CMU_RESET_MFC_LOWPWR               S5P_PMUREG(0x1168)
-#define S5P_CMU_RESET_G3D_LOWPWR               S5P_PMUREG(0x116C)
-#define S5P_CMU_RESET_LCD0_LOWPWR              S5P_PMUREG(0x1170)
-#define S5P_CMU_RESET_LCD1_LOWPWR              S5P_PMUREG(0x1174)
-#define S5P_CMU_RESET_MAUDIO_LOWPWR            S5P_PMUREG(0x1178)
-#define S5P_CMU_RESET_GPS_LOWPWR               S5P_PMUREG(0x117C)
-#define S5P_TOP_BUS_LOWPWR                     S5P_PMUREG(0x1180)
-#define S5P_TOP_RETENTION_LOWPWR               S5P_PMUREG(0x1184)
-#define S5P_TOP_PWR_LOWPWR                     S5P_PMUREG(0x1188)
-#define S5P_LOGIC_RESET_LOWPWR                 S5P_PMUREG(0x11A0)
-#define S5P_ONENAND_MEM_LOWPWR                 S5P_PMUREG(0x11C0)
-#define S5P_MODIMIF_MEM_LOWPWR                 S5P_PMUREG(0x11C4)
-#define S5P_G2D_ACP_MEM_LOWPWR                 S5P_PMUREG(0x11C8)
-#define S5P_USBOTG_MEM_LOWPWR                  S5P_PMUREG(0x11CC)
-#define S5P_HSMMC_MEM_LOWPWR                   S5P_PMUREG(0x11D0)
-#define S5P_CSSYS_MEM_LOWPWR                   S5P_PMUREG(0x11D4)
-#define S5P_SECSS_MEM_LOWPWR                   S5P_PMUREG(0x11D8)
-#define S5P_PCIE_MEM_LOWPWR                    S5P_PMUREG(0x11E0)
-#define S5P_SATA_MEM_LOWPWR                    S5P_PMUREG(0x11E4)
-#define S5P_PAD_RETENTION_DRAM_LOWPWR          S5P_PMUREG(0x1200)
-#define S5P_PAD_RETENTION_MAUDIO_LOWPWR                S5P_PMUREG(0x1204)
-#define S5P_PAD_RETENTION_GPIO_LOWPWR          S5P_PMUREG(0x1220)
-#define S5P_PAD_RETENTION_UART_LOWPWR          S5P_PMUREG(0x1224)
-#define S5P_PAD_RETENTION_MMCA_LOWPWR          S5P_PMUREG(0x1228)
-#define S5P_PAD_RETENTION_MMCB_LOWPWR          S5P_PMUREG(0x122C)
-#define S5P_PAD_RETENTION_EBIA_LOWPWR          S5P_PMUREG(0x1230)
-#define S5P_PAD_RETENTION_EBIB_LOWPWR          S5P_PMUREG(0x1234)
-#define S5P_PAD_RETENTION_ISOLATION_LOWPWR     S5P_PMUREG(0x1240)
-#define S5P_PAD_RETENTION_ALV_SEL_LOWPWR       S5P_PMUREG(0x1260)
-#define S5P_XUSBXTI_LOWPWR                     S5P_PMUREG(0x1280)
-#define S5P_XXTI_LOWPWR                                S5P_PMUREG(0x1284)
-#define S5P_EXT_REGULATOR_LOWPWR               S5P_PMUREG(0x12C0)
-#define S5P_GPIO_MODE_LOWPWR                   S5P_PMUREG(0x1300)
-#define S5P_GPIO_MODE_MAUDIO_LOWPWR            S5P_PMUREG(0x1340)
-#define S5P_CAM_LOWPWR                         S5P_PMUREG(0x1380)
-#define S5P_TV_LOWPWR                          S5P_PMUREG(0x1384)
-#define S5P_MFC_LOWPWR                         S5P_PMUREG(0x1388)
-#define S5P_G3D_LOWPWR                         S5P_PMUREG(0x138C)
-#define S5P_LCD0_LOWPWR                                S5P_PMUREG(0x1390)
-#define S5P_LCD1_LOWPWR                                S5P_PMUREG(0x1394)
-#define S5P_MAUDIO_LOWPWR                      S5P_PMUREG(0x1398)
-#define S5P_GPS_LOWPWR                         S5P_PMUREG(0x139C)
-#define S5P_GPS_ALIVE_LOWPWR                   S5P_PMUREG(0x13A0)
-
-#define S5P_ARM_CORE0_CONFIGURATION            S5P_PMUREG(0x2000)
-#define S5P_ARM_CORE0_OPTION                   S5P_PMUREG(0x2008)
-#define S5P_ARM_CORE1_CONFIGURATION            S5P_PMUREG(0x2080)
-#define S5P_ARM_CORE1_STATUS                   S5P_PMUREG(0x2084)
-#define S5P_ARM_CORE1_OPTION                   S5P_PMUREG(0x2088)
-
-#define S5P_ARM_COMMON_OPTION                  S5P_PMUREG(0x2408)
-#define S5P_TOP_PWR_OPTION                     S5P_PMUREG(0x2C48)
-#define S5P_CAM_OPTION                         S5P_PMUREG(0x3C08)
-#define S5P_TV_OPTION                          S5P_PMUREG(0x3C28)
-#define S5P_MFC_OPTION                         S5P_PMUREG(0x3C48)
-#define S5P_G3D_OPTION                         S5P_PMUREG(0x3C68)
-#define S5P_LCD0_OPTION                                S5P_PMUREG(0x3C88)
-#define S5P_LCD1_OPTION                                S5P_PMUREG(0x3CA8)
-#define S5P_MAUDIO_OPTION                      S5P_PMUREG(0x3CC8)
-#define S5P_GPS_OPTION                         S5P_PMUREG(0x3CE8)
-#define S5P_GPS_ALIVE_OPTION                   S5P_PMUREG(0x3D08)
-
-#define S5P_PAD_RET_MAUDIO_OPTION              S5P_PMUREG(0x3028)
-#define S5P_PAD_RET_GPIO_OPTION                        S5P_PMUREG(0x3108)
-#define S5P_PAD_RET_UART_OPTION                        S5P_PMUREG(0x3128)
-#define S5P_PAD_RET_MMCA_OPTION                        S5P_PMUREG(0x3148)
-#define S5P_PAD_RET_MMCB_OPTION                        S5P_PMUREG(0x3168)
-#define S5P_PAD_RET_EBIA_OPTION                        S5P_PMUREG(0x3188)
-#define S5P_PAD_RET_EBIB_OPTION                        S5P_PMUREG(0x31A8)
-
-#define S5P_PMU_CAM_CONF                       S5P_PMUREG(0x3C00)
-#define S5P_PMU_TV_CONF                                S5P_PMUREG(0x3C20)
-#define S5P_PMU_MFC_CONF                       S5P_PMUREG(0x3C40)
-#define S5P_PMU_G3D_CONF                       S5P_PMUREG(0x3C60)
-#define S5P_PMU_LCD0_CONF                      S5P_PMUREG(0x3C80)
-#define S5P_PMU_LCD1_CONF                      S5P_PMUREG(0x3CA0)
-#define S5P_PMU_GPS_CONF                       S5P_PMUREG(0x3CE0)
-
-#define S5P_PMU_SATA_PHY_CONTROL_EN            0x1
-#define S5P_CORE_LOCAL_PWR_EN                  0x3
-#define S5P_INT_LOCAL_PWR_EN                   0x7
-
-#define S5P_CHECK_SLEEP                                0x00000BAD
-
-#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
deleted file mode 100644 (file)
index 68ff6ad..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - System MMU register
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_SYSMMU_H
-#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
-
-#define S5P_MMU_CTRL                   0x000
-#define S5P_MMU_CFG                    0x004
-#define S5P_MMU_STATUS                 0x008
-#define S5P_MMU_FLUSH                  0x00C
-#define S5P_PT_BASE_ADDR               0x014
-#define S5P_INT_STATUS                 0x018
-#define S5P_INT_CLEAR                  0x01C
-#define S5P_PAGE_FAULT_ADDR            0x024
-#define S5P_AW_FAULT_ADDR              0x028
-#define S5P_AR_FAULT_ADDR              0x02C
-#define S5P_DEFAULT_SLAVE_ADDR         0x030
-
-#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
deleted file mode 100644 (file)
index c337cf3..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_REGS_USB_PHY_H
-#define __PLAT_S5P_REGS_USB_PHY_H
-
-#define EXYNOS4_HSOTG_PHYREG(x)                ((x) + S3C_VA_USB_HSPHY)
-
-#define EXYNOS4_PHYPWR                 EXYNOS4_HSOTG_PHYREG(0x00)
-#define PHY1_HSIC_NORMAL_MASK          (0xf << 9)
-#define PHY1_HSIC1_SLEEP               (1 << 12)
-#define PHY1_HSIC1_FORCE_SUSPEND       (1 << 11)
-#define PHY1_HSIC0_SLEEP               (1 << 10)
-#define PHY1_HSIC0_FORCE_SUSPEND       (1 << 9)
-
-#define PHY1_STD_NORMAL_MASK           (0x7 << 6)
-#define PHY1_STD_SLEEP                 (1 << 8)
-#define PHY1_STD_ANALOG_POWERDOWN      (1 << 7)
-#define PHY1_STD_FORCE_SUSPEND         (1 << 6)
-
-#define PHY0_NORMAL_MASK               (0x39 << 0)
-#define PHY0_SLEEP                     (1 << 5)
-#define PHY0_OTG_DISABLE               (1 << 4)
-#define PHY0_ANALOG_POWERDOWN          (1 << 3)
-#define PHY0_FORCE_SUSPEND             (1 << 0)
-
-#define EXYNOS4_PHYCLK                 EXYNOS4_HSOTG_PHYREG(0x04)
-#define PHY1_COMMON_ON_N               (1 << 7)
-#define PHY0_COMMON_ON_N               (1 << 4)
-#define PHY0_ID_PULLUP                 (1 << 2)
-#define CLKSEL_MASK                    (0x3 << 0)
-#define CLKSEL_SHIFT                   (0)
-#define CLKSEL_48M                     (0x0 << 0)
-#define CLKSEL_12M                     (0x2 << 0)
-#define CLKSEL_24M                     (0x3 << 0)
-
-#define EXYNOS4_RSTCON                 EXYNOS4_HSOTG_PHYREG(0x08)
-#define HOST_LINK_PORT_SWRST_MASK      (0xf << 6)
-#define HOST_LINK_PORT2_SWRST          (1 << 9)
-#define HOST_LINK_PORT1_SWRST          (1 << 8)
-#define HOST_LINK_PORT0_SWRST          (1 << 7)
-#define HOST_LINK_ALL_SWRST            (1 << 6)
-
-#define PHY1_SWRST_MASK                        (0x7 << 3)
-#define PHY1_HSIC_SWRST                        (1 << 5)
-#define PHY1_STD_SWRST                 (1 << 4)
-#define PHY1_ALL_SWRST                 (1 << 3)
-
-#define PHY0_SWRST_MASK                        (0x7 << 0)
-#define PHY0_PHYLINK_SWRST             (1 << 2)
-#define PHY0_HLINK_SWRST               (1 << 1)
-#define PHY0_SWRST                     (1 << 0)
-
-#define EXYNOS4_PHY1CON                        EXYNOS4_HSOTG_PHYREG(0x34)
-#define FPENABLEN                      (1 << 0)
-
-#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/mach-exynos4/include/mach/sysmmu.h b/arch/arm/mach-exynos4/include/mach/sysmmu.h
deleted file mode 100644 (file)
index 6a5fbb5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Samsung sysmmu driver for EXYNOS4
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARM_ARCH_SYSMMU_H
-#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
-
-enum exynos4_sysmmu_ips {
-       SYSMMU_MDMA,
-       SYSMMU_SSS,
-       SYSMMU_FIMC0,
-       SYSMMU_FIMC1,
-       SYSMMU_FIMC2,
-       SYSMMU_FIMC3,
-       SYSMMU_JPEG,
-       SYSMMU_FIMD0,
-       SYSMMU_FIMD1,
-       SYSMMU_PCIe,
-       SYSMMU_G2D,
-       SYSMMU_ROTATOR,
-       SYSMMU_MDMA2,
-       SYSMMU_TV,
-       SYSMMU_MFC_L,
-       SYSMMU_MFC_R,
-       EXYNOS4_SYSMMU_TOTAL_IPNUM,
-};
-
-#define S5P_SYSMMU_TOTAL_IPNUM         EXYNOS4_SYSMMU_TOTAL_IPNUM
-
-extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
-
-typedef enum exynos4_sysmmu_ips sysmmu_ips;
-
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
-void sysmmu_clk_enable(sysmmu_ips ips);
-void sysmmu_clk_disable(sysmmu_ips ips);
-
-#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/system.h b/arch/arm/mach-exynos4/include/mach/system.h
deleted file mode 100644 (file)
index 5e3220c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/system.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-#include <plat/system-reset.h>
-
-static void arch_idle(void)
-{
-       /* nothing here yet */
-}
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/timex.h b/arch/arm/mach-exynos4/include/mach/timex.h
deleted file mode 100644 (file)
index 6d13875..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/timex.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2003-2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Based on arch/arm/mach-s5p6442/include/mach/timex.h
- *
- * EXYNOS4 - time parameters
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_TIMEX_H
-#define __ASM_ARCH_TIMEX_H __FILE__
-
-/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
- * a variable is useless. It seems as long as we make our timers an
- * exact multiple of HZ, any value that makes a 1->1 correspondence
- * for the time conversion functions to/from jiffies is acceptable.
-*/
-
-#define CLOCK_TICK_RATE 12000000
-
-#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-exynos4/include/mach/uncompress.h b/arch/arm/mach-exynos4/include/mach/uncompress.h
deleted file mode 100644 (file)
index 21d97bc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - uncompress code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H __FILE__
-
-#include <mach/map.h>
-#include <plat/uncompress.h>
-
-static void arch_detect_cpu(void)
-{
-       /* we do not need to do any cpu detection here at the moment. */
-
-       /*
-        * For preventing FIFO overrun or infinite loop of UART console,
-        * fifo_max should be the minimum fifo size of all of the UART channels
-        */
-       fifo_mask = S5PV210_UFSTAT_TXMASK;
-       fifo_max = 15 << S5PV210_UFSTAT_TXSHIFT;
-}
-#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/vmalloc.h b/arch/arm/mach-exynos4/include/mach/vmalloc.h
deleted file mode 100644 (file)
index 284330e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
- *
- * Based on arch/arm/mach-s5p6440/include/mach/vmalloc.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * EXYNOS4 vmalloc definition
-*/
-
-#ifndef __ASM_ARCH_VMALLOC_H
-#define __ASM_ARCH_VMALLOC_H __FILE__
-
-#define VMALLOC_END    0xF6000000UL
-
-#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
deleted file mode 100644 (file)
index a8a83e3..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/mach-exynos4/init.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
-       [0] = {
-               .name           = "uclk1",
-               .divisor        = 1,
-               .min_baud       = 0,
-               .max_baud       = 0,
-       },
-};
-
-/* uart registration process */
-void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-       struct s3c2410_uartcfg *tcfg = cfg;
-       u32 ucnt;
-
-       for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
-               if (!tcfg->clocks) {
-                       tcfg->has_fracval = 1;
-                       tcfg->clocks = exynos4_serial_clocks;
-                       tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
-               }
-               tcfg->flags |= NO_NEED_CHECK_CLKSRC;
-       }
-
-       s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
-}
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c
deleted file mode 100644 (file)
index 5a2758a..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* linux/arch/arm/mach-exynos4/irq-combiner.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Based on arch/arm/common/gic.c
- *
- * IRQ COMBINER support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-
-#include <asm/mach/irq.h>
-
-#define COMBINER_ENABLE_SET    0x0
-#define COMBINER_ENABLE_CLEAR  0x4
-#define COMBINER_INT_STATUS    0xC
-
-static DEFINE_SPINLOCK(irq_controller_lock);
-
-struct combiner_chip_data {
-       unsigned int irq_offset;
-       unsigned int irq_mask;
-       void __iomem *base;
-};
-
-static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
-
-static inline void __iomem *combiner_base(struct irq_data *data)
-{
-       struct combiner_chip_data *combiner_data =
-               irq_data_get_irq_chip_data(data);
-
-       return combiner_data->base;
-}
-
-static void combiner_mask_irq(struct irq_data *data)
-{
-       u32 mask = 1 << (data->irq % 32);
-
-       __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
-}
-
-static void combiner_unmask_irq(struct irq_data *data)
-{
-       u32 mask = 1 << (data->irq % 32);
-
-       __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
-}
-
-static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
-{
-       struct combiner_chip_data *chip_data = irq_get_handler_data(irq);
-       struct irq_chip *chip = irq_get_chip(irq);
-       unsigned int cascade_irq, combiner_irq;
-       unsigned long status;
-
-       chained_irq_enter(chip, desc);
-
-       spin_lock(&irq_controller_lock);
-       status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
-       spin_unlock(&irq_controller_lock);
-       status &= chip_data->irq_mask;
-
-       if (status == 0)
-               goto out;
-
-       combiner_irq = __ffs(status);
-
-       cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
-       if (unlikely(cascade_irq >= NR_IRQS))
-               do_bad_IRQ(cascade_irq, desc);
-       else
-               generic_handle_irq(cascade_irq);
-
- out:
-       chained_irq_exit(chip, desc);
-}
-
-static struct irq_chip combiner_chip = {
-       .name           = "COMBINER",
-       .irq_mask       = combiner_mask_irq,
-       .irq_unmask     = combiner_unmask_irq,
-};
-
-void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
-{
-       if (combiner_nr >= MAX_COMBINER_NR)
-               BUG();
-       if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
-               BUG();
-       irq_set_chained_handler(irq, combiner_handle_cascade_irq);
-}
-
-void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
-                         unsigned int irq_start)
-{
-       unsigned int i;
-
-       if (combiner_nr >= MAX_COMBINER_NR)
-               BUG();
-
-       combiner_data[combiner_nr].base = base;
-       combiner_data[combiner_nr].irq_offset = irq_start;
-       combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
-
-       /* Disable all interrupts */
-
-       __raw_writel(combiner_data[combiner_nr].irq_mask,
-                    base + COMBINER_ENABLE_CLEAR);
-
-       /* Setup the Linux IRQ subsystem */
-
-       for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
-                               + MAX_IRQ_IN_COMBINER; i++) {
-               irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq);
-               irq_set_chip_data(i, &combiner_data[combiner_nr]);
-               set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-       }
-}
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos4/irq-eint.c
deleted file mode 100644 (file)
index badb8c6..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/* linux/arch/arm/mach-exynos4/irq-eint.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - IRQ EINT support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/sysdev.h>
-#include <linux/gpio.h>
-
-#include <plat/pm.h>
-#include <plat/cpu.h>
-#include <plat/gpio-cfg.h>
-
-#include <mach/regs-gpio.h>
-
-#include <asm/mach/irq.h>
-
-static DEFINE_SPINLOCK(eint_lock);
-
-static unsigned int eint0_15_data[16];
-
-static unsigned int exynos4_get_irq_nr(unsigned int number)
-{
-       u32 ret = 0;
-
-       switch (number) {
-       case 0 ... 3:
-               ret = (number + IRQ_EINT0);
-               break;
-       case 4 ... 7:
-               ret = (number + (IRQ_EINT4 - 4));
-               break;
-       case 8 ... 15:
-               ret = (number + (IRQ_EINT8 - 8));
-               break;
-       default:
-               printk(KERN_ERR "number available : %d\n", number);
-       }
-
-       return ret;
-}
-
-static inline void exynos4_irq_eint_mask(struct irq_data *data)
-{
-       u32 mask;
-
-       spin_lock(&eint_lock);
-       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       mask |= eint_irq_to_bit(data->irq);
-       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       spin_unlock(&eint_lock);
-}
-
-static void exynos4_irq_eint_unmask(struct irq_data *data)
-{
-       u32 mask;
-
-       spin_lock(&eint_lock);
-       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       mask &= ~(eint_irq_to_bit(data->irq));
-       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
-       spin_unlock(&eint_lock);
-}
-
-static inline void exynos4_irq_eint_ack(struct irq_data *data)
-{
-       __raw_writel(eint_irq_to_bit(data->irq),
-                    S5P_EINT_PEND(EINT_REG_NR(data->irq)));
-}
-
-static void exynos4_irq_eint_maskack(struct irq_data *data)
-{
-       exynos4_irq_eint_mask(data);
-       exynos4_irq_eint_ack(data);
-}
-
-static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
-{
-       int offs = EINT_OFFSET(data->irq);
-       int shift;
-       u32 ctrl, mask;
-       u32 newvalue = 0;
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               newvalue = S5P_IRQ_TYPE_EDGE_RISING;
-               break;
-
-       case IRQ_TYPE_EDGE_FALLING:
-               newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
-               break;
-
-       case IRQ_TYPE_EDGE_BOTH:
-               newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
-               break;
-
-       case IRQ_TYPE_LEVEL_LOW:
-               newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
-               break;
-
-       case IRQ_TYPE_LEVEL_HIGH:
-               newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
-               break;
-
-       default:
-               printk(KERN_ERR "No such irq type %d", type);
-               return -EINVAL;
-       }
-
-       shift = (offs & 0x7) * 4;
-       mask = 0x7 << shift;
-
-       spin_lock(&eint_lock);
-       ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
-       ctrl &= ~mask;
-       ctrl |= newvalue << shift;
-       __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
-       spin_unlock(&eint_lock);
-
-       switch (offs) {
-       case 0 ... 7:
-               s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
-               break;
-       case 8 ... 15:
-               s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
-               break;
-       case 16 ... 23:
-               s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
-               break;
-       case 24 ... 31:
-               s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
-               break;
-       default:
-               printk(KERN_ERR "No such irq number %d", offs);
-       }
-
-       return 0;
-}
-
-static struct irq_chip exynos4_irq_eint = {
-       .name           = "exynos4-eint",
-       .irq_mask       = exynos4_irq_eint_mask,
-       .irq_unmask     = exynos4_irq_eint_unmask,
-       .irq_mask_ack   = exynos4_irq_eint_maskack,
-       .irq_ack        = exynos4_irq_eint_ack,
-       .irq_set_type   = exynos4_irq_eint_set_type,
-#ifdef CONFIG_PM
-       .irq_set_wake   = s3c_irqext_wake,
-#endif
-};
-
-/* exynos4_irq_demux_eint
- *
- * This function demuxes the IRQ from from EINTs 16 to 31.
- * It is designed to be inlined into the specific handler
- * s5p_irq_demux_eintX_Y.
- *
- * Each EINT pend/mask registers handle eight of them.
- */
-static inline void exynos4_irq_demux_eint(unsigned int start)
-{
-       unsigned int irq;
-
-       u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
-       u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
-
-       status &= ~mask;
-       status &= 0xff;
-
-       while (status) {
-               irq = fls(status) - 1;
-               generic_handle_irq(irq + start);
-               status &= ~(1 << irq);
-       }
-}
-
-static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-       chained_irq_enter(chip, desc);
-       exynos4_irq_demux_eint(IRQ_EINT(16));
-       exynos4_irq_demux_eint(IRQ_EINT(24));
-       chained_irq_exit(chip, desc);
-}
-
-static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
-{
-       u32 *irq_data = irq_get_handler_data(irq);
-       struct irq_chip *chip = irq_get_chip(irq);
-
-       chained_irq_enter(chip, desc);
-       chip->irq_mask(&desc->irq_data);
-
-       if (chip->irq_ack)
-               chip->irq_ack(&desc->irq_data);
-
-       generic_handle_irq(*irq_data);
-
-       chip->irq_unmask(&desc->irq_data);
-       chained_irq_exit(chip, desc);
-}
-
-int __init exynos4_init_irq_eint(void)
-{
-       int irq;
-
-       for (irq = 0 ; irq <= 31 ; irq++) {
-               irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
-                                        handle_level_irq);
-               set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
-       }
-
-       irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
-
-       for (irq = 0 ; irq <= 15 ; irq++) {
-               eint0_15_data[irq] = IRQ_EINT(irq);
-
-               irq_set_handler_data(exynos4_get_irq_nr(irq),
-                                    &eint0_15_data[irq]);
-               irq_set_chained_handler(exynos4_get_irq_nr(irq),
-                                       exynos4_irq_eint0_15);
-       }
-
-       return 0;
-}
-
-arch_initcall(exynos4_init_irq_eint);
diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c
deleted file mode 100644 (file)
index f0ca6c1..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-armlex4210.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/smsc911x.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/exynos4.h>
-#include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/sdhci.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define ARMLEX4210_UCON_DEFAULT        (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define ARMLEX4210_ULCON_DEFAULT       S3C2410_LCON_CS8
-
-#define ARMLEX4210_UFCON_DEFAULT       (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG4 |        \
-                                S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport         = 0,
-               .flags          = 0,
-               .ucon           = ARMLEX4210_UCON_DEFAULT,
-               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
-               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
-       },
-       [1] = {
-               .hwport         = 1,
-               .flags          = 0,
-               .ucon           = ARMLEX4210_UCON_DEFAULT,
-               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
-               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
-       },
-       [2] = {
-               .hwport         = 2,
-               .flags          = 0,
-               .ucon           = ARMLEX4210_UCON_DEFAULT,
-               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
-               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
-       },
-       [3] = {
-               .hwport         = 3,
-               .flags          = 0,
-               .ucon           = ARMLEX4210_UCON_DEFAULT,
-               .ulcon          = ARMLEX4210_ULCON_DEFAULT,
-               .ufcon          = ARMLEX4210_UFCON_DEFAULT,
-       },
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc0_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_PERMANENT,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
-       .max_width              = 8,
-       .host_caps              = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPX2(5),
-       .ext_cd_gpio_invert     = 1,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-       .max_width              = 4,
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_PERMANENT,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-       .max_width              = 4,
-};
-
-static void __init armlex4210_sdhci_init(void)
-{
-       s3c_sdhci0_set_platdata(&armlex4210_hsmmc0_pdata);
-       s3c_sdhci2_set_platdata(&armlex4210_hsmmc2_pdata);
-       s3c_sdhci3_set_platdata(&armlex4210_hsmmc3_pdata);
-}
-
-static void __init armlex4210_wlan_init(void)
-{
-       /* enable */
-       s3c_gpio_cfgpin(EXYNOS4_GPX2(0), S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(EXYNOS4_GPX2(0), S3C_GPIO_PULL_UP);
-
-       /* reset */
-       s3c_gpio_cfgpin(EXYNOS4_GPX1(6), S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
-
-       /* wakeup */
-       s3c_gpio_cfgpin(EXYNOS4_GPX1(5), S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(EXYNOS4_GPX1(5), S3C_GPIO_PULL_UP);
-}
-
-static struct resource armlex4210_smsc911x_resources[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_SROM_BANK(3),
-               .end    = EXYNOS4_PA_SROM_BANK(3) + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_EINT(27),
-               .end    = IRQ_EINT(27),
-               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
-       },
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
-       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
-       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-       .phy_interface  = PHY_INTERFACE_MODE_MII,
-       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device armlex4210_smsc911x = {
-       .name           = "smsc911x",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(armlex4210_smsc911x_resources),
-       .resource       = armlex4210_smsc911x_resources,
-       .dev            = {
-               .platform_data  = &smsc9215_config,
-       },
-};
-
-static struct platform_device *armlex4210_devices[] __initdata = {
-       &s3c_device_hsmmc0,
-       &s3c_device_hsmmc2,
-       &s3c_device_hsmmc3,
-       &s3c_device_rtc,
-       &s3c_device_wdt,
-       &exynos4_device_sysmmu,
-       &samsung_asoc_dma,
-       &armlex4210_smsc911x,
-       &exynos4_device_ahci,
-};
-
-static void __init armlex4210_smsc911x_init(void)
-{
-       u32 cs1;
-
-       /* configure nCS1 width to 16 bits */
-       cs1 = __raw_readl(S5P_SROM_BW) &
-               ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
-       cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
-               (0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
-               (1 << S5P_SROM_BW__ADDRMODE__SHIFT) |
-               (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
-               S5P_SROM_BW__NCS1__SHIFT;
-       __raw_writel(cs1, S5P_SROM_BW);
-
-       /* set timing for nCS1 suitable for ethernet chip */
-       __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
-                    (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
-                    (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
-                    (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-static void __init armlex4210_map_io(void)
-{
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(24000000);
-       s3c24xx_init_uarts(armlex4210_uartcfgs,
-                          ARRAY_SIZE(armlex4210_uartcfgs));
-}
-
-static void __init armlex4210_machine_init(void)
-{
-       armlex4210_smsc911x_init();
-
-       armlex4210_sdhci_init();
-
-       armlex4210_wlan_init();
-
-       platform_add_devices(armlex4210_devices,
-                            ARRAY_SIZE(armlex4210_devices));
-}
-
-MACHINE_START(ARMLEX4210, "ARMLEX4210")
-       /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = armlex4210_map_io,
-       .init_machine   = armlex4210_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
deleted file mode 100644 (file)
index 6e05368..0000000
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/mach-nuri.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/i2c-gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
-#include <linux/power/max8903_charger.h>
-#include <linux/power/max17042_battery.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/mfd/max8997.h>
-#include <linux/mfd/max8997-private.h>
-#include <linux/mmc/host.h>
-#include <linux/fb.h>
-#include <linux/pwm_backlight.h>
-
-#include <video/platform_lcd.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/adc.h>
-#include <plat/regs-serial.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/sdhci.h>
-#include <plat/ehci.h>
-#include <plat/clock.h>
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-#include <plat/mfc.h>
-#include <plat/pd.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define NURI_UCON_DEFAULT      (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define NURI_ULCON_DEFAULT     S3C2410_LCON_CS8
-
-#define NURI_UFCON_DEFAULT     (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG256 |      \
-                                S5PV210_UFCON_RXTRIG256)
-
-enum fixed_regulator_id {
-       FIXED_REG_ID_MMC = 0,
-       FIXED_REG_ID_MAX8903,
-};
-
-static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
-       {
-               .hwport         = 0,
-               .ucon           = NURI_UCON_DEFAULT,
-               .ulcon          = NURI_ULCON_DEFAULT,
-               .ufcon          = NURI_UFCON_DEFAULT,
-       },
-       {
-               .hwport         = 1,
-               .ucon           = NURI_UCON_DEFAULT,
-               .ulcon          = NURI_ULCON_DEFAULT,
-               .ufcon          = NURI_UFCON_DEFAULT,
-       },
-       {
-               .hwport         = 2,
-               .ucon           = NURI_UCON_DEFAULT,
-               .ulcon          = NURI_ULCON_DEFAULT,
-               .ufcon          = NURI_UFCON_DEFAULT,
-       },
-       {
-               .hwport         = 3,
-               .ucon           = NURI_UCON_DEFAULT,
-               .ulcon          = NURI_ULCON_DEFAULT,
-               .ufcon          = NURI_UFCON_DEFAULT,
-       },
-};
-
-/* eMMC */
-static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
-       .max_width              = 8,
-       .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE | MMC_CAP_ERASE),
-       .cd_type                = S3C_SDHCI_CD_PERMANENT,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct regulator_consumer_supply emmc_supplies[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
-       REGULATOR_SUPPLY("vmmc", "dw_mmc"),
-};
-
-static struct regulator_init_data emmc_fixed_voltage_init_data = {
-       .constraints            = {
-               .name           = "VMEM_VDD_2.8V",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(emmc_supplies),
-       .consumer_supplies      = emmc_supplies,
-};
-
-static struct fixed_voltage_config emmc_fixed_voltage_config = {
-       .supply_name            = "MASSMEMORY_EN (inverted)",
-       .microvolts             = 2800000,
-       .gpio                   = EXYNOS4_GPL1(1),
-       .enable_high            = false,
-       .init_data              = &emmc_fixed_voltage_init_data,
-};
-
-static struct platform_device emmc_fixed_voltage = {
-       .name                   = "reg-fixed-voltage",
-       .id                     = FIXED_REG_ID_MMC,
-       .dev                    = {
-               .platform_data  = &emmc_fixed_voltage_config,
-       },
-};
-
-/* SD */
-static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
-       .max_width              = 4,
-       .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
-       .ext_cd_gpio            = EXYNOS4_GPX3(3),      /* XEINT_27 */
-       .ext_cd_gpio_invert     = 1,
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-/* WLAN */
-static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
-       .max_width              = 4,
-       .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-       .cd_type                = S3C_SDHCI_CD_EXTERNAL,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static void __init nuri_sdhci_init(void)
-{
-       s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
-       s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
-       s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
-}
-
-/* GPIO KEYS */
-static struct gpio_keys_button nuri_gpio_keys_tables[] = {
-       {
-               .code                   = KEY_VOLUMEUP,
-               .gpio                   = EXYNOS4_GPX2(0),      /* XEINT16 */
-               .desc                   = "gpio-keys: KEY_VOLUMEUP",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_VOLUMEDOWN,
-               .gpio                   = EXYNOS4_GPX2(1),      /* XEINT17 */
-               .desc                   = "gpio-keys: KEY_VOLUMEDOWN",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_POWER,
-               .gpio                   = EXYNOS4_GPX2(7),      /* XEINT23 */
-               .desc                   = "gpio-keys: KEY_POWER",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .wakeup                 = 1,
-               .debounce_interval      = 1,
-       },
-};
-
-static struct gpio_keys_platform_data nuri_gpio_keys_data = {
-       .buttons                = nuri_gpio_keys_tables,
-       .nbuttons               = ARRAY_SIZE(nuri_gpio_keys_tables),
-};
-
-static struct platform_device nuri_gpio_keys = {
-       .name                   = "gpio-keys",
-       .dev                    = {
-               .platform_data  = &nuri_gpio_keys_data,
-       },
-};
-
-static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
-{
-       int gpio = EXYNOS4_GPE1(5);
-
-       gpio_request(gpio, "LVDS_nSHDN");
-       gpio_direction_output(gpio, power);
-       gpio_free(gpio);
-}
-
-static int nuri_bl_init(struct device *dev)
-{
-       int ret, gpio = EXYNOS4_GPE2(3);
-
-       ret = gpio_request(gpio, "LCD_LDO_EN");
-       if (!ret)
-               gpio_direction_output(gpio, 0);
-
-       return ret;
-}
-
-static int nuri_bl_notify(struct device *dev, int brightness)
-{
-       if (brightness < 1)
-               brightness = 0;
-
-       gpio_set_value(EXYNOS4_GPE2(3), 1);
-
-       return brightness;
-}
-
-static void nuri_bl_exit(struct device *dev)
-{
-       gpio_free(EXYNOS4_GPE2(3));
-}
-
-/* nuri pwm backlight */
-static struct platform_pwm_backlight_data nuri_backlight_data = {
-       .pwm_id                 = 0,
-       .pwm_period_ns          = 30000,
-       .max_brightness         = 100,
-       .dft_brightness         = 50,
-       .init                   = nuri_bl_init,
-       .notify                 = nuri_bl_notify,
-       .exit                   = nuri_bl_exit,
-};
-
-static struct platform_device nuri_backlight_device = {
-       .name                   = "pwm-backlight",
-       .id                     = -1,
-       .dev                    = {
-               .parent         = &s3c_device_timer[0].dev,
-               .platform_data  = &nuri_backlight_data,
-       },
-};
-
-static struct plat_lcd_data nuri_lcd_platform_data = {
-       .set_power              = nuri_lcd_power_on,
-};
-
-static struct platform_device nuri_lcd_device = {
-       .name                   = "platform-lcd",
-       .id                     = -1,
-       .dev                    = {
-               .platform_data  = &nuri_lcd_platform_data,
-       },
-};
-
-/* I2C1 */
-static struct i2c_board_info i2c1_devs[] __initdata = {
-       /* Gyro, To be updated */
-};
-
-/* TSP */
-static u8 mxt_init_vals[] = {
-       /* MXT_GEN_COMMAND(6) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_GEN_POWER(7) */
-       0x20, 0xff, 0x32,
-       /* MXT_GEN_ACQUIRE(8) */
-       0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
-       /* MXT_TOUCH_MULTI(9) */
-       0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
-       0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00,
-       /* MXT_TOUCH_KEYARRAY(15) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-       0x00,
-       /* MXT_SPT_GPIOPWM(19) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_GRIPFACE(20) */
-       0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
-       0x0f, 0x0a,
-       /* MXT_PROCG_NOISE(22) */
-       0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
-       0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
-       /* MXT_TOUCH_PROXIMITY(23) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_ONETOUCH(24) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_SPT_SELFTEST(25) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00,
-       /* MXT_PROCI_TWOTOUCH(27) */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       /* MXT_SPT_CTECONFIG(28) */
-       0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
-};
-
-static struct mxt_platform_data mxt_platform_data = {
-       .config                 = mxt_init_vals,
-       .config_length          = ARRAY_SIZE(mxt_init_vals),
-
-       .x_line                 = 18,
-       .y_line                 = 11,
-       .x_size                 = 1024,
-       .y_size                 = 600,
-       .blen                   = 0x1,
-       .threshold              = 0x28,
-       .voltage                = 2800000,              /* 2.8V */
-       .orient                 = MXT_DIAGONAL_COUNTER,
-       .irqflags               = IRQF_TRIGGER_FALLING,
-};
-
-static struct s3c2410_platform_i2c i2c3_data __initdata = {
-       .flags          = 0,
-       .bus_num        = 3,
-       .slave_addr     = 0x10,
-       .frequency      = 400 * 1000,
-       .sda_delay      = 100,
-};
-
-static struct i2c_board_info i2c3_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
-               .platform_data  = &mxt_platform_data,
-               .irq            = IRQ_EINT(4),
-       },
-};
-
-static void __init nuri_tsp_init(void)
-{
-       int gpio;
-
-       /* TOUCH_INT: XEINT_4 */
-       gpio = EXYNOS4_GPX0(4);
-       gpio_request(gpio, "TOUCH_INT");
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-}
-
-static struct regulator_consumer_supply __initdata max8997_ldo1_[] = {
-       REGULATOR_SUPPLY("vdd", "s5p-adc"), /* Used by CPU's ADC drv */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo3_[] = {
-       REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"), /* MIPI */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
-       REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"), /* MIPI */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
-       REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
-       REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo8_[] = {
-       REGULATOR_SUPPLY("vusb_d", NULL), /* Used by CPU */
-       REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo11_[] = {
-       REGULATOR_SUPPLY("vcc", "platform-lcd"), /* U804 LVDS */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo12_[] = {
-       REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo13_[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo14_[] = {
-       REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
-};
-static struct regulator_consumer_supply __initdata max8997_ldo15_[] = {
-       REGULATOR_SUPPLY("avdd", "3-004a"), /* Touch Screen */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo16_[] = {
-       REGULATOR_SUPPLY("d_sensor", "0-001f"), /* HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo18_[] = {
-       REGULATOR_SUPPLY("vdd", "3-004a"), /* Touch Screen */
-};
-static struct regulator_consumer_supply __initdata max8997_buck1_[] = {
-       REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata max8997_buck2_[] = {
-       REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata max8997_buck3_[] = {
-       REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
-};
-static struct regulator_consumer_supply __initdata max8997_buck4_[] = {
-       REGULATOR_SUPPLY("core", "0-001f"), /* HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_buck6_[] = {
-       REGULATOR_SUPPLY("dig_28", "0-001f"), /* pin "7" of HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_esafeout1_[] = {
-       REGULATOR_SUPPLY("usb_vbus", NULL), /* CPU's USB OTG */
-};
-static struct regulator_consumer_supply __initdata max8997_esafeout2_[] = {
-       REGULATOR_SUPPLY("usb_vbus", "modemctl"), /* VBUS of Modem */
-};
-
-static struct regulator_consumer_supply __initdata max8997_charger_[] = {
-       REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
-};
-static struct regulator_consumer_supply __initdata max8997_chg_toff_[] = {
-       REGULATOR_SUPPLY("vinchg_stop", NULL), /* for jack interrupt handlers */
-};
-
-static struct regulator_consumer_supply __initdata max8997_32khz_ap_[] = {
-       REGULATOR_SUPPLY("gps_clk", "bcm4751"),
-       REGULATOR_SUPPLY("bt_clk", "bcm4330-b1"),
-       REGULATOR_SUPPLY("wifi_clk", "bcm433-b1"),
-};
-
-static struct regulator_init_data __initdata max8997_ldo1_data = {
-       .constraints    = {
-               .name           = "VADC_3.3V_C210",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo1_),
-       .consumer_supplies      = max8997_ldo1_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo2_data = {
-       .constraints    = {
-               .name           = "VALIVE_1.1V_C210",
-               .min_uV         = 1100000,
-               .max_uV         = 1100000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_ldo3_data = {
-       .constraints    = {
-               .name           = "VUSB_1.1V_C210",
-               .min_uV         = 1100000,
-               .max_uV         = 1100000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo3_),
-       .consumer_supplies      = max8997_ldo3_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo4_data = {
-       .constraints    = {
-               .name           = "VMIPI_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo4_),
-       .consumer_supplies      = max8997_ldo4_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo5_data = {
-       .constraints    = {
-               .name           = "VHSIC_1.2V_C210",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo5_),
-       .consumer_supplies      = max8997_ldo5_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo6_data = {
-       .constraints    = {
-               .name           = "VCC_1.8V_PDA",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_ldo7_data = {
-       .constraints    = {
-               .name           = "CAM_ISP_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo7_),
-       .consumer_supplies      = max8997_ldo7_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo8_data = {
-       .constraints    = {
-               .name           = "VUSB/VDAC_3.3V_C210",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo8_),
-       .consumer_supplies      = max8997_ldo8_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo9_data = {
-       .constraints    = {
-               .name           = "VCC_2.8V_PDA",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_ldo10_data = {
-       .constraints    = {
-               .name           = "VPLL_1.1V_C210",
-               .min_uV         = 1100000,
-               .max_uV         = 1100000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_ldo11_data = {
-       .constraints    = {
-               .name           = "LVDS_VDD3.3V",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .boot_on        = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo11_),
-       .consumer_supplies      = max8997_ldo11_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo12_data = {
-       .constraints    = {
-               .name           = "VT_CAM_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo12_),
-       .consumer_supplies      = max8997_ldo12_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo13_data = {
-       .constraints    = {
-               .name           = "VTF_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo13_),
-       .consumer_supplies      = max8997_ldo13_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo14_data = {
-       .constraints    = {
-               .name           = "VCC_3.0V_MOTOR",
-               .min_uV         = 3000000,
-               .max_uV         = 3000000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo14_),
-       .consumer_supplies      = max8997_ldo14_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo15_data = {
-       .constraints    = {
-               .name           = "VTOUCH_ADVV2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo15_),
-       .consumer_supplies      = max8997_ldo15_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo16_data = {
-       .constraints    = {
-               .name           = "CAM_SENSOR_IO_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo16_),
-       .consumer_supplies      = max8997_ldo16_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo18_data = {
-       .constraints    = {
-               .name           = "VTOUCH_VDD2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_ldo18_),
-       .consumer_supplies      = max8997_ldo18_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo21_data = {
-       .constraints    = {
-               .name           = "VDDQ_M1M2_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_buck1_data = {
-       .constraints    = {
-               .name           = "VARM_1.2V_C210",
-               .min_uV         = 900000,
-               .max_uV         = 1350000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-               .always_on      = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_buck1_),
-       .consumer_supplies = max8997_buck1_,
-};
-
-static struct regulator_init_data __initdata max8997_buck2_data = {
-       .constraints    = {
-               .name           = "VINT_1.1V_C210",
-               .min_uV         = 900000,
-               .max_uV         = 1100000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-               .always_on      = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_buck2_),
-       .consumer_supplies = max8997_buck2_,
-};
-
-static struct regulator_init_data __initdata max8997_buck3_data = {
-       .constraints    = {
-               .name           = "VG3D_1.1V_C210",
-               .min_uV         = 900000,
-               .max_uV         = 1100000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-                                 REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_buck3_),
-       .consumer_supplies = max8997_buck3_,
-};
-
-static struct regulator_init_data __initdata max8997_buck4_data = {
-       .constraints    = {
-               .name           = "CAM_ISP_CORE_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_buck4_),
-       .consumer_supplies = max8997_buck4_,
-};
-
-static struct regulator_init_data __initdata max8997_buck5_data = {
-       .constraints    = {
-               .name           = "VMEM_1.2V_C210",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_buck6_data = {
-       .constraints    = {
-               .name           = "CAM_AF_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_buck6_),
-       .consumer_supplies = max8997_buck6_,
-};
-
-static struct regulator_init_data __initdata max8997_buck7_data = {
-       .constraints    = {
-               .name           = "VCC_SUB_2.0V",
-               .min_uV         = 2000000,
-               .max_uV         = 2000000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_32khz_ap_data = {
-       .constraints    = {
-               .name           = "32KHz AP",
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-       .num_consumer_supplies = ARRAY_SIZE(max8997_32khz_ap_),
-       .consumer_supplies = max8997_32khz_ap_,
-};
-
-static struct regulator_init_data __initdata max8997_32khz_cp_data = {
-       .constraints    = {
-               .name           = "32KHz CP",
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_vichg_data = {
-       .constraints    = {
-               .name           = "VICHG",
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data __initdata max8997_esafeout1_data = {
-       .constraints    = {
-               .name           = "SAFEOUT1",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_esafeout1_),
-       .consumer_supplies      = max8997_esafeout1_,
-};
-
-static struct regulator_init_data __initdata max8997_esafeout2_data = {
-       .constraints    = {
-               .name           = "SAFEOUT2",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_esafeout2_),
-       .consumer_supplies      = max8997_esafeout2_,
-};
-
-static struct regulator_init_data __initdata max8997_charger_cv_data = {
-       .constraints    = {
-               .name           = "CHARGER_CV",
-               .min_uV         = 4200000,
-               .max_uV         = 4200000,
-               .apply_uV       = 1,
-       },
-};
-
-static struct regulator_init_data __initdata max8997_charger_data = {
-       .constraints    = {
-               .name           = "CHARGER",
-               .min_uA         = 200000,
-               .max_uA         = 950000,
-               .boot_on        = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS |
-                               REGULATOR_CHANGE_CURRENT,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_charger_),
-       .consumer_supplies      = max8997_charger_,
-};
-
-static struct regulator_init_data __initdata max8997_charger_topoff_data = {
-       .constraints    = {
-               .name           = "CHARGER TOPOFF",
-               .min_uA         = 50000,
-               .max_uA         = 200000,
-               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(max8997_chg_toff_),
-       .consumer_supplies      = max8997_chg_toff_,
-};
-
-static struct max8997_regulator_data __initdata nuri_max8997_regulators[] = {
-       { MAX8997_LDO1, &max8997_ldo1_data },
-       { MAX8997_LDO2, &max8997_ldo2_data },
-       { MAX8997_LDO3, &max8997_ldo3_data },
-       { MAX8997_LDO4, &max8997_ldo4_data },
-       { MAX8997_LDO5, &max8997_ldo5_data },
-       { MAX8997_LDO6, &max8997_ldo6_data },
-       { MAX8997_LDO7, &max8997_ldo7_data },
-       { MAX8997_LDO8, &max8997_ldo8_data },
-       { MAX8997_LDO9, &max8997_ldo9_data },
-       { MAX8997_LDO10, &max8997_ldo10_data },
-       { MAX8997_LDO11, &max8997_ldo11_data },
-       { MAX8997_LDO12, &max8997_ldo12_data },
-       { MAX8997_LDO13, &max8997_ldo13_data },
-       { MAX8997_LDO14, &max8997_ldo14_data },
-       { MAX8997_LDO15, &max8997_ldo15_data },
-       { MAX8997_LDO16, &max8997_ldo16_data },
-
-       { MAX8997_LDO18, &max8997_ldo18_data },
-       { MAX8997_LDO21, &max8997_ldo21_data },
-
-       { MAX8997_BUCK1, &max8997_buck1_data },
-       { MAX8997_BUCK2, &max8997_buck2_data },
-       { MAX8997_BUCK3, &max8997_buck3_data },
-       { MAX8997_BUCK4, &max8997_buck4_data },
-       { MAX8997_BUCK5, &max8997_buck5_data },
-       { MAX8997_BUCK6, &max8997_buck6_data },
-       { MAX8997_BUCK7, &max8997_buck7_data },
-
-       { MAX8997_EN32KHZ_AP, &max8997_32khz_ap_data },
-       { MAX8997_EN32KHZ_CP, &max8997_32khz_cp_data },
-
-       { MAX8997_ENVICHG, &max8997_vichg_data },
-       { MAX8997_ESAFEOUT1, &max8997_esafeout1_data },
-       { MAX8997_ESAFEOUT2, &max8997_esafeout2_data },
-       { MAX8997_CHARGER_CV, &max8997_charger_cv_data },
-       { MAX8997_CHARGER, &max8997_charger_data },
-       { MAX8997_CHARGER_TOPOFF, &max8997_charger_topoff_data },
-};
-
-static struct max8997_platform_data __initdata nuri_max8997_pdata = {
-       .wakeup                 = 1,
-
-       .num_regulators         = ARRAY_SIZE(nuri_max8997_regulators),
-       .regulators             = nuri_max8997_regulators,
-
-       .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
-       .buck2_gpiodvs = true,
-
-       .buck1_voltage[0] = 1350000, /* 1.35V */
-       .buck1_voltage[1] = 1300000, /* 1.3V */
-       .buck1_voltage[2] = 1250000, /* 1.25V */
-       .buck1_voltage[3] = 1200000, /* 1.2V */
-       .buck1_voltage[4] = 1150000, /* 1.15V */
-       .buck1_voltage[5] = 1100000, /* 1.1V */
-       .buck1_voltage[6] = 1000000, /* 1.0V */
-       .buck1_voltage[7] = 950000, /* 0.95V */
-
-       .buck2_voltage[0] = 1100000, /* 1.1V */
-       .buck2_voltage[1] = 1000000, /* 1.0V */
-       .buck2_voltage[2] = 950000, /* 0.95V */
-       .buck2_voltage[3] = 900000, /* 0.9V */
-       .buck2_voltage[4] = 1100000, /* 1.1V */
-       .buck2_voltage[5] = 1000000, /* 1.0V */
-       .buck2_voltage[6] = 950000, /* 0.95V */
-       .buck2_voltage[7] = 900000, /* 0.9V */
-
-       .buck5_voltage[0] = 1200000, /* 1.2V */
-       .buck5_voltage[1] = 1200000, /* 1.2V */
-       .buck5_voltage[2] = 1200000, /* 1.2V */
-       .buck5_voltage[3] = 1200000, /* 1.2V */
-       .buck5_voltage[4] = 1200000, /* 1.2V */
-       .buck5_voltage[5] = 1200000, /* 1.2V */
-       .buck5_voltage[6] = 1200000, /* 1.2V */
-       .buck5_voltage[7] = 1200000, /* 1.2V */
-};
-
-/* GPIO I2C 5 (PMIC) */
-enum { I2C5_MAX8997 };
-static struct i2c_board_info i2c5_devs[] __initdata = {
-       [I2C5_MAX8997] = {
-               I2C_BOARD_INFO("max8997", 0xCC >> 1),
-               .platform_data  = &nuri_max8997_pdata,
-       },
-};
-
-static struct max17042_platform_data nuri_battery_platform_data = {
-};
-
-/* GPIO I2C 9 (Fuel Gauge) */
-static struct i2c_gpio_platform_data i2c9_gpio_data = {
-       .sda_pin                = EXYNOS4_GPY4(0),      /* XM0ADDR_8 */
-       .scl_pin                = EXYNOS4_GPY4(1),      /* XM0ADDR_9 */
-};
-static struct platform_device i2c9_gpio = {
-       .name                   = "i2c-gpio",
-       .id                     = 9,
-       .dev                    = {
-               .platform_data  = &i2c9_gpio_data,
-       },
-};
-enum { I2C9_MAX17042};
-static struct i2c_board_info i2c9_devs[] __initdata = {
-       [I2C9_MAX17042] = {
-               I2C_BOARD_INFO("max17042", 0x36),
-               .platform_data = &nuri_battery_platform_data,
-       },
-};
-
-/* MAX8903 Secondary Charger */
-static struct regulator_consumer_supply supplies_max8903[] = {
-       REGULATOR_SUPPLY("vinchg2", "charger-manager.0"),
-};
-
-static struct regulator_init_data max8903_charger_en_data = {
-       .constraints = {
-               .name           = "VOUT_CHARGER",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .boot_on        = 1,
-       },
-       .num_consumer_supplies = ARRAY_SIZE(supplies_max8903),
-       .consumer_supplies = supplies_max8903,
-};
-
-static struct fixed_voltage_config max8903_charger_en = {
-       .supply_name = "VOUT_CHARGER",
-       .microvolts = 5000000, /* Assume 5VDC */
-       .gpio = EXYNOS4_GPY4(5), /* TA_EN negaged */
-       .enable_high = 0, /* Enable = Low */
-       .enabled_at_boot = 1,
-       .init_data = &max8903_charger_en_data,
-};
-
-static struct platform_device max8903_fixed_reg_dev = {
-       .name = "reg-fixed-voltage",
-       .id = FIXED_REG_ID_MAX8903,
-       .dev = { .platform_data = &max8903_charger_en },
-};
-
-static struct max8903_pdata nuri_max8903 = {
-       /*
-        * cen: don't control with the driver, let it be
-        * controlled by regulator above
-        */
-       .dok = EXYNOS4_GPX1(4), /* TA_nCONNECTED */
-       /* uok, usus: not connected */
-       .chg = EXYNOS4_GPE2(0), /* TA_nCHG */
-       /* flt: vcc_1.8V_pda */
-       .dcm = EXYNOS4_GPL0(1), /* CURR_ADJ */
-
-       .dc_valid = true,
-       .usb_valid = false, /* USB is not wired to MAX8903 */
-};
-
-static struct platform_device nuri_max8903_device = {
-       .name                   = "max8903-charger",
-       .dev                    = {
-               .platform_data  = &nuri_max8903,
-       },
-};
-
-static struct device *nuri_cm_devices[] = {
-       &s3c_device_i2c5.dev,
-       &s3c_device_adc.dev,
-       NULL, /* Reserved for UART */
-       NULL,
-};
-
-static void __init nuri_power_init(void)
-{
-       int gpio;
-       int irq_base = IRQ_GPIO_END + 1;
-       int ta_en = 0;
-
-       nuri_max8997_pdata.irq_base = irq_base;
-       irq_base += MAX8997_IRQ_NR;
-
-       gpio = EXYNOS4_GPX0(7);
-       gpio_request(gpio, "AP_PMIC_IRQ");
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-
-       gpio = EXYNOS4_GPX2(3);
-       gpio_request(gpio, "FUEL_ALERT");
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-
-       gpio = nuri_max8903.dok;
-       gpio_request(gpio, "TA_nCONNECTED");
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       ta_en = gpio_get_value(gpio) ? 0 : 1;
-
-       gpio = nuri_max8903.chg;
-       gpio_request(gpio, "TA_nCHG");
-       gpio_direction_input(gpio);
-
-       gpio = nuri_max8903.dcm;
-       gpio_request(gpio, "CURR_ADJ");
-       gpio_direction_output(gpio, ta_en);
-}
-
-/* USB EHCI */
-static struct s5p_ehci_platdata nuri_ehci_pdata;
-
-static void __init nuri_ehci_init(void)
-{
-       struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
-
-       s5p_ehci_set_platdata(pdata);
-}
-
-static struct platform_device *nuri_devices[] __initdata = {
-       /* Samsung Platform Devices */
-       &s3c_device_i2c5, /* PMIC should initialize first */
-       &emmc_fixed_voltage,
-       &s3c_device_hsmmc0,
-       &s3c_device_hsmmc2,
-       &s3c_device_hsmmc3,
-       &s3c_device_wdt,
-       &s3c_device_timer[0],
-       &s5p_device_ehci,
-       &s3c_device_i2c3,
-       &i2c9_gpio,
-       &s3c_device_adc,
-       &s3c_device_rtc,
-       &s5p_device_mfc,
-       &s5p_device_mfc_l,
-       &s5p_device_mfc_r,
-       &exynos4_device_pd[PD_MFC],
-
-       /* NURI Devices */
-       &nuri_gpio_keys,
-       &nuri_lcd_device,
-       &nuri_backlight_device,
-       &max8903_fixed_reg_dev,
-       &nuri_max8903_device,
-};
-
-static void __init nuri_map_io(void)
-{
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(24000000);
-       s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
-}
-
-static void __init nuri_reserve(void)
-{
-       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init nuri_machine_init(void)
-{
-       nuri_sdhci_init();
-       nuri_tsp_init();
-       nuri_power_init();
-
-       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
-       s3c_i2c3_set_platdata(&i2c3_data);
-       i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
-       s3c_i2c5_set_platdata(NULL);
-       i2c5_devs[I2C5_MAX8997].irq = gpio_to_irq(EXYNOS4_GPX0(7));
-       i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
-       i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
-       i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
-
-       nuri_ehci_init();
-       clk_xusbxti.rate = 24000000;
-
-       /* Last */
-       platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
-       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-}
-
-MACHINE_START(NURI, "NURI")
-       /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = nuri_map_io,
-       .init_machine   = nuri_machine_init,
-       .timer          = &exynos4_timer,
-       .reserve        = &nuri_reserve,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-origen.c b/arch/arm/mach-exynos4/mach-origen.c
deleted file mode 100644 (file)
index b5f6f38..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-origen.c
- *
- * Copyright (c) 2011 Insignal Co., Ltd.
- *             http://www.insignal.co.kr/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/input.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/sdhci.h>
-#include <plat/iic.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define ORIGEN_UCON_DEFAULT    (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define ORIGEN_ULCON_DEFAULT   S3C2410_LCON_CS8
-
-#define ORIGEN_UFCON_DEFAULT   (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG4 |        \
-                                S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport         = 0,
-               .flags          = 0,
-               .ucon           = ORIGEN_UCON_DEFAULT,
-               .ulcon          = ORIGEN_ULCON_DEFAULT,
-               .ufcon          = ORIGEN_UFCON_DEFAULT,
-       },
-       [1] = {
-               .hwport         = 1,
-               .flags          = 0,
-               .ucon           = ORIGEN_UCON_DEFAULT,
-               .ulcon          = ORIGEN_ULCON_DEFAULT,
-               .ufcon          = ORIGEN_UFCON_DEFAULT,
-       },
-       [2] = {
-               .hwport         = 2,
-               .flags          = 0,
-               .ucon           = ORIGEN_UCON_DEFAULT,
-               .ulcon          = ORIGEN_ULCON_DEFAULT,
-               .ufcon          = ORIGEN_UFCON_DEFAULT,
-       },
-       [3] = {
-               .hwport         = 3,
-               .flags          = 0,
-               .ucon           = ORIGEN_UCON_DEFAULT,
-               .ulcon          = ORIGEN_ULCON_DEFAULT,
-               .ufcon          = ORIGEN_UFCON_DEFAULT,
-       },
-};
-
-static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPK2(2),
-       .ext_cd_gpio_invert     = 1,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct platform_device *origen_devices[] __initdata = {
-       &s3c_device_hsmmc2,
-       &s3c_device_rtc,
-       &s3c_device_wdt,
-};
-
-static void __init origen_map_io(void)
-{
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(24000000);
-       s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
-}
-
-static void __init origen_machine_init(void)
-{
-       s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
-       platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
-}
-
-MACHINE_START(ORIGEN, "ORIGEN")
-       /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = origen_map_io,
-       .init_machine   = origen_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdk4x12.c b/arch/arm/mach-exynos4/mach-smdk4x12.c
deleted file mode 100644 (file)
index fcf2e0e..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/mach-smdk4x12.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/mfd/max8997.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/pwm_backlight.h>
-#include <linux/regulator/machine.h>
-#include <linux/serial_core.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/backlight.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/exynos4.h>
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-#include <plat/keypad.h>
-#include <plat/regs-serial.h>
-#include <plat/sdhci.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDK4X12_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8
-
-#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG4 |        \
-                                S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport         = 0,
-               .flags          = 0,
-               .ucon           = SMDK4X12_UCON_DEFAULT,
-               .ulcon          = SMDK4X12_ULCON_DEFAULT,
-               .ufcon          = SMDK4X12_UFCON_DEFAULT,
-       },
-       [1] = {
-               .hwport         = 1,
-               .flags          = 0,
-               .ucon           = SMDK4X12_UCON_DEFAULT,
-               .ulcon          = SMDK4X12_ULCON_DEFAULT,
-               .ufcon          = SMDK4X12_UFCON_DEFAULT,
-       },
-       [2] = {
-               .hwport         = 2,
-               .flags          = 0,
-               .ucon           = SMDK4X12_UCON_DEFAULT,
-               .ulcon          = SMDK4X12_ULCON_DEFAULT,
-               .ufcon          = SMDK4X12_UFCON_DEFAULT,
-       },
-       [3] = {
-               .hwport         = 3,
-               .flags          = 0,
-               .ucon           = SMDK4X12_UCON_DEFAULT,
-               .ulcon          = SMDK4X12_ULCON_DEFAULT,
-               .ufcon          = SMDK4X12_UFCON_DEFAULT,
-       },
-};
-
-static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_INTERNAL,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
-       .max_width              = 8,
-       .host_caps              = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_INTERNAL,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct regulator_consumer_supply max8997_buck1 =
-       REGULATOR_SUPPLY("vdd_arm", NULL);
-
-static struct regulator_consumer_supply max8997_buck2 =
-       REGULATOR_SUPPLY("vdd_int", NULL);
-
-static struct regulator_consumer_supply max8997_buck3 =
-       REGULATOR_SUPPLY("vdd_g3d", NULL);
-
-static struct regulator_init_data max8997_buck1_data = {
-       .constraints    = {
-               .name           = "VDD_ARM_SMDK4X12",
-               .min_uV         = 925000,
-               .max_uV         = 1350000,
-               .always_on      = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = 1,
-       .consumer_supplies      = &max8997_buck1,
-};
-
-static struct regulator_init_data max8997_buck2_data = {
-       .constraints    = {
-               .name           = "VDD_INT_SMDK4X12",
-               .min_uV         = 950000,
-               .max_uV         = 1150000,
-               .always_on      = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = 1,
-       .consumer_supplies      = &max8997_buck2,
-};
-
-static struct regulator_init_data max8997_buck3_data = {
-       .constraints    = {
-               .name           = "VDD_G3D_SMDK4X12",
-               .min_uV         = 950000,
-               .max_uV         = 1150000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-                                 REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies  = 1,
-       .consumer_supplies      = &max8997_buck3,
-};
-
-static struct max8997_regulator_data smdk4x12_max8997_regulators[] = {
-       { MAX8997_BUCK1, &max8997_buck1_data },
-       { MAX8997_BUCK2, &max8997_buck2_data },
-       { MAX8997_BUCK3, &max8997_buck3_data },
-};
-
-static struct max8997_platform_data smdk4x12_max8997_pdata = {
-       .num_regulators = ARRAY_SIZE(smdk4x12_max8997_regulators),
-       .regulators     = smdk4x12_max8997_regulators,
-
-       .buck1_voltage[0] = 1100000,    /* 1.1V */
-       .buck1_voltage[1] = 1100000,    /* 1.1V */
-       .buck1_voltage[2] = 1100000,    /* 1.1V */
-       .buck1_voltage[3] = 1100000,    /* 1.1V */
-       .buck1_voltage[4] = 1100000,    /* 1.1V */
-       .buck1_voltage[5] = 1100000,    /* 1.1V */
-       .buck1_voltage[6] = 1000000,    /* 1.0V */
-       .buck1_voltage[7] = 950000,     /* 0.95V */
-
-       .buck2_voltage[0] = 1100000,    /* 1.1V */
-       .buck2_voltage[1] = 1000000,    /* 1.0V */
-       .buck2_voltage[2] = 950000,     /* 0.95V */
-       .buck2_voltage[3] = 900000,     /* 0.9V */
-       .buck2_voltage[4] = 1100000,    /* 1.1V */
-       .buck2_voltage[5] = 1000000,    /* 1.0V */
-       .buck2_voltage[6] = 950000,     /* 0.95V */
-       .buck2_voltage[7] = 900000,     /* 0.9V */
-
-       .buck5_voltage[0] = 1100000,    /* 1.1V */
-       .buck5_voltage[1] = 1100000,    /* 1.1V */
-       .buck5_voltage[2] = 1100000,    /* 1.1V */
-       .buck5_voltage[3] = 1100000,    /* 1.1V */
-       .buck5_voltage[4] = 1100000,    /* 1.1V */
-       .buck5_voltage[5] = 1100000,    /* 1.1V */
-       .buck5_voltage[6] = 1100000,    /* 1.1V */
-       .buck5_voltage[7] = 1100000,    /* 1.1V */
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs0[] __initdata = {
-       {
-               I2C_BOARD_INFO("max8997", 0x66),
-               .platform_data  = &smdk4x12_max8997_pdata,
-       }
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs1[] __initdata = {
-       { I2C_BOARD_INFO("wm8994", 0x1a), }
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = {
-       /* nothing here yet */
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs7[] __initdata = {
-       /* nothing here yet */
-};
-
-static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = {
-       .no = EXYNOS4_GPD0(1),
-       .func = S3C_GPIO_SFN(2),
-};
-
-static struct platform_pwm_backlight_data smdk4x12_bl_data = {
-       .pwm_id = 1,
-       .pwm_period_ns  = 1000,
-};
-
-static uint32_t smdk4x12_keymap[] __initdata = {
-       /* KEY(row, col, keycode) */
-       KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B),
-       KEY(1, 3, KEY_E), KEY(1, 4, KEY_C)
-};
-
-static struct matrix_keymap_data smdk4x12_keymap_data __initdata = {
-       .keymap         = smdk4x12_keymap,
-       .keymap_size    = ARRAY_SIZE(smdk4x12_keymap),
-};
-
-static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = {
-       .keymap_data    = &smdk4x12_keymap_data,
-       .rows           = 2,
-       .cols           = 5,
-};
-
-static struct platform_device *smdk4x12_devices[] __initdata = {
-       &s3c_device_hsmmc2,
-       &s3c_device_hsmmc3,
-       &s3c_device_i2c0,
-       &s3c_device_i2c1,
-       &s3c_device_i2c3,
-       &s3c_device_i2c7,
-       &s3c_device_rtc,
-       &s3c_device_wdt,
-       &samsung_device_keypad,
-};
-
-static void __init smdk4x12_map_io(void)
-{
-       clk_xusbxti.rate = 24000000;
-
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
-       s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
-}
-
-static void __init smdk4x12_machine_init(void)
-{
-       s3c_i2c0_set_platdata(NULL);
-       i2c_register_board_info(0, smdk4x12_i2c_devs0,
-                               ARRAY_SIZE(smdk4x12_i2c_devs0));
-
-       s3c_i2c1_set_platdata(NULL);
-       i2c_register_board_info(1, smdk4x12_i2c_devs1,
-                               ARRAY_SIZE(smdk4x12_i2c_devs1));
-
-       s3c_i2c3_set_platdata(NULL);
-       i2c_register_board_info(3, smdk4x12_i2c_devs3,
-                               ARRAY_SIZE(smdk4x12_i2c_devs3));
-
-       s3c_i2c7_set_platdata(NULL);
-       i2c_register_board_info(7, smdk4x12_i2c_devs7,
-                               ARRAY_SIZE(smdk4x12_i2c_devs7));
-
-       samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);
-
-       samsung_keypad_set_platdata(&smdk4x12_keypad_data);
-
-       s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata);
-       s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata);
-
-       platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices));
-}
-
-MACHINE_START(SMDK4212, "SMDK4212")
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = smdk4x12_map_io,
-       .init_machine   = smdk4x12_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
-
-MACHINE_START(SMDK4412, "SMDK4412")
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = smdk4x12_map_io,
-       .init_machine   = smdk4x12_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
deleted file mode 100644 (file)
index 2c1a076..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-smdkv310.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/lcd.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/smsc911x.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/pwm_backlight.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <video/platform_lcd.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/regs-fb-v4.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/fb.h>
-#include <plat/keypad.h>
-#include <plat/sdhci.h>
-#include <plat/iic.h>
-#include <plat/pd.h>
-#include <plat/gpio-cfg.h>
-#include <plat/backlight.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDKV310_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
-
-#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG4 |        \
-                                S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport         = 0,
-               .flags          = 0,
-               .ucon           = SMDKV310_UCON_DEFAULT,
-               .ulcon          = SMDKV310_ULCON_DEFAULT,
-               .ufcon          = SMDKV310_UFCON_DEFAULT,
-       },
-       [1] = {
-               .hwport         = 1,
-               .flags          = 0,
-               .ucon           = SMDKV310_UCON_DEFAULT,
-               .ulcon          = SMDKV310_ULCON_DEFAULT,
-               .ufcon          = SMDKV310_UFCON_DEFAULT,
-       },
-       [2] = {
-               .hwport         = 2,
-               .flags          = 0,
-               .ucon           = SMDKV310_UCON_DEFAULT,
-               .ulcon          = SMDKV310_ULCON_DEFAULT,
-               .ufcon          = SMDKV310_UFCON_DEFAULT,
-       },
-       [3] = {
-               .hwport         = 3,
-               .flags          = 0,
-               .ucon           = SMDKV310_UCON_DEFAULT,
-               .ulcon          = SMDKV310_ULCON_DEFAULT,
-               .ufcon          = SMDKV310_UFCON_DEFAULT,
-       },
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_INTERNAL,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
-       .max_width              = 8,
-       .host_caps              = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPK0(2),
-       .ext_cd_gpio_invert     = 1,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_INTERNAL,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
-       .max_width              = 8,
-       .host_caps              = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .ext_cd_gpio            = EXYNOS4_GPK2(2),
-       .ext_cd_gpio_invert     = 1,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
-                                  unsigned int power)
-{
-       if (power) {
-#if !defined(CONFIG_BACKLIGHT_PWM)
-               gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
-               gpio_free(EXYNOS4_GPD0(1));
-#endif
-               /* fire nRESET on power up */
-               gpio_request(EXYNOS4_GPX0(6), "GPX0");
-
-               gpio_direction_output(EXYNOS4_GPX0(6), 1);
-               mdelay(100);
-
-               gpio_set_value(EXYNOS4_GPX0(6), 0);
-               mdelay(10);
-
-               gpio_set_value(EXYNOS4_GPX0(6), 1);
-               mdelay(10);
-
-               gpio_free(EXYNOS4_GPX0(6));
-       } else {
-#if !defined(CONFIG_BACKLIGHT_PWM)
-               gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
-               gpio_free(EXYNOS4_GPD0(1));
-#endif
-       }
-}
-
-static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
-       .set_power              = lcd_lte480wv_set_power,
-};
-
-static struct platform_device smdkv310_lcd_lte480wv = {
-       .name                   = "platform-lcd",
-       .dev.parent             = &s5p_device_fimd0.dev,
-       .dev.platform_data      = &smdkv310_lcd_lte480wv_data,
-};
-
-static struct s3c_fb_pd_win smdkv310_fb_win0 = {
-       .win_mode = {
-               .left_margin    = 13,
-               .right_margin   = 8,
-               .upper_margin   = 7,
-               .lower_margin   = 5,
-               .hsync_len      = 3,
-               .vsync_len      = 1,
-               .xres           = 800,
-               .yres           = 480,
-       },
-       .max_bpp                = 32,
-       .default_bpp            = 24,
-};
-
-static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
-       .win[0]         = &smdkv310_fb_win0,
-       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-       .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
-};
-
-static struct resource smdkv310_smsc911x_resources[] = {
-       [0] = {
-               .start  = EXYNOS4_PA_SROM_BANK(1),
-               .end    = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_EINT(5),
-               .end    = IRQ_EINT(5),
-               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
-       },
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
-       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
-       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-       .phy_interface  = PHY_INTERFACE_MODE_MII,
-       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device smdkv310_smsc911x = {
-       .name           = "smsc911x",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(smdkv310_smsc911x_resources),
-       .resource       = smdkv310_smsc911x_resources,
-       .dev            = {
-               .platform_data  = &smsc9215_config,
-       },
-};
-
-static uint32_t smdkv310_keymap[] __initdata = {
-       /* KEY(row, col, keycode) */
-       KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
-       KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
-       KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
-       KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
-};
-
-static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
-       .keymap         = smdkv310_keymap,
-       .keymap_size    = ARRAY_SIZE(smdkv310_keymap),
-};
-
-static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
-       .keymap_data    = &smdkv310_keymap_data,
-       .rows           = 2,
-       .cols           = 8,
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
-       {I2C_BOARD_INFO("wm8994", 0x1a),},
-};
-
-static struct platform_device *smdkv310_devices[] __initdata = {
-       &s3c_device_hsmmc0,
-       &s3c_device_hsmmc1,
-       &s3c_device_hsmmc2,
-       &s3c_device_hsmmc3,
-       &s3c_device_i2c1,
-       &s3c_device_rtc,
-       &s3c_device_wdt,
-       &exynos4_device_ac97,
-       &exynos4_device_i2s0,
-       &samsung_device_keypad,
-       &exynos4_device_pd[PD_MFC],
-       &exynos4_device_pd[PD_G3D],
-       &exynos4_device_pd[PD_LCD0],
-       &exynos4_device_pd[PD_LCD1],
-       &exynos4_device_pd[PD_CAM],
-       &exynos4_device_pd[PD_TV],
-       &exynos4_device_pd[PD_GPS],
-       &exynos4_device_spdif,
-       &exynos4_device_sysmmu,
-       &samsung_asoc_dma,
-       &samsung_asoc_idma,
-       &s5p_device_fimd0,
-       &smdkv310_lcd_lte480wv,
-       &smdkv310_smsc911x,
-       &exynos4_device_ahci,
-};
-
-static void __init smdkv310_smsc911x_init(void)
-{
-       u32 cs1;
-
-       /* configure nCS1 width to 16 bits */
-       cs1 = __raw_readl(S5P_SROM_BW) &
-               ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
-       cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
-               (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
-               (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
-               S5P_SROM_BW__NCS1__SHIFT;
-       __raw_writel(cs1, S5P_SROM_BW);
-
-       /* set timing for nCS1 suitable for ethernet chip */
-       __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
-                    (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
-                    (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
-                    (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
-                    (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-/* LCD Backlight data */
-static struct samsung_bl_gpio_info smdkv310_bl_gpio_info = {
-       .no = EXYNOS4_GPD0(1),
-       .func = S3C_GPIO_SFN(2),
-};
-
-static struct platform_pwm_backlight_data smdkv310_bl_data = {
-       .pwm_id = 1,
-       .pwm_period_ns  = 1000,
-};
-
-static void __init smdkv310_map_io(void)
-{
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(24000000);
-       s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
-}
-
-static void __init smdkv310_machine_init(void)
-{
-       s3c_i2c1_set_platdata(NULL);
-       i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-
-       smdkv310_smsc911x_init();
-
-       s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
-       s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
-       s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
-       s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
-
-       samsung_keypad_set_platdata(&smdkv310_keypad_data);
-
-       samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
-       s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
-
-       platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-}
-
-MACHINE_START(SMDKV310, "SMDKV310")
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = smdkv310_map_io,
-       .init_machine   = smdkv310_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
-
-MACHINE_START(SMDKC210, "SMDKC210")
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = smdkv310_map_io,
-       .init_machine   = smdkv310_machine_init,
-       .timer          = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c
deleted file mode 100644 (file)
index 2aac6f7..0000000
+++ /dev/null
@@ -1,771 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-universal_c210.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
-#include <linux/mfd/max8998.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/max8952.h>
-#include <linux/mmc/host.h>
-#include <linux/i2c-gpio.h>
-#include <linux/i2c/mcs.h>
-#include <linux/i2c/atmel_mxt_ts.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-#include <plat/mfc.h>
-#include <plat/sdhci.h>
-#include <plat/pd.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL |        \
-                                S3C2410_UCON_RXILEVEL |        \
-                                S3C2410_UCON_TXIRQMODE |       \
-                                S3C2410_UCON_RXIRQMODE |       \
-                                S3C2410_UCON_RXFIFO_TOI |      \
-                                S3C2443_UCON_RXERR_IRQEN)
-
-#define UNIVERSAL_ULCON_DEFAULT        S3C2410_LCON_CS8
-
-#define UNIVERSAL_UFCON_DEFAULT        (S3C2410_UFCON_FIFOMODE |       \
-                                S5PV210_UFCON_TXTRIG256 |      \
-                                S5PV210_UFCON_RXTRIG256)
-
-static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
-       [0] = {
-               .hwport         = 0,
-               .ucon           = UNIVERSAL_UCON_DEFAULT,
-               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
-               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
-       },
-       [1] = {
-               .hwport         = 1,
-               .ucon           = UNIVERSAL_UCON_DEFAULT,
-               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
-               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
-       },
-       [2] = {
-               .hwport         = 2,
-               .ucon           = UNIVERSAL_UCON_DEFAULT,
-               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
-               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
-       },
-       [3] = {
-               .hwport         = 3,
-               .ucon           = UNIVERSAL_UCON_DEFAULT,
-               .ulcon          = UNIVERSAL_ULCON_DEFAULT,
-               .ufcon          = UNIVERSAL_UFCON_DEFAULT,
-       },
-};
-
-static struct regulator_consumer_supply max8952_consumer =
-       REGULATOR_SUPPLY("vdd_arm", NULL);
-
-static struct max8952_platform_data universal_max8952_pdata __initdata = {
-       .gpio_vid0      = EXYNOS4_GPX0(3),
-       .gpio_vid1      = EXYNOS4_GPX0(4),
-       .gpio_en        = -1, /* Not controllable, set "Always High" */
-       .default_mode   = 0, /* vid0 = 0, vid1 = 0 */
-       .dvs_mode       = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
-       .sync_freq      = 0, /* default: fastest */
-       .ramp_speed     = 0, /* default: fastest */
-
-       .reg_data       = {
-               .constraints    = {
-                       .name           = "VARM_1.2V",
-                       .min_uV         = 770000,
-                       .max_uV         = 1400000,
-                       .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
-                       .always_on      = 1,
-                       .boot_on        = 1,
-               },
-               .num_consumer_supplies  = 1,
-               .consumer_supplies      = &max8952_consumer,
-       },
-};
-
-static struct regulator_consumer_supply lp3974_buck1_consumer =
-       REGULATOR_SUPPLY("vdd_int", NULL);
-
-static struct regulator_consumer_supply lp3974_buck2_consumer =
-       REGULATOR_SUPPLY("vddg3d", NULL);
-
-static struct regulator_init_data lp3974_buck1_data = {
-       .constraints    = {
-               .name           = "VINT_1.1V",
-               .min_uV         = 750000,
-               .max_uV         = 1500000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-                       REGULATOR_CHANGE_STATUS,
-               .boot_on        = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = 1,
-       .consumer_supplies = &lp3974_buck1_consumer,
-};
-
-static struct regulator_init_data lp3974_buck2_data = {
-       .constraints    = {
-               .name           = "VG3D_1.1V",
-               .min_uV         = 750000,
-               .max_uV         = 1500000,
-               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-                       REGULATOR_CHANGE_STATUS,
-               .boot_on        = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-       .num_consumer_supplies = 1,
-       .consumer_supplies = &lp3974_buck2_consumer,
-};
-
-static struct regulator_init_data lp3974_buck3_data = {
-       .constraints    = {
-               .name           = "VCC_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_buck4_data = {
-       .constraints    = {
-               .name           = "VMEM_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .apply_uV       = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo2_data = {
-       .constraints    = {
-               .name           = "VALIVE_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo3_data = {
-       .constraints    = {
-               .name           = "VUSB+MIPI_1.1V",
-               .min_uV         = 1100000,
-               .max_uV         = 1100000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo4_data = {
-       .constraints    = {
-               .name           = "VADC_3.3V",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo5_data = {
-       .constraints    = {
-               .name           = "VTF_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo6_data = {
-       .constraints    = {
-               .name           = "LDO6",
-               .min_uV         = 2000000,
-               .max_uV         = 2000000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo7_data = {
-       .constraints    = {
-               .name           = "VLCD+VMIPI_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo8_data = {
-       .constraints    = {
-               .name           = "VUSB+VDAC_3.3V",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo9_data = {
-       .constraints    = {
-               .name           = "VCC_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo10_data = {
-       .constraints    = {
-               .name           = "VPLL_1.1V",
-               .min_uV         = 1100000,
-               .max_uV         = 1100000,
-               .boot_on        = 1,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo11_data = {
-       .constraints    = {
-               .name           = "CAM_AF_3.3V",
-               .min_uV         = 3300000,
-               .max_uV         = 3300000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo12_data = {
-       .constraints    = {
-               .name           = "PS_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo13_data = {
-       .constraints    = {
-               .name           = "VHIC_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo14_data = {
-       .constraints    = {
-               .name           = "CAM_I_HOST_1.8V",
-               .min_uV         = 1800000,
-               .max_uV         = 1800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo15_data = {
-       .constraints    = {
-               .name           = "CAM_S_DIG+FM33_CORE_1.2V",
-               .min_uV         = 1200000,
-               .max_uV         = 1200000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo16_data = {
-       .constraints    = {
-               .name           = "CAM_S_ANA_2.8V",
-               .min_uV         = 2800000,
-               .max_uV         = 2800000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_ldo17_data = {
-       .constraints    = {
-               .name           = "VCC_3.0V_LCD",
-               .min_uV         = 3000000,
-               .max_uV         = 3000000,
-               .apply_uV       = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .boot_on        = 1,
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_32khz_ap_data = {
-       .constraints    = {
-               .name           = "32KHz AP",
-               .always_on      = 1,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_32khz_cp_data = {
-       .constraints    = {
-               .name           = "32KHz CP",
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_vichg_data = {
-       .constraints    = {
-               .name           = "VICHG",
-               .state_mem      = {
-                       .disabled       = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_esafeout1_data = {
-       .constraints    = {
-               .name           = "SAFEOUT1",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct regulator_init_data lp3974_esafeout2_data = {
-       .constraints    = {
-               .name           = "SAFEOUT2",
-               .boot_on        = 1,
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-               .state_mem      = {
-                       .enabled        = 1,
-               },
-       },
-};
-
-static struct max8998_regulator_data lp3974_regulators[] = {
-       { MAX8998_LDO2,  &lp3974_ldo2_data },
-       { MAX8998_LDO3,  &lp3974_ldo3_data },
-       { MAX8998_LDO4,  &lp3974_ldo4_data },
-       { MAX8998_LDO5,  &lp3974_ldo5_data },
-       { MAX8998_LDO6,  &lp3974_ldo6_data },
-       { MAX8998_LDO7,  &lp3974_ldo7_data },
-       { MAX8998_LDO8,  &lp3974_ldo8_data },
-       { MAX8998_LDO9,  &lp3974_ldo9_data },
-       { MAX8998_LDO10, &lp3974_ldo10_data },
-       { MAX8998_LDO11, &lp3974_ldo11_data },
-       { MAX8998_LDO12, &lp3974_ldo12_data },
-       { MAX8998_LDO13, &lp3974_ldo13_data },
-       { MAX8998_LDO14, &lp3974_ldo14_data },
-       { MAX8998_LDO15, &lp3974_ldo15_data },
-       { MAX8998_LDO16, &lp3974_ldo16_data },
-       { MAX8998_LDO17, &lp3974_ldo17_data },
-       { MAX8998_BUCK1, &lp3974_buck1_data },
-       { MAX8998_BUCK2, &lp3974_buck2_data },
-       { MAX8998_BUCK3, &lp3974_buck3_data },
-       { MAX8998_BUCK4, &lp3974_buck4_data },
-       { MAX8998_EN32KHZ_AP, &lp3974_32khz_ap_data },
-       { MAX8998_EN32KHZ_CP, &lp3974_32khz_cp_data },
-       { MAX8998_ENVICHG, &lp3974_vichg_data },
-       { MAX8998_ESAFEOUT1, &lp3974_esafeout1_data },
-       { MAX8998_ESAFEOUT2, &lp3974_esafeout2_data },
-};
-
-static struct max8998_platform_data universal_lp3974_pdata = {
-       .num_regulators         = ARRAY_SIZE(lp3974_regulators),
-       .regulators             = lp3974_regulators,
-       .buck1_voltage1         = 1100000,      /* INT */
-       .buck1_voltage2         = 1000000,
-       .buck1_voltage3         = 1100000,
-       .buck1_voltage4         = 1000000,
-       .buck1_set1             = EXYNOS4_GPX0(5),
-       .buck1_set2             = EXYNOS4_GPX0(6),
-       .buck2_voltage1         = 1200000,      /* G3D */
-       .buck2_voltage2         = 1100000,
-       .buck1_default_idx      = 0,
-       .buck2_set3             = EXYNOS4_GPE2(0),
-       .buck2_default_idx      = 0,
-       .wakeup                 = true,
-};
-
-/* GPIO I2C 5 (PMIC) */
-static struct i2c_board_info i2c5_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("max8952", 0xC0 >> 1),
-               .platform_data  = &universal_max8952_pdata,
-       }, {
-               I2C_BOARD_INFO("lp3974", 0xCC >> 1),
-               .platform_data  = &universal_lp3974_pdata,
-       },
-};
-
-/* I2C3 (TSP) */
-static struct mxt_platform_data qt602240_platform_data = {
-       .x_line         = 19,
-       .y_line         = 11,
-       .x_size         = 800,
-       .y_size         = 480,
-       .blen           = 0x11,
-       .threshold      = 0x28,
-       .voltage        = 2800000,              /* 2.8V */
-       .orient         = MXT_DIAGONAL,
-};
-
-static struct i2c_board_info i2c3_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("qt602240_ts", 0x4a),
-               .platform_data = &qt602240_platform_data,
-       },
-};
-
-static void __init universal_tsp_init(void)
-{
-       int gpio;
-
-       /* TSP_LDO_ON: XMDMADDR_11 */
-       gpio = EXYNOS4_GPE2(3);
-       gpio_request(gpio, "TSP_LDO_ON");
-       gpio_direction_output(gpio, 1);
-       gpio_export(gpio, 0);
-
-       /* TSP_INT: XMDMADDR_7 */
-       gpio = EXYNOS4_GPE1(7);
-       gpio_request(gpio, "TSP_INT");
-
-       s5p_register_gpio_interrupt(gpio);
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-       i2c3_devs[0].irq = gpio_to_irq(gpio);
-}
-
-
-/* GPIO I2C 12 (3 Touchkey) */
-static uint32_t touchkey_keymap[] = {
-       /* MCS_KEY_MAP(value, keycode) */
-       MCS_KEY_MAP(0, KEY_MENU),               /* KEY_SEND */
-       MCS_KEY_MAP(1, KEY_BACK),               /* KEY_END */
-};
-
-static struct mcs_platform_data touchkey_data = {
-       .keymap         = touchkey_keymap,
-       .keymap_size    = ARRAY_SIZE(touchkey_keymap),
-       .key_maxval     = 2,
-};
-
-/* GPIO I2C 3_TOUCH 2.8V */
-#define I2C_GPIO_BUS_12                12
-static struct i2c_gpio_platform_data i2c_gpio12_data = {
-       .sda_pin        = EXYNOS4_GPE4(0),      /* XMDMDATA_8 */
-       .scl_pin        = EXYNOS4_GPE4(1),      /* XMDMDATA_9 */
-};
-
-static struct platform_device i2c_gpio12 = {
-       .name           = "i2c-gpio",
-       .id             = I2C_GPIO_BUS_12,
-       .dev            = {
-               .platform_data  = &i2c_gpio12_data,
-       },
-};
-
-static struct i2c_board_info i2c_gpio12_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("mcs5080_touchkey", 0x20),
-               .platform_data = &touchkey_data,
-       },
-};
-
-static void __init universal_touchkey_init(void)
-{
-       int gpio;
-
-       gpio = EXYNOS4_GPE3(7);                 /* XMDMDATA_7 */
-       gpio_request(gpio, "3_TOUCH_INT");
-       s5p_register_gpio_interrupt(gpio);
-       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-       i2c_gpio12_devs[0].irq = gpio_to_irq(gpio);
-
-       gpio = EXYNOS4_GPE3(3);                 /* XMDMDATA_3 */
-       gpio_request(gpio, "3_TOUCH_EN");
-       gpio_direction_output(gpio, 1);
-}
-
-/* GPIO KEYS */
-static struct gpio_keys_button universal_gpio_keys_tables[] = {
-       {
-               .code                   = KEY_VOLUMEUP,
-               .gpio                   = EXYNOS4_GPX2(0),      /* XEINT16 */
-               .desc                   = "gpio-keys: KEY_VOLUMEUP",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_VOLUMEDOWN,
-               .gpio                   = EXYNOS4_GPX2(1),      /* XEINT17 */
-               .desc                   = "gpio-keys: KEY_VOLUMEDOWN",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_CONFIG,
-               .gpio                   = EXYNOS4_GPX2(2),      /* XEINT18 */
-               .desc                   = "gpio-keys: KEY_CONFIG",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_CAMERA,
-               .gpio                   = EXYNOS4_GPX2(3),      /* XEINT19 */
-               .desc                   = "gpio-keys: KEY_CAMERA",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       }, {
-               .code                   = KEY_OK,
-               .gpio                   = EXYNOS4_GPX3(5),      /* XEINT29 */
-               .desc                   = "gpio-keys: KEY_OK",
-               .type                   = EV_KEY,
-               .active_low             = 1,
-               .debounce_interval      = 1,
-       },
-};
-
-static struct gpio_keys_platform_data universal_gpio_keys_data = {
-       .buttons        = universal_gpio_keys_tables,
-       .nbuttons       = ARRAY_SIZE(universal_gpio_keys_tables),
-};
-
-static struct platform_device universal_gpio_keys = {
-       .name                   = "gpio-keys",
-       .dev                    = {
-               .platform_data  = &universal_gpio_keys_data,
-       },
-};
-
-/* eMMC */
-static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
-       .max_width              = 8,
-       .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE),
-       .cd_type                = S3C_SDHCI_CD_PERMANENT,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct regulator_consumer_supply mmc0_supplies[] = {
-       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
-};
-
-static struct regulator_init_data mmc0_fixed_voltage_init_data = {
-       .constraints            = {
-               .name           = "VMEM_VDD_2.8V",
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
-       },
-       .num_consumer_supplies  = ARRAY_SIZE(mmc0_supplies),
-       .consumer_supplies      = mmc0_supplies,
-};
-
-static struct fixed_voltage_config mmc0_fixed_voltage_config = {
-       .supply_name            = "MASSMEMORY_EN",
-       .microvolts             = 2800000,
-       .gpio                   = EXYNOS4_GPE1(3),
-       .enable_high            = true,
-       .init_data              = &mmc0_fixed_voltage_init_data,
-};
-
-static struct platform_device mmc0_fixed_voltage = {
-       .name                   = "reg-fixed-voltage",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = &mmc0_fixed_voltage_config,
-       },
-};
-
-/* SD */
-static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
-       .max_width              = 4,
-       .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
-       .ext_cd_gpio            = EXYNOS4_GPX3(4),      /* XEINT_28 */
-       .ext_cd_gpio_invert     = 1,
-       .cd_type                = S3C_SDHCI_CD_GPIO,
-       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-/* WiFi */
-static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
-       .max_width              = 4,
-       .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
-       .cd_type                = S3C_SDHCI_CD_EXTERNAL,
-};
-
-static void __init universal_sdhci_init(void)
-{
-       s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
-       s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
-       s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
-}
-
-/* I2C0 */
-static struct i2c_board_info i2c0_devs[] __initdata = {
-       /* Camera, To be updated */
-};
-
-/* I2C1 */
-static struct i2c_board_info i2c1_devs[] __initdata = {
-       /* Gyro, To be updated */
-};
-
-static struct platform_device *universal_devices[] __initdata = {
-       /* Samsung Platform Devices */
-       &s5p_device_fimc0,
-       &s5p_device_fimc1,
-       &s5p_device_fimc2,
-       &s5p_device_fimc3,
-       &mmc0_fixed_voltage,
-       &s3c_device_hsmmc0,
-       &s3c_device_hsmmc2,
-       &s3c_device_hsmmc3,
-       &s3c_device_i2c3,
-       &s3c_device_i2c5,
-
-       /* Universal Devices */
-       &i2c_gpio12,
-       &universal_gpio_keys,
-       &s5p_device_onenand,
-       &s5p_device_mfc,
-       &s5p_device_mfc_l,
-       &s5p_device_mfc_r,
-       &exynos4_device_pd[PD_MFC],
-};
-
-static void __init universal_map_io(void)
-{
-       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
-       s3c24xx_init_clocks(24000000);
-       s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
-}
-
-static void __init universal_reserve(void)
-{
-       s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init universal_machine_init(void)
-{
-       universal_sdhci_init();
-
-       i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
-       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
-
-       universal_tsp_init();
-       s3c_i2c3_set_platdata(NULL);
-       i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
-
-       s3c_i2c5_set_platdata(NULL);
-       i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
-
-       universal_touchkey_init();
-       i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
-                       ARRAY_SIZE(i2c_gpio12_devs));
-
-       /* Last */
-       platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
-       s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-}
-
-MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
-       /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
-       .atag_offset    = 0x100,
-       .init_irq       = exynos4_init_irq,
-       .map_io         = universal_map_io,
-       .init_machine   = universal_machine_init,
-       .timer          = &exynos4_timer,
-       .reserve        = &universal_reserve,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
deleted file mode 100644 (file)
index f191608..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mct.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 MCT(Multi-Core Timer) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/percpu.h>
-
-#include <asm/hardware/gic.h>
-
-#include <plat/cpu.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/regs-mct.h>
-#include <asm/mach/time.h>
-
-enum {
-       MCT_INT_SPI,
-       MCT_INT_PPI
-};
-
-static unsigned long clk_cnt_per_tick;
-static unsigned long clk_rate;
-static unsigned int mct_int_type;
-
-struct mct_clock_event_device {
-       struct clock_event_device *evt;
-       void __iomem *base;
-       char name[10];
-};
-
-struct mct_clock_event_device mct_tick[NR_CPUS];
-
-static void exynos4_mct_write(unsigned int value, void *addr)
-{
-       void __iomem *stat_addr;
-       u32 mask;
-       u32 i;
-
-       __raw_writel(value, addr);
-
-       if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) {
-               u32 base = (u32) addr & EXYNOS4_MCT_L_MASK;
-               switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) {
-               case (u32) MCT_L_TCON_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 3;          /* L_TCON write status */
-                       break;
-               case (u32) MCT_L_ICNTB_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 1;          /* L_ICNTB write status */
-                       break;
-               case (u32) MCT_L_TCNTB_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 0;          /* L_TCNTB write status */
-                       break;
-               default:
-                       return;
-               }
-       } else {
-               switch ((u32) addr) {
-               case (u32) EXYNOS4_MCT_G_TCON:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 16;         /* G_TCON write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_L:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 0;          /* G_COMP0_L write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_U:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 1;          /* G_COMP0_U write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 2;          /* G_COMP0_ADD_INCR w status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_CNT_L:
-                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
-                       mask = 1 << 0;          /* G_CNT_L write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_CNT_U:
-                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
-                       mask = 1 << 1;          /* G_CNT_U write status */
-                       break;
-               default:
-                       return;
-               }
-       }
-
-       /* Wait maximum 1 ms until written values are applied */
-       for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
-               if (__raw_readl(stat_addr) & mask) {
-                       __raw_writel(mask, stat_addr);
-                       return;
-               }
-
-       panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
-}
-
-/* Clocksource handling */
-static void exynos4_mct_frc_start(u32 hi, u32 lo)
-{
-       u32 reg;
-
-       exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
-       exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
-
-       reg = __raw_readl(EXYNOS4_MCT_G_TCON);
-       reg |= MCT_G_TCON_START;
-       exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
-}
-
-static cycle_t exynos4_frc_read(struct clocksource *cs)
-{
-       unsigned int lo, hi;
-       u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
-
-       do {
-               hi = hi2;
-               lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
-               hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
-       } while (hi != hi2);
-
-       return ((cycle_t)hi << 32) | lo;
-}
-
-static void exynos4_frc_resume(struct clocksource *cs)
-{
-       exynos4_mct_frc_start(0, 0);
-}
-
-struct clocksource mct_frc = {
-       .name           = "mct-frc",
-       .rating         = 400,
-       .read           = exynos4_frc_read,
-       .mask           = CLOCKSOURCE_MASK(64),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-       .resume         = exynos4_frc_resume,
-};
-
-static void __init exynos4_clocksource_init(void)
-{
-       exynos4_mct_frc_start(0, 0);
-
-       if (clocksource_register_hz(&mct_frc, clk_rate))
-               panic("%s: can't register clocksource\n", mct_frc.name);
-}
-
-static void exynos4_mct_comp0_stop(void)
-{
-       unsigned int tcon;
-
-       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
-       tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
-
-       exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
-       exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
-}
-
-static void exynos4_mct_comp0_start(enum clock_event_mode mode,
-                                   unsigned long cycles)
-{
-       unsigned int tcon;
-       cycle_t comp_cycle;
-
-       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
-
-       if (mode == CLOCK_EVT_MODE_PERIODIC) {
-               tcon |= MCT_G_TCON_COMP0_AUTO_INC;
-               exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
-       }
-
-       comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
-       exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
-       exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
-
-       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
-
-       tcon |= MCT_G_TCON_COMP0_ENABLE;
-       exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
-}
-
-static int exynos4_comp_set_next_event(unsigned long cycles,
-                                      struct clock_event_device *evt)
-{
-       exynos4_mct_comp0_start(evt->mode, cycles);
-
-       return 0;
-}
-
-static void exynos4_comp_set_mode(enum clock_event_mode mode,
-                                 struct clock_event_device *evt)
-{
-       exynos4_mct_comp0_stop();
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static struct clock_event_device mct_comp_device = {
-       .name           = "mct-comp",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .rating         = 250,
-       .set_next_event = exynos4_comp_set_next_event,
-       .set_mode       = exynos4_comp_set_mode,
-};
-
-static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
-
-       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mct_comp_event_irq = {
-       .name           = "mct_comp_irq",
-       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = exynos4_mct_comp_isr,
-       .dev_id         = &mct_comp_device,
-};
-
-static void exynos4_clockevent_init(void)
-{
-       clk_cnt_per_tick = clk_rate / 2 / HZ;
-
-       clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
-       mct_comp_device.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &mct_comp_device);
-       mct_comp_device.min_delta_ns =
-               clockevent_delta2ns(0xf, &mct_comp_device);
-       mct_comp_device.cpumask = cpumask_of(0);
-       clockevents_register_device(&mct_comp_device);
-
-       setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
-}
-
-#ifdef CONFIG_LOCAL_TIMERS
-/* Clock event handling */
-static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
-{
-       unsigned long tmp;
-       unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
-       void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
-
-       tmp = __raw_readl(addr);
-       if (tmp & mask) {
-               tmp &= ~mask;
-               exynos4_mct_write(tmp, addr);
-       }
-}
-
-static void exynos4_mct_tick_start(unsigned long cycles,
-                                  struct mct_clock_event_device *mevt)
-{
-       unsigned long tmp;
-
-       exynos4_mct_tick_stop(mevt);
-
-       tmp = (1 << 31) | cycles;       /* MCT_L_UPDATE_ICNTB */
-
-       /* update interrupt count buffer */
-       exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
-
-       /* enable MCT tick interrupt */
-       exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
-
-       tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
-       tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
-              MCT_L_TCON_INTERVAL_MODE;
-       exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
-}
-
-static int exynos4_tick_set_next_event(unsigned long cycles,
-                                      struct clock_event_device *evt)
-{
-       struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
-
-       exynos4_mct_tick_start(cycles, mevt);
-
-       return 0;
-}
-
-static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
-                                        struct clock_event_device *evt)
-{
-       struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
-
-       exynos4_mct_tick_stop(mevt);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
-{
-       struct clock_event_device *evt = mevt->evt;
-
-       /*
-        * This is for supporting oneshot mode.
-        * Mct would generate interrupt periodically
-        * without explicit stopping.
-        */
-       if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
-               exynos4_mct_tick_stop(mevt);
-
-       /* Clear the MCT tick interrupt */
-       if (__raw_readl(mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
-               exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
-{
-       struct mct_clock_event_device *mevt = dev_id;
-       struct clock_event_device *evt = mevt->evt;
-
-       exynos4_mct_tick_clear(mevt);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mct_tick0_event_irq = {
-       .name           = "mct_tick0_irq",
-       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
-       .handler        = exynos4_mct_tick_isr,
-};
-
-static struct irqaction mct_tick1_event_irq = {
-       .name           = "mct_tick1_irq",
-       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
-       .handler        = exynos4_mct_tick_isr,
-};
-
-static void exynos4_mct_tick_init(struct clock_event_device *evt)
-{
-       unsigned int cpu = smp_processor_id();
-
-       mct_tick[cpu].evt = evt;
-
-       mct_tick[cpu].base = EXYNOS4_MCT_L_BASE(cpu);
-       sprintf(mct_tick[cpu].name, "mct_tick%d", cpu);
-
-       evt->name = mct_tick[cpu].name;
-       evt->cpumask = cpumask_of(cpu);
-       evt->set_next_event = exynos4_tick_set_next_event;
-       evt->set_mode = exynos4_tick_set_mode;
-       evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
-       evt->rating = 450;
-
-       clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
-       evt->max_delta_ns =
-               clockevent_delta2ns(0x7fffffff, evt);
-       evt->min_delta_ns =
-               clockevent_delta2ns(0xf, evt);
-
-       clockevents_register_device(evt);
-
-       exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET);
-
-       if (mct_int_type == MCT_INT_SPI) {
-               if (cpu == 0) {
-                       mct_tick0_event_irq.dev_id = &mct_tick[cpu];
-                       evt->irq = IRQ_MCT_L0;
-                       setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
-               } else {
-                       mct_tick1_event_irq.dev_id = &mct_tick[cpu];
-                       evt->irq = IRQ_MCT_L1;
-                       setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
-                       irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
-               }
-       } else {
-               gic_enable_ppi(IRQ_MCT_LOCALTIMER);
-       }
-}
-
-/* Setup the local clock events for a CPU */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-       exynos4_mct_tick_init(evt);
-
-       return 0;
-}
-
-void local_timer_stop(struct clock_event_device *evt)
-{
-       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-       disable_irq(evt->irq);
-}
-
-#endif /* CONFIG_LOCAL_TIMERS */
-
-static void __init exynos4_timer_resources(void)
-{
-       struct clk *mct_clk;
-       mct_clk = clk_get(NULL, "xtal");
-
-       clk_rate = clk_get_rate(mct_clk);
-}
-
-static void __init exynos4_timer_init(void)
-{
-       if (soc_is_exynos4210())
-               mct_int_type = MCT_INT_SPI;
-       else
-               mct_int_type = MCT_INT_PPI;
-
-       exynos4_timer_resources();
-       exynos4_clocksource_init();
-       exynos4_clockevent_init();
-}
-
-struct sys_timer exynos4_timer = {
-       .init           = exynos4_timer_init,
-};
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
deleted file mode 100644 (file)
index 0559540..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/* linux/arch/arm/mach-exynos4/platsmp.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-#include <asm/hardware/gic.h>
-#include <asm/smp_scu.h>
-#include <asm/unified.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-pmu.h>
-
-#include <plat/cpu.h>
-
-extern unsigned int gic_bank_offset;
-extern void exynos4_secondary_startup(void);
-
-#define CPU1_BOOT_REG          (samsung_rev() == EXYNOS4210_REV_1_1 ? \
-                               S5P_INFORM5 : S5P_VA_SYSRAM)
-
-/*
- * control for which core is the next to come out of the secondary
- * boot "holding pen"
- */
-
-volatile int __cpuinitdata pen_release = -1;
-
-/*
- * Write pen_release in a way that is guaranteed to be visible to all
- * observers, irrespective of whether they're taking part in coherency
- * or not.  This is necessary for the hotplug code to work reliably.
- */
-static void write_pen_release(int val)
-{
-       pen_release = val;
-       smp_wmb();
-       __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
-       outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
-}
-
-static void __iomem *scu_base_addr(void)
-{
-       return (void __iomem *)(S5P_VA_SCU);
-}
-
-static DEFINE_SPINLOCK(boot_lock);
-
-static void __cpuinit exynos4_gic_secondary_init(void)
-{
-       void __iomem *dist_base = S5P_VA_GIC_DIST +
-                               (gic_bank_offset * smp_processor_id());
-       void __iomem *cpu_base = S5P_VA_GIC_CPU +
-                               (gic_bank_offset * smp_processor_id());
-       int i;
-
-       /*
-        * Deal with the banked PPI and SGI interrupts - disable all
-        * PPI interrupts, ensure all SGI interrupts are enabled.
-        */
-       __raw_writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
-       __raw_writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
-
-       /*
-        * Set priority on PPI and SGI interrupts
-        */
-       for (i = 0; i < 32; i += 4)
-               __raw_writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
-
-       __raw_writel(0xf0, cpu_base + GIC_CPU_PRIMASK);
-       __raw_writel(1, cpu_base + GIC_CPU_CTRL);
-}
-
-void __cpuinit platform_secondary_init(unsigned int cpu)
-{
-       /*
-        * if any interrupts are already enabled for the primary
-        * core (e.g. timer irq), then they will not have been enabled
-        * for us: do so
-        */
-       exynos4_gic_secondary_init();
-
-       /*
-        * let the primary processor know we're out of the
-        * pen, then head off into the C entry point
-        */
-       write_pen_release(-1);
-
-       /*
-        * Synchronise with the boot thread.
-        */
-       spin_lock(&boot_lock);
-       spin_unlock(&boot_lock);
-
-       set_cpu_online(cpu, true);
-}
-
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       unsigned long timeout;
-
-       /*
-        * Set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       spin_lock(&boot_lock);
-
-       /*
-        * The secondary processor is waiting to be released from
-        * the holding pen - release it, then wait for it to flag
-        * that it has been released by resetting pen_release.
-        *
-        * Note that "pen_release" is the hardware CPU ID, whereas
-        * "cpu" is Linux's internal ID.
-        */
-       write_pen_release(cpu_logical_map(cpu));
-
-       if (!(__raw_readl(S5P_ARM_CORE1_STATUS) & S5P_CORE_LOCAL_PWR_EN)) {
-               __raw_writel(S5P_CORE_LOCAL_PWR_EN,
-                            S5P_ARM_CORE1_CONFIGURATION);
-
-               timeout = 10;
-
-               /* wait max 10 ms until cpu1 is on */
-               while ((__raw_readl(S5P_ARM_CORE1_STATUS)
-                       & S5P_CORE_LOCAL_PWR_EN) != S5P_CORE_LOCAL_PWR_EN) {
-                       if (timeout-- == 0)
-                               break;
-
-                       mdelay(1);
-               }
-
-               if (timeout == 0) {
-                       printk(KERN_ERR "cpu1 power enable failed");
-                       spin_unlock(&boot_lock);
-                       return -ETIMEDOUT;
-               }
-       }
-       /*
-        * Send the secondary CPU a soft interrupt, thereby causing
-        * the boot monitor to read the system wide flags register,
-        * and branch to the address found there.
-        */
-
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               smp_rmb();
-
-               __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
-                       CPU1_BOOT_REG);
-               gic_raise_softirq(cpumask_of(cpu), 1);
-
-               if (pen_release == -1)
-                       break;
-
-               udelay(10);
-       }
-
-       /*
-        * now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       spin_unlock(&boot_lock);
-
-       return pen_release != -1 ? -ENOSYS : 0;
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-
-void __init smp_init_cpus(void)
-{
-       void __iomem *scu_base = scu_base_addr();
-       unsigned int i, ncores;
-
-       ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
-       /* sanity check */
-       if (ncores > nr_cpu_ids) {
-               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-                       ncores, nr_cpu_ids);
-               ncores = nr_cpu_ids;
-       }
-
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
-
-       set_smp_cross_call(gic_raise_softirq);
-}
-
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
-{
-
-       scu_enable(scu_base_addr());
-
-       /*
-        * Write the address of secondary startup into the
-        * system-wide flags register. The boot monitor waits
-        * until it receives a soft interrupt, and then the
-        * secondary CPU branches to this address.
-        */
-       __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
-                       CPU1_BOOT_REG);
-}
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c
deleted file mode 100644 (file)
index 62e4f43..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/* linux/arch/arm/mach-exynos4/pm.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4210 - Power Management support
- *
- * Based on arch/arm/mach-s3c2410/pm.c
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/syscore_ops.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-
-#include <asm/cacheflush.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-#include <plat/pll.h>
-#include <plat/regs-srom.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-pmu.h>
-#include <mach/pm-core.h>
-#include <mach/pmu.h>
-
-static struct sleep_save exynos4_set_clksrc[] = {
-       { .reg = S5P_CLKSRC_MASK_TOP                    , .val = 0x00000001, },
-       { .reg = S5P_CLKSRC_MASK_CAM                    , .val = 0x11111111, },
-       { .reg = S5P_CLKSRC_MASK_TV                     , .val = 0x00000111, },
-       { .reg = S5P_CLKSRC_MASK_LCD0                   , .val = 0x00001111, },
-       { .reg = S5P_CLKSRC_MASK_MAUDIO                 , .val = 0x00000001, },
-       { .reg = S5P_CLKSRC_MASK_FSYS                   , .val = 0x01011111, },
-       { .reg = S5P_CLKSRC_MASK_PERIL0                 , .val = 0x01111111, },
-       { .reg = S5P_CLKSRC_MASK_PERIL1                 , .val = 0x01110111, },
-       { .reg = S5P_CLKSRC_MASK_DMC                    , .val = 0x00010000, },
-};
-
-static struct sleep_save exynos4210_set_clksrc[] = {
-       { .reg = S5P_CLKSRC_MASK_LCD1                   , .val = 0x00001111, },
-};
-
-static struct sleep_save exynos4_epll_save[] = {
-       SAVE_ITEM(S5P_EPLL_CON0),
-       SAVE_ITEM(S5P_EPLL_CON1),
-};
-
-static struct sleep_save exynos4_vpll_save[] = {
-       SAVE_ITEM(S5P_VPLL_CON0),
-       SAVE_ITEM(S5P_VPLL_CON1),
-};
-
-static struct sleep_save exynos4_core_save[] = {
-       /* GIC side */
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x014),
-       SAVE_ITEM(S5P_VA_GIC_CPU + 0x018),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
-
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
-
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
-       SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
-
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
-       SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
-
-       /* SROM side */
-       SAVE_ITEM(S5P_SROM_BW),
-       SAVE_ITEM(S5P_SROM_BC0),
-       SAVE_ITEM(S5P_SROM_BC1),
-       SAVE_ITEM(S5P_SROM_BC2),
-       SAVE_ITEM(S5P_SROM_BC3),
-};
-
-static struct sleep_save exynos4_l2cc_save[] = {
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
-       SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
-};
-
-/* For Cortex-A9 Diagnostic and Power control register */
-static unsigned int save_arm_register[2];
-
-static int exynos4_cpu_suspend(unsigned long arg)
-{
-       outer_flush_all();
-
-       /* issue the standby signal into the pm unit. */
-       cpu_do_idle();
-
-       /* we should never get past here */
-       panic("sleep resumed to originator?");
-}
-
-static void exynos4_pm_prepare(void)
-{
-       u32 tmp;
-
-       s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
-       s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
-       s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
-       s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
-
-       tmp = __raw_readl(S5P_INFORM1);
-
-       /* Set value of power down register for sleep mode */
-
-       exynos4_sys_powerdown_conf(SYS_SLEEP);
-       __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
-
-       /* ensure at least INFORM0 has the resume address */
-
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
-
-       /* Before enter central sequence mode, clock src register have to set */
-
-       s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
-
-       if (soc_is_exynos4210())
-               s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
-
-}
-
-static int exynos4_pm_add(struct sys_device *sysdev)
-{
-       pm_cpu_prep = exynos4_pm_prepare;
-       pm_cpu_sleep = exynos4_cpu_suspend;
-
-       return 0;
-}
-
-/* This function copy from linux/arch/arm/kernel/smp_scu.c */
-
-void exynos4_scu_enable(void __iomem *scu_base)
-{
-       u32 scu_ctrl;
-
-       scu_ctrl = __raw_readl(scu_base);
-       /* already enabled? */
-       if (scu_ctrl & 1)
-               return;
-
-       scu_ctrl |= 1;
-       __raw_writel(scu_ctrl, scu_base);
-
-       /*
-        * Ensure that the data accessed by CPU0 before the SCU was
-        * initialised is visible to the other CPUs.
-        */
-       flush_cache_all();
-}
-
-static unsigned long pll_base_rate;
-
-static void exynos4_restore_pll(void)
-{
-       unsigned long pll_con, locktime, lockcnt;
-       unsigned long pll_in_rate;
-       unsigned int p_div, epll_wait = 0, vpll_wait = 0;
-
-       if (pll_base_rate == 0)
-               return;
-
-       pll_in_rate = pll_base_rate;
-
-       /* EPLL */
-       pll_con = exynos4_epll_save[0].val;
-
-       if (pll_con & (1 << 31)) {
-               pll_con &= (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT);
-               p_div = (pll_con >> PLL46XX_PDIV_SHIFT);
-
-               pll_in_rate /= 1000000;
-
-               locktime = (3000 / pll_in_rate) * p_div;
-               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
-
-               __raw_writel(lockcnt, S5P_EPLL_LOCK);
-
-               s3c_pm_do_restore_core(exynos4_epll_save,
-                                       ARRAY_SIZE(exynos4_epll_save));
-               epll_wait = 1;
-       }
-
-       pll_in_rate = pll_base_rate;
-
-       /* VPLL */
-       pll_con = exynos4_vpll_save[0].val;
-
-       if (pll_con & (1 << 31)) {
-               pll_in_rate /= 1000000;
-               /* 750us */
-               locktime = 750;
-               lockcnt = locktime * 10000 / (10000 / pll_in_rate);
-
-               __raw_writel(lockcnt, S5P_VPLL_LOCK);
-
-               s3c_pm_do_restore_core(exynos4_vpll_save,
-                                       ARRAY_SIZE(exynos4_vpll_save));
-               vpll_wait = 1;
-       }
-
-       /* Wait PLL locking */
-
-       do {
-               if (epll_wait) {
-                       pll_con = __raw_readl(S5P_EPLL_CON0);
-                       if (pll_con & (1 << S5P_EPLLCON0_LOCKED_SHIFT))
-                               epll_wait = 0;
-               }
-
-               if (vpll_wait) {
-                       pll_con = __raw_readl(S5P_VPLL_CON0);
-                       if (pll_con & (1 << S5P_VPLLCON0_LOCKED_SHIFT))
-                               vpll_wait = 0;
-               }
-       } while (epll_wait || vpll_wait);
-}
-
-static struct sysdev_driver exynos4_pm_driver = {
-       .add            = exynos4_pm_add,
-};
-
-static __init int exynos4_pm_drvinit(void)
-{
-       struct clk *pll_base;
-       unsigned int tmp;
-
-       s3c_pm_init();
-
-       /* All wakeup disable */
-
-       tmp = __raw_readl(S5P_WAKEUP_MASK);
-       tmp |= ((0xFF << 8) | (0x1F << 1));
-       __raw_writel(tmp, S5P_WAKEUP_MASK);
-
-       pll_base = clk_get(NULL, "xtal");
-
-       if (!IS_ERR(pll_base)) {
-               pll_base_rate = clk_get_rate(pll_base);
-               clk_put(pll_base);
-       }
-
-       return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
-}
-arch_initcall(exynos4_pm_drvinit);
-
-static int exynos4_pm_suspend(void)
-{
-       unsigned long tmp;
-
-       /* Setting Central Sequence Register for power down mode */
-
-       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-       tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
-       __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-
-       /* Save Power control register */
-       asm ("mrc p15, 0, %0, c15, c0, 0"
-            : "=r" (tmp) : : "cc");
-       save_arm_register[0] = tmp;
-
-       /* Save Diagnostic register */
-       asm ("mrc p15, 0, %0, c15, c0, 1"
-            : "=r" (tmp) : : "cc");
-       save_arm_register[1] = tmp;
-
-       return 0;
-}
-
-static void exynos4_pm_resume(void)
-{
-       unsigned long tmp;
-
-       /*
-        * If PMU failed while entering sleep mode, WFI will be
-        * ignored by PMU and then exiting cpu_do_idle().
-        * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
-        * in this situation.
-        */
-       tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
-       if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
-               tmp |= S5P_CENTRAL_LOWPWR_CFG;
-               __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-               /* No need to perform below restore code */
-               goto early_wakeup;
-       }
-       /* Restore Power control register */
-       tmp = save_arm_register[0];
-       asm volatile ("mcr p15, 0, %0, c15, c0, 0"
-                     : : "r" (tmp)
-                     : "cc");
-
-       /* Restore Diagnostic register */
-       tmp = save_arm_register[1];
-       asm volatile ("mcr p15, 0, %0, c15, c0, 1"
-                     : : "r" (tmp)
-                     : "cc");
-
-       /* For release retention */
-
-       __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
-       __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
-
-       s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
-
-       exynos4_restore_pll();
-
-       exynos4_scu_enable(S5P_VA_SCU);
-
-#ifdef CONFIG_CACHE_L2X0
-       s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
-       outer_inv_all();
-       /* enable L2X0*/
-       writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
-#endif
-
-early_wakeup:
-       return;
-}
-
-static struct syscore_ops exynos4_pm_syscore_ops = {
-       .suspend        = exynos4_pm_suspend,
-       .resume         = exynos4_pm_resume,
-};
-
-static __init int exynos4_pm_syscore_init(void)
-{
-       register_syscore_ops(&exynos4_pm_syscore_ops);
-       return 0;
-}
-arch_initcall(exynos4_pm_syscore_init);
diff --git a/arch/arm/mach-exynos4/pmu.c b/arch/arm/mach-exynos4/pmu.c
deleted file mode 100644 (file)
index 7ea9eb2..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* linux/arch/arm/mach-exynos4/pmu.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * EXYNOS4210 - CPU PMU(Power Management Unit) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-
-#include <mach/regs-clock.h>
-#include <mach/pmu.h>
-
-static void __iomem *sys_powerdown_reg[] = {
-       S5P_ARM_CORE0_LOWPWR,
-       S5P_DIS_IRQ_CORE0,
-       S5P_DIS_IRQ_CENTRAL0,
-       S5P_ARM_CORE1_LOWPWR,
-       S5P_DIS_IRQ_CORE1,
-       S5P_DIS_IRQ_CENTRAL1,
-       S5P_ARM_COMMON_LOWPWR,
-       S5P_L2_0_LOWPWR,
-       S5P_L2_1_LOWPWR,
-       S5P_CMU_ACLKSTOP_LOWPWR,
-       S5P_CMU_SCLKSTOP_LOWPWR,
-       S5P_CMU_RESET_LOWPWR,
-       S5P_APLL_SYSCLK_LOWPWR,
-       S5P_MPLL_SYSCLK_LOWPWR,
-       S5P_VPLL_SYSCLK_LOWPWR,
-       S5P_EPLL_SYSCLK_LOWPWR,
-       S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,
-       S5P_CMU_RESET_GPSALIVE_LOWPWR,
-       S5P_CMU_CLKSTOP_CAM_LOWPWR,
-       S5P_CMU_CLKSTOP_TV_LOWPWR,
-       S5P_CMU_CLKSTOP_MFC_LOWPWR,
-       S5P_CMU_CLKSTOP_G3D_LOWPWR,
-       S5P_CMU_CLKSTOP_LCD0_LOWPWR,
-       S5P_CMU_CLKSTOP_LCD1_LOWPWR,
-       S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,
-       S5P_CMU_CLKSTOP_GPS_LOWPWR,
-       S5P_CMU_RESET_CAM_LOWPWR,
-       S5P_CMU_RESET_TV_LOWPWR,
-       S5P_CMU_RESET_MFC_LOWPWR,
-       S5P_CMU_RESET_G3D_LOWPWR,
-       S5P_CMU_RESET_LCD0_LOWPWR,
-       S5P_CMU_RESET_LCD1_LOWPWR,
-       S5P_CMU_RESET_MAUDIO_LOWPWR,
-       S5P_CMU_RESET_GPS_LOWPWR,
-       S5P_TOP_BUS_LOWPWR,
-       S5P_TOP_RETENTION_LOWPWR,
-       S5P_TOP_PWR_LOWPWR,
-       S5P_LOGIC_RESET_LOWPWR,
-       S5P_ONENAND_MEM_LOWPWR,
-       S5P_MODIMIF_MEM_LOWPWR,
-       S5P_G2D_ACP_MEM_LOWPWR,
-       S5P_USBOTG_MEM_LOWPWR,
-       S5P_HSMMC_MEM_LOWPWR,
-       S5P_CSSYS_MEM_LOWPWR,
-       S5P_SECSS_MEM_LOWPWR,
-       S5P_PCIE_MEM_LOWPWR,
-       S5P_SATA_MEM_LOWPWR,
-       S5P_PAD_RETENTION_DRAM_LOWPWR,
-       S5P_PAD_RETENTION_MAUDIO_LOWPWR,
-       S5P_PAD_RETENTION_GPIO_LOWPWR,
-       S5P_PAD_RETENTION_UART_LOWPWR,
-       S5P_PAD_RETENTION_MMCA_LOWPWR,
-       S5P_PAD_RETENTION_MMCB_LOWPWR,
-       S5P_PAD_RETENTION_EBIA_LOWPWR,
-       S5P_PAD_RETENTION_EBIB_LOWPWR,
-       S5P_PAD_RETENTION_ISOLATION_LOWPWR,
-       S5P_PAD_RETENTION_ALV_SEL_LOWPWR,
-       S5P_XUSBXTI_LOWPWR,
-       S5P_XXTI_LOWPWR,
-       S5P_EXT_REGULATOR_LOWPWR,
-       S5P_GPIO_MODE_LOWPWR,
-       S5P_GPIO_MODE_MAUDIO_LOWPWR,
-       S5P_CAM_LOWPWR,
-       S5P_TV_LOWPWR,
-       S5P_MFC_LOWPWR,
-       S5P_G3D_LOWPWR,
-       S5P_LCD0_LOWPWR,
-       S5P_LCD1_LOWPWR,
-       S5P_MAUDIO_LOWPWR,
-       S5P_GPS_LOWPWR,
-       S5P_GPS_ALIVE_LOWPWR,
-};
-
-static const unsigned int sys_powerdown_val[][NUM_SYS_POWERDOWN] = {
-       /* { AFTR, LPA, SLEEP }*/
-       { 0, 0, 2 },    /* ARM_CORE0 */
-       { 0, 0, 0 },    /* ARM_DIS_IRQ_CORE0 */
-       { 0, 0, 0 },    /* ARM_DIS_IRQ_CENTRAL0 */
-       { 0, 0, 2 },    /* ARM_CORE1 */
-       { 0, 0, 0 },    /* ARM_DIS_IRQ_CORE1 */
-       { 0, 0, 0 },    /* ARM_DIS_IRQ_CENTRAL1 */
-       { 0, 0, 2 },    /* ARM_COMMON */
-       { 2, 2, 3 },    /* ARM_CPU_L2_0 */
-       { 2, 2, 3 },    /* ARM_CPU_L2_1 */
-       { 1, 0, 0 },    /* CMU_ACLKSTOP */
-       { 1, 0, 0 },    /* CMU_SCLKSTOP */
-       { 1, 1, 0 },    /* CMU_RESET */
-       { 1, 0, 0 },    /* APLL_SYSCLK */
-       { 1, 0, 0 },    /* MPLL_SYSCLK */
-       { 1, 0, 0 },    /* VPLL_SYSCLK */
-       { 1, 1, 0 },    /* EPLL_SYSCLK */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_GPS_ALIVE */
-       { 1, 1, 0 },    /* CMU_RESET_GPS_ALIVE */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_CAM */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_TV */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_MFC */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_G3D */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_LCD0 */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_LCD1 */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_MAUDIO */
-       { 1, 1, 0 },    /* CMU_CLKSTOP_GPS */
-       { 1, 1, 0 },    /* CMU_RESET_CAM */
-       { 1, 1, 0 },    /* CMU_RESET_TV */
-       { 1, 1, 0 },    /* CMU_RESET_MFC */
-       { 1, 1, 0 },    /* CMU_RESET_G3D */
-       { 1, 1, 0 },    /* CMU_RESET_LCD0 */
-       { 1, 1, 0 },    /* CMU_RESET_LCD1 */
-       { 1, 1, 0 },    /* CMU_RESET_MAUDIO */
-       { 1, 1, 0 },    /* CMU_RESET_GPS */
-       { 3, 0, 0 },    /* TOP_BUS */
-       { 1, 0, 1 },    /* TOP_RETENTION */
-       { 3, 0, 3 },    /* TOP_PWR */
-       { 1, 1, 0 },    /* LOGIC_RESET */
-       { 3, 0, 0 },    /* ONENAND_MEM */
-       { 3, 0, 0 },    /* MODIMIF_MEM */
-       { 3, 0, 0 },    /* G2D_ACP_MEM */
-       { 3, 0, 0 },    /* USBOTG_MEM */
-       { 3, 0, 0 },    /* HSMMC_MEM */
-       { 3, 0, 0 },    /* CSSYS_MEM */
-       { 3, 0, 0 },    /* SECSS_MEM */
-       { 3, 0, 0 },    /* PCIE_MEM */
-       { 3, 0, 0 },    /* SATA_MEM */
-       { 1, 0, 0 },    /* PAD_RETENTION_DRAM */
-       { 1, 1, 0 },    /* PAD_RETENTION_MAUDIO */
-       { 1, 0, 0 },    /* PAD_RETENTION_GPIO */
-       { 1, 0, 0 },    /* PAD_RETENTION_UART */
-       { 1, 0, 0 },    /* PAD_RETENTION_MMCA */
-       { 1, 0, 0 },    /* PAD_RETENTION_MMCB */
-       { 1, 0, 0 },    /* PAD_RETENTION_EBIA */
-       { 1, 0, 0 },    /* PAD_RETENTION_EBIB */
-       { 1, 0, 0 },    /* PAD_RETENTION_ISOLATION */
-       { 1, 0, 0 },    /* PAD_RETENTION_ALV_SEL */
-       { 1, 1, 0 },    /* XUSBXTI */
-       { 1, 1, 0 },    /* XXTI */
-       { 1, 1, 0 },    /* EXT_REGULATOR */
-       { 1, 0, 0 },    /* GPIO_MODE */
-       { 1, 1, 0 },    /* GPIO_MODE_MAUDIO */
-       { 7, 0, 0 },    /* CAM */
-       { 7, 0, 0 },    /* TV */
-       { 7, 0, 0 },    /* MFC */
-       { 7, 0, 0 },    /* G3D */
-       { 7, 0, 0 },    /* LCD0 */
-       { 7, 0, 0 },    /* LCD1 */
-       { 7, 7, 0 },    /* MAUDIO */
-       { 7, 0, 0 },    /* GPS */
-       { 7, 0, 0 },    /* GPS_ALIVE */
-};
-
-void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
-{
-       unsigned int count = ARRAY_SIZE(sys_powerdown_reg);
-
-       for (; count > 0; count--)
-               __raw_writel(sys_powerdown_val[count - 1][mode],
-                               sys_powerdown_reg[count - 1]);
-}
diff --git a/arch/arm/mach-exynos4/setup-fimc.c b/arch/arm/mach-exynos4/setup-fimc.c
deleted file mode 100644 (file)
index 6a45078..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * Exynos4 camera interface GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gpio.h>
-#include <plat/gpio-cfg.h>
-#include <plat/camport.h>
-
-int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
-{
-       u32 gpio8, gpio5;
-       u32 sfn;
-       int ret;
-
-       switch (id) {
-       case S5P_CAMPORT_A:
-               gpio8 = EXYNOS4_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
-               gpio5 = EXYNOS4_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
-               sfn = S3C_GPIO_SFN(2);
-               break;
-
-       case S5P_CAMPORT_B:
-               gpio8 = EXYNOS4_GPE0(0); /* DATA[0:7] */
-               gpio5 = EXYNOS4_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
-               sfn = S3C_GPIO_SFN(3);
-               break;
-
-       default:
-               WARN(1, "Wrong camport id: %d\n", id);
-               return -EINVAL;
-       }
-
-       ret = s3c_gpio_cfgall_range(gpio8, 8, sfn, S3C_GPIO_PULL_UP);
-       if (ret)
-               return ret;
-
-       return s3c_gpio_cfgall_range(gpio5, 5, sfn, S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-fimd0.c b/arch/arm/mach-exynos4/setup-fimd0.c
deleted file mode 100644 (file)
index 07a6dbe..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-fimd0.c
- *
- * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Base Exynos4 FIMD 0 configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/fb.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
-
-#include <mach/map.h>
-
-void exynos4_fimd0_gpio_setup_24bpp(void)
-{
-       unsigned int reg;
-
-       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
-       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
-       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
-       s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
-
-       /*
-        * Set DISPLAY_CONTROL register for Display path selection.
-        *
-        * DISPLAY_CONTROL[1:0]
-        * ---------------------
-        *  00 | MIE
-        *  01 | MDINE
-        *  10 | FIMD : selected
-        *  11 | FIMD
-        */
-       reg = __raw_readl(S3C_VA_SYS + 0x0210);
-       reg |= (1 << 1);
-       __raw_writel(reg, S3C_VA_SYS + 0x0210);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos4/setup-i2c0.c
deleted file mode 100644 (file)
index d395bd1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c0.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
-                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c1.c b/arch/arm/mach-exynos4/setup-i2c1.c
deleted file mode 100644 (file)
index fd7235a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c1.c
- *
- * Copyright (C) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C1 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPD1(2), 2,
-                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c2.c b/arch/arm/mach-exynos4/setup-i2c2.c
deleted file mode 100644 (file)
index 2694b19..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c2.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *
- * I2C2 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c2_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPA0(6), 2,
-                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c3.c b/arch/arm/mach-exynos4/setup-i2c3.c
deleted file mode 100644 (file)
index 379bd30..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C3 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c3_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
-                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c4.c b/arch/arm/mach-exynos4/setup-i2c4.c
deleted file mode 100644 (file)
index 9f3c048..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c4.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C4 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c4_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
-                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c5.c b/arch/arm/mach-exynos4/setup-i2c5.c
deleted file mode 100644 (file)
index 77e1a1e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c5.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C5 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c5_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
-                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c6.c b/arch/arm/mach-exynos4/setup-i2c6.c
deleted file mode 100644 (file)
index 284d12b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c6.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C6 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c6_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
-                             S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-i2c7.c b/arch/arm/mach-exynos4/setup-i2c7.c
deleted file mode 100644 (file)
index b7611ee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c7.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C7 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c7_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
-                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-exynos4/setup-keypad.c b/arch/arm/mach-exynos4/setup-keypad.c
deleted file mode 100644 (file)
index 7862bfb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-keypad.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * GPIO configuration for Exynos4 KeyPad device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <plat/gpio-cfg.h>
-
-void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
-{
-       /* Keypads can be of various combinations, Just making sure */
-
-       if (rows > 8) {
-               /* Set all the necessary GPX2 pins: KP_ROW[0~7] */
-               s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), 8, S3C_GPIO_SFN(3),
-                                       S3C_GPIO_PULL_UP);
-
-               /* Set all the necessary GPX3 pins: KP_ROW[8~] */
-               s3c_gpio_cfgall_range(EXYNOS4_GPX3(0), (rows - 8),
-                                        S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-       } else {
-               /* Set all the necessary GPX2 pins: KP_ROW[x] */
-               s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), rows, S3C_GPIO_SFN(3),
-                                       S3C_GPIO_PULL_UP);
-       }
-
-       /* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
-       s3c_gpio_cfgrange_nopull(EXYNOS4_GPX1(0), cols, S3C_GPIO_SFN(3));
-}
diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
deleted file mode 100644 (file)
index e8d08bf..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-sdhci-gpio.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-
-       /* Set all the necessary GPK0[0:1] pins to special-function 2 */
-       for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       switch (width) {
-       case 8:
-               for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
-                       /* Data pin GPK1[3:6] to special-function 3 */
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-               }
-       case 4:
-               for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
-                       /* Data pin GPK0[3:6] to special-function 2 */
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-               }
-       default:
-               break;
-       }
-
-       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-               s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-}
-
-void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-
-       /* Set all the necessary GPK1[0:1] pins to special-function 2 */
-       for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
-               /* Data pin GPK1[3:6] to special-function 2 */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-               s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-}
-
-void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
-       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-
-       /* Set all the necessary GPK2[0:1] pins to special-function 2 */
-       for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       switch (width) {
-       case 8:
-               for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
-                       /* Data pin GPK3[3:6] to special-function 3 */
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-               }
-       case 4:
-               for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
-                       /* Data pin GPK2[3:6] to special-function 2 */
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-               }
-       default:
-               break;
-       }
-
-       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-               s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-}
-
-void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
-{
-       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-
-       /* Set all the necessary GPK3[0:1] pins to special-function 2 */
-       for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
-               /* Data pin GPK3[3:6] to special-function 2 */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-               s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_UP);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-}
diff --git a/arch/arm/mach-exynos4/setup-sdhci.c b/arch/arm/mach-exynos4/setup-sdhci.c
deleted file mode 100644 (file)
index 1e83f8c..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-sdhci.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-
-/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
-
-char *exynos4_hsmmc_clksrcs[4] = {
-       [0] = NULL,
-       [1] = NULL,
-       [2] = "sclk_mmc",       /* mmc_bus */
-       [3] = NULL,
-};
-
-void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
-                                 struct mmc_ios *ios, struct mmc_card *card)
-{
-       u32 ctrl2, ctrl3;
-
-       /* don't need to alter anything according to card-type */
-
-       ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-
-       /* select base clock source to HCLK */
-
-       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-
-       /*
-        * clear async mode, enable conflict mask, rx feedback ctrl, SD
-        * clk hold and no use debounce count
-        */
-
-       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-                 S3C_SDHCI_CTRL2_ENFBCLKRX |
-                 S3C_SDHCI_CTRL2_DFCNT_NONE |
-                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-       /* Tx and Rx feedback clock delay control */
-
-       if (ios->clock < 25 * 1000000)
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-                        S3C_SDHCI_CTRL3_FCSEL2 |
-                        S3C_SDHCI_CTRL3_FCSEL1 |
-                        S3C_SDHCI_CTRL3_FCSEL0);
-       else
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-       writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-       writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c
deleted file mode 100644 (file)
index 39aca04..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <mach/regs-pmu.h>
-#include <mach/regs-usb-phy.h>
-#include <plat/cpu.h>
-#include <plat/usb-phy.h>
-
-static int exynos4_usb_phy1_init(struct platform_device *pdev)
-{
-       struct clk *otg_clk;
-       struct clk *xusbxti_clk;
-       u32 phyclk;
-       u32 rstcon;
-       int err;
-
-       otg_clk = clk_get(&pdev->dev, "otg");
-       if (IS_ERR(otg_clk)) {
-               dev_err(&pdev->dev, "Failed to get otg clock\n");
-               return PTR_ERR(otg_clk);
-       }
-
-       err = clk_enable(otg_clk);
-       if (err) {
-               clk_put(otg_clk);
-               return err;
-       }
-
-       writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
-                       S5P_USBHOST_PHY_CONTROL);
-
-       /* set clock frequency for PLL */
-       phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
-
-       xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
-       if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
-               switch (clk_get_rate(xusbxti_clk)) {
-               case 12 * MHZ:
-                       phyclk |= CLKSEL_12M;
-                       break;
-               case 24 * MHZ:
-                       phyclk |= CLKSEL_24M;
-                       break;
-               default:
-               case 48 * MHZ:
-                       /* default reference clock */
-                       break;
-               }
-               clk_put(xusbxti_clk);
-       }
-
-       writel(phyclk, EXYNOS4_PHYCLK);
-
-       /* floating prevention logic: disable */
-       writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
-
-       /* set to normal HSIC 0 and 1 of PHY1 */
-       writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
-                       EXYNOS4_PHYPWR);
-
-       /* set to normal standard USB of PHY1 */
-       writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
-
-       /* reset all ports of both PHY and Link */
-       rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
-               PHY1_SWRST_MASK;
-       writel(rstcon, EXYNOS4_RSTCON);
-       udelay(10);
-
-       rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
-       writel(rstcon, EXYNOS4_RSTCON);
-       udelay(80);
-
-       clk_disable(otg_clk);
-       clk_put(otg_clk);
-
-       return 0;
-}
-
-static int exynos4_usb_phy1_exit(struct platform_device *pdev)
-{
-       struct clk *otg_clk;
-       int err;
-
-       otg_clk = clk_get(&pdev->dev, "otg");
-       if (IS_ERR(otg_clk)) {
-               dev_err(&pdev->dev, "Failed to get otg clock\n");
-               return PTR_ERR(otg_clk);
-       }
-
-       err = clk_enable(otg_clk);
-       if (err) {
-               clk_put(otg_clk);
-               return err;
-       }
-
-       writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
-                       EXYNOS4_PHYPWR);
-
-       writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
-                       S5P_USBHOST_PHY_CONTROL);
-
-       clk_disable(otg_clk);
-       clk_put(otg_clk);
-
-       return 0;
-}
-
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
-{
-       if (type == S5P_USB_PHY_HOST)
-               return exynos4_usb_phy1_init(pdev);
-
-       return -EINVAL;
-}
-
-int s5p_usb_phy_exit(struct platform_device *pdev, int type)
-{
-       if (type == S5P_USB_PHY_HOST)
-               return exynos4_usb_phy1_exit(pdev);
-
-       return -EINVAL;
-}
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S
deleted file mode 100644 (file)
index 0984078..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* linux/arch/arm/mach-exynos4/sleep.S
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4210 power Manager (Suspend-To-RAM) support
- * Based on S3C2410 sleep code by:
- *     Ben Dooks, (c) 2004 Simtec Electronics
- *
- * Based on PXA/SA1100 sleep code by:
- *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- *     Cliff Brake, (c) 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/memory.h>
-
-       .text
-
-       /*
-        * sleep magic, to allow the bootloader to check for an valid
-        * image to resume to. Must be the first word before the
-        * s3c_cpu_resume entry.
-        */
-
-       .word   0x2bedf00d
-
-       /*
-        * s3c_cpu_resume
-        *
-        * resume code entry for bootloader to call
-        *
-        * we must put this code here in the data segment as we have no
-        * other way of restoring the stack pointer after sleep, and we
-        * must not write to the code segment (code is read-only)
-        */
-
-ENTRY(s3c_cpu_resume)
-       b       cpu_resume
index b82dcf08e747e1052ea13b4a11feef25b7f7775b..88660d500f5be259bde8bd94389805881cf8975e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
+#include <linux/smp.h>
 
 #include <asm/cacheflush.h>
 #include <asm/unified.h>
@@ -72,6 +73,9 @@ static void __init highbank_map_io(void)
 
 void highbank_set_cpu_jump(int cpu, void *jump_addr)
 {
+#ifdef CONFIG_SMP
+       cpu = cpu_logical_map(cpu);
+#endif
        writel(BSYM(virt_to_phys(jump_addr)), HB_JUMP_TABLE_VIRT(cpu));
        __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
        outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
index 5f7f9c2a34aec39cdd4f312c326cd0005d5ea027..c44aa974e79c473d123631236269bdb8c2daa8a3 100644 (file)
@@ -10,11 +10,6 @@ config HAVE_IMX_MMDC
 config HAVE_IMX_SRC
        bool
 
-#
-# ARCH_MX31 and ARCH_MX35 are left for compatibility
-# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
-# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
-# more sensible) names are used: SOC_IMX31 and SOC_IMX35
 config ARCH_MX1
        bool
 
@@ -27,12 +22,6 @@ config ARCH_MX25
 config MACH_MX27
        bool
 
-config ARCH_MX31
-       bool
-
-config ARCH_MX35
-       bool
-
 config SOC_IMX1
        bool
        select ARCH_MX1
@@ -72,7 +61,6 @@ config SOC_IMX31
        select CPU_V6
        select IMX_HAVE_PLATFORM_MXC_RNGA
        select ARCH_MXC_AUDMUX_V2
-       select ARCH_MX31
        select MXC_AVIC
        select SMP_ON_UP if SMP
 
@@ -82,7 +70,6 @@ config SOC_IMX35
        select ARCH_MXC_IOMUX_V3
        select ARCH_MXC_AUDMUX_V2
        select HAVE_EPIT
-       select ARCH_MX35
        select MXC_AVIC
        select SMP_ON_UP if SMP
 
index 22d85889f622917ece0fe5310751bf4ab488fed3..cfede5768aa0f788a6d8f6fd8893578a5c4ed75b 100644 (file)
@@ -1,22 +1,26 @@
-zreladdr-$(CONFIG_ARCH_MX1)    += 0x08008000
-params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
-initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
+zreladdr-$(CONFIG_SOC_IMX1)    += 0x08008000
+params_phys-$(CONFIG_SOC_IMX1) := 0x08000100
+initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000
 
-zreladdr-$(CONFIG_MACH_MX21)   += 0xC0008000
-params_phys-$(CONFIG_MACH_MX21)        := 0xC0000100
-initrd_phys-$(CONFIG_MACH_MX21)        := 0xC0800000
+zreladdr-$(CONFIG_SOC_IMX21)   += 0xC0008000
+params_phys-$(CONFIG_SOC_IMX21)        := 0xC0000100
+initrd_phys-$(CONFIG_SOC_IMX21)        := 0xC0800000
 
-zreladdr-$(CONFIG_ARCH_MX25)   += 0x80008000
-params_phys-$(CONFIG_ARCH_MX25)        := 0x80000100
-initrd_phys-$(CONFIG_ARCH_MX25)        := 0x80800000
+zreladdr-$(CONFIG_SOC_IMX25)   += 0x80008000
+params_phys-$(CONFIG_SOC_IMX25)        := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX25)        := 0x80800000
 
-zreladdr-$(CONFIG_MACH_MX27)   += 0xA0008000
-params_phys-$(CONFIG_MACH_MX27)        := 0xA0000100
-initrd_phys-$(CONFIG_MACH_MX27)        := 0xA0800000
+zreladdr-$(CONFIG_SOC_IMX27)   += 0xA0008000
+params_phys-$(CONFIG_SOC_IMX27)        := 0xA0000100
+initrd_phys-$(CONFIG_SOC_IMX27)        := 0xA0800000
 
-zreladdr-$(CONFIG_ARCH_MX3)    += 0x80008000
-params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
-initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
+zreladdr-$(CONFIG_SOC_IMX31)   += 0x80008000
+params_phys-$(CONFIG_SOC_IMX31)        := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX31)        := 0x80800000
+
+zreladdr-$(CONFIG_SOC_IMX35)   += 0x80008000
+params_phys-$(CONFIG_SOC_IMX35)        := 0x80000100
+initrd_phys-$(CONFIG_SOC_IMX35)        := 0x80800000
 
 zreladdr-$(CONFIG_SOC_IMX6Q)   += 0x10008000
 params_phys-$(CONFIG_SOC_IMX6Q)        := 0x10000100
index e0b926dfecedbf2874b03ec726acaf591cd2e94a..039a7abb165a35f4afc10ae08dbb7cc62f1121f7 100644 (file)
@@ -1139,7 +1139,7 @@ static int _clk_set_rate(struct clk *clk, unsigned long rate)
                return -EINVAL;
 
        max_div = ((d->bm_pred >> d->bp_pred) + 1) *
-                 ((d->bm_pred >> d->bp_pred) + 1);
+                 ((d->bm_podf >> d->bp_podf) + 1);
 
        div = parent_rate / rate;
        if (div == 0)
@@ -1953,14 +1953,17 @@ static struct map_desc imx6q_clock_desc[] = {
        imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
 };
 
+void __init imx6q_clock_map_io(void)
+{
+       iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
+}
+
 int __init mx6q_clocks_init(void)
 {
        struct device_node *np;
        void __iomem *base;
        int i, irq;
 
-       iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
-
        /* retrieve the freqency of fixed clocks from device tree */
        for_each_compatible_node(np, NULL, "fixed-clock") {
                u32 rate;
@@ -2002,6 +2005,21 @@ int __init mx6q_clocks_init(void)
        clk_set_rate(&asrc_serial_clk, 1500000);
        clk_set_rate(&enfc_clk, 11000000);
 
+       /*
+        * Before pinctrl API is available, we have to rely on the pad
+        * configuration set up by bootloader.  For usdhc example here,
+        * u-boot sets up the pads for 49.5 MHz case, and we have to lower
+        * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
+        *
+        * FIXME: This is should be removed after pinctrl API is available.
+        * At that time, usdhc driver can call pinctrl API to change pad
+        * configuration dynamically per different usdhc clock settings.
+        */
+       clk_set_rate(&usdhc1_clk, 49500000);
+       clk_set_rate(&usdhc2_clk, 49500000);
+       clk_set_rate(&usdhc3_clk, 49500000);
+       clk_set_rate(&usdhc4_clk, 49500000);
+
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
        base = of_iomap(np, 0);
        WARN_ON(!base);
index 8bf5fa349484e2da42a4c6deea64bc042b1263e3..8deb012189b5a7e185f7299a8ad8c8503edad587 100644 (file)
@@ -34,16 +34,18 @@ static void __init imx6q_map_io(void)
 {
        imx_lluart_map_io();
        imx_scu_map_io();
+       imx6q_clock_map_io();
 }
 
-static void __init imx6q_gpio_add_irq_domain(struct device_node *np,
+static int __init imx6q_gpio_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
-       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
-                                  32 * 7; /* imx6q gets 7 gpio ports */
+       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
+       gpio_irq_base -= 32;
        irq_domain_add_simple(np, gpio_irq_base);
-       gpio_irq_base += 32;
+
+       return 0;
 }
 
 static const struct of_device_id imx6q_irq_match[] __initconst = {
index 5defd8e70fc488e4d6c852827fcdb551fcb1e2ac..102ec99357ccb99bec5e83551d3d0f1303b6a25f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/moduleparam.h>
 #include <linux/smsc911x.h>
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
index 05f1c71ba409f77cc0032a5c14b9f2285d18d93a..5366d2de18fdc4b75047a435dc8d27e8f39f023e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/memory.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/moduleparam.h>
 #include <linux/smsc911x.h>
 #include <linux/mfd/mc13783.h>
 #include <linux/spi/spi.h>
index 07034f44466a8c30f2c8ff3aaedca60513a61827..93269150309cfd11571c9b84c770d31bf510bc31 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/moduleparam.h>
 #include <linux/leds.h>
 #include <linux/memory.h>
 #include <linux/mtd/physmap.h>
index 9f0e82ec3398dfcf7e83c8df246e54cdf53b9503..31807d2a8b7bf1a65d57c8f4cb748bb9e6697934 100644 (file)
 static void imx3_idle(void)
 {
        unsigned long reg = 0;
-       __asm__ __volatile__(
-               /* disable I and D cache */
-               "mrc p15, 0, %0, c1, c0, 0\n"
-               "bic %0, %0, #0x00001000\n"
-               "bic %0, %0, #0x00000004\n"
-               "mcr p15, 0, %0, c1, c0, 0\n"
-               /* invalidate I cache */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c5, 0\n"
-               /* clear and invalidate D cache */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c14, 0\n"
-               /* WFI */
-               "mov %0, #0\n"
-               "mcr p15, 0, %0, c7, c0, 4\n"
-               "nop\n" "nop\n" "nop\n" "nop\n"
-               "nop\n" "nop\n" "nop\n"
-               /* enable I and D cache */
-               "mrc p15, 0, %0, c1, c0, 0\n"
-               "orr %0, %0, #0x00001000\n"
-               "orr %0, %0, #0x00000004\n"
-               "mcr p15, 0, %0, c1, c0, 0\n"
-               : "=r" (reg));
+
+       if (!need_resched())
+               __asm__ __volatile__(
+                       /* disable I and D cache */
+                       "mrc p15, 0, %0, c1, c0, 0\n"
+                       "bic %0, %0, #0x00001000\n"
+                       "bic %0, %0, #0x00000004\n"
+                       "mcr p15, 0, %0, c1, c0, 0\n"
+                       /* invalidate I cache */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c5, 0\n"
+                       /* clear and invalidate D cache */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c14, 0\n"
+                       /* WFI */
+                       "mov %0, #0\n"
+                       "mcr p15, 0, %0, c7, c0, 4\n"
+                       "nop\n" "nop\n" "nop\n" "nop\n"
+                       "nop\n" "nop\n" "nop\n"
+                       /* enable I and D cache */
+                       "mrc p15, 0, %0, c1, c0, 0\n"
+                       "orr %0, %0, #0x00001000\n"
+                       "orr %0, %0, #0x00000004\n"
+                       "mcr p15, 0, %0, c1, c0, 0\n"
+                       : "=r" (reg));
+       local_irq_enable();
 }
 
 static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size,
@@ -108,6 +111,7 @@ void imx3_init_l2x0(void)
        l2x0_init(l2x0_base, 0x00030024, 0x00000000);
 }
 
+#ifdef CONFIG_SOC_IMX31
 static struct map_desc mx31_io_desc[] __initdata = {
        imx_map_entry(MX31, X_MEMC, MT_DEVICE),
        imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
@@ -126,33 +130,11 @@ void __init mx31_map_io(void)
        iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
 }
 
-static struct map_desc mx35_io_desc[] __initdata = {
-       imx_map_entry(MX35, X_MEMC, MT_DEVICE),
-       imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
-       imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
-};
-
-void __init mx35_map_io(void)
-{
-       iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
-}
-
 void __init imx31_init_early(void)
 {
        mxc_set_cpu_type(MXC_CPU_MX31);
        mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
-       imx_idle = imx3_idle;
-       imx_ioremap = imx3_ioremap;
-}
-
-void __init imx35_init_early(void)
-{
-       mxc_set_cpu_type(MXC_CPU_MX35);
-       mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
-       mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
-       imx_idle = imx3_idle;
+       pm_idle = imx3_idle;
        imx_ioremap = imx3_ioremap;
 }
 
@@ -161,11 +143,6 @@ void __init mx31_init_irq(void)
        mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
 }
 
-void __init mx35_init_irq(void)
-{
-       mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
-}
-
 static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = {
        .per_2_per_addr = 1677,
 };
@@ -199,6 +176,35 @@ void __init imx31_soc_init(void)
 
        imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
 }
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+static struct map_desc mx35_io_desc[] __initdata = {
+       imx_map_entry(MX35, X_MEMC, MT_DEVICE),
+       imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
+       imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+void __init mx35_map_io(void)
+{
+       iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
+}
+
+void __init imx35_init_early(void)
+{
+       mxc_set_cpu_type(MXC_CPU_MX35);
+       mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
+       mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+       pm_idle = imx3_idle;
+       imx_ioremap = imx3_ioremap;
+}
+
+void __init mx35_init_irq(void)
+{
+       mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+}
 
 static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = {
        .ap_2_ap_addr = 642,
@@ -254,3 +260,4 @@ void __init imx35_soc_init(void)
 
        imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
 }
+#endif /* ifdef CONFIG_SOC_IMX35 */
index 36cacbd0dcc2fa8c5d98bd5cb1e141a9d30e3503..a8e33681b73251f498a7cfee463f20c3f6d0e1ff 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/smp.h>
 #include <asm/unified.h>
 
 #define SRC_SCR                                0x000
 
 static void __iomem *src_base;
 
+#ifndef CONFIG_SMP
+#define cpu_logical_map(cpu)           0
+#endif
+
 void imx_enable_cpu(int cpu, bool enable)
 {
        u32 mask, val;
 
+       cpu = cpu_logical_map(cpu);
        mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
        val = readl_relaxed(src_base + SRC_SCR);
        val = enable ? val | mask : val & ~mask;
@@ -35,6 +41,7 @@ void imx_enable_cpu(int cpu, bool enable)
 
 void imx_set_cpu_jump(int cpu, void *jump_addr)
 {
+       cpu = cpu_logical_map(cpu);
        writel_relaxed(BSYM(virt_to_phys(jump_addr)),
                       src_base + SRC_GPR1 + cpu * 8);
 }
index 251c40897dad44085f23e9850bf29c23540c0a65..db012fadf88c652e96d3d3d74c30cb132424f4b2 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
+#include <linux/export.h>
 #include <asm/irq.h>
 #include <mach/hardware.h>
 #include <asm/sizes.h>
index 59a512672bb9de9035b6e695c7e1e914bc7eb3c4..24f0fe35f4adfca63249cf5a099db5234298087b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/bitops.h>
 #include <linux/serial_8250.h>
 #include <linux/mm.h>
+#include <linux/export.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
index f72a3a893c478b8d954b5e5d060d2d63a76a960e..8325058ef8711d1019bea1eea7ad1383e79101d6 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
+#include <linux/export.h>
 #include <asm/dma-mapping.h>
 
 #include <asm/cputype.h>
index 07772575d7ab22d3205238003322487cd9fead2b..b86a0055ab969694dc931be487a33aaef4368a4c 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include <mach/udc.h>
 #include <mach/hardware.h>
index f68d33f1f396c5a72b62629e736f3a7265bbc442..7088180b018b6087546b2c5761f9618baca27c6a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/cpuidle.h>
 #include <linux/io.h>
+#include <linux/export.h>
 #include <asm/proc-fns.h>
 #include <mach/kirkwood.h>
 
@@ -32,17 +33,18 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
 
 /* Actual code that puts the SoC in different idle states */
 static int kirkwood_enter_idle(struct cpuidle_device *dev,
-                              struct cpuidle_state *state)
+                               struct cpuidle_driver *drv,
+                              int index)
 {
        struct timeval before, after;
        int idle_time;
 
        local_irq_disable();
        do_gettimeofday(&before);
-       if (state == &dev->states[0])
+       if (index == 0)
                /* Wait for interrupt state */
                cpu_do_idle();
-       else if (state == &dev->states[1]) {
+       else if (index == 1) {
                /*
                 * Following write will put DDR in self refresh.
                 * Note that we have 256 cycles before DDR puts it
@@ -57,35 +59,40 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev,
        local_irq_enable();
        idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
                        (after.tv_usec - before.tv_usec);
-       return idle_time;
+
+       /* Update last residency */
+       dev->last_residency = idle_time;
+
+       return index;
 }
 
 /* Initialize CPU idle by registering the idle states */
 static int kirkwood_init_cpuidle(void)
 {
        struct cpuidle_device *device;
-
-       cpuidle_register_driver(&kirkwood_idle_driver);
+       struct cpuidle_driver *driver = &kirkwood_idle_driver;
 
        device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
        device->state_count = KIRKWOOD_MAX_STATES;
+       driver->state_count = KIRKWOOD_MAX_STATES;
 
        /* Wait for interrupt state */
-       device->states[0].enter = kirkwood_enter_idle;
-       device->states[0].exit_latency = 1;
-       device->states[0].target_residency = 10000;
-       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[0].name, "WFI");
-       strcpy(device->states[0].desc, "Wait for interrupt");
+       driver->states[0].enter = kirkwood_enter_idle;
+       driver->states[0].exit_latency = 1;
+       driver->states[0].target_residency = 10000;
+       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[0].name, "WFI");
+       strcpy(driver->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and DDR self refresh state */
-       device->states[1].enter = kirkwood_enter_idle;
-       device->states[1].exit_latency = 10;
-       device->states[1].target_residency = 10000;
-       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(device->states[1].name, "DDR SR");
-       strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+       driver->states[1].enter = kirkwood_enter_idle;
+       driver->states[1].exit_latency = 10;
+       driver->states[1].target_residency = 10000;
+       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(driver->states[1].name, "DDR SR");
+       strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
 
+       cpuidle_register_driver(&kirkwood_idle_driver);
        if (cpuidle_register_device(device)) {
                printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
                return -EIO;
index 8f948f9816463e3d5333ea56cde47dad1087b282..ba254a71691a6a1e81fb0f57a31c36578d18d64a 100644 (file)
@@ -7,7 +7,7 @@ obj-y                           += common.o clock.o devices.o time.o
 # SoC support
 obj-$(CONFIG_CPU_PXA168)       += pxa168.o irq-pxa168.o
 obj-$(CONFIG_CPU_PXA910)       += pxa910.o irq-pxa168.o
-obj-$(CONFIG_CPU_MMP2)         += mmp2.o irq-mmp2.o
+obj-$(CONFIG_CPU_MMP2)         += mmp2.o irq-mmp2.o sram.o
 
 # board support
 obj-$(CONFIG_MACH_ASPENITE)    += aspenite.o
index 06b5ad77460475acd8199adb289b8ccbeb390dd5..7a60bbbce7a43523c888f04a9ae8444fb95c1993 100644 (file)
@@ -167,8 +167,9 @@ static struct mtd_partition aspenite_nand_partitions[] = {
 
 static struct pxa3xx_nand_platform_data aspenite_nand_info = {
        .enable_arbiter = 1,
-       .parts          = aspenite_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(aspenite_nand_partitions),
+       .num_cs = 1,
+       .parts[0]       = aspenite_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(aspenite_nand_partitions),
 };
 
 static struct i2c_board_info aspenite_i2c_info[] __initdata = {
index e411252e3d397b000066d9fe04c96bb516ab043d..983cfb15fbde99bc0b394b56a779cc4708f6be9c 100644 (file)
@@ -185,6 +185,15 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
                | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
 };
 
+static struct sram_platdata mmp2_asram_platdata = {
+       .pool_name      = "asram",
+       .granularity    = SRAM_GRANULARITY,
+};
+
+static struct sram_platdata mmp2_isram_platdata = {
+       .pool_name      = "isram",
+       .granularity    = SRAM_GRANULARITY,
+};
 
 static void __init brownstone_init(void)
 {
@@ -196,6 +205,8 @@ static void __init brownstone_init(void)
        mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
        mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
        mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
+       mmp2_add_asram(&mmp2_asram_platdata);
+       mmp2_add_isram(&mmp2_isram_platdata);
 
        /* enable 5v regulator */
        platform_device_register(&brownstone_v_5vp_device);
index 69156568bc41f95891df3c17ca06836a9c3bf5bb..4665767a4f79ee918ec1fd24053d296ce13d0806 100644 (file)
@@ -182,7 +182,7 @@ static void __init gplugd_init(void)
 
        /* on-chip devices */
        pxa168_add_uart(3);
-       pxa168_add_ssp(0);
+       pxa168_add_ssp(1);
        pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
 
        pxa168_add_eth(&gplugd_eth_platform_data);
index d14eeaf163226d3b2ff53c394976be090b1e4d62..99b4ce1b6562cebf64651b9a0039599d624593d6 100644 (file)
@@ -7,7 +7,7 @@
 #define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000)
 
 #define BANK_OFF(n)    (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
-#define GPIO_REG(x)    (GPIO_REGS_VIRT + (x))
+#define GPIO_REG(x)    (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
 
 #define NR_BUILTIN_GPIO                IRQ_GPIO_NUM
 
index de7b88826ad792f8ff44c7c55244b98adc1b0eca..2f7b2d3c2b184f9717307076d281c82619f628c8 100644 (file)
@@ -13,6 +13,7 @@ extern void mmp2_clear_pmic_int(void);
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <mach/devices.h>
+#include <mach/sram.h>
 
 extern struct pxa_device_desc mmp2_device_uart1;
 extern struct pxa_device_desc mmp2_device_uart2;
@@ -28,6 +29,8 @@ extern struct pxa_device_desc mmp2_device_sdh0;
 extern struct pxa_device_desc mmp2_device_sdh1;
 extern struct pxa_device_desc mmp2_device_sdh2;
 extern struct pxa_device_desc mmp2_device_sdh3;
+extern struct pxa_device_desc mmp2_device_asram;
+extern struct pxa_device_desc mmp2_device_isram;
 
 static inline int mmp2_add_uart(int id)
 {
@@ -85,5 +88,15 @@ static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
        return pxa_register_device(d, data, sizeof(*data));
 }
 
+static inline int mmp2_add_asram(struct sram_platdata *data)
+{
+       return pxa_register_device(&mmp2_device_asram, data, sizeof(*data));
+}
+
+static inline int mmp2_add_isram(struct sram_platdata *data)
+{
+       return pxa_register_device(&mmp2_device_isram, data, sizeof(*data));
+}
+
 #endif /* __ASM_MACH_MMP2_H */
 
diff --git a/arch/arm/mach-mmp/include/mach/sram.h b/arch/arm/mach-mmp/include/mach/sram.h
new file mode 100644 (file)
index 0000000..239e0fc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  linux/arch/arm/mach-mmp/include/mach/sram.h
+ *
+ *  SRAM Memory Management
+ *
+ *  Copyright (c) 2011 Marvell Semiconductors Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_SRAM_H
+#define __ASM_ARCH_SRAM_H
+
+#include <linux/genalloc.h>
+
+/* ARBITRARY:  SRAM allocations are multiples of this 2^N size */
+#define SRAM_GRANULARITY       512
+
+enum sram_type {
+       MMP_SRAM_UNDEFINED = 0,
+       MMP_ASRAM,
+       MMP_ISRAM,
+};
+
+struct sram_platdata {
+       char *pool_name;
+       int granularity;
+};
+
+extern struct gen_pool *sram_get_gpool(char *pool_name);
+
+#endif /* __ASM_ARCH_SRAM_H */
index 7a7e8e4dde410be822953f186318972f4b51c35e..5dd1d4a6aeb90d4458ffeca378d1f08233908442 100644 (file)
@@ -226,4 +226,7 @@ MMP2_DEVICE(sdh0, "sdhci-pxav3", 0, MMC, 0xd4280000, 0x120);
 MMP2_DEVICE(sdh1, "sdhci-pxav3", 1, MMC2, 0xd4280800, 0x120);
 MMP2_DEVICE(sdh2, "sdhci-pxav3", 2, MMC3, 0xd4281000, 0x120);
 MMP2_DEVICE(sdh3, "sdhci-pxav3", 3, MMC4, 0xd4281800, 0x120);
+MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000);
+/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */
+MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000);
 
diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c
new file mode 100644 (file)
index 0000000..4304f95
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  linux/arch/arm/mach-mmp/sram.c
+ *
+ *  based on mach-davinci/sram.c - DaVinci simple SRAM allocator
+ *
+ *  Copyright (c) 2011 Marvell Semiconductors Inc.
+ *  All Rights Reserved
+ *
+ *  Add for mmp sram support - Leo Yan <leoy@marvell.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/genalloc.h>
+
+#include <mach/sram.h>
+
+struct sram_bank_info {
+       char *pool_name;
+       struct gen_pool *gpool;
+       int granularity;
+
+       phys_addr_t sram_phys;
+       void __iomem *sram_virt;
+       u32 sram_size;
+
+       struct list_head node;
+};
+
+static DEFINE_MUTEX(sram_lock);
+static LIST_HEAD(sram_bank_list);
+
+struct gen_pool *sram_get_gpool(char *pool_name)
+{
+       struct sram_bank_info *info = NULL;
+
+       if (!pool_name)
+               return NULL;
+
+       mutex_lock(&sram_lock);
+
+       list_for_each_entry(info, &sram_bank_list, node)
+               if (!strcmp(pool_name, info->pool_name))
+                       break;
+
+       mutex_unlock(&sram_lock);
+
+       if (&info->node == &sram_bank_list)
+               return NULL;
+
+       return info->gpool;
+}
+EXPORT_SYMBOL(sram_get_gpool);
+
+static int __devinit sram_probe(struct platform_device *pdev)
+{
+       struct sram_platdata *pdata = pdev->dev.platform_data;
+       struct sram_bank_info *info;
+       struct resource *res;
+       int ret = 0;
+
+       if (!pdata && !pdata->pool_name)
+               return -ENODEV;
+
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               ret = -ENODEV;
+               goto out;
+       }
+
+       if (!resource_size(res))
+               return 0;
+
+       info->sram_phys   = (phys_addr_t)res->start;
+       info->sram_size   = resource_size(res);
+       info->sram_virt   = ioremap(info->sram_phys, info->sram_size);
+       info->pool_name   = kstrdup(pdata->pool_name, GFP_KERNEL);
+       info->granularity = pdata->granularity;
+
+       info->gpool = gen_pool_create(ilog2(info->granularity), -1);
+       if (!info->gpool) {
+               dev_err(&pdev->dev, "create pool failed\n");
+               ret = -ENOMEM;
+               goto create_pool_err;
+       }
+
+       ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
+                               info->sram_phys, info->sram_size, -1);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "add new chunk failed\n");
+               ret = -ENOMEM;
+               goto add_chunk_err;
+       }
+
+       mutex_lock(&sram_lock);
+       list_add(&info->node, &sram_bank_list);
+       mutex_unlock(&sram_lock);
+
+       platform_set_drvdata(pdev, info);
+
+       dev_info(&pdev->dev, "initialized\n");
+       return 0;
+
+add_chunk_err:
+       gen_pool_destroy(info->gpool);
+create_pool_err:
+       iounmap(info->sram_virt);
+       kfree(info->pool_name);
+out:
+       kfree(info);
+       return ret;
+}
+
+static int __devexit sram_remove(struct platform_device *pdev)
+{
+       struct sram_bank_info *info;
+
+       info = platform_get_drvdata(pdev);
+       if (info == NULL)
+               return -ENODEV;
+
+       mutex_lock(&sram_lock);
+       list_del(&info->node);
+       mutex_unlock(&sram_lock);
+
+       gen_pool_destroy(info->gpool);
+       iounmap(info->sram_virt);
+       kfree(info->pool_name);
+       kfree(info);
+       return 0;
+}
+
+static const struct platform_device_id sram_id_table[] = {
+       { "asram", MMP_ASRAM },
+       { "isram", MMP_ISRAM },
+       { }
+};
+
+static struct platform_driver sram_driver = {
+       .probe          = sram_probe,
+       .remove         = sram_remove,
+       .driver         = {
+               .name   = "mmp-sram",
+       },
+       .id_table       = sram_id_table,
+};
+
+static int __init sram_init(void)
+{
+       return platform_driver_register(&sram_driver);
+}
+core_initcall(sram_init);
+
+MODULE_LICENSE("GPL");
index 4285dfd80b6ff30d36eaa378699dc709670e0e8f..4ad3969b98817cc42446d22476aae2ce5771efc6 100644 (file)
@@ -15,6 +15,8 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
 obj-$(CONFIG_MSM_SMD) += last_radio_log.o
 obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
 
+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
 
index 71de5062c71efd6d86e3e5a4e5927e7dbdf733ea..db81ed531031354b7547c3e48996af1845202c94 100644 (file)
@@ -42,8 +42,8 @@
 
 extern struct sys_timer msm_timer;
 
-static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag,
-                        char **cmdline, struct meminfo *mi)
+static void __init msm7x30_fixup(struct tag *tag, char **cmdline,
+               struct meminfo *mi)
 {
        for (; tag->hdr.size; tag = tag_next(tag))
                if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) {
index b04468e7d00e5b1663c9832bc3f5f5ad51e329b5..6dc1cbd2a595b559824dc485a1e0bb74e880d93a 100644 (file)
@@ -32,8 +32,8 @@
 
 #include "devices.h"
 
-static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag,
-                        char **cmdline, struct meminfo *mi)
+static void __init msm8960_fixup(struct tag *tag, char **cmdline,
+               struct meminfo *mi)
 {
        for (; tag->hdr.size; tag = tag_next(tag))
                if (tag->hdr.tag == ATAG_MEM &&
index cf38e2284fa956437ea3161f92c5fb1be09e147c..44bf71688373b4af31907f744b28f7765f150e75 100644 (file)
@@ -28,8 +28,8 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
-static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag,
-                        char **cmdline, struct meminfo *mi)
+static void __init msm8x60_fixup(struct tag *tag, char **cmdline,
+               struct meminfo *mi)
 {
        for (; tag->hdr.size; tag = tag_next(tag))
                if (tag->hdr.tag == ATAG_MEM &&
index 24030d0da6e3c59ec9ddfa2a76995001f747bc62..0fb7a17df3987e259297d21de210971d2f65fb80 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
+#include <linux/module.h>
 #include <mach/irqs.h>
 #include <mach/iommu.h>
 
index 140ddbbc3a8a5509ddbabb6520bb1605ae038d70..8759ecf7454f367cead42922f8de900b24b45879 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <asm/page.h>
index 232f97a045041cdd98e53e9f04dc6c2aaebc7f36..bafabb502580e87cd4473e2261582bd796404897 100644 (file)
@@ -180,6 +180,9 @@ static u32 smc(u32 cmd_addr)
                        __asmeq("%1", "r0")
                        __asmeq("%2", "r1")
                        __asmeq("%3", "r2")
+#ifdef REQUIRES_SEC
+                       ".arch_extension sec\n"
+#endif
                        "smc    #0      @ switch to secure world\n"
                        : "=r" (r0)
                        : "r" (r0), "r" (r1), "r" (r2)
index 2aacf41c48e7d3fd02f38a6e80ee9f6087953bf6..4cb276977190e98174c70419a64a63696179ac73 100644 (file)
@@ -1281,9 +1281,9 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
        NULL,  NULL, &ipg_clk, &gpt_ipg_clk);
 
 DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
-       NULL, NULL, &ipg_clk, NULL);
+       NULL, NULL, &ipg_perclk, NULL);
 DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
-       NULL, NULL, &ipg_clk, NULL);
+       NULL, NULL, &ipg_perclk, NULL);
 
 /* I2C */
 DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
@@ -1634,6 +1634,7 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
        return 0;
 }
 
+#ifdef CONFIG_OF
 static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
                                   unsigned long *ckih1, unsigned long *ckih2)
 {
@@ -1671,3 +1672,4 @@ int __init mx53_clocks_init_dt(void)
        clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
        return mx53_clocks_init(ckil, osc, ckih1, ckih2);
 }
+#endif
index 5c5328257dca2f5560ccaa33bf98a27b80582b27..5e2e7a8438606f43015d90115046e555eee1a3c5 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <mach/hardware.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int mx5_cpu_rev = -1;
 
@@ -67,7 +67,8 @@ static int __init mx51_neon_fixup(void)
        if (!cpu_is_mx51())
                return 0;
 
-       if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) {
+       if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
+                       (elf_hwcap & HWCAP_NEON)) {
                elf_hwcap &= ~HWCAP_NEON;
                pr_info("Turning off NEON support, detected broken NEON implementation\n");
        }
index ccc61585659bdb17d55bb91bfc1cbb2ebf6cca1c..596edd967dbfef9a21b009b327f42cdda3ad60b0 100644 (file)
@@ -44,20 +44,22 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
        { /* sentinel */ }
 };
 
-static void __init imx51_tzic_add_irq_domain(struct device_node *np,
+static int __init imx51_tzic_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
        irq_domain_add_simple(np, 0);
+       return 0;
 }
 
-static void __init imx51_gpio_add_irq_domain(struct device_node *np,
+static int __init imx51_gpio_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
-       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
-                                  32 * 4; /* imx51 gets 4 gpio ports */
+       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
+       gpio_irq_base -= 32;
        irq_domain_add_simple(np, gpio_irq_base);
-       gpio_irq_base += 32;
+
+       return 0;
 }
 
 static const struct of_device_id imx51_irq_match[] __initconst = {
index ccaa0b81b7683f86b7750ca852f6b8b67d80eabd..85bfd5ff21b0bb925583679260321fbc7e25731b 100644 (file)
@@ -48,20 +48,22 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
        { /* sentinel */ }
 };
 
-static void __init imx53_tzic_add_irq_domain(struct device_node *np,
+static int __init imx53_tzic_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
        irq_domain_add_simple(np, 0);
+       return 0;
 }
 
-static void __init imx53_gpio_add_irq_domain(struct device_node *np,
+static int __init imx53_gpio_add_irq_domain(struct device_node *np,
                                struct device_node *interrupt_parent)
 {
-       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
-                                  32 * 7; /* imx53 gets 7 gpio ports */
+       static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
+       gpio_irq_base -= 32;
        irq_domain_add_simple(np, gpio_irq_base);
-       gpio_irq_base += 32;
+
+       return 0;
 }
 
 static const struct of_device_id imx53_irq_match[] __initconst = {
index 26eacc9d0d90fbf88930bd6a009c58efe6914c70..df4a508f240a04a47ce8bb5abbf6074f843c8aae 100644 (file)
@@ -23,7 +23,9 @@
 
 static void imx5_idle(void)
 {
-       mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+       if (!need_resched())
+               mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+       local_irq_enable();
 }
 
 /*
@@ -89,7 +91,7 @@ void __init imx51_init_early(void)
        mxc_set_cpu_type(MXC_CPU_MX51);
        mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
        mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
-       imx_idle = imx5_idle;
+       pm_idle = imx5_idle;
 }
 
 void __init imx53_init_early(void)
index 229ae3494216da2920bddb5164d66ce523a6ddeb..da6e4aad177c2097b12515b2ddd2572e8b397ea2 100644 (file)
@@ -404,7 +404,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)             \
        reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
        reg &= ~BM_CLKCTRL_##dr##_DIV;                                  \
        reg |= div << BP_CLKCTRL_##dr##_DIV;                            \
-       if (reg | (1 << clk->enable_shift)) {                           \
+       if (reg & (1 << clk->enable_shift)) {                           \
                pr_err("%s: clock is gated\n", __func__);               \
                return -EINVAL;                                         \
        }                                                               \
index 75d86118b76a2c524cea92c7320d25bb7d4225a5..30c7990f3c01d65c1f05ad9d425a090381661c9b 100644 (file)
 #define MX28_INT_CAN1                  9
 #define MX28_INT_LRADC_TOUCH           10
 #define MX28_INT_HSADC                 13
-#define MX28_INT_IRADC_THRESH0         14
-#define MX28_INT_IRADC_THRESH1         15
+#define MX28_INT_LRADC_THRESH0         14
+#define MX28_INT_LRADC_THRESH1         15
 #define MX28_INT_LRADC_CH0             16
 #define MX28_INT_LRADC_CH1             17
 #define MX28_INT_LRADC_CH2             18
index 0d2d2b470998a9d2cfac229654a9ee2135272a2f..bde5f6634747c639af514ecf9d699b1176891802 100644 (file)
@@ -30,6 +30,7 @@
  */
 #define cpu_is_mx23()          (                                       \
                machine_is_mx23evk() ||                                 \
+               machine_is_stmp378x() ||                                \
                0)
 #define cpu_is_mx28()          (                                       \
                machine_is_mx28evk() ||                                 \
index 3b1681e4f49a1ae633e5ac4b3d31137f2f92b014..6b00577b70256254e29951bdf8828a2ecd613fdb 100644 (file)
@@ -361,6 +361,6 @@ static struct sys_timer m28evk_timer = {
 MACHINE_START(M28EVK, "DENX M28 EVK")
        .map_io         = mx28_map_io,
        .init_irq       = mx28_init_irq,
-       .init_machine   = m28evk_init,
        .timer          = &m28evk_timer,
+       .init_machine   = m28evk_init,
 MACHINE_END
index ac2316d53d3c8dd3d173147eda9cfbf4b5e5f47b..064ec5abaa557f7c6679bf4fe965c67f3fb6a022 100644 (file)
@@ -471,7 +471,8 @@ static void __init mx28evk_init(void)
                               "mmc0-slot-power");
        if (ret)
                pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
-       mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+       else
+               mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
 
        ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
                               "mmc1-slot-power");
@@ -480,7 +481,6 @@ static void __init mx28evk_init(void)
        else
                mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 
-       mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
        mx28_add_rtc_stmp3xxx();
 
        gpio_led_register_device(0, &mx28evk_led_data);
index 177e53123a02e5b67f617e5031c047354703103c..6834dea38c04cce77e20bffc2baa3019327d9610 100644 (file)
@@ -115,6 +115,6 @@ static struct sys_timer stmp378x_dvb_timer = {
 MACHINE_START(STMP378X, "STMP378X")
        .map_io         = mx23_map_io,
        .init_irq       = mx23_init_irq,
-       .init_machine   = stmp378x_dvb_init,
        .timer          = &stmp378x_dvb_timer,
+       .init_machine   = stmp378x_dvb_init,
 MACHINE_END
index 0fcff47009cf13ff53db9757e58c9dc0cbf5b927..9a7b08b2a92559caf1028df076040c5e5dc798ae 100644 (file)
@@ -66,11 +66,11 @@ static const iomux_cfg_t tx28_fec1_pads[] __initconst = {
        MX28_PAD_ENET0_CRS__ENET1_RX_EN,
 };
 
-static struct fec_platform_data tx28_fec0_data = {
+static const struct fec_platform_data tx28_fec0_data __initconst = {
        .phy = PHY_INTERFACE_MODE_RMII,
 };
 
-static struct fec_platform_data tx28_fec1_data = {
+static const struct fec_platform_data tx28_fec1_data __initconst = {
        .phy = PHY_INTERFACE_MODE_RMII,
 };
 
index f009b54e8d20e37a33311eb39782c0076a99164e..e4cfb7e5361d2fa25978502fbab1ac296208d61e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
index e0a028161ddee89a4119014ed83420bd0a21ad4e..73f287d6429b629d57f7c093645962ce48cee318 100644 (file)
@@ -171,14 +171,6 @@ config MACH_OMAP_GENERIC
 comment "OMAP CPU Speed"
        depends on ARCH_OMAP1
 
-config OMAP_CLOCKS_SET_BY_BOOTLOADER
-       bool "OMAP clocks set by bootloader"
-       depends on ARCH_OMAP1
-       help
-         Enable this option to prevent the kernel from overriding the clock
-         frequencies programmed by bootloader for MPU, DSP, MMUs, TC,
-         internal LCD controller and MPU peripherals.
-
 config OMAP_ARM_216MHZ
        bool "OMAP ARM 216 MHz CPU (1710 only)"
         depends on ARCH_OMAP1 && ARCH_OMAP16XX
index 1f1db76d704a48e3573101c78acbfe8f6dfcfb4f..b0f15d234a12b4ad9dd1beb34da7df187e3f86b4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/export.h>
 
 #include <media/soc_camera.h>
 
@@ -301,8 +302,6 @@ static void __init ams_delta_init(void)
        omap_cfg_reg(J19_1610_CAM_D6);
        omap_cfg_reg(J18_1610_CAM_D7);
 
-       iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
-
        omap_board_config = ams_delta_config;
        omap_board_config_size = ARRAY_SIZE(ams_delta_config);
        omap_serial_init();
@@ -372,10 +371,16 @@ static int __init ams_delta_modem_init(void)
 }
 arch_initcall(ams_delta_modem_init);
 
+static void __init ams_delta_map_io(void)
+{
+       omap15xx_map_io();
+       iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
+}
+
 MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
        /* Maintainer: Jonathan McDowell <noodles@earth.li> */
        .atag_offset    = 0x100,
-       .map_io         = omap15xx_map_io,
+       .map_io         = ams_delta_map_io,
        .init_early     = omap1_init_early,
        .reserve        = omap_reserve,
        .init_irq       = omap1_init_irq,
index c6fe61dfe856b9a42739c4b11b4e6a4d8e486b72..42061573e3803b449a314d1c0ccc0553371f854b 100644 (file)
@@ -42,7 +42,6 @@
 #include <plat/irda.h>
 #include <plat/keypad.h>
 #include <plat/common.h>
-#include <plat/omap-alsa.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
index 667a7cbdb11c394f889373dd32825d0abd9f3a36..092a4c04640757f4d8d7c92f464c20d17f068938 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
index 2a6545ba61c4028efa206ac3c724e91c913a19d4..61ed6cdab2bdb9adbe9af4b8104f2508b902e84d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
 #include <linux/smc91x.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <mach/system.h>
index eaf09efb91caec613eeb73e961e7fbd77a93cf21..16b1423b454a32dea7197460a393b12a4bd4e2b0 100644 (file)
@@ -17,7 +17,8 @@
 
 #include <plat/clock.h>
 
-extern int __init omap1_clk_init(void);
+int omap1_clk_init(void);
+void omap1_clk_late_init(void);
 extern int omap1_clk_enable(struct clk *clk);
 extern void omap1_clk_disable(struct clk *clk);
 extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
index 92400b9eb69f10c419c7e1295e238d56d5ef6110..9ff90a744a2140a0bf5168403301ac9cec68b927 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
 #include <linux/io.h>
 
 #include <asm/mach-types.h>  /* for machine_is_* */
@@ -767,6 +769,15 @@ static struct clk_functions omap1_clk_functions = {
        .clk_disable_unused     = omap1_clk_disable_unused,
 };
 
+static void __init omap1_show_rates(void)
+{
+       pr_notice("Clocking rate (xtal/DPLL1/MPU): "
+                       "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+               ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+               ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+               arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+}
+
 int __init omap1_clk_init(void)
 {
        struct omap_clk *c;
@@ -835,9 +846,12 @@ int __init omap1_clk_init(void)
        /* We want to be in syncronous scalable mode */
        omap_writew(0x1000, ARM_SYSST);
 
-#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
-       /* Use values set by bootloader. Determine PLL rate and recalculate
-        * dependent clocks as if kernel had changed PLL or divisors.
+
+       /*
+        * Initially use the values set by bootloader. Determine PLL rate and
+        * recalculate dependent clocks as if kernel had changed PLL or
+        * divisors. See also omap1_clk_late_init() that can reprogram dpll1
+        * after the SRAM is initialized.
         */
        {
                unsigned pll_ctl_val = omap_readw(DPLL_CTL);
@@ -862,25 +876,10 @@ int __init omap1_clk_init(void)
                        }
                }
        }
-#else
-       /* Find the highest supported frequency and enable it */
-       if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
-               printk(KERN_ERR "System frequencies not set. Check your config.\n");
-               /* Guess sane values (60MHz) */
-               omap_writew(0x2290, DPLL_CTL);
-               omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL);
-               ck_dpll1.rate = 60000000;
-       }
-#endif
        propagate_rate(&ck_dpll1);
        /* Cache rates for clocks connected to ck_ref (not dpll1) */
        propagate_rate(&ck_ref);
-       printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
-               "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
-              ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
-              ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
-              arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
-
+       omap1_show_rates();
        if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
                /* Select slicer output as OMAP input clock */
                omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
@@ -925,3 +924,27 @@ int __init omap1_clk_init(void)
 
        return 0;
 }
+
+#define OMAP1_DPLL1_SANE_VALUE 60000000
+
+void __init omap1_clk_late_init(void)
+{
+       unsigned long rate = ck_dpll1.rate;
+
+       if (rate >= OMAP1_DPLL1_SANE_VALUE)
+               return;
+
+       /* System booting at unusable rate, force reprogramming of DPLL1 */
+       ck_dpll1_p->rate = 0;
+
+       /* Find the highest supported frequency and enable it */
+       if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+               pr_err("System frequencies not set, using default. Check your config.\n");
+               omap_writew(0x2290, DPLL_CTL);
+               omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL);
+               ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE;
+       }
+       propagate_rate(&ck_dpll1);
+       omap1_show_rates();
+       loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate);
+}
index 48ef9888e820e5d95ecbd61274d2904a712ce63f..475cb2f50d872f326325991b76d0c5348aa5cfd2 100644 (file)
@@ -30,6 +30,8 @@
 #include <plat/omap7xx.h>
 #include <plat/mcbsp.h>
 
+#include "clock.h"
+
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
@@ -293,6 +295,7 @@ static int __init omap1_init_devices(void)
                return -ENODEV;
 
        omap_sram_init();
+       omap1_clk_late_init();
 
        /* please keep these calls, and their implementations above,
         * in alphabetical order so they're easier to sort through.
index c0e1f48aa119b0c53eeb7d2ee7a4d95bae7cc0cc..e962926b67bc48dcd146fab36901971910164556 100644 (file)
@@ -9,6 +9,7 @@
  * for more details.
  */
 
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
index 495b3987d461f840434d547977c716ce1cc8149d..89ea20ca0cccbc02c0ccba365547942e8c41ea93 100644 (file)
@@ -116,7 +116,7 @@ void omap1_pm_idle(void)
                return;
        }
 
-#ifdef CONFIG_OMAP_MPU_TIMER
+#if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
 #warning Enable 32kHz OS timer in order to allow sleep states in idle
        use_idlect1 = use_idlect1 & ~(1 << 9);
 #else
index 503414718905862d12e104b7940bfc7dc1524971..e1293aa513d338fe19ffd7990b189109b7ca0787 100644 (file)
@@ -334,6 +334,7 @@ config MACH_OMAP4_PANDA
 config OMAP3_EMU
        bool "OMAP3 debugging peripherals"
        depends on ARCH_OMAP3
+       select ARM_AMBA
        select OC_ETM
        help
          Say Y here to enable debugging hardware of omap3
index 69ab1c069134ccee42da01c015aea9d219408f4a..b009f17dee5606de2acbb1b7ba25c8938d0c5adb 100644 (file)
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
-        common.o gpio.o dma.o wd_timer.o
+        common.o gpio.o dma.o wd_timer.o display.o
 
 omap-2-3-common                                = irq.o sdrc.o
 hwmod-common                           = omap_hwmod.o \
@@ -264,7 +264,4 @@ smsc911x-$(CONFIG_SMSC911X)         := gpmc-smsc911x.o
 obj-y                                  += $(smsc911x-m) $(smsc911x-y)
 obj-$(CONFIG_ARCH_OMAP4)               += hwspinlock.o
 
-disp-$(CONFIG_OMAP2_DSS)               := display.o
-obj-y                                  += $(disp-m) $(disp-y)
-
 obj-y                                  += common-board-devices.o twl-common.o
index 42918940c530ac5264960a808ec4fdfc117ece25..90154e411da0f27c2850fa4075ba44255bda7eb4 100644 (file)
@@ -226,7 +226,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 {
        int ret;
 
-       omap_mux_init_gpio(29, OMAP_PIN_INPUT);
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
        mmc[0].gpio_cd = gpio + 0;
        omap2_hsmmc_init(mmc);
index 0cc9094e5ee046afe40095bce2dc1cbd09d52264..fb55fa3dad5ae6d94cd76b4085b08f12aa07da2e 100644 (file)
@@ -28,6 +28,7 @@
  * XXX: Still needed to boot until the i2c & twl driver is adapted to
  * device-tree
  */
+#ifdef CONFIG_ARCH_OMAP4
 static struct twl4030_platform_data sdp4430_twldata = {
        .irq_base       = TWL6030_IRQ_BASE,
        .irq_end        = TWL6030_IRQ_END,
@@ -37,7 +38,9 @@ static void __init omap4_i2c_init(void)
 {
        omap4_pmic_init("twl6030", &sdp4430_twldata);
 }
+#endif
 
+#ifdef CONFIG_ARCH_OMAP3
 static struct twl4030_platform_data beagle_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
@@ -47,6 +50,7 @@ static void __init omap3_i2c_init(void)
 {
        omap3_pmic_init("twl4030", &beagle_twldata);
 }
+#endif
 
 static struct of_device_id omap_dt_match_table[] __initdata = {
        { .compatible = "simple-bus", },
@@ -72,17 +76,21 @@ static void __init omap_generic_init(void)
        of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
 }
 
+#ifdef CONFIG_ARCH_OMAP4
 static void __init omap4_init(void)
 {
        omap4_i2c_init();
        omap_generic_init();
 }
+#endif
 
+#ifdef CONFIG_ARCH_OMAP3
 static void __init omap3_init(void)
 {
        omap3_i2c_init();
        omap_generic_init();
 }
+#endif
 
 #if defined(CONFIG_SOC_OMAP2420)
 static const char *omap242x_boards_compat[] __initdata = {
index c12666ee7017a8880ff9cfd151b9a1e5d7ba77b3..8b351d92a1cce289cf1af4eba51577b788f5b602 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/input/matrix_keypad.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -34,7 +35,6 @@
 #include <plat/usb.h>
 #include <plat/board.h>
 #include <plat/common.h>
-#include <plat/keypad.h>
 #include <plat/menelaus.h>
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 
 #define H4_ETHR_GPIO_IRQ               92
 
-static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
-static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
-
-static const unsigned int h4_keymap[] = {
+#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
+static const uint32_t board_matrix_keys[] = {
        KEY(0, 0, KEY_LEFT),
        KEY(1, 0, KEY_RIGHT),
        KEY(2, 0, KEY_A),
@@ -86,6 +84,71 @@ static const unsigned int h4_keymap[] = {
        KEY(4, 5, KEY_ENTER),
 };
 
+static const struct matrix_keymap_data board_keymap_data = {
+       .keymap                 = board_matrix_keys,
+       .keymap_size            = ARRAY_SIZE(board_matrix_keys),
+};
+
+static unsigned int board_keypad_row_gpios[] = {
+       88, 89, 124, 11, 6, 96
+};
+
+static unsigned int board_keypad_col_gpios[] = {
+       90, 91, 100, 36, 12, 97, 98
+};
+
+static struct matrix_keypad_platform_data board_keypad_platform_data = {
+       .keymap_data    = &board_keymap_data,
+       .row_gpios      = board_keypad_row_gpios,
+       .num_row_gpios  = ARRAY_SIZE(board_keypad_row_gpios),
+       .col_gpios      = board_keypad_col_gpios,
+       .num_col_gpios  = ARRAY_SIZE(board_keypad_col_gpios),
+       .active_low     = 1,
+
+       .debounce_ms            = 20,
+       .col_scan_delay_us      = 5,
+};
+
+static struct platform_device board_keyboard = {
+       .name   = "matrix-keypad",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &board_keypad_platform_data,
+       },
+};
+static void __init board_mkp_init(void)
+{
+       omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
+       omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
+       omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
+       omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
+       if (omap_has_menelaus()) {
+               omap_mux_init_signal("sdrc_a14.gpio0",
+                       OMAP_PULL_ENA | OMAP_PULL_UP);
+               omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+               omap_mux_init_signal("gpio_98", 0);
+               board_keypad_row_gpios[5] = 0;
+               board_keypad_col_gpios[2] = 15;
+               board_keypad_col_gpios[6] = 18;
+       } else {
+               omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
+               omap_mux_init_signal("gpio_100", 0);
+               omap_mux_init_signal("gpio_98", 0);
+       }
+       omap_mux_init_signal("gpio_90", 0);
+       omap_mux_init_signal("gpio_91", 0);
+       omap_mux_init_signal("gpio_36", 0);
+       omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+       omap_mux_init_signal("gpio_97", 0);
+
+       platform_device_register(&board_keyboard);
+}
+#else
+static inline void board_mkp_init(void)
+{
+}
+#endif
+
 static struct mtd_partition h4_partitions[] = {
        /* bootloader (U-Boot, etc) in first sector */
        {
@@ -137,31 +200,8 @@ static struct platform_device h4_flash_device = {
        .resource       = &h4_flash_resource,
 };
 
-static const struct matrix_keymap_data h4_keymap_data = {
-       .keymap         = h4_keymap,
-       .keymap_size    = ARRAY_SIZE(h4_keymap),
-};
-
-static struct omap_kp_platform_data h4_kp_data = {
-       .rows           = 6,
-       .cols           = 7,
-       .keymap_data    = &h4_keymap_data,
-       .rep            = true,
-       .row_gpios      = row_gpios,
-       .col_gpios      = col_gpios,
-};
-
-static struct platform_device h4_kp_device = {
-       .name           = "omap-keypad",
-       .id             = -1,
-       .dev            = {
-               .platform_data = &h4_kp_data,
-       },
-};
-
 static struct platform_device *h4_devices[] __initdata = {
        &h4_flash_device,
-       &h4_kp_device,
 };
 
 static struct panel_generic_dpi_data h4_panel_data = {
@@ -336,31 +376,7 @@ static void __init omap_h4_init(void)
         * if not needed.
         */
 
-#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
-       omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
-       omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
-       omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
-       omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
-       if (omap_has_menelaus()) {
-               omap_mux_init_signal("sdrc_a14.gpio0",
-                       OMAP_PULL_ENA | OMAP_PULL_UP);
-               omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
-               omap_mux_init_signal("gpio_98", 0);
-               row_gpios[5] = 0;
-               col_gpios[2] = 15;
-               col_gpios[6] = 18;
-       } else {
-               omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
-               omap_mux_init_signal("gpio_100", 0);
-               omap_mux_init_signal("gpio_98", 0);
-       }
-       omap_mux_init_signal("gpio_90", 0);
-       omap_mux_init_signal("gpio_91", 0);
-       omap_mux_init_signal("gpio_36", 0);
-       omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
-       omap_mux_init_signal("gpio_97", 0);
-#endif
-
+       board_mkp_init();
        i2c_register_board_info(1, h4_i2c_board_info,
                        ARRAY_SIZE(h4_i2c_board_info));
 
index 2d24e287e8c165b3126b7d39b2b32823ba0e91b1..ec00b2ec70227ffa164fc928c5bc403d05c52f32 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/mmc/host.h>
+#include <linux/export.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
index bcffee001bfa424c6f5a029292ef11e84f3f3eca..e069a9be93dfe0e9aafc3411e560de700529e13a 100644 (file)
                                         (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
 
 /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
-#define DPLL_FINT_BAND1_MIN            750000
-#define DPLL_FINT_BAND1_MAX            2100000
-#define DPLL_FINT_BAND2_MIN            7500000
-#define DPLL_FINT_BAND2_MAX            21000000
+#define OMAP3430_DPLL_FINT_BAND1_MIN   750000
+#define OMAP3430_DPLL_FINT_BAND1_MAX   2100000
+#define OMAP3430_DPLL_FINT_BAND2_MIN   7500000
+#define OMAP3430_DPLL_FINT_BAND2_MAX   21000000
+
+/*
+ * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
+ * From device data manual section 4.3 "DPLL and DLL Specifications".
+ */
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MIN  500000
+#define OMAP3PLUS_DPLL_FINT_JTYPE_MAX  2500000
+#define OMAP3PLUS_DPLL_FINT_MIN                32000
+#define OMAP3PLUS_DPLL_FINT_MAX                52000000
 
 /* _dpll_test_fint() return codes */
 #define DPLL_FINT_UNDERFLOW            -1
 static int _dpll_test_fint(struct clk *clk, u8 n)
 {
        struct dpll_data *dd;
-       long fint;
+       long fint, fint_min, fint_max;
        int ret = 0;
 
        dd = clk->dpll_data;
 
        /* DPLL divider must result in a valid jitter correction val */
        fint = clk->parent->rate / n;
-       if (fint < DPLL_FINT_BAND1_MIN) {
 
+       if (cpu_is_omap24xx()) {
+               /* Should not be called for OMAP2, so warn if it is called */
+               WARN(1, "No fint limits available for OMAP2!\n");
+               return DPLL_FINT_INVALID;
+       } else if (cpu_is_omap3430()) {
+               fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
+               fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
+       } else if (dd->flags & DPLL_J_TYPE) {
+               fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN;
+               fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX;
+       } else {
+               fint_min = OMAP3PLUS_DPLL_FINT_MIN;
+               fint_max = OMAP3PLUS_DPLL_FINT_MAX;
+       }
+
+       if (fint < fint_min) {
                pr_debug("rejecting n=%d due to Fint failure, "
                         "lowering max_divider\n", n);
                dd->max_divider = n;
                ret = DPLL_FINT_UNDERFLOW;
-
-       } else if (fint > DPLL_FINT_BAND1_MAX &&
-                  fint < DPLL_FINT_BAND2_MIN) {
-
-               pr_debug("rejecting n=%d due to Fint failure\n", n);
-               ret = DPLL_FINT_INVALID;
-
-       } else if (fint > DPLL_FINT_BAND2_MAX) {
-
+       } else if (fint > fint_max) {
                pr_debug("rejecting n=%d due to Fint failure, "
                         "boosting min_divider\n", n);
                dd->min_divider = n;
                ret = DPLL_FINT_INVALID;
-
+       } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX &&
+                  fint < OMAP3430_DPLL_FINT_BAND2_MIN) {
+               pr_debug("rejecting n=%d due to Fint failure\n", n);
+               ret = DPLL_FINT_INVALID;
        }
 
        return ret;
index 48ac568881bd4de531808d092356b440687b9fee..2311bc2172264248aa181f75fb579c6e6b218fbd 100644 (file)
@@ -66,6 +66,8 @@ void omap3_noncore_dpll_disable(struct clk *clk);
 int omap4_dpllmx_gatectrl_read(struct clk *clk);
 void omap4_dpllmx_allow_gatectrl(struct clk *clk);
 void omap4_dpllmx_deny_gatectrl(struct clk *clk);
+long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
+unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 void omap2_clk_disable_unused(struct clk *clk);
index 14a6277dd184c0e27323efbd1cef5161c3c60562..61ad3855f10a61e479e994d547e9d0955aed166d 100644 (file)
@@ -1898,18 +1898,6 @@ static struct omap_clk omap2420_clks[] = {
        CLK(NULL,       "pka_ick",      &pka_ick,       CK_242X),
        CLK(NULL,       "usb_fck",      &usb_fck,       CK_242X),
        CLK("musb-hdrc",        "fck",  &osc_ck,        CK_242X),
-       CLK("omap_timer.1",     "fck",  &gpt1_fck,      CK_242X),
-       CLK("omap_timer.2",     "fck",  &gpt2_fck,      CK_242X),
-       CLK("omap_timer.3",     "fck",  &gpt3_fck,      CK_242X),
-       CLK("omap_timer.4",     "fck",  &gpt4_fck,      CK_242X),
-       CLK("omap_timer.5",     "fck",  &gpt5_fck,      CK_242X),
-       CLK("omap_timer.6",     "fck",  &gpt6_fck,      CK_242X),
-       CLK("omap_timer.7",     "fck",  &gpt7_fck,      CK_242X),
-       CLK("omap_timer.8",     "fck",  &gpt8_fck,      CK_242X),
-       CLK("omap_timer.9",     "fck",  &gpt9_fck,      CK_242X),
-       CLK("omap_timer.10",    "fck",  &gpt10_fck,     CK_242X),
-       CLK("omap_timer.11",    "fck",  &gpt11_fck,     CK_242X),
-       CLK("omap_timer.12",    "fck",  &gpt12_fck,     CK_242X),
        CLK("omap_timer.1",     "32k_ck",       &func_32k_ck,   CK_243X),
        CLK("omap_timer.2",     "32k_ck",       &func_32k_ck,   CK_243X),
        CLK("omap_timer.3",     "32k_ck",       &func_32k_ck,   CK_243X),
index ea6717cfa3c84245b390502349eb262850e7df23..0cc12879e7b955b1bee0e256e597d34c42b51f57 100644 (file)
@@ -1998,18 +1998,6 @@ static struct omap_clk omap2430_clks[] = {
        CLK(NULL,       "mdm_intc_ick", &mdm_intc_ick,  CK_243X),
        CLK("omap_hsmmc.0", "mmchsdb_fck",      &mmchsdb1_fck,  CK_243X),
        CLK("omap_hsmmc.1", "mmchsdb_fck",      &mmchsdb2_fck,  CK_243X),
-       CLK("omap_timer.1",     "fck",  &gpt1_fck,      CK_243X),
-       CLK("omap_timer.2",     "fck",  &gpt2_fck,      CK_243X),
-       CLK("omap_timer.3",     "fck",  &gpt3_fck,      CK_243X),
-       CLK("omap_timer.4",     "fck",  &gpt4_fck,      CK_243X),
-       CLK("omap_timer.5",     "fck",  &gpt5_fck,      CK_243X),
-       CLK("omap_timer.6",     "fck",  &gpt6_fck,      CK_243X),
-       CLK("omap_timer.7",     "fck",  &gpt7_fck,      CK_243X),
-       CLK("omap_timer.8",     "fck",  &gpt8_fck,      CK_243X),
-       CLK("omap_timer.9",     "fck",  &gpt9_fck,      CK_243X),
-       CLK("omap_timer.10",    "fck",  &gpt10_fck,     CK_243X),
-       CLK("omap_timer.11",    "fck",  &gpt11_fck,     CK_243X),
-       CLK("omap_timer.12",    "fck",  &gpt12_fck,     CK_243X),
        CLK("omap_timer.1",     "32k_ck",  &func_32k_ck,   CK_243X),
        CLK("omap_timer.2",     "32k_ck",  &func_32k_ck,   CK_243X),
        CLK("omap_timer.3",     "32k_ck",  &func_32k_ck,   CK_243X),
index 65dd363163bccdfa6890b112458aac36e1b7f704..5d0064a4fb5a638bb1141489354244e95899c1a1 100644 (file)
@@ -3464,18 +3464,6 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK("musb-am35x",       "fck",          &hsotgusb_fck_am35xx,   CK_AM35XX),
        CLK(NULL,       "hecc_ck",      &hecc_ck,       CK_AM35XX),
        CLK(NULL,       "uart4_ick",    &uart4_ick_am35xx,      CK_AM35XX),
-       CLK("omap_timer.1",     "fck",  &gpt1_fck,      CK_3XXX),
-       CLK("omap_timer.2",     "fck",  &gpt2_fck,      CK_3XXX),
-       CLK("omap_timer.3",     "fck",  &gpt3_fck,      CK_3XXX),
-       CLK("omap_timer.4",     "fck",  &gpt4_fck,      CK_3XXX),
-       CLK("omap_timer.5",     "fck",  &gpt5_fck,      CK_3XXX),
-       CLK("omap_timer.6",     "fck",  &gpt6_fck,      CK_3XXX),
-       CLK("omap_timer.7",     "fck",  &gpt7_fck,      CK_3XXX),
-       CLK("omap_timer.8",     "fck",  &gpt8_fck,      CK_3XXX),
-       CLK("omap_timer.9",     "fck",  &gpt9_fck,      CK_3XXX),
-       CLK("omap_timer.10",    "fck",  &gpt10_fck,     CK_3XXX),
-       CLK("omap_timer.11",    "fck",  &gpt11_fck,     CK_3XXX),
-       CLK("omap_timer.12",    "fck",  &gpt12_fck,     CK_3XXX),
        CLK("omap_timer.1",     "32k_ck",       &omap_32k_fck,  CK_3XXX),
        CLK("omap_timer.2",     "32k_ck",       &omap_32k_fck,  CK_3XXX),
        CLK("omap_timer.3",     "32k_ck",       &omap_32k_fck,  CK_3XXX),
index 7ceb870e7ab8d6abf330227c0f266eb8aef03561..287a46f78d976c5002207581370676e2680b8dce 100644 (file)
@@ -8,6 +8,13 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
 
+/*
+ * OMAP4430_REGM4XEN_MULT: If the CM_CLKMODE_DPLL_ABE.DPLL_REGM4XEN bit is
+ *    set, then the DPLL's lock frequency is multiplied by 4 (OMAP4430 TRM
+ *    vV Section 3.6.3.3.1 "DPLLs Output Clocks Parameters")
+ */
+#define OMAP4430_REGM4XEN_MULT 4
+
 int omap4xxx_clk_init(void);
 
 #endif
index 946bf04a956db5638035ea591c262d3944e8a3d2..0798a802497a543dbfc2bff9b71da28772ffa6be 100644 (file)
@@ -270,8 +270,8 @@ static struct clk dpll_abe_ck = {
        .dpll_data      = &dpll_abe_dd,
        .init           = &omap2_init_dpll_parent,
        .ops            = &clkops_omap3_noncore_dpll_ops,
-       .recalc         = &omap3_dpll_recalc,
-       .round_rate     = &omap2_dpll_round_rate,
+       .recalc         = &omap4_dpll_regm4xen_recalc,
+       .round_rate     = &omap4_dpll_regm4xen_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
 };
 
@@ -1195,11 +1195,25 @@ static struct clk l4_wkup_clk_mux_ck = {
        .recalc         = &omap2_clksel_recalc,
 };
 
+static const struct clksel_rate div2_2to1_rates[] = {
+       { .div = 1, .val = 1, .flags = RATE_IN_4430 },
+       { .div = 2, .val = 0, .flags = RATE_IN_4430 },
+       { .div = 0 },
+};
+
+static const struct clksel ocp_abe_iclk_div[] = {
+       { .parent = &aess_fclk, .rates = div2_2to1_rates },
+       { .parent = NULL },
+};
+
 static struct clk ocp_abe_iclk = {
        .name           = "ocp_abe_iclk",
        .parent         = &aess_fclk,
+       .clksel         = ocp_abe_iclk_div,
+       .clksel_reg     = OMAP4430_CM1_ABE_AESS_CLKCTRL,
+       .clksel_mask    = OMAP4430_CLKSEL_AESS_FCLK_MASK,
        .ops            = &clkops_null,
-       .recalc         = &followparent_recalc,
+       .recalc         = &omap2_clksel_recalc,
 };
 
 static struct clk per_abe_24m_fclk = {
@@ -1398,9 +1412,9 @@ static struct clk dss_dss_clk = {
 };
 
 static const struct clksel_rate div3_8to32_rates[] = {
-       { .div = 8, .val = 0, .flags = RATE_IN_44XX },
-       { .div = 16, .val = 1, .flags = RATE_IN_44XX },
-       { .div = 32, .val = 2, .flags = RATE_IN_44XX },
+       { .div = 8, .val = 0, .flags = RATE_IN_4460 },
+       { .div = 16, .val = 1, .flags = RATE_IN_4460 },
+       { .div = 32, .val = 2, .flags = RATE_IN_4460 },
        { .div = 0 },
 };
 
@@ -3363,17 +3377,6 @@ static struct omap_clk omap44xx_clks[] = {
        CLK("usbhs-omap.0",     "usbhost_ick",          &dummy_ck,              CK_443X),
        CLK("usbhs-omap.0",     "usbtll_fck",           &dummy_ck,      CK_443X),
        CLK("omap_wdt", "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap_timer.1",     "fck",                  &timer1_fck,    CK_443X),
-       CLK("omap_timer.2",     "fck",                  &timer2_fck,    CK_443X),
-       CLK("omap_timer.3",     "fck",                  &timer3_fck,    CK_443X),
-       CLK("omap_timer.4",     "fck",                  &timer4_fck,    CK_443X),
-       CLK("omap_timer.5",     "fck",                  &timer5_fck,    CK_443X),
-       CLK("omap_timer.6",     "fck",                  &timer6_fck,    CK_443X),
-       CLK("omap_timer.7",     "fck",                  &timer7_fck,    CK_443X),
-       CLK("omap_timer.8",     "fck",                  &timer8_fck,    CK_443X),
-       CLK("omap_timer.9",     "fck",                  &timer9_fck,    CK_443X),
-       CLK("omap_timer.10",    "fck",                  &timer10_fck,   CK_443X),
-       CLK("omap_timer.11",    "fck",                  &timer11_fck,   CK_443X),
        CLK("omap_timer.1",     "32k_ck",       &sys_32k_ck,    CK_443X),
        CLK("omap_timer.2",     "32k_ck",       &sys_32k_ck,    CK_443X),
        CLK("omap_timer.3",     "32k_ck",       &sys_32k_ck,    CK_443X),
@@ -3403,12 +3406,12 @@ int __init omap4xxx_clk_init(void)
        struct omap_clk *c;
        u32 cpu_clkflg;
 
-       if (cpu_is_omap44xx()) {
+       if (cpu_is_omap443x()) {
                cpu_mask = RATE_IN_4430;
                cpu_clkflg = CK_443X;
        } else if (cpu_is_omap446x()) {
-               cpu_mask = RATE_IN_4460;
-               cpu_clkflg = CK_446X;
+               cpu_mask = RATE_IN_4460 | RATE_IN_4430;
+               cpu_clkflg = CK_446X | CK_443X;
        } else {
                return 0;
        }
index 8480ee4344ea0ad1d12ef437735585efb25d34ea..ad07689e15639ba1bee03c411c5c9ad173142673 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/limits.h>
index 4bf6e6e8b1001ae5b14ab0e86c44dec7c8b1043d..942bb4f19f9fd6df5af92b1b551cb1a3f3bb2313 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
+#include <linux/export.h>
 
 #include <plat/prcm.h>
 #include <plat/irqs.h>
@@ -88,17 +89,21 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
 /**
  * omap3_enter_idle - Programs OMAP3 to enter the specified state
  * @dev: cpuidle device
- * @state: The target state to be programmed
+ * @drv: cpuidle driver
+ * @index: the index of state to be entered
  *
  * Called from the CPUidle framework to program the device to the
  * specified target state selected by the governor.
  */
 static int omap3_enter_idle(struct cpuidle_device *dev,
-                       struct cpuidle_state *state)
+                               struct cpuidle_driver *drv,
+                               int index)
 {
-       struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
+       struct omap3_idle_statedata *cx =
+                       cpuidle_get_statedata(&dev->states_usage[index]);
        struct timespec ts_preidle, ts_postidle, ts_idle;
        u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
+       int idle_time;
 
        /* Used to keep track of the total time in idle */
        getnstimeofday(&ts_preidle);
@@ -113,7 +118,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
                goto return_sleep_time;
 
        /* Deny idle for C1 */
-       if (state == &dev->states[0]) {
+       if (index == 0) {
                pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
                pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
        }
@@ -122,7 +127,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
        omap_sram_idle();
 
        /* Re-allow idle for C1 */
-       if (state == &dev->states[0]) {
+       if (index == 0) {
                pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
                pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
        }
@@ -134,28 +139,38 @@ return_sleep_time:
        local_irq_enable();
        local_fiq_enable();
 
-       return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
+       idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
+                                                               USEC_PER_SEC;
+
+       /* Update cpuidle counters */
+       dev->last_residency = idle_time;
+
+       return index;
 }
 
 /**
  * next_valid_state - Find next valid C-state
  * @dev: cpuidle device
- * @state: Currently selected C-state
+ * @drv: cpuidle driver
+ * @index: Index of currently selected c-state
  *
- * If the current state is valid, it is returned back to the caller.
- * Else, this function searches for a lower c-state which is still
- * valid.
+ * If the state corresponding to index is valid, index is returned back
+ * to the caller. Else, this function searches for a lower c-state which is
+ * still valid (as defined in omap3_power_states[]) and returns its index.
  *
  * A state is valid if the 'valid' field is enabled and
  * if it satisfies the enable_off_mode condition.
  */
-static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
-                                             struct cpuidle_state *curr)
+static int next_valid_state(struct cpuidle_device *dev,
+                       struct cpuidle_driver *drv,
+                               int index)
 {
-       struct cpuidle_state *next = NULL;
-       struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+       struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
+       struct cpuidle_state *curr = &drv->states[index];
+       struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
        u32 mpu_deepest_state = PWRDM_POWER_RET;
        u32 core_deepest_state = PWRDM_POWER_RET;
+       int next_index = -1;
 
        if (enable_off_mode) {
                mpu_deepest_state = PWRDM_POWER_OFF;
@@ -172,20 +187,20 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
        if ((cx->valid) &&
            (cx->mpu_state >= mpu_deepest_state) &&
            (cx->core_state >= core_deepest_state)) {
-               return curr;
+               return index;
        } else {
                int idx = OMAP3_NUM_STATES - 1;
 
                /* Reach the current state starting at highest C-state */
                for (; idx >= 0; idx--) {
-                       if (&dev->states[idx] == curr) {
-                               next = &dev->states[idx];
+                       if (&drv->states[idx] == curr) {
+                               next_index = idx;
                                break;
                        }
                }
 
                /* Should never hit this condition */
-               WARN_ON(next == NULL);
+               WARN_ON(next_index == -1);
 
                /*
                 * Drop to next valid state.
@@ -193,41 +208,44 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
                 */
                idx--;
                for (; idx >= 0; idx--) {
-                       cx = cpuidle_get_statedata(&dev->states[idx]);
+                       cx = cpuidle_get_statedata(&dev->states_usage[idx]);
                        if ((cx->valid) &&
                            (cx->mpu_state >= mpu_deepest_state) &&
                            (cx->core_state >= core_deepest_state)) {
-                               next = &dev->states[idx];
+                               next_index = idx;
                                break;
                        }
                }
                /*
                 * C1 is always valid.
-                * So, no need to check for 'next==NULL' outside this loop.
+                * So, no need to check for 'next_index == -1' outside
+                * this loop.
                 */
        }
 
-       return next;
+       return next_index;
 }
 
 /**
  * omap3_enter_idle_bm - Checks for any bus activity
  * @dev: cpuidle device
- * @state: The target state to be programmed
+ * @drv: cpuidle driver
+ * @index: array index of target state to be programmed
  *
  * This function checks for any pending activity and then programs
  * the device to the specified or a safer state.
  */
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
-                              struct cpuidle_state *state)
+                               struct cpuidle_driver *drv,
+                              int index)
 {
-       struct cpuidle_state *new_state;
+       int new_state_idx;
        u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
        struct omap3_idle_statedata *cx;
        int ret;
 
        if (!omap3_can_sleep()) {
-               new_state = dev->safe_state;
+               new_state_idx = drv->safe_state_index;
                goto select_state;
        }
 
@@ -237,7 +255,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
         */
        cam_state = pwrdm_read_pwrst(cam_pd);
        if (cam_state == PWRDM_POWER_ON) {
-               new_state = dev->safe_state;
+               new_state_idx = drv->safe_state_index;
                goto select_state;
        }
 
@@ -253,7 +271,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
         * Prevent PER off if CORE is not in retention or off as this
         * would disable PER wakeups completely.
         */
-       cx = cpuidle_get_statedata(state);
+       cx = cpuidle_get_statedata(&dev->states_usage[index]);
        core_next_state = cx->core_state;
        per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
        if ((per_next_state == PWRDM_POWER_OFF) &&
@@ -264,11 +282,10 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
        if (per_next_state != per_saved_state)
                pwrdm_set_next_pwrst(per_pd, per_next_state);
 
-       new_state = next_valid_state(dev, state);
+       new_state_idx = next_valid_state(dev, drv, index);
 
 select_state:
-       dev->last_state = new_state;
-       ret = omap3_enter_idle(dev, new_state);
+       ret = omap3_enter_idle(dev, drv, new_state_idx);
 
        /* Restore original PER state if it was modified */
        if (per_next_state != per_saved_state)
@@ -301,22 +318,31 @@ struct cpuidle_driver omap3_idle_driver = {
        .owner =        THIS_MODULE,
 };
 
-/* Helper to fill the C-state common data and register the driver_data */
-static inline struct omap3_idle_statedata *_fill_cstate(
-                                       struct cpuidle_device *dev,
+/* Helper to fill the C-state common data*/
+static inline void _fill_cstate(struct cpuidle_driver *drv,
                                        int idx, const char *descr)
 {
-       struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
-       struct cpuidle_state *state = &dev->states[idx];
+       struct cpuidle_state *state = &drv->states[idx];
 
        state->exit_latency     = cpuidle_params_table[idx].exit_latency;
        state->target_residency = cpuidle_params_table[idx].target_residency;
        state->flags            = CPUIDLE_FLAG_TIME_VALID;
        state->enter            = omap3_enter_idle_bm;
-       cx->valid               = cpuidle_params_table[idx].valid;
        sprintf(state->name, "C%d", idx + 1);
        strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
-       cpuidle_set_statedata(state, cx);
+
+}
+
+/* Helper to register the driver_data */
+static inline struct omap3_idle_statedata *_fill_cstate_usage(
+                                       struct cpuidle_device *dev,
+                                       int idx)
+{
+       struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
+
+       cx->valid               = cpuidle_params_table[idx].valid;
+       cpuidle_set_statedata(state_usage, cx);
 
        return cx;
 }
@@ -330,6 +356,7 @@ static inline struct omap3_idle_statedata *_fill_cstate(
 int __init omap3_idle_init(void)
 {
        struct cpuidle_device *dev;
+       struct cpuidle_driver *drv = &omap3_idle_driver;
        struct omap3_idle_statedata *cx;
 
        mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -337,44 +364,52 @@ int __init omap3_idle_init(void)
        per_pd = pwrdm_lookup("per_pwrdm");
        cam_pd = pwrdm_lookup("cam_pwrdm");
 
-       cpuidle_register_driver(&omap3_idle_driver);
+
+       drv->safe_state_index = -1;
        dev = &per_cpu(omap3_idle_dev, smp_processor_id());
 
        /* C1 . MPU WFI + Core active */
-       cx = _fill_cstate(dev, 0, "MPU ON + CORE ON");
-       (&dev->states[0])->enter = omap3_enter_idle;
-       dev->safe_state = &dev->states[0];
+       _fill_cstate(drv, 0, "MPU ON + CORE ON");
+       (&drv->states[0])->enter = omap3_enter_idle;
+       drv->safe_state_index = 0;
+       cx = _fill_cstate_usage(dev, 0);
        cx->valid = 1;  /* C1 is always valid */
        cx->mpu_state = PWRDM_POWER_ON;
        cx->core_state = PWRDM_POWER_ON;
 
        /* C2 . MPU WFI + Core inactive */
-       cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
+       _fill_cstate(drv, 1, "MPU ON + CORE ON");
+       cx = _fill_cstate_usage(dev, 1);
        cx->mpu_state = PWRDM_POWER_ON;
        cx->core_state = PWRDM_POWER_ON;
 
        /* C3 . MPU CSWR + Core inactive */
-       cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
+       _fill_cstate(drv, 2, "MPU RET + CORE ON");
+       cx = _fill_cstate_usage(dev, 2);
        cx->mpu_state = PWRDM_POWER_RET;
        cx->core_state = PWRDM_POWER_ON;
 
        /* C4 . MPU OFF + Core inactive */
-       cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
+       _fill_cstate(drv, 3, "MPU OFF + CORE ON");
+       cx = _fill_cstate_usage(dev, 3);
        cx->mpu_state = PWRDM_POWER_OFF;
        cx->core_state = PWRDM_POWER_ON;
 
        /* C5 . MPU RET + Core RET */
-       cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
+       _fill_cstate(drv, 4, "MPU RET + CORE RET");
+       cx = _fill_cstate_usage(dev, 4);
        cx->mpu_state = PWRDM_POWER_RET;
        cx->core_state = PWRDM_POWER_RET;
 
        /* C6 . MPU OFF + Core RET */
-       cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
+       _fill_cstate(drv, 5, "MPU OFF + CORE RET");
+       cx = _fill_cstate_usage(dev, 5);
        cx->mpu_state = PWRDM_POWER_OFF;
        cx->core_state = PWRDM_POWER_RET;
 
        /* C7 . MPU OFF + Core OFF */
-       cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
+       _fill_cstate(drv, 6, "MPU OFF + CORE OFF");
+       cx = _fill_cstate_usage(dev, 6);
        /*
         * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
         * enable OFF mode in a stable form for previous revisions.
@@ -388,6 +423,9 @@ int __init omap3_idle_init(void)
        cx->mpu_state = PWRDM_POWER_OFF;
        cx->core_state = PWRDM_POWER_OFF;
 
+       drv->state_count = OMAP3_NUM_STATES;
+       cpuidle_register_driver(&omap3_idle_driver);
+
        dev->state_count = OMAP3_NUM_STATES;
        if (cpuidle_register_device(dev)) {
                printk(KERN_ERR "%s: CPUidle register device failed\n",
index 68ec03152d5fc4e811842f4cb4c5c6e634a5fae5..c15cfada5f13b5975e36c70331e24032f39e2d66 100644 (file)
@@ -318,18 +318,10 @@ static inline void omap_init_audio(void) {}
 #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
                defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
 
-static struct omap_device_pm_latency omap_mcpdm_latency[] = {
-       {
-               .deactivate_func = omap_device_idle_hwmods,
-               .activate_func = omap_device_enable_hwmods,
-               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
-       },
-};
-
 static void omap_init_mcpdm(void)
 {
        struct omap_hwmod *oh;
-       struct omap_device *od;
+       struct platform_device *pdev;
 
        oh = omap_hwmod_lookup("mcpdm");
        if (!oh) {
@@ -337,11 +329,8 @@ static void omap_init_mcpdm(void)
                return;
        }
 
-       od = omap_device_build("omap-mcpdm", -1, oh, NULL, 0,
-                               omap_mcpdm_latency,
-                               ARRAY_SIZE(omap_mcpdm_latency), 0);
-       if (IS_ERR(od))
-               printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n");
+       pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0);
+       WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");
 }
 #else
 static inline void omap_init_mcpdm(void) {}
index 4036821a01f3da5d18556fb18bed95e16cc186c9..dce9905d64bb6e1af6c0b80d012142ffdfca49ee 100644 (file)
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 #include <plat/omap-pm.h>
+#include <plat/common.h>
 
 #include "control.h"
+#include "display.h"
+
+#define DISPC_CONTROL          0x0040
+#define DISPC_CONTROL2         0x0238
+#define DISPC_IRQSTATUS                0x0018
+
+#define DSS_SYSCONFIG          0x10
+#define DSS_SYSSTATUS          0x14
+#define DSS_CONTROL            0x40
+#define DSS_SDI_CONTROL                0x44
+#define DSS_PLL_CONTROL                0x48
+
+#define LCD_EN_MASK            (0x1 << 0)
+#define DIGIT_EN_MASK          (0x1 << 1)
+
+#define FRAMEDONE_IRQ_SHIFT    0
+#define EVSYNC_EVEN_IRQ_SHIFT  2
+#define EVSYNC_ODD_IRQ_SHIFT   3
+#define FRAMEDONE2_IRQ_SHIFT   22
+#define FRAMEDONETV_IRQ_SHIFT  24
+
+/*
+ * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC
+ *     reset before deciding that something has gone wrong
+ */
+#define FRAMEDONE_IRQ_TIMEOUT          100
 
 static struct platform_device omap_display_device = {
        .name          = "omapdss",
@@ -171,3 +199,135 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
 
        return r;
 }
+
+static void dispc_disable_outputs(void)
+{
+       u32 v, irq_mask = 0;
+       bool lcd_en, digit_en, lcd2_en = false;
+       int i;
+       struct omap_dss_dispc_dev_attr *da;
+       struct omap_hwmod *oh;
+
+       oh = omap_hwmod_lookup("dss_dispc");
+       if (!oh) {
+               WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n");
+               return;
+       }
+
+       if (!oh->dev_attr) {
+               pr_err("display: could not disable outputs during reset due to missing dev_attr\n");
+               return;
+       }
+
+       da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr;
+
+       /* store value of LCDENABLE and DIGITENABLE bits */
+       v = omap_hwmod_read(oh, DISPC_CONTROL);
+       lcd_en = v & LCD_EN_MASK;
+       digit_en = v & DIGIT_EN_MASK;
+
+       /* store value of LCDENABLE for LCD2 */
+       if (da->manager_count > 2) {
+               v = omap_hwmod_read(oh, DISPC_CONTROL2);
+               lcd2_en = v & LCD_EN_MASK;
+       }
+
+       if (!(lcd_en | digit_en | lcd2_en))
+               return; /* no managers currently enabled */
+
+       /*
+        * If any manager was enabled, we need to disable it before
+        * DSS clocks are disabled or DISPC module is reset
+        */
+       if (lcd_en)
+               irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT;
+
+       if (digit_en) {
+               if (da->has_framedonetv_irq) {
+                       irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT;
+               } else {
+                       irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT |
+                               1 << EVSYNC_ODD_IRQ_SHIFT;
+               }
+       }
+
+       if (lcd2_en)
+               irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT;
+
+       /*
+        * clear any previous FRAMEDONE, FRAMEDONETV,
+        * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts
+        */
+       omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS);
+
+       /* disable LCD and TV managers */
+       v = omap_hwmod_read(oh, DISPC_CONTROL);
+       v &= ~(LCD_EN_MASK | DIGIT_EN_MASK);
+       omap_hwmod_write(v, oh, DISPC_CONTROL);
+
+       /* disable LCD2 manager */
+       if (da->manager_count > 2) {
+               v = omap_hwmod_read(oh, DISPC_CONTROL2);
+               v &= ~LCD_EN_MASK;
+               omap_hwmod_write(v, oh, DISPC_CONTROL2);
+       }
+
+       i = 0;
+       while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) !=
+              irq_mask) {
+               i++;
+               if (i > FRAMEDONE_IRQ_TIMEOUT) {
+                       pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n");
+                       break;
+               }
+               mdelay(1);
+       }
+}
+
+#define MAX_MODULE_SOFTRESET_WAIT      10000
+int omap_dss_reset(struct omap_hwmod *oh)
+{
+       struct omap_hwmod_opt_clk *oc;
+       int c = 0;
+       int i, r;
+
+       if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) {
+               pr_err("dss_core: hwmod data doesn't contain reset data\n");
+               return -EINVAL;
+       }
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk)
+                       clk_enable(oc->_clk);
+
+       dispc_disable_outputs();
+
+       /* clear SDI registers */
+       if (cpu_is_omap3430()) {
+               omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL);
+               omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL);
+       }
+
+       /*
+        * clear DSS_CONTROL register to switch DSS clock sources to
+        * PRCM clock, if any
+        */
+       omap_hwmod_write(0x0, oh, DSS_CONTROL);
+
+       omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs)
+                               & SYSS_RESETDONE_MASK),
+                       MAX_MODULE_SOFTRESET_WAIT, c);
+
+       if (c == MAX_MODULE_SOFTRESET_WAIT)
+               pr_warning("dss_core: waiting for reset to finish failed\n");
+       else
+               pr_debug("dss_core: softreset done\n");
+
+       for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+               if (oc->_clk)
+                       clk_disable(oc->_clk);
+
+       r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
+
+       return r;
+}
diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h
new file mode 100644 (file)
index 0000000..b871b01
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * display.h - OMAP2+ integration-specific DSS header
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+#define __ARCH_ARM_MACH_OMAP2_DISPLAY_H
+
+#include <linux/kernel.h>
+
+struct omap_dss_dispc_dev_attr {
+       u8      manager_count;
+       bool    has_framedonetv_irq;
+};
+
+#endif
index f77022be783d7fe9d3244fe1df2bf4be94298c6d..fc56745676fa1ea713f8cdc6cff80e5b2b3ac3d5 100644 (file)
@@ -390,7 +390,8 @@ int omap3_noncore_dpll_enable(struct clk *clk)
         * propagating?
         */
        if (!r)
-               clk->rate = omap2_get_dpll_rate(clk);
+               clk->rate = (clk->recalc) ? clk->recalc(clk) :
+                       omap2_get_dpll_rate(clk);
 
        return r;
 }
@@ -424,6 +425,7 @@ void omap3_noncore_dpll_disable(struct clk *clk)
 int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
 {
        struct clk *new_parent = NULL;
+       unsigned long hw_rate;
        u16 freqsel = 0;
        struct dpll_data *dd;
        int ret;
@@ -435,7 +437,8 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
        if (!dd)
                return -EINVAL;
 
-       if (rate == omap2_get_dpll_rate(clk))
+       hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk);
+       if (rate == hw_rate)
                return 0;
 
        /*
@@ -455,7 +458,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
                        new_parent = dd->clk_bypass;
        } else {
                if (dd->last_rounded_rate != rate)
-                       omap2_dpll_round_rate(clk, rate);
+                       rate = clk->round_rate(clk, rate);
 
                if (dd->last_rounded_rate == 0)
                        return -EINVAL;
index 4e4da6160d05cdad339ab0fdab9233816e6b84b1..9c6a296b3dc3a0dd6856580b9ddbf5e54ea79e0e 100644 (file)
@@ -19,6 +19,7 @@
 #include <plat/clock.h>
 
 #include "clock.h"
+#include "clock44xx.h"
 #include "cm-regbits-44xx.h"
 
 /* Supported only on OMAP4 */
@@ -82,3 +83,71 @@ const struct clkops clkops_omap4_dpllmx_ops = {
        .deny_idle      = omap4_dpllmx_deny_gatectrl,
 };
 
+/**
+ * omap4_dpll_regm4xen_recalc - compute DPLL rate, considering REGM4XEN bit
+ * @clk: struct clk * of the DPLL to compute the rate for
+ *
+ * Compute the output rate for the OMAP4 DPLL represented by @clk.
+ * Takes the REGM4XEN bit into consideration, which is needed for the
+ * OMAP4 ABE DPLL.  Returns the DPLL's output rate (before M-dividers)
+ * upon success, or 0 upon error.
+ */
+unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
+{
+       u32 v;
+       unsigned long rate;
+       struct dpll_data *dd;
+
+       if (!clk || !clk->dpll_data)
+               return 0;
+
+       dd = clk->dpll_data;
+
+       rate = omap2_get_dpll_rate(clk);
+
+       /* regm4xen adds a multiplier of 4 to DPLL calculations */
+       v = __raw_readl(dd->control_reg);
+       if (v & OMAP4430_DPLL_REGM4XEN_MASK)
+               rate *= OMAP4430_REGM4XEN_MULT;
+
+       return rate;
+}
+
+/**
+ * omap4_dpll_regm4xen_round_rate - round DPLL rate, considering REGM4XEN bit
+ * @clk: struct clk * of the DPLL to round a rate for
+ * @target_rate: the desired rate of the DPLL
+ *
+ * Compute the rate that would be programmed into the DPLL hardware
+ * for @clk if set_rate() were to be provided with the rate
+ * @target_rate.  Takes the REGM4XEN bit into consideration, which is
+ * needed for the OMAP4 ABE DPLL.  Returns the rounded rate (before
+ * M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
+ * ~0 if an error occurred in omap2_dpll_round_rate().
+ */
+long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
+{
+       u32 v;
+       struct dpll_data *dd;
+       long r;
+
+       if (!clk || !clk->dpll_data)
+               return -EINVAL;
+
+       dd = clk->dpll_data;
+
+       /* regm4xen adds a multiplier of 4 to DPLL calculations */
+       v = __raw_readl(dd->control_reg) & OMAP4430_DPLL_REGM4XEN_MASK;
+
+       if (v)
+               target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
+
+       r = omap2_dpll_round_rate(clk, target_rate);
+       if (r == ~0)
+               return r;
+
+       if (v)
+               clk->dpll_data->last_rounded_rate *= OMAP4430_REGM4XEN_MULT;
+
+       return clk->dpll_data->last_rounded_rate;
+}
index 911cd2e68d46e060291e67a14110e86f17e232f5..74f18f2952df220107c1846e98c4d34b7007243f 100644 (file)
@@ -18,6 +18,7 @@
  * of the OMAP PM core code.
  */
 
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include "cm2xxx_3xxx.h"
 #include "prm2xxx_3xxx.h"
index d776ded9830d922188d87873268ac522697e6228..5cdce10d61835d50f9ebca84d108f6b31509cb5b 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/onenand_regs.h>
index 77085847e4e7dafc893a2d255bee5dbac90d4d55..f4a1020559a7b84529f3f6f22e8ffec9ec41c6e3 100644 (file)
@@ -129,15 +129,11 @@ static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
         * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
         * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
         * 1.8V and 3.0V modes, controlled by the PBIAS register.
-        *
-        * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
-        * is most naturally TWL VSIM; those pins also use PBIAS.
-        *
-        * FIXME handle VMMC1A as needed ...
         */
        reg = omap4_ctrl_pad_readl(control_pbias_offset);
        reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-               OMAP4_MMC1_PWRDNZ_MASK);
+               OMAP4_MMC1_PWRDNZ_MASK |
+               OMAP4_MMC1_PBIASLITE_VMODE_MASK);
        omap4_ctrl_pad_writel(reg, control_pbias_offset);
 }
 
@@ -172,12 +168,6 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
                        reg &= ~(OMAP4_MMC1_PWRDNZ_MASK);
                        omap4_ctrl_pad_writel(reg, control_pbias_offset);
                }
-       } else {
-               reg = omap4_ctrl_pad_readl(control_pbias_offset);
-               reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-                       OMAP4_MMC1_PWRDNZ_MASK |
-                       OMAP4_MMC1_PBIASLITE_VMODE_MASK);
-               omap4_ctrl_pad_writel(reg, control_pbias_offset);
        }
 }
 
@@ -489,7 +479,7 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
                        OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK);
                reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK |
                        OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK);
-               reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK|
+               reg |= (OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK |
                        OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK |
                        OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK);
                omap4_ctrl_pad_writel(reg, control_mmc1);
index d27daf921c7ee83d18a82e474c93d3088190d3f3..7f47092a193f71444fee33d01c857f51b8c2c318 100644 (file)
@@ -187,8 +187,11 @@ static void __init omap3_check_features(void)
        OMAP3_CHECK_FEATURE(status, ISP);
        if (cpu_is_omap3630())
                omap_features |= OMAP3_HAS_192MHZ_CLK;
-       if (!cpu_is_omap3505() && !cpu_is_omap3517())
+       if (cpu_is_omap3430() || cpu_is_omap3630())
                omap_features |= OMAP3_HAS_IO_WAKEUP;
+       if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
+           omap_rev() == OMAP3430_REV_ES3_1_2)
+               omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
 
        omap_features |= OMAP3_HAS_SDRC;
 
index c88420de1151f9495c0ccf92aa8b718f38218b77..1e2d3322f33eec1e644350c2aeda84718569378a 100644 (file)
 #define OMAP4_DSI2_LANEENABLE_MASK                             (0x7 << 29)
 #define OMAP4_DSI1_LANEENABLE_SHIFT                            24
 #define OMAP4_DSI1_LANEENABLE_MASK                             (0x1f << 24)
-#define OMAP4_DSI1_PIPD_SHIFT                                  19
-#define OMAP4_DSI1_PIPD_MASK                                   (0x1f << 19)
-#define OMAP4_DSI2_PIPD_SHIFT                                  14
-#define OMAP4_DSI2_PIPD_MASK                                   (0x1f << 14)
+#define OMAP4_DSI2_PIPD_SHIFT                                  19
+#define OMAP4_DSI2_PIPD_MASK                                   (0x1f << 19)
+#define OMAP4_DSI1_PIPD_SHIFT                                  14
+#define OMAP4_DSI1_PIPD_MASK                                   (0x1f << 14)
 
 /* CONTROL_MCBSPLP */
 #define OMAP4_ALBCTRLRX_FSX_SHIFT                              31
index a5d8dce2a70b507507221b262d6bc3469bbd06dd..25d20ced03e13cb18bc7d6f27d44d11c5c671d90 100644 (file)
@@ -359,6 +359,7 @@ static void __init omap_hwmod_init_postsetup(void)
        omap_pm_if_early_init();
 }
 
+#ifdef CONFIG_ARCH_OMAP2
 void __init omap2420_init_early(void)
 {
        omap2_set_globals_242x();
@@ -382,11 +383,13 @@ void __init omap2430_init_early(void)
        omap_hwmod_init_postsetup();
        omap2430_clk_init();
 }
+#endif
 
 /*
  * Currently only board-omap3beagle.c should call this because of the
  * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT.
  */
+#ifdef CONFIG_ARCH_OMAP3
 void __init omap3_init_early(void)
 {
        omap2_set_globals_3xxx();
@@ -430,7 +433,9 @@ void __init ti816x_init_early(void)
        omap_hwmod_init_postsetup();
        omap3xxx_clk_init();
 }
+#endif
 
+#ifdef CONFIG_ARCH_OMAP4
 void __init omap4430_init_early(void)
 {
        omap2_set_globals_443x();
@@ -442,6 +447,7 @@ void __init omap4430_init_early(void)
        omap_hwmod_init_postsetup();
        omap4xxx_clk_init();
 }
+#endif
 
 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
                                      struct omap_sdrc_params *sdrc_cs1)
diff --git a/arch/arm/mach-omap2/io.h b/arch/arm/mach-omap2/io.h
deleted file mode 100644 (file)
index e69de29..0000000
index 86d564a640bb80f8adf1dc961637907592530da4..609ea2ded7e388a22ed9c9d59ba888672ebb13ab 100644 (file)
@@ -10,6 +10,7 @@
  * for more details.
  */
 
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
index e61feadcda4ee6438b64eb5418871d1733dfebad..b8822048e409c490c949bd8eb4e7329967ac12c9 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include <plat/iommu.h>
index d713807050807778e33881872413ef354ba33ec7..207a2ff9a8c4e1473c6c497ab8c969f64e0ac0c7 100644 (file)
@@ -749,7 +749,7 @@ static int _count_mpu_irqs(struct omap_hwmod *oh)
                ohii = &oh->mpu_irqs[i++];
        } while (ohii->irq != -1);
 
-       return i;
+       return i-1;
 }
 
 /**
@@ -772,7 +772,7 @@ static int _count_sdma_reqs(struct omap_hwmod *oh)
                ohdi = &oh->sdma_reqs[i++];
        } while (ohdi->dma_req != -1);
 
-       return i;
+       return i-1;
 }
 
 /**
@@ -795,7 +795,7 @@ static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os)
                mem = &os->addr[i++];
        } while (mem->pa_start != mem->pa_end);
 
-       return i;
+       return i-1;
 }
 
 /**
@@ -2625,7 +2625,7 @@ ohsps_unlock:
  * Returns the context loss count of the powerdomain assocated with @oh
  * upon success, or zero if no powerdomain exists for @oh.
  */
-u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
 {
        struct powerdomain *pwrdm;
        int ret = 0;
index 6d7206213525d03ac830d8ca6092ce4317863f37..a5409ce3f3233eaac531ed070fc1f9cf74e8398f 100644 (file)
@@ -875,6 +875,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "tv_clk", .clk = "dss_54m_fck" },
        { .role = "sys_clk", .clk = "dss2_fck" },
 };
@@ -899,7 +903,7 @@ static struct omap_hwmod omap2420_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_slaves),
        .masters        = omap2420_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap2420_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 /* l4_core -> dss_dispc */
@@ -939,6 +943,7 @@ static struct omap_hwmod omap2420_dss_dispc_hwmod = {
        .slaves         = omap2420_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /* l4_core -> dss_rfbi */
@@ -961,6 +966,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = {
        &omap2420_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -972,6 +981,8 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
                        .module_offs = CORE_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap2420_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -981,7 +992,7 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
        .master         = &omap2420_l4_core_hwmod,
        .slave          = &omap2420_dss_venc_hwmod,
-       .clk            = "dss_54m_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .fw = {
                .omap2 = {
@@ -1001,7 +1012,7 @@ static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = {
 static struct omap_hwmod omap2420_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_fck",
+       .main_clk       = "dss_54m_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
index a2580d01c3ff98b25a57b6508bd959d0e58c700f..c4f56cb60d7d676ddda36e232c8b385a58fef6ba 100644 (file)
@@ -942,6 +942,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "tv_clk", .clk = "dss_54m_fck" },
        { .role = "sys_clk", .clk = "dss2_fck" },
 };
@@ -966,7 +970,7 @@ static struct omap_hwmod omap2430_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_slaves),
        .masters        = omap2430_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap2430_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 /* l4_core -> dss_dispc */
@@ -1000,6 +1004,7 @@ static struct omap_hwmod omap2430_dss_dispc_hwmod = {
        .slaves         = omap2430_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /* l4_core -> dss_rfbi */
@@ -1016,6 +1021,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = {
        &omap2430_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -1027,6 +1036,8 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
                        .module_offs = CORE_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap2430_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1036,7 +1047,7 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
        .master         = &omap2430_l4_core_hwmod,
        .slave          = &omap2430_dss_venc_hwmod,
-       .clk            = "dss_54m_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .flags          = OCPIF_SWSUP_IDLE,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
@@ -1050,7 +1061,7 @@ static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = {
 static struct omap_hwmod omap2430_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_fck",
+       .main_clk       = "dss_54m_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
index c451729d289adfd17090c3be58c53937626835fe..c11273da5dcc33f046e94babfdb6f34c1d6f2778 100644 (file)
@@ -11,6 +11,7 @@
 #include <plat/omap_hwmod.h>
 #include <plat/serial.h>
 #include <plat/dma.h>
+#include <plat/common.h>
 
 #include <mach/irqs.h>
 
@@ -43,13 +44,15 @@ static struct omap_hwmod_class_sysconfig omap2_dss_sysc = {
        .rev_offs       = 0x0000,
        .sysc_offs      = 0x0010,
        .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+                          SYSS_HAS_RESET_STATUS),
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
 struct omap_hwmod_class omap2_dss_hwmod_class = {
        .name   = "dss",
        .sysc   = &omap2_dss_sysc,
+       .reset  = omap_dss_reset,
 };
 
 /*
index 3008e1672c7a051e54e84ed2e147ea2674e019e4..7f8915ad50990b1af2e877ed169c32cd0d15cd02 100644 (file)
@@ -1369,9 +1369,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
 };
 
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
-       { .role = "tv_clk", .clk = "dss_tv_fck" },
-       { .role = "video_clk", .clk = "dss_96m_fck" },
+       /*
+        * The DSS HW needs all DSS clocks enabled during reset. The dss_core
+        * driver does not use these clocks.
+        */
        { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+       { .role = "tv_clk", .clk = "dss_tv_fck" },
+       /* required only on OMAP3430 */
+       { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
 };
 
 static struct omap_hwmod omap3430es1_dss_core_hwmod = {
@@ -1394,11 +1399,12 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = {
        .slaves_cnt     = ARRAY_SIZE(omap3430es1_dss_slaves),
        .masters        = omap3xxx_dss_masters,
        .masters_cnt    = ARRAY_SIZE(omap3xxx_dss_masters),
-       .flags          = HWMOD_NO_IDLEST,
+       .flags          = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET,
 };
 
 static struct omap_hwmod omap3xxx_dss_core_hwmod = {
        .name           = "dss_core",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .class          = &omap2_dss_hwmod_class,
        .main_clk       = "dss1_alwon_fck", /* instead of dss_fck */
        .sdma_reqs      = omap3xxx_dss_sdma_chs,
@@ -1456,6 +1462,7 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
        .slaves         = omap3xxx_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_dispc_slaves),
        .flags          = HWMOD_NO_IDLEST,
+       .dev_attr       = &omap2_3_dss_dispc_dev_attr
 };
 
 /*
@@ -1486,6 +1493,7 @@ static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap3xxx_dss_dsi1_hwmod,
+       .clk            = "dss_ick",
        .addr           = omap3xxx_dss_dsi1_addrs,
        .fw = {
                .omap2 = {
@@ -1502,6 +1510,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
        &omap3xxx_l4_core__dss_dsi1,
 };
 
+static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = {
+       { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
 static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
        .name           = "dss_dsi1",
        .class          = &omap3xxx_dsi_hwmod_class,
@@ -1514,6 +1526,8 @@ static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_dsi1_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_dsi1_opt_clks),
        .slaves         = omap3xxx_dss_dsi1_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1540,6 +1554,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = {
        &omap3xxx_l4_core__dss_rfbi,
 };
 
+static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
+       { .role = "ick", .clk = "dss_ick" },
+};
+
 static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
        .name           = "dss_rfbi",
        .class          = &omap2_rfbi_hwmod_class,
@@ -1551,6 +1569,8 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_rfbi_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_rfbi_opt_clks),
        .slaves         = omap3xxx_dss_rfbi_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -1560,7 +1580,7 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
        .master         = &omap3xxx_l4_core_hwmod,
        .slave          = &omap3xxx_dss_venc_hwmod,
-       .clk            = "dss_tv_fck",
+       .clk            = "dss_ick",
        .addr           = omap2_dss_venc_addrs,
        .fw = {
                .omap2 = {
@@ -1578,10 +1598,15 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = {
        &omap3xxx_l4_core__dss_venc,
 };
 
+static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = {
+       /* required only on OMAP3430 */
+       { .role = "tv_dac_clk", .clk = "dss_96m_fck" },
+};
+
 static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap2_venc_hwmod_class,
-       .main_clk       = "dss1_alwon_fck",
+       .main_clk       = "dss_tv_fck",
        .prcm           = {
                .omap2 = {
                        .prcm_reg_id = 1,
@@ -1589,6 +1614,8 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
                        .module_offs = OMAP3430_DSS_MOD,
                },
        },
+       .opt_clks       = dss_venc_opt_clks,
+       .opt_clks_cnt   = ARRAY_SIZE(dss_venc_opt_clks),
        .slaves         = omap3xxx_dss_venc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_dss_venc_slaves),
        .flags          = HWMOD_NO_IDLEST,
@@ -3159,7 +3186,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
        &omap3xxx_mmc2_hwmod,
        &omap3xxx_mmc3_hwmod,
        &omap3xxx_mpu_hwmod,
-       &omap3xxx_iva_hwmod,
 
        &omap3xxx_timer1_hwmod,
        &omap3xxx_timer2_hwmod,
@@ -3188,8 +3214,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
        &omap3xxx_i2c1_hwmod,
        &omap3xxx_i2c2_hwmod,
        &omap3xxx_i2c3_hwmod,
-       &omap34xx_sr1_hwmod,
-       &omap34xx_sr2_hwmod,
 
        /* gpio class */
        &omap3xxx_gpio1_hwmod,
@@ -3211,8 +3235,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
        &omap3xxx_mcbsp2_sidetone_hwmod,
        &omap3xxx_mcbsp3_sidetone_hwmod,
 
-       /* mailbox class */
-       &omap3xxx_mailbox_hwmod,
 
        /* mcspi class */
        &omap34xx_mcspi1,
@@ -3225,31 +3247,39 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 
 /* 3430ES1-only hwmods */
 static __initdata struct omap_hwmod *omap3430es1_hwmods[] = {
+       &omap3xxx_iva_hwmod,
        &omap3430es1_dss_core_hwmod,
+       &omap3xxx_mailbox_hwmod,
        NULL
 };
 
 /* 3430ES2+-only hwmods */
 static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = {
+       &omap3xxx_iva_hwmod,
        &omap3xxx_dss_core_hwmod,
        &omap3xxx_usbhsotg_hwmod,
+       &omap3xxx_mailbox_hwmod,
        NULL
 };
 
 /* 34xx-only hwmods (all ES revisions) */
 static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
+       &omap3xxx_iva_hwmod,
        &omap34xx_sr1_hwmod,
        &omap34xx_sr2_hwmod,
+       &omap3xxx_mailbox_hwmod,
        NULL
 };
 
 /* 36xx-only hwmods (all ES revisions) */
 static __initdata struct omap_hwmod *omap36xx_hwmods[] = {
+       &omap3xxx_iva_hwmod,
        &omap3xxx_uart4_hwmod,
        &omap3xxx_dss_core_hwmod,
        &omap36xx_sr1_hwmod,
        &omap36xx_sr2_hwmod,
        &omap3xxx_usbhsotg_hwmod,
+       &omap3xxx_mailbox_hwmod,
        NULL
 };
 
@@ -3267,7 +3297,7 @@ int __init omap3xxx_hwmod_init(void)
 
        /* Register hwmods common to all OMAP3 */
        r = omap_hwmod_register(omap3xxx_hwmods);
-       if (!r)
+       if (r < 0)
                return r;
 
        rev = omap_rev();
@@ -3292,7 +3322,7 @@ int __init omap3xxx_hwmod_init(void)
        };
 
        r = omap_hwmod_register(h);
-       if (!r)
+       if (r < 0)
                return r;
 
        /*
index 7695e5d43316686429158ec56aafacbc7d25a6a7..daaf165af696f212c6dcadb4db7ac3539d54dcd6 100644 (file)
@@ -30,6 +30,7 @@
 #include <plat/mmc.h>
 #include <plat/i2c.h>
 #include <plat/dmtimer.h>
+#include <plat/common.h>
 
 #include "omap_hwmod_common_data.h"
 
@@ -1187,6 +1188,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = {
 static struct omap_hwmod_class omap44xx_dss_hwmod_class = {
        .name   = "dss",
        .sysc   = &omap44xx_dss_sysc,
+       .reset  = omap_dss_reset,
 };
 
 /* dss */
@@ -1240,12 +1242,12 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = {
 static struct omap_hwmod_opt_clk dss_opt_clks[] = {
        { .role = "sys_clk", .clk = "dss_sys_clk" },
        { .role = "tv_clk", .clk = "dss_tv_clk" },
-       { .role = "dss_clk", .clk = "dss_dss_clk" },
-       { .role = "video_clk", .clk = "dss_48mhz_clk" },
+       { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
 };
 
 static struct omap_hwmod omap44xx_dss_hwmod = {
        .name           = "dss_core",
+       .flags          = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
        .class          = &omap44xx_dss_hwmod_class,
        .clkdm_name     = "l3_dss_clkdm",
        .main_clk       = "dss_dss_clk",
@@ -1325,6 +1327,11 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = {
        { }
 };
 
+static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = {
+       .manager_count          = 3,
+       .has_framedonetv_irq    = 1
+};
+
 /* l4_per -> dss_dispc */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = {
        .master         = &omap44xx_l4_per_hwmod,
@@ -1340,12 +1347,6 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
        &omap44xx_l4_per__dss_dispc,
 };
 
-static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = {
-       { .role = "sys_clk", .clk = "dss_sys_clk" },
-       { .role = "tv_clk", .clk = "dss_tv_clk" },
-       { .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
-};
-
 static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
        .name           = "dss_dispc",
        .class          = &omap44xx_dispc_hwmod_class,
@@ -1359,10 +1360,9 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
                        .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
                },
        },
-       .opt_clks       = dss_dispc_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(dss_dispc_opt_clks),
        .slaves         = omap44xx_dss_dispc_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
+       .dev_attr       = &omap44xx_dss_dispc_dev_attr
 };
 
 /*
@@ -1624,7 +1624,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
        .clkdm_name     = "l3_dss_clkdm",
        .mpu_irqs       = omap44xx_dss_hdmi_irqs,
        .sdma_reqs      = omap44xx_dss_hdmi_sdma_reqs,
-       .main_clk       = "dss_dss_clk",
+       .main_clk       = "dss_48mhz_clk",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
@@ -1785,7 +1785,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
        .name           = "dss_venc",
        .class          = &omap44xx_venc_hwmod_class,
        .clkdm_name     = "l3_dss_clkdm",
-       .main_clk       = "dss_dss_clk",
+       .main_clk       = "dss_tv_clk",
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
index de832ebc93a98c8d2556675de6ae3bfd7a5b2342..51e5418899fb446cd2317efe2622e3683860eec4 100644 (file)
@@ -49,3 +49,7 @@ struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
        .srst_shift     = SYSC_TYPE2_SOFTRESET_SHIFT,
 };
 
+struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = {
+       .manager_count          = 2,
+       .has_framedonetv_irq    = 0
+};
index 39a7c37f45870446a9f61d682eb5cc333cbac94c..ad5d8f04c0b8803edeac09dff53686c156365b91 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <plat/omap_hwmod.h>
 
+#include "display.h"
+
 /* Common address space across OMAP2xxx */
 extern struct omap_hwmod_addr_space omap2xxx_uart1_addr_space[];
 extern struct omap_hwmod_addr_space omap2xxx_uart2_addr_space[];
@@ -111,4 +113,6 @@ extern struct omap_hwmod_class omap2xxx_dma_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mcspi_class;
 
+extern struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr;
+
 #endif
index c8b1bef92e5ad372cf02699bed78a302da236dc4..d15225ff5c4969b3ddde9cc79ece7caf725001eb 100644 (file)
@@ -20,6 +20,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
@@ -236,7 +237,7 @@ static int __devexit omap4_l3_remove(struct platform_device *pdev)
 static const struct of_device_id l3_noc_match[] = {
        {.compatible = "ti,omap4-l3-noc", },
        {},
-}
+};
 MODULE_DEVICE_TABLE(of, l3_noc_match);
 #else
 #define l3_noc_match NULL
index 2ab7a9e17fe2683889762494249f356c3b5beab0..00bff46ca48beb606557f8fba7a1974f571ebb91 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/opp.h>
+#include <linux/export.h>
 
 #include <plat/omap-pm.h>
 #include <plat/omap_device.h>
@@ -23,6 +24,7 @@
 #include "powerdomain.h"
 #include "clockdomain.h"
 #include "pm.h"
+#include "twl-common.h"
 
 static struct omap_device_pm_latency *pm_lats;
 
@@ -225,11 +227,8 @@ postcore_initcall(omap2_common_pm_init);
 
 static int __init omap2_common_pm_late_init(void)
 {
-       /* Init the OMAP TWL parameters */
-       omap3_twl_init();
-       omap4_twl_init();
-
        /* Init the voltage layer */
+       omap_pmic_late_init();
        omap_voltage_late_init();
 
        /* Initialize the voltages */
index c8cbd00a41af9cf6da518a67f9bff37784ebcbd3..efa66494c1e3c82ff6e1adfee5ef812d57e13089 100644 (file)
@@ -99,31 +99,27 @@ static void omap3_enable_io_chain(void)
 {
        int timeout = 0;
 
-       if (omap_rev() >= OMAP3430_REV_ES3_1) {
-               omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-                                    PM_WKEN);
-               /* Do a readback to assure write has been done */
-               omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-
-               while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
-                        OMAP3430_ST_IO_CHAIN_MASK)) {
-                       timeout++;
-                       if (timeout > 1000) {
-                               printk(KERN_ERR "Wake up daisy chain "
-                                      "activation failed.\n");
-                               return;
-                       }
-                       omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
-                                            WKUP_MOD, PM_WKEN);
+       omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+                                  PM_WKEN);
+       /* Do a readback to assure write has been done */
+       omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+       while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+                OMAP3430_ST_IO_CHAIN_MASK)) {
+               timeout++;
+               if (timeout > 1000) {
+                       pr_err("Wake up daisy chain activation failed.\n");
+                       return;
                }
+               omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
+                                          WKUP_MOD, PM_WKEN);
        }
 }
 
 static void omap3_disable_io_chain(void)
 {
-       if (omap_rev() >= OMAP3430_REV_ES3_1)
-               omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-                                      PM_WKEN);
+       omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+                                    PM_WKEN);
 }
 
 static void omap3_core_save_context(void)
@@ -363,7 +359,6 @@ void omap_sram_idle(void)
                printk(KERN_ERR "Invalid mpu state in sram_idle\n");
                return;
        }
-       pwrdm_pre_transition();
 
        /* NEON control */
        if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
@@ -376,7 +371,8 @@ void omap_sram_idle(void)
            (per_next_state < PWRDM_POWER_ON ||
             core_next_state < PWRDM_POWER_ON)) {
                omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
-               omap3_enable_io_chain();
+               if (omap3_has_io_chain_ctrl())
+                       omap3_enable_io_chain();
        }
 
        /* Block console output in case it is on one of the OMAP UARTs */
@@ -386,6 +382,8 @@ void omap_sram_idle(void)
                        if (!console_trylock())
                                goto console_still_active;
 
+       pwrdm_pre_transition();
+
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
                per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
@@ -409,13 +407,14 @@ void omap_sram_idle(void)
        omap3_intc_prepare_idle();
 
        /*
-       * On EMU/HS devices ROM code restores a SRDC value
-       * from scratchpad which has automatic self refresh on timeout
-       * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
-       * Hence store/restore the SDRC_POWER register here.
-       */
-       if (omap_rev() >= OMAP3430_REV_ES3_0 &&
-           omap_type() != OMAP2_DEVICE_TYPE_GP &&
+        * On EMU/HS devices ROM code restores a SRDC value
+        * from scratchpad which has automatic self refresh on timeout
+        * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
+        * Hence store/restore the SDRC_POWER register here.
+        */
+       if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
+           (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
+            omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
            core_next_state == PWRDM_POWER_OFF)
                sdrc_pwr = sdrc_read_reg(SDRC_POWER);
 
@@ -432,8 +431,9 @@ void omap_sram_idle(void)
                omap34xx_do_sram_idle(save_state);
 
        /* Restore normal SDRC POWER settings */
-       if (omap_rev() >= OMAP3430_REV_ES3_0 &&
-           omap_type() != OMAP2_DEVICE_TYPE_GP &&
+       if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 &&
+           (omap_type() == OMAP2_DEVICE_TYPE_EMU ||
+            omap_type() == OMAP2_DEVICE_TYPE_SEC) &&
            core_next_state == PWRDM_POWER_OFF)
                sdrc_write_reg(sdrc_pwr, SDRC_POWER);
 
@@ -455,6 +455,8 @@ void omap_sram_idle(void)
        }
        omap3_intc_resume_idle();
 
+       pwrdm_post_transition();
+
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
                per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
@@ -475,11 +477,10 @@ console_still_active:
             core_next_state < PWRDM_POWER_ON)) {
                omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
                                             PM_WKEN);
-               omap3_disable_io_chain();
+               if (omap3_has_io_chain_ctrl())
+                       omap3_disable_io_chain();
        }
 
-       pwrdm_post_transition();
-
        clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
@@ -870,6 +871,9 @@ static int __init omap3_pm_init(void)
        if (!cpu_is_omap34xx())
                return -ENODEV;
 
+       if (!omap3_has_io_chain_ctrl())
+               pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
+
        pm_errata_configure();
 
        /* XXX prcm_setup_regs needs to be before enabling hw
index 5164d587ef52a17fa5083c71506ed801ce9dd382..8a18d1bd61c80af893e3cc549daaaa2e10b90db3 100644 (file)
@@ -1002,16 +1002,16 @@ int pwrdm_post_transition(void)
  * @pwrdm: struct powerdomain * to wait for
  *
  * Context loss count is the sum of powerdomain off-mode counter, the
- * logic off counter and the per-bank memory off counter.  Returns 0
+ * logic off counter and the per-bank memory off counter.  Returns negative
  * (and WARNs) upon error, otherwise, returns the context loss count.
  */
-u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
 {
        int i, count;
 
        if (!pwrdm) {
                WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
-               return 0;
+               return -ENODEV;
        }
 
        count = pwrdm->state_counter[PWRDM_POWER_OFF];
@@ -1020,7 +1020,13 @@ u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
        for (i = 0; i < pwrdm->banks; i++)
                count += pwrdm->ret_mem_off_counter[i];
 
-       pr_debug("powerdomain: %s: context loss count = %u\n",
+       /*
+        * Context loss count has to be a non-negative value. Clear the sign
+        * bit to get a value range from 0 to INT_MAX.
+        */
+       count &= INT_MAX;
+
+       pr_debug("powerdomain: %s: context loss count = %d\n",
                 pwrdm->name, count);
 
        return count;
index 42e6dd8f2a78dd37521f06780cc76bb5050b01de..0d72a8a8ce4d36a00ce23fcfbe297d6087854c0f 100644 (file)
@@ -217,7 +217,7 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
 int pwrdm_pre_transition(void);
 int pwrdm_post_transition(void);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
-u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
 extern void omap242x_powerdomains_init(void);
index 8db5f035eb0aaae03b85cfd9a0542e2e85ce65c1..597e2da831b30c048181cbd38e2d925c5d143213 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include <mach/system.h>
 #include <plat/common.h>
index 0347b93211e6d468257f3a0bd365ebb28726edd8..cf246b39bac745dc315576ecc161c35666643381 100644 (file)
@@ -17,6 +17,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -138,7 +139,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
                sr_write_reg(sr_info, ERRCONFIG_V1, status);
        } else if (sr_info->ip_type == SR_TYPE_V2) {
                /* Read the status bits */
-               sr_read_reg(sr_info, IRQSTATUS);
+               status = sr_read_reg(sr_info, IRQSTATUS);
 
                /* Clear them by writing back */
                sr_write_reg(sr_info, IRQSTATUS, status);
index e49fc7be2229badcd274038b7a308ce6def8c478..037b0d7d4e05b1b77f0d93035283484ce3ba1078 100644 (file)
@@ -408,14 +408,6 @@ static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)
        return ret;
 }
 
-struct omap_device_pm_latency omap2_dmtimer_latency[] = {
-       {
-               .deactivate_func = omap_device_idle_hwmods,
-               .activate_func   = omap_device_enable_hwmods,
-               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
-       },
-};
-
 /**
  * omap_timer_init - build and register timer device with an
  * associated timer hwmod
@@ -477,9 +469,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
        pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
 #endif
        pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
-                       omap2_dmtimer_latency,
-                       ARRAY_SIZE(omap2_dmtimer_latency),
-                       0);
+                                NULL, 0, 0);
 
        if (IS_ERR(pdev)) {
                pr_err("%s: Can't build omap_device for %s: %s.\n",
index 5224357721686dc41d5a703a3ba02ae1e1e7bf6a..10b20c652e5dc390026bc1eec5042ff351c387f4 100644 (file)
@@ -30,6 +30,7 @@
 #include <plat/usb.h>
 
 #include "twl-common.h"
+#include "pm.h"
 
 static struct i2c_board_info __initdata pmic_i2c_board_info = {
        .addr           = 0x48,
@@ -48,6 +49,16 @@ void __init omap_pmic_init(int bus, u32 clkrate,
        omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
 }
 
+void __init omap_pmic_late_init(void)
+{
+       /* Init the OMAP TWL parameters (if PMIC has been registerd) */
+       if (!pmic_i2c_board_info.irq)
+               return;
+
+       omap3_twl_init();
+       omap4_twl_init();
+}
+
 #if defined(CONFIG_ARCH_OMAP3)
 static struct twl4030_usb_data omap3_usb_pdata = {
        .usb_mode       = T2_USB_MODE_ULPI,
index 5e83a5bd37fb719dd06ea8deac01e0c3c2922e80..275dde8cb27aa789ce4d9bfa89c8ed92fb122711 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __OMAP_PMIC_COMMON__
 #define __OMAP_PMIC_COMMON__
 
+#include <plat/irqs.h>
+
 #define TWL_COMMON_PDATA_USB           (1 << 0)
 #define TWL_COMMON_PDATA_BCI           (1 << 1)
 #define TWL_COMMON_PDATA_MADC          (1 << 2)
@@ -30,6 +32,7 @@ struct twl4030_platform_data;
 
 void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
                    struct twl4030_platform_data *pmic_data);
+void omap_pmic_late_init(void);
 
 static inline void omap2_pmic_init(const char *pmic_type,
                                   struct twl4030_platform_data *pmic_data)
index 47fb5d607630678e6ce076ef9e311f3cdbb309b6..267975086a7b5b04a14fe2184c3ed02678f67ea4 100644 (file)
@@ -60,44 +60,6 @@ static struct musb_hdrc_platform_data musb_plat = {
 
 static u64 musb_dmamask = DMA_BIT_MASK(32);
 
-static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
-{
-       switch (board_data->interface_type) {
-       case MUSB_INTERFACE_UTMI:
-               omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT);
-               omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT);
-               break;
-       case MUSB_INTERFACE_ULPI:
-               omap_mux_init_signal("usba0_ulpiphy_clk",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_stp",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dir",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_nxt",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat0",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat1",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat2",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat3",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat4",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat5",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat6",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               omap_mux_init_signal("usba0_ulpiphy_dat7",
-                                               OMAP_PIN_INPUT_PULLDOWN);
-               break;
-       default:
-               break;
-       }
-}
-
 static struct omap_musb_board_data musb_default_board_data = {
        .interface_type         = MUSB_INTERFACE_ULPI,
        .mode                   = MUSB_OTG,
index 8dd26b765b7d3f3aa976d8907f6eb8d0b631b1d1..994d8f591a1d623b5afc3b7e2602e08636cf4a84 100644 (file)
@@ -8,11 +8,13 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/string.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 
 #include <linux/usb/musb.h>
 
index 64070ac1e761048caf85bf5fb4ebad2e06b85197..1f8fdf736e630976bc97fc781d58bfbf85704179 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
index 6c75cd35c4c836b5700c367c346db1b1f0c79bc7..b35e2005a348e6fbc4c960d83e0d2d0d75cf889f 100644 (file)
@@ -275,7 +275,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = {
                .partitions             = ts78xx_ts_nand_parts,
                .nr_partitions          = ARRAY_SIZE(ts78xx_ts_nand_parts),
                .chip_delay             = 15,
-               .options                = NAND_USE_FLASH_BBT,
+               .bbt_options            = NAND_BBT_USE_FLASH,
        },
        .ctrl   = {
                /*
index 8f2c234ed9d9bd7a59767562f896a9ec85005349..58d4ee3ae9499d062cd68e972596dbc6f0ffc521 100644 (file)
@@ -14,7 +14,7 @@
 
 #define UART_SHIFT 2
 
-               .macro  addruart, rp, rv
+               .macro  addruart, rp, rv, tmp
                ldr     \rv, =PHYS_TO_IO(PICOXCELL_UART1_BASE)
                ldr     \rp, =PICOXCELL_UART1_BASE
                .endm
index cb53160f6c5d3127b961edbf102e70ab34733712..26ebb57719df5d3fbf389e46cb723b92029b8191 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/suspend.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
index ef555c041962983814be50c03d606b91bcd15b0d..a12b689a87026c9e06af50351b2b20d8c7e01d7d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <asm/sizes.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <linux/of.h>
index fc0b8544e17455f27fb020cee143dbaee16123b2..4b81f59a4cbaf5aebbac8c1d55980d9b4dd45618 100644 (file)
@@ -307,7 +307,7 @@ static inline void balloon3_mmc_init(void) {}
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static void balloon3_udc_command(int cmd)
 {
        if (cmd == PXA2XX_UDC_CMD_CONNECT)
index 3a7387f93c387412cac3adc9c3129d645cc1997c..e096bba8fd57c231aaa0593c4b0efc19f2649e93 100644 (file)
@@ -424,8 +424,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = cm_x300_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(cm_x300_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = cm_x300_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(cm_x300_nand_partitions),
 };
 
 static void __init cm_x300_init_nand(void)
index 7db66465716f5bc7be2376831bf34b52cf0fdef9..05bfa1b1c001756b465731e5ac67fa0185ef79c5 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 692e1ffc558628526105f3b378f6ce745650480e..d23b92b80488257db2ef2bf4af458fc4060feaf8 100644 (file)
@@ -146,7 +146,7 @@ static void __init colibri_pxa320_init_eth(void)
 static inline void __init colibri_pxa320_init_eth(void) {}
 #endif /* CONFIG_AX88796 */
 
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = {
        .gpio_vbus              = mfp_to_gpio(MFP_PIN_GPIO96),
        .gpio_pullup            = -1,
index 3f9be419959da6356025a2b23a385a9e40db6ec7..2b8ca0de8a3d7369b4c133ad6c29796f2ca85d7e 100644 (file)
@@ -139,8 +139,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data colibri_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = colibri_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(colibri_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = colibri_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(colibri_nand_partitions),
 };
 
 void __init colibri_pxa3xx_init_nand(void)
index 3e9483b06053bcf28e5fd7e6b83a88fcc47775dc..549468d088b9e0e34336ef0b50a3551258b8c366 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mtd/sharpsl.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/module.h>
 #include <video/w100fb.h>
 
 #include <asm/setup.h>
index 8e697dd8accdf0f1898f60d65db7a2396629ef30..d82b7aa3c096eaf09f6b99d83953efad07bb07b4 100644 (file)
@@ -144,7 +144,7 @@ static struct clk_lookup eseries_clkregs[] = {
        INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"),
 };
 
-void eseries_register_clks(void)
+static void __init eseries_register_clks(void)
 {
        clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
 }
index be921965e91ae6c4c27c52bbd2abc8f98db89bff..b96949dd5adb30fb1592d23ccbdbdcc01d2cc888 100644 (file)
@@ -11,5 +11,4 @@ extern int eseries_tmio_resume(struct platform_device *dev);
 extern void eseries_get_tmio_gpios(void);
 extern struct resource eseries_tmio_resources[];
 extern struct platform_device e300_tc6387xb_device;
-extern void eseries_register_clks(void);
 
index 9c8208ca04150e4a3bbb2d41cccb28287a0efe99..ffdd70dad327dd135f1a2d5fc36a3cde45f2f86b 100644 (file)
@@ -106,7 +106,7 @@ static void __init gumstix_mmc_init(void)
 }
 #endif
 
-#ifdef CONFIG_USB_GADGET_PXA25X
+#ifdef CONFIG_USB_PXA25X
 static struct gpio_vbus_mach_info gumstix_udc_info = {
        .gpio_vbus              = GPIO_GUMSTIX_USB_GPIOn,
        .gpio_pullup            = GPIO_GUMSTIX_USB_GPIOx,
index 576868f8b8c547c68b4c6196402382afcd082ae0..41b4c93a96c2f56152f5cbd2cb6f160696273fed 100644 (file)
@@ -25,7 +25,7 @@
 #define GPIO_REGS_VIRT io_p2v(0x40E00000)
 
 #define BANK_OFF(n)    (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
-#define GPIO_REG(x)    (GPIO_REGS_VIRT + (x))
+#define GPIO_REG(x)    (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
 
 /* GPIO Pin Level Registers */
 #define GPLR0          GPIO_REG(BANK_OFF(0) + 0x00)
index f80bbe246afe5812b17db200d709b13f6160f72c..d4eac3d6ffb5ecd04df4abeb0ed45b32a2882705 100644 (file)
@@ -37,8 +37,8 @@ extern void __init palm27x_lcd_init(int power,
 #define palm27x_lcd_init(power, mode)  do {} while (0)
 #endif
 
-#if    defined(CONFIG_USB_GADGET_PXA27X) || \
-       defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if    defined(CONFIG_USB_PXA27X) || \
+       defined(CONFIG_USB_PXA27X_MODULE)
 extern void __init palm27x_udc_init(int vbus, int pullup,
                                        int vbus_inverted);
 #else
index 0037e57e0cec91386c178a03e624bcce2875b461..7b324ec6449f49553654d45b4aba900da01f23ed 100644 (file)
@@ -325,8 +325,9 @@ static struct mtd_partition littleton_nand_partitions[] = {
 
 static struct pxa3xx_nand_platform_data littleton_nand_info = {
        .enable_arbiter = 1,
-       .parts          = littleton_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(littleton_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = littleton_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(littleton_nand_partitions),
 };
 
 static void __init littleton_init_nand(void)
index b5a8fd3fce04cff4f5ad83f20c285f985eeb3c7e..90928d6e1a5bc05f3579c2901a2036eb34872aa3 100644 (file)
@@ -389,10 +389,11 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
 };
 
 static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
-       .enable_arbiter = 1,
-       .keep_config = 1,
-       .parts = mxm_8x10_nand_partitions,
-       .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
+       .enable_arbiter = 1,
+       .keep_config    = 1,
+       .num_cs         = 1,
+       .parts[0]       = mxm_8x10_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(mxm_8x10_nand_partitions)
 };
 
 static void __init mxm_8x10_nand_init(void)
index 325c245c0a0dd3916129b2875caaec931758137e..fbc10d7b95d1e8ef7ceec5dd03d512c7c2d314bf 100644 (file)
@@ -164,8 +164,8 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if    defined(CONFIG_USB_GADGET_PXA27X) || \
-       defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if    defined(CONFIG_USB_PXA27X) || \
+       defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info palm27x_udc_info = {
        .gpio_vbus_inverted     = 1,
 };
index 6ec7caefb37c8219d02f45fc0088249295006fa5..2c24c67fd92b6d863fc2e534b6ad9f15b7daaaf7 100644 (file)
@@ -338,7 +338,7 @@ static inline void palmtc_mkp_init(void) {}
 /******************************************************************************
  * UDC
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA25X)||defined(CONFIG_USB_GADGET_PXA25X_MODULE)
+#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
 static struct gpio_vbus_mach_info palmtc_udc_info = {
        .gpio_vbus              = GPIO_NR_PALMTC_USB_DETECT_N,
        .gpio_vbus_inverted     = 1,
index 948ce3e729fa738934de86654267f3933956c536..50c8331778668c66c97b4ff99b2b345e01efb999 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/fb.h>
 #include <linux/pm.h>
index 6810cddec9277d47d1cceeb61a5664f528cb4b67..f0c05f4d12ed5eb48715d8433665b20199bde3bd 100644 (file)
@@ -346,8 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
 static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
        .enable_arbiter = 1,
        .keep_config    = 1,
-       .parts          = raumfeld_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(raumfeld_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = raumfeld_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(raumfeld_nand_partitions),
 };
 
 /**
index d8dec9113aad8b0711e2d79f460013b6508b8e3a..953a9195f9e5bdd9850f62c2632c8f62c27fc9b2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
index 35bbf13724b9941a0171f90c8e78c036e9a5387a..1aaed2b17e102ef90adb4add2065b472a5d7fb76 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/fb.h>
index a7539a6ed1ff2a5d1ce4a460183a17fe28900e45..ca0c6615028c42aa0414cc2e76de4a0a29c83918 100644 (file)
@@ -343,7 +343,7 @@ static inline void vpac270_uhc_init(void) {}
 /******************************************************************************
  * USB Gadget
  ******************************************************************************/
-#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
 static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
        .gpio_vbus              = GPIO41_VPAC270_UDC_DETECT,
        .gpio_pullup            = -1,
index 31d4968918918909e0ab5e94d7259a0a87af0bc3..6c39c332841807325864e14c77cf0cfdc6bb2bc5 100644 (file)
@@ -366,8 +366,9 @@ static struct mtd_partition zylonite_nand_partitions[] = {
 
 static struct pxa3xx_nand_platform_data zylonite_nand_info = {
        .enable_arbiter = 1,
-       .parts          = zylonite_nand_partitions,
-       .nr_parts       = ARRAY_SIZE(zylonite_nand_partitions),
+       .num_cs         = 1,
+       .parts[0]       = zylonite_nand_partitions,
+       .nr_parts[0]    = ARRAY_SIZE(zylonite_nand_partitions),
 };
 
 static void __init zylonite_init_nand(void)
index 3700cf32af0f4c95b0c7711b08d6768330ef1af0..5261a7ed09991fd9feba227432a851e22ec2bb59 100644 (file)
@@ -6,7 +6,6 @@ config CPU_S3C2410
        bool
        depends on ARCH_S3C2410
        select CPU_ARM920T
-       select S3C_GPIO_PULL_UP
        select S3C2410_CLOCK
        select CPU_LLSERIAL_S3C2410
        select S3C2410_PM if PM
index eee0654eb8fbadca38e477c306a594c95ba4f6f5..a957bc8ed44f3f60121414e38fd62c1bf76fe72a 100644 (file)
@@ -1,74 +1 @@
-/* arch/arm/mach-s3c2410/include/mach/fb.h
- *
- * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * Inspired by pxafb.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARM_FB_H
-#define __ASM_ARM_FB_H
-
-#include <mach/regs-lcd.h>
-
-struct s3c2410fb_hw {
-       unsigned long   lcdcon1;
-       unsigned long   lcdcon2;
-       unsigned long   lcdcon3;
-       unsigned long   lcdcon4;
-       unsigned long   lcdcon5;
-};
-
-/* LCD description */
-struct s3c2410fb_display {
-       /* LCD type */
-       unsigned type;
-
-       /* Screen size */
-       unsigned short width;
-       unsigned short height;
-
-       /* Screen info */
-       unsigned short xres;
-       unsigned short yres;
-       unsigned short bpp;
-
-       unsigned pixclock;              /* pixclock in picoseconds */
-       unsigned short left_margin;  /* value in pixels (TFT) or HCLKs (STN) */
-       unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
-       unsigned short hsync_len;    /* value in pixels (TFT) or HCLKs (STN) */
-       unsigned short upper_margin;    /* value in lines (TFT) or 0 (STN) */
-       unsigned short lower_margin;    /* value in lines (TFT) or 0 (STN) */
-       unsigned short vsync_len;       /* value in lines (TFT) or 0 (STN) */
-
-       /* lcd configuration registers */
-       unsigned long   lcdcon5;
-};
-
-struct s3c2410fb_mach_info {
-
-       struct s3c2410fb_display *displays;     /* attached diplays info */
-       unsigned num_displays;                  /* number of defined displays */
-       unsigned default_display;
-
-       /* GPIOs */
-
-       unsigned long   gpcup;
-       unsigned long   gpcup_mask;
-       unsigned long   gpccon;
-       unsigned long   gpccon_mask;
-       unsigned long   gpdup;
-       unsigned long   gpdup_mask;
-       unsigned long   gpdcon;
-       unsigned long   gpdcon_mask;
-
-       /* lpc3600 control register */
-       unsigned long   lpcsel;
-};
-
-extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
-
-#endif /* __ASM_ARM_FB_H */
+#include <plat/fb-s3c2410.h>
index bab1392017614bc964a6586f92af65287b7b8e7a..c53ad34c6579d53bef8c2acb9fc8e614133521c0 100644 (file)
@@ -1,98 +1 @@
-/* arch/arm/mach-s3c2410/include/mach/gpio-fns.h
- *
- * Copyright (c) 2003-2009 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - hardware
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __MACH_GPIO_FNS_H
-#define __MACH_GPIO_FNS_H __FILE__
-
-/* These functions are in the to-be-removed category and it is strongly
- * encouraged not to use these in new code. They will be marked deprecated
- * very soon.
- *
- * Most of the functionality can be either replaced by the gpiocfg calls
- * for the s3c platform or by the generic GPIOlib API.
- *
- * As of 2.6.35-rc, these will be removed, with the few drivers using them
- * either replaced or given a wrapper until the calls can be removed.
-*/
-
-#include <plat/gpio-cfg.h>
-
-static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
-{
-       /* 1:1 mapping between cfgpin and setcfg calls at the moment */
-       s3c_gpio_cfgpin(pin, cfg);
-}
-
-/* external functions for GPIO support
- *
- * These allow various different clients to access the same GPIO
- * registers without conflicting. If your driver only owns the entire
- * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
-*/
-
-extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
-
-/* s3c2410_gpio_getirq
- *
- * turn the given pin number into the corresponding IRQ number
- *
- * returns:
- *     < 0 = no interrupt for this pin
- *     >=0 = interrupt number for the pin
-*/
-
-extern int s3c2410_gpio_getirq(unsigned int pin);
-
-/* s3c2410_gpio_irqfilter
- *
- * set the irq filtering on the given pin
- *
- * on = 0 => disable filtering
- *      1 => enable filtering
- *
- * config = S3C2410_EINTFLT_PCLK or S3C2410_EINTFLT_EXTCLK orred with
- *          width of filter (0 through 63)
- *
- *
-*/
-
-extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
-                                 unsigned int config);
-
-/* s3c2410_gpio_pullup
- *
- * This call should be replaced with s3c_gpio_setpull().
- *
- * As a note, there is currently no distinction between pull-up and pull-down
- * in the s3c24xx series devices with only an on/off configuration.
- */
-
-/* s3c2410_gpio_pullup
- *
- * configure the pull-up control on the given pin
- *
- * to = 1 => disable the pull-up
- *      0 => enable the pull-up
- *
- * eg;
- *
- *   s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
- *   s3c2410_gpio_pullup(S3C2410_GPE(8), 0);
-*/
-
-extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
-
-extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
-
-extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
-
-#endif /* __MACH_GPIO_FNS_H */
+#include <plat/gpio-fns.h>
index 4f7bf3272e8730fa6d108870edce120abe49c17e..019ea86057f69b4b7e383a3f871c13fb4d5fba0f 100644 (file)
@@ -53,7 +53,7 @@
 #define S3C2410_GPIO_M_NR      (32)    /* technically 2. */
 
 #if CONFIG_S3C_GPIO_SPACE != 0
-#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
+#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment
 #endif
 
 #define S3C2410_GPIO_NEXT(__gpio) \
index d67819dde42a11cba9ab5bb6c1abb89ae14f189d..c410a078622ce62efc89bc8b4b2114b7c31a613c 100644 (file)
 
 #include <mach/regs-gpio.h>
 
-extern struct s3c_gpio_chip s3c24xx_gpios[];
+extern struct samsung_gpio_chip s3c24xx_gpios[];
 
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
+static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
 {
-       struct s3c_gpio_chip *chip;
+       struct samsung_gpio_chip *chip;
 
        if (pin > S3C_GPIO_END)
                return NULL;
index e5a68ea131138637e715628eb2ab01cfd00dc115..e53b2177319e701cdb44e8f479e2de62282e826d 100644 (file)
 #define IRQ_LCD_SYSTEM         IRQ_S3C2443_LCD2
 
 #ifdef CONFIG_CPU_S3C2440
-#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
+#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97
 #else
-#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
+#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97
 #endif
 
 /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
index 4cf495f813a70da5380d2abb09e63718cbd3fc21..78ae807f1281e6a250cfab6b440428c4283ed7fa 100644 (file)
 #define S3C24XX_PA_RTC      S3C2410_PA_RTC
 #define S3C24XX_PA_ADC      S3C2410_PA_ADC
 #define S3C24XX_PA_SPI      S3C2410_PA_SPI
+#define S3C24XX_PA_SPI1                (S3C2410_PA_SPI + S3C2410_SPI1)
 #define S3C24XX_PA_SDI      S3C2410_PA_SDI
 #define S3C24XX_PA_NAND            S3C2410_PA_NAND
 
index 45eea5210c87d55a76c34b752fdf20954c8e7df0..2eef7e6f76758497094c1b0fe8865b0ee34cda2a 100644 (file)
@@ -64,4 +64,4 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
 }
 
 static inline void s3c_pm_restored_gpios(void) { }
-static inline void s3c_pm_saved_gpios(void) { }
+static inline void samsung_pm_saved_gpios(void) { }
index 5e06c72658358ef3d263b84e61766635b03c37b3..c3feff3c0488156fd1c89d833e7f979371e46229 100644 (file)
@@ -65,6 +65,7 @@
 #define S3C2443_CLKDIV0_PREDIV_MASK    (3<<4)
 #define S3C2443_CLKDIV0_PREDIV_SHIFT   (4)
 
+#define S3C2416_CLKDIV0_ARMDIV_MASK    (7 << 9)
 #define S3C2443_CLKDIV0_ARMDIV_MASK    (15<<9)
 #define S3C2443_CLKDIV0_ARMDIV_SHIFT   (9)
 #define S3C2443_CLKDIV0_ARMDIV_1       (0<<9)
 #define S3C2443_PCLKCON_UART3          (1<<3)
 #define S3C2443_PCLKCON_IIC            (1<<4)
 #define S3C2443_PCLKCON_SDI            (1<<5)
+#define S3C2443_PCLKCON_HSSPI          (1<<6)
 #define S3C2443_PCLKCON_ADC            (1<<7)
 #define S3C2443_PCLKCON_AC97           (1<<8)
 #define S3C2443_PCLKCON_IIS            (1<<9)
index 556c535829f02c7f7286d3d4f3a6a5dc146d8c38..05a7d16e59f501214dd89d05f6b66eb87db22fdd 100644 (file)
@@ -35,6 +35,7 @@
 #include <video/platform_lcd.h>
 
 #include <linux/mmc/host.h>
+#include <linux/export.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -696,9 +697,9 @@ static void __init h1940_init(void)
                              S3C2410_MISCCR_USBSUSPND0 |
                              S3C2410_MISCCR_USBSUSPND1, 0x0);
 
-       tmp =   (0x78 << S3C24XX_PLLCON_MDIVSHIFT)
-             | (0x02 << S3C24XX_PLLCON_PDIVSHIFT)
-             | (0x03 << S3C24XX_PLLCON_SDIVSHIFT);
+       tmp =   (0x78 << S3C24XX_PLL_MDIV_SHIFT)
+             | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
+             | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
        writel(tmp, S3C2410_UPLLCON);
 
        gpio_request(S3C2410_GPC(0), "LCD power");
index 367d376deb96ec2ea80c9b5029ac0f2c32a4066a..45185215625415f0040c8b211d5b11e57a468144 100644 (file)
@@ -49,6 +49,7 @@
 
 #include <mach/regs-gpio.h>
 #include <mach/leds-gpio.h>
+#include <mach/regs-lcd.h>
 #include <plat/regs-serial.h>
 #include <mach/fb.h>
 #include <plat/nand.h>
index 343a540d86a988d4d55a54b8dea79c87eb876ef7..3d7ebc557a723aa3446b5a6287e8d446d254274f 100644 (file)
@@ -72,8 +72,8 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
 void __init s3c2410_map_io(void)
 {
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
 
        iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
new file mode 100644 (file)
index 0000000..4526f6b
--- /dev/null
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s3c2412/gpio.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * S3C2412/S3C2413 specific GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/hardware.h>
+
+#include <plat/gpio-core.h>
+
+int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
+       unsigned long flags;
+       unsigned long slpcon;
+
+       offs *= 2;
+
+       if (pin < S3C2410_GPB(0))
+               return -EINVAL;
+
+       if (pin >= S3C2410_GPF(0) &&
+           pin <= S3C2410_GPG(16))
+               return -EINVAL;
+
+       if (pin > S3C2410_GPH(16))
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       slpcon = __raw_readl(chip->base + 0x0C);
+
+       slpcon &= ~(3 << offs);
+       slpcon |= state << offs;
+
+       __raw_writel(slpcon, chip->base + 0x0C);
+
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg);
index 69b48a7d1dbdb4502d55d103bb1fa382def5538e..84c7b03e5a306b239d851ad67b967fda1f30719b 100644 (file)
@@ -13,7 +13,6 @@ config CPU_S3C2416
        select CPU_ARM926T
        select S3C2416_DMA if S3C2410_DMA
        select CPU_LLSERIAL_S3C2440
-       select S3C_GPIO_PULL_UPDOWN
        select SAMSUNG_CLKSRC
        select S3C2443_CLOCK
        help
index 21a5e81f0ab570460ba67c99fd017c32df566838..afbbe8bc21d14dd7a93e5acd5d359c1175d04e26 100644 (file)
@@ -21,7 +21,6 @@
 #include <plat/cpu.h>
 
 #include <plat/cpu-freq.h>
-#include <plat/pll6553x.h>
 #include <plat/pll.h>
 
 #include <asm/mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-s3c2443-clock.h>
 
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
+*/
+
 static unsigned int armdiv[8] = {
        [0] = 1,
        [1] = 2,
@@ -38,6 +45,32 @@ static unsigned int armdiv[8] = {
        [7] = 8,
 };
 
+static struct clksrc_clk hsspi_eplldiv = {
+       .clk = {
+               .name   = "hsspi-eplldiv",
+               .parent = &clk_esysclk.clk,
+               .ctrlbit = (1 << 14),
+               .enable = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 },
+};
+
+static struct clk *hsspi_sources[] = {
+       [0] = &hsspi_eplldiv.clk,
+       [1] = NULL, /* to fix */
+};
+
+static struct clksrc_clk hsspi_mux = {
+       .clk    = {
+               .name   = "hsspi-if",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = hsspi_sources,
+               .nr_sources = ARRAY_SIZE(hsspi_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 },
+};
+
 static struct clksrc_clk hsmmc_div[] = {
        [0] = {
                .clk = {
@@ -100,20 +133,15 @@ static struct clk hsmmc0_clk = {
        .ctrlbit        = S3C2416_HCLKCON_HSMMC0,
 };
 
-static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
-{
-       clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
-
-       return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
-}
-
 void __init_or_cpufreq s3c2416_setup_clocks(void)
 {
-       s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+       s3c2443_common_setup_clocks(s3c2416_get_pll);
 }
 
 
 static struct clksrc_clk *clksrcs[] __initdata = {
+       &hsspi_eplldiv,
+       &hsspi_mux,
        &hsmmc_div[0],
        &hsmmc_div[1],
        &hsmmc_mux[0],
@@ -131,7 +159,9 @@ void __init s3c2416_init_clocks(int xtal)
 
        clk_epll.parent = &clk_epllref.clk;
 
-       s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+       s3c2443_common_init_clocks(xtal, s3c2416_get_pll,
+                                  armdiv, ARRAY_SIZE(armdiv),
+                                  S3C2416_CLKDIV0_ARMDIV_MASK);
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_register_clksrc(clksrcs[ptr], 1);
index 20b3fdfb3051fb7533ec67cee9b5659b13dfda22..ee214bc83c8352a0e520401a5013dd01fe13a04f 100644 (file)
@@ -60,6 +60,7 @@
 #include <plat/iic-core.h>
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
+#include <plat/adc-core.h>
 
 static struct map_desc s3c2416_iodesc[] __initdata = {
        IODESC_ENT(WATCHDOG),
@@ -97,6 +98,8 @@ int __init s3c2416_init(void)
 
        s3c_fb_setname("s3c2443-fb");
 
+       s3c_adc_setname("s3c2416-adc");
+
 #ifdef CONFIG_PM
        register_syscore_ops(&s3c2416_pm_syscore_ops);
 #endif
@@ -120,8 +123,8 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
 void __init s3c2416_map_io(void)
 {
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
+       s3c24xx_gpiocfg_default.set_pull = samsung_gpio_setpull_updown;
+       s3c24xx_gpiocfg_default.get_pull = samsung_gpio_getpull_updown;
 
        /* initialize device information early */
        s3c2416_default_sdhci0();
index ed34fad8f2c6a4362712ecbb263480c1eb497736..cee53955eb027ee9ea4d7fc8c6ae9e03adc196ad 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
@@ -32,30 +22,3 @@ char *s3c2416_hsmmc_clksrcs[4] = {
        [2] = "hsmmc-if",
        /* [3] = "48m", - note not successfully used yet */
 };
-
-void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
-                                 void __iomem *r,
-                                 struct mmc_ios *ios,
-                                 struct mmc_card *card)
-{
-       u32 ctrl2, ctrl3;
-
-       ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2);
-       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-                 S3C_SDHCI_CTRL2_ENFBCLKRX |
-                 S3C_SDHCI_CTRL2_DFCNT_NONE |
-                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-       if (ios->clock < 25 * 1000000)
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-                        S3C_SDHCI_CTRL3_FCSEL2 |
-                        S3C_SDHCI_CTRL3_FCSEL1 |
-                        S3C_SDHCI_CTRL3_FCSEL0);
-       else
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-       __raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-       __raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
index c461fb8e15c02db73448dbfabbb25c4cb46661f5..914e620f1257a75d808077d41d91599466119a58 100644 (file)
@@ -5,7 +5,6 @@
 config CPU_S3C2440
        bool
        select CPU_ARM920T
-       select S3C_GPIO_PULL_UP
        select S3C2410_CLOCK
        select S3C2410_PM if PM
        select S3C2440_DMA if S3C2410_DMA
@@ -17,7 +16,6 @@ config CPU_S3C2440
 config CPU_S3C2442
        bool
        select CPU_ARM920T
-       select S3C_GPIO_PULL_DOWN
        select S3C2410_CLOCK
        select S3C2410_PM if PM
        select CPU_S3C244X
index 684dbb3567f5a251001d81f0e8df0241d9d76dbb..0d3453bf567c29e85290774973bd19e0a59b5d89 100644 (file)
@@ -43,6 +43,7 @@
 
 #include <mach/regs-gpio.h>
 #include <mach/regs-gpioj.h>
+#include <mach/regs-lcd.h>
 #include <mach/h1940.h>
 #include <mach/fb.h>
 
index 2270d3360216abffa913fcbdfff19384a300e558..37f8cc6aabd4636ba5d8166e93ba473c204978cc 100644 (file)
@@ -70,6 +70,6 @@ void __init s3c2440_map_io(void)
 {
        s3c244x_map_io();
 
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1up;
 }
index 6f2b65e6e06868ba96bc27df27dfec5643eac254..2c822e09392f7a00e4bf935f055f16a40eb80303 100644 (file)
@@ -182,6 +182,6 @@ void __init s3c2442_map_io(void)
 {
        s3c244x_map_io();
 
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down;
+       s3c24xx_gpiocfg_default.set_pull = s3c24xx_gpio_setpull_1down;
+       s3c24xx_gpiocfg_default.get_pull = s3c24xx_gpio_getpull_1down;
 }
index d8eb86823df7b92a3027bcd384cebbb0e6941a3f..8814031516ce2de3f15e5d7757b3579df5169763 100644 (file)
@@ -10,7 +10,6 @@ config CPU_S3C2443
        select CPU_LLSERIAL_S3C2440
        select SAMSUNG_CLKSRC
        select S3C2443_CLOCK
-       select S3C_GPIO_PULL_S3C2443
        help
          Support for the S3C2443 SoC from the S3C24XX line
 
index 38058af48972d7cf10409885b6e7578032a94d90..1c2c088aa2e8dc9c6d743d54a9f655e33e25a9d6 100644 (file)
 
 /* clock selections */
 
-static struct clk clk_i2s_ext = {
-       .name           = "i2s-ext",
-};
-
 /* armdiv
  *
  * this clock is sourced from msysclk and can have a number of
  * divider values applied to it to then be fed into armclk.
+ * The real clock definition is done in s3c2443-clock.c,
+ * only the armdiv divisor table must be defined here.
 */
 
-/* armdiv divisor table */
-
 static unsigned int armdiv[16] = {
        [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 1,
        [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]      = 2,
@@ -80,92 +76,6 @@ static unsigned int armdiv[16] = {
        [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]     = 16,
 };
 
-static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
-{
-       clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
-
-       return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
-}
-
-static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
-                                             unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       unsigned long calc;
-       unsigned best = 256; /* bigger than any value */
-       unsigned div;
-       int ptr;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
-               div = armdiv[ptr];
-               calc = parent / div;
-               if (calc <= rate && div < best)
-                       best = div;
-       }
-
-       return parent / best;
-}
-
-static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent = clk_get_rate(clk->parent);
-       unsigned long calc;
-       unsigned div;
-       unsigned best = 256; /* bigger than any value */
-       int ptr;
-       int val = -1;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
-               div = armdiv[ptr];
-               calc = parent / div;
-               if (calc <= rate && div < best) {
-                       best = div;
-                       val = ptr;
-               }
-       }
-
-       if (val >= 0) {
-               unsigned long clkcon0;
-
-               clkcon0 = __raw_readl(S3C2443_CLKDIV0);
-               clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK;
-               clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
-               __raw_writel(clkcon0, S3C2443_CLKDIV0);
-       }
-
-       return (val == -1) ? -EINVAL : 0;
-}
-
-static struct clk clk_armdiv = {
-       .name           = "armdiv",
-       .parent         = &clk_msysclk.clk,
-       .ops            = &(struct clk_ops) {
-               .round_rate = s3c2443_armclk_roundrate,
-               .set_rate = s3c2443_armclk_setrate,
-       },
-};
-
-/* armclk
- *
- * this is the clock fed into the ARM core itself, from armdiv or from hclk.
- */
-
-static struct clk *clk_arm_sources[] = {
-       [0] = &clk_armdiv,
-       [1] = &clk_h,
-};
-
-static struct clksrc_clk clk_arm = {
-       .clk    = {
-               .name           = "armclk",
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_arm_sources,
-               .nr_sources = ARRAY_SIZE(clk_arm_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
-};
-
 /* hsspi
  *
  * high-speed spi clock, sourced from esysclk
@@ -173,7 +83,7 @@ static struct clksrc_clk clk_arm = {
 
 static struct clksrc_clk clk_hsspi = {
        .clk    = {
-               .name           = "hsspi",
+               .name           = "hsspi-if",
                .parent         = &clk_esysclk.clk,
                .ctrlbit        = S3C2443_SCLKCON_HSSPICLK,
                .enable         = s3c2443_clkcon_enable_s,
@@ -235,48 +145,6 @@ static struct clk clk_hsmmc = {
        },
 };
 
-/* i2s_eplldiv
- *
- * This clock is the output from the I2S divisor of ESYSCLK, and is separate
- * from the mux that comes after it (cannot merge into one single clock)
-*/
-
-static struct clksrc_clk clk_i2s_eplldiv = {
-       .clk    = {
-               .name           = "i2s-eplldiv",
-               .parent         = &clk_esysclk.clk,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
-};
-
-/* i2s-ref
- *
- * i2s bus reference clock, selectable from external, esysclk or epllref
- *
- * Note, this used to be two clocks, but was compressed into one.
-*/
-
-struct clk *clk_i2s_srclist[] = {
-       [0] = &clk_i2s_eplldiv.clk,
-       [1] = &clk_i2s_ext,
-       [2] = &clk_epllref.clk,
-       [3] = &clk_epllref.clk,
-};
-
-static struct clksrc_clk clk_i2s = {
-       .clk    = {
-               .name           = "i2s-if",
-               .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
-               .enable         = s3c2443_clkcon_enable_s,
-
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_i2s_srclist,
-               .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
-};
-
 /* standard clock definitions */
 
 static struct clk init_clocks_off[] = {
@@ -285,11 +153,6 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_p,
                .enable         = s3c2443_clkcon_enable_p,
                .ctrlbit        = S3C2443_PCLKCON_SDI,
-       }, {
-               .name           = "iis",
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_IIS,
        }, {
                .name           = "spi",
                .devname        = "s3c2410-spi.0",
@@ -305,27 +168,20 @@ static struct clk init_clocks_off[] = {
        }
 };
 
-static struct clk init_clocks[] = {
-};
-
 /* clocks to add straight away */
 
 static struct clksrc_clk *clksrcs[] __initdata = {
-       &clk_arm,
-       &clk_i2s_eplldiv,
-       &clk_i2s,
        &clk_hsspi,
        &clk_hsmmc_div,
 };
 
 static struct clk *clks[] __initdata = {
        &clk_hsmmc,
-       &clk_armdiv,
 };
 
 void __init_or_cpufreq s3c2443_setup_clocks(void)
 {
-       s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
+       s3c2443_common_setup_clocks(s3c2443_get_mpll);
 }
 
 void __init s3c2443_init_clocks(int xtal)
@@ -336,7 +192,9 @@ void __init s3c2443_init_clocks(int xtal)
        clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
        clk_epll.parent = &clk_epllref.clk;
 
-       s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
+       s3c2443_common_init_clocks(xtal, s3c2443_get_mpll,
+                                  armdiv, ARRAY_SIZE(armdiv),
+                                  S3C2443_CLKDIV0_ARMDIV_MASK);
 
        s3c2443_setup_clocks();
 
@@ -345,10 +203,6 @@ void __init s3c2443_init_clocks(int xtal)
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_register_clksrc(clksrcs[ptr], 1);
 
-       /* register clocks from clock array */
-
-       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
        /* We must be careful disabling the clocks we are not intending to
         * be using at boot time, as subsystems such as the LCD which do
         * their own DMA requests to the bus can cause the system to lockup
index e6a28ba52c7d16f9c8468a4f186bcdf3296b8eb5..a22b771b0f36c4c05ab9429fab4aea4ad14f4729 100644 (file)
@@ -41,6 +41,7 @@
 #include <plat/cpu.h>
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
+#include <plat/adc-core.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
        IODESC_ENT(WATCHDOG),
@@ -70,6 +71,8 @@ int __init s3c2443_init(void)
        s3c_nand_setname("s3c2412-nand");
        s3c_fb_setname("s3c2443-fb");
 
+       s3c_adc_setname("s3c2443-adc");
+
        /* change WDT IRQ number */
        s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
        s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
@@ -90,8 +93,8 @@ void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
 void __init s3c2443_map_io(void)
 {
-       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_s3c2443;
-       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_s3c2443;
+       s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull;
+       s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull;
 
        iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
 }
index f057b6ae4f905d65f9f837cceebf3e0c573bfd74..5552e048c2be510608bd6fbd1f1418c9e5ab74a7 100644 (file)
@@ -288,5 +288,6 @@ config MACH_WLF_CRAGG_6410
        select S3C_DEV_RTC
        select S3C64XX_DEV_SPI
        select S3C24XX_GPIO_EXTRA128
+       select I2C
        help
          Machine support for the Wolfson Cragganmore S3C6410 variant.
index 61b4034a0c224d24ea95a135487be42ecae112dc..cfc0b9941808e9ed4e80f183cfe193e927ebc7ae 100644 (file)
@@ -13,7 +13,6 @@ obj-                          :=
 # Core files
 obj-y                          += cpu.o
 obj-y                          += clock.o
-obj-y                          += gpiolib.o
 
 # Core support for S3C6400 system
 
@@ -55,12 +54,10 @@ obj-$(CONFIG_MACH_HMT)              += mach-hmt.o
 obj-$(CONFIG_MACH_SMARTQ)      += mach-smartq.o
 obj-$(CONFIG_MACH_SMARTQ5)     += mach-smartq5.o
 obj-$(CONFIG_MACH_SMARTQ7)     += mach-smartq7.o
-obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o
+obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o
 
 # device support
 
 obj-y                          += dev-uart.o
 obj-y                          += dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
-obj-$(CONFIG_S3C64XX_DEV_TS)   += dev-ts.o
-obj-$(CONFIG_S3C64XX_DEV_ONENAND1)     += dev-onenand1.o
index 8cf39e33579e3bb9c7d30eceb6afcaa5914e6d2c..39c238d7a3dc5a9eff3272aa84609c88f3f84465 100644 (file)
 
 #include <mach/regs-sys.h>
 #include <mach/regs-clock.h>
-#include <mach/pll.h>
 
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/cpu-freq.h>
 #include <plat/clock.h>
 #include <plat/clock-clksrc.h>
+#include <plat/pll.h>
 
 /* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
  * ext_xtal_mux for want of an actual name from the manual.
@@ -735,7 +735,8 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
        /* For now assume the mux always selects the crystal */
        clk_ext_xtal_mux.parent = xtal_clk;
 
-       epll = s3c6400_get_epll(xtal);
+       epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0),
+                               __raw_readl(S3C_EPLL_CON1));
        mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
        apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
 
@@ -744,7 +745,13 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
        printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
               apll, mpll, epll);
 
-       hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+       if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL)
+               /* Synchronous mode */
+               hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+       else
+               /* Asynchronous mode */
+               hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+
        hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
        pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
 
index c7047838e1122adaa9916b21cb870c2c11068ae7..de085b798aa47572ba6827dff79dd82b5d395809 100644 (file)
@@ -34,8 +34,8 @@
 #include <plat/devs.h>
 #include <plat/clock.h>
 
-#include <mach/s3c6400.h>
-#include <mach/s3c6410.h>
+#include <plat/s3c6400.h>
+#include <plat/s3c6410.h>
 
 /* table of supported CPUs */
 
index cad67022fa2577330663ec035a1a96ea36c7e1de..93470b158a4eec73a4cd621e38b4be6b50344c94 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 
 #include <mach/irqs.h>
 #include <mach/map.h>
diff --git a/arch/arm/mach-s3c64xx/dev-onenand1.c b/arch/arm/mach-s3c64xx/dev-onenand1.c
deleted file mode 100644 (file)
index 999f9e1..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * linux/arch/arm/mach-s3c64xx/dev-onenand1.c
- *
- *  Copyright (c) 2008-2010 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S3C64XX series device definition for OneNAND devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c64xx_onenand1_resources[] = {
-       [0] = {
-               .start  = S3C64XX_PA_ONENAND1,
-               .end    = S3C64XX_PA_ONENAND1 + 0x400 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = S3C64XX_PA_ONENAND1_BUF,
-               .end    = S3C64XX_PA_ONENAND1_BUF + S3C64XX_SZ_ONENAND1_BUF - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start  = IRQ_ONENAND1,
-               .end    = IRQ_ONENAND1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c64xx_device_onenand1 = {
-       .name           = "samsung-onenand",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(s3c64xx_onenand1_resources),
-       .resource       = s3c64xx_onenand1_resources,
-};
-
-void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
-{
-       s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
-                        &s3c64xx_device_onenand1);
-}
index 5e6b42089eb44d7048b39cc2855403cd44cc0ddc..3341fd118723ff11cc7a21df95241c1252c2f6a0 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
index 67c97fab62fde2c4956e47ba6e0f79f96b159103..17d62f4f8204a2c551903914f5e5df4588e79fa4 100644 (file)
@@ -740,7 +740,7 @@ static int __init s3c64xx_dma_init(void)
        }
 
        /* Set all DMA configuration to be DMA, not SDMA */
-       writel(0xffffff, S3C_SYSREG(0x110));
+       writel(0xffffff, S3C64XX_SDMA_SEL);
 
        /* Register standard DMA controllers */
        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 (file)
index 92b0908..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/* arch/arm/plat-s3c64xx/gpiolib.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - GPIOlib support 
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <mach/regs-gpio.h>
-
-/* GPIO bank summary:
- *
- * Bank        GPIOs   Style   SlpCon  ExtInt Group
- * A   8       4Bit    Yes     1
- * B   7       4Bit    Yes     1
- * C   8       4Bit    Yes     2
- * D   5       4Bit    Yes     3
- * E   5       4Bit    Yes     None
- * F   16      2Bit    Yes     4 [1]
- * G   7       4Bit    Yes     5
- * H   10      4Bit[2] Yes     6
- * I   16      2Bit    Yes     None
- * J   12      2Bit    Yes     None
- * K   16      4Bit[2] No      None
- * L   15      4Bit[2] No      None
- * M   6       4Bit    No      IRQ_EINT
- * N   16      2Bit    No      IRQ_EINT
- * O   16      2Bit    Yes     7
- * P   15      2Bit    Yes     8
- * Q   9       2Bit    Yes     9
- *
- * [1] BANKF pins 14,15 do not form part of the external interrupt sources
- * [2] BANK has two control registers, GPxCON0 and GPxCON1
- */
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
-       .cfg_eint       = 7,
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
-       .cfg_eint       = 3,
-       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
-{
-       return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit[] = {
-       {
-               .base   = S3C64XX_GPA_BASE,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPA(0),
-                       .ngpio  = S3C64XX_GPIO_A_NR,
-                       .label  = "GPA",
-               },
-       }, {
-               .base   = S3C64XX_GPB_BASE,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPB(0),
-                       .ngpio  = S3C64XX_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .base   = S3C64XX_GPC_BASE,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPC(0),
-                       .ngpio  = S3C64XX_GPIO_C_NR,
-                       .label  = "GPC",
-               },
-       }, {
-               .base   = S3C64XX_GPD_BASE,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPD(0),
-                       .ngpio  = S3C64XX_GPIO_D_NR,
-                       .label  = "GPD",
-               },
-       }, {
-               .base   = S3C64XX_GPE_BASE,
-               .config = &gpio_4bit_cfg_noint,
-               .chip   = {
-                       .base   = S3C64XX_GPE(0),
-                       .ngpio  = S3C64XX_GPIO_E_NR,
-                       .label  = "GPE",
-               },
-       }, {
-               .base   = S3C64XX_GPG_BASE,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPG(0),
-                       .ngpio  = S3C64XX_GPIO_G_NR,
-                       .label  = "GPG",
-               },
-       }, {
-               .base   = S3C64XX_GPM_BASE,
-               .config = &gpio_4bit_cfg_eint0011,
-               .chip   = {
-                       .base   = S3C64XX_GPM(0),
-                       .ngpio  = S3C64XX_GPIO_M_NR,
-                       .label  = "GPM",
-                       .to_irq = s3c64xx_gpio2int_gpm,
-               },
-       },
-};
-
-static int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
-{
-       return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
-}
-
-static struct s3c_gpio_chip gpio_4bit2[] = {
-       {
-               .base   = S3C64XX_GPH_BASE + 0x4,
-               .config = &gpio_4bit_cfg_eint0111,
-               .chip   = {
-                       .base   = S3C64XX_GPH(0),
-                       .ngpio  = S3C64XX_GPIO_H_NR,
-                       .label  = "GPH",
-               },
-       }, {
-               .base   = S3C64XX_GPK_BASE + 0x4,
-               .config = &gpio_4bit_cfg_noint,
-               .chip   = {
-                       .base   = S3C64XX_GPK(0),
-                       .ngpio  = S3C64XX_GPIO_K_NR,
-                       .label  = "GPK",
-               },
-       }, {
-               .base   = S3C64XX_GPL_BASE + 0x4,
-               .config = &gpio_4bit_cfg_eint0011,
-               .chip   = {
-                       .base   = S3C64XX_GPL(0),
-                       .ngpio  = S3C64XX_GPIO_L_NR,
-                       .label  = "GPL",
-                       .to_irq = s3c64xx_gpio2int_gpl,
-               },
-       },
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c24xx,
-       .get_config     = s3c_gpio_getcfg_s3c24xx,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
-       .cfg_eint       = 2,
-       .set_config     = s3c_gpio_setcfg_s3c24xx,
-       .get_config     = s3c_gpio_getcfg_s3c24xx,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
-       .cfg_eint       = 3,
-       .set_config     = s3c_gpio_setcfg_s3c24xx,
-       .get_config     = s3c_gpio_getcfg_s3c24xx,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_chip gpio_2bit[] = {
-       {
-               .base   = S3C64XX_GPF_BASE,
-               .config = &gpio_2bit_cfg_eint11,
-               .chip   = {
-                       .base   = S3C64XX_GPF(0),
-                       .ngpio  = S3C64XX_GPIO_F_NR,
-                       .label  = "GPF",
-               },
-       }, {
-               .base   = S3C64XX_GPI_BASE,
-               .config = &gpio_2bit_cfg_noint,
-               .chip   = {
-                       .base   = S3C64XX_GPI(0),
-                       .ngpio  = S3C64XX_GPIO_I_NR,
-                       .label  = "GPI",
-               },
-       }, {
-               .base   = S3C64XX_GPJ_BASE,
-               .config = &gpio_2bit_cfg_noint,
-               .chip   = {
-                       .base   = S3C64XX_GPJ(0),
-                       .ngpio  = S3C64XX_GPIO_J_NR,
-                       .label  = "GPJ",
-               },
-       }, {
-               .base   = S3C64XX_GPN_BASE,
-               .irq_base = IRQ_EINT(0),
-               .config = &gpio_2bit_cfg_eint10,
-               .chip   = {
-                       .base   = S3C64XX_GPN(0),
-                       .ngpio  = S3C64XX_GPIO_N_NR,
-                       .label  = "GPN",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = S3C64XX_GPO_BASE,
-               .config = &gpio_2bit_cfg_eint11,
-               .chip   = {
-                       .base   = S3C64XX_GPO(0),
-                       .ngpio  = S3C64XX_GPIO_O_NR,
-                       .label  = "GPO",
-               },
-       }, {
-               .base   = S3C64XX_GPP_BASE,
-               .config = &gpio_2bit_cfg_eint11,
-               .chip   = {
-                       .base   = S3C64XX_GPP(0),
-                       .ngpio  = S3C64XX_GPIO_P_NR,
-                       .label  = "GPP",
-               },
-       }, {
-               .base   = S3C64XX_GPQ_BASE,
-               .config = &gpio_2bit_cfg_eint11,
-               .chip   = {
-                       .base   = S3C64XX_GPQ(0),
-                       .ngpio  = S3C64XX_GPIO_Q_NR,
-                       .label  = "GPQ",
-               },
-       },
-};
-
-static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
-{
-       chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
-}
-
-static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
-                                      int nr_chips,
-                                      void (*fn)(struct s3c_gpio_chip *))
-{
-       for (; nr_chips > 0; nr_chips--, chips++) {
-               if (fn)
-                       (fn)(chips);
-               s3c_gpiolib_add(chips);
-       }
-}
-
-static __init int s3c64xx_gpiolib_init(void)
-{
-       s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
-                           samsung_gpiolib_add_4bit);
-
-       s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
-                           samsung_gpiolib_add_4bit2);
-
-       s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
-                           s3c64xx_gpiolib_add_2bit);
-
-       return 0;
-}
-
-core_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 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#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 (file)
index 0000000..be9074e
--- /dev/null
@@ -0,0 +1,23 @@
+/* Cragganmore 6410 shared definitions
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *     Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MACH_CRAG6410_H
+#define MACH_CRAG6410_H
+
+#include <linux/gpio.h>
+
+#define BANFF_PMIC_IRQ_BASE            IRQ_BOARD_START
+#define GLENFARCLAS_PMIC_IRQ_BASE      (IRQ_BOARD_START + 64)
+
+#define PCA935X_GPIO_BASE              GPIO_BOARD_START
+#define CODEC_GPIO_BASE                (GPIO_BOARD_START + 8)
+#define GLENFARCLAS_PMIC_GPIO_BASE     (GPIO_BOARD_START + 16)
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
deleted file mode 100644 (file)
index 5ef0bb6..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* arch/arm/plat-s3c64xx/include/plat/pll.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C64XX PLL code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#define S3C6400_PLL_MDIV_MASK  ((1 << (25-16+1)) - 1)
-#define S3C6400_PLL_PDIV_MASK  ((1 << (13-8+1)) - 1)
-#define S3C6400_PLL_SDIV_MASK  ((1 << (2-0+1)) - 1)
-#define S3C6400_PLL_MDIV_SHIFT (16)
-#define S3C6400_PLL_PDIV_SHIFT (8)
-#define S3C6400_PLL_SDIV_SHIFT (0)
-
-#include <asm/div64.h>
-#include <plat/pll6553x.h>
-
-static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
-                                           u32 pllcon)
-{
-       u32 mdiv, pdiv, sdiv;
-       u64 fvco = baseclk;
-
-       mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
-       pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
-       sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
-
-       fvco *= mdiv;
-       do_div(fvco, (pdiv << sdiv));
-
-       return (unsigned long)fvco;
-}
-
-static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
-{
-       return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
-                               __raw_readl(S3C_EPLL_CON1));
-}
index 38659bebe4b17de87387dfd4f8d60f23615bfe9b..fcf3dcabb6944678e9dfabd5cbc67a3e490deade 100644 (file)
@@ -104,7 +104,7 @@ static inline void s3c_pm_restored_gpios(void)
        __raw_writel(0, S3C64XX_SLPEN);
 }
 
-static inline void s3c_pm_saved_gpios(void)
+static inline void samsung_pm_saved_gpios(void)
 {
        /* turn on the sleep mode and keep it there, as it seems that during
         * 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 (file)
index b25bede..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64xx - pwm clock and timer support
- */
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
index 69b78d9f83b8f2b4f04b72d85cf3e5562fa10c9a..b91e02093289d6af7c9a216adaa1273acf8f5f4b 100644 (file)
 #define S3C64XX_AHB_CON1       S3C_SYSREG(0x104)
 #define S3C64XX_AHB_CON2       S3C_SYSREG(0x108)
 
+#define S3C64XX_SDMA_SEL       S3C_SYSREG(0x110)
+
 #define S3C64XX_OTHERS         S3C_SYSREG(0x900)
 
 #define S3C64XX_OTHERS_USBMASK (1 << 16)
+#define S3C64XX_OTHERS_SYNCMUXSEL      (1 << 6)
 
 #endif /* _PLAT_REGS_SYS_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6400.h b/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
deleted file mode 100644 (file)
index f86958d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/mach-s3c64xx/include/macht/s3c6400.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6400 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for S3C6400 related SoCs */
-
-extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s3c6400_setup_clocks(void);
-
-extern void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
-
-#ifdef CONFIG_CPU_S3C6400
-
-extern  int s3c6400_init(void);
-extern void s3c6400_init_irq(void);
-extern void s3c6400_map_io(void);
-extern void s3c6400_init_clocks(int xtal);
-
-#define s3c6400_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6400_init_clocks NULL
-#define s3c6400_init_uarts NULL
-#define s3c6400_map_io NULL
-#define s3c6400_init NULL
-#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6410.h b/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
deleted file mode 100644 (file)
index 24f1141..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* arch/arm/mach-s3c64xx/include/mach/s3c6410.h
- *
- * Copyright 2008 Openmoko,  Inc.
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * Header file for s3c6410 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C6410
-
-extern  int s3c6410_init(void);
-extern void s3c6410_init_irq(void);
-extern void s3c6410_map_io(void);
-extern void s3c6410_init_clocks(int xtal);
-
-#define s3c6410_init_uarts s3c6400_common_init_uarts
-
-#else
-#define s3c6410_init_clocks NULL
-#define s3c6410_init_uarts NULL
-#define s3c6410_map_io NULL
-#define s3c6410_init NULL
-#endif
index d164a282bfb4808483818e5fa8d6c4b7dead4b44..8eba88e7209e123df3eaede76cb08f9833f5db5f 100644 (file)
@@ -45,7 +45,7 @@
 #include <plat/fb.h>
 #include <plat/regs-fb-v4.h>
 
-#include <mach/s3c6410.h>
+#include <plat/s3c6410.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #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 (file)
index 0000000..f208154
--- /dev/null
@@ -0,0 +1,182 @@
+/* Speyside modules for Cragganmore - board data probing
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *     Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/gpio.h>
+
+#include <sound/wm8996.h>
+#include <sound/wm8962.h>
+#include <sound/wm9081.h>
+
+#include <mach/crag6410.h>
+
+static struct wm8996_retune_mobile_config wm8996_retune[] = {
+       {
+               .name = "Sub LPF",
+               .rate = 48000,
+               .regs = {
+                       0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+       {
+               .name = "Sub HPF",
+               .rate = 48000,
+               .regs = {
+                       0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
+                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
+                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
+               },
+       },
+};
+
+static struct wm8996_pdata wm8996_pdata __initdata = {
+       .ldo_ena = S3C64XX_GPN(7),
+       .gpio_base = CODEC_GPIO_BASE,
+       .micdet_def = 1,
+       .inl_mode = WM8996_DIFFERRENTIAL_1,
+       .inr_mode = WM8996_DIFFERRENTIAL_1,
+
+       .irq_flags = IRQF_TRIGGER_RISING,
+
+       .gpio_default = {
+               0x8001, /* GPIO1 == ADCLRCLK1 */
+               0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
+               0x0141, /* GPIO3 == HP_SEL */
+               0x0002, /* GPIO4 == IRQ */
+               0x020e, /* GPIO5 == CLKOUT */
+       },
+
+       .retune_mobile_cfgs = wm8996_retune,
+       .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
+};
+
+static struct wm8962_pdata wm8962_pdata __initdata = {
+       .gpio_init = {
+               0,
+               WM8962_GPIO_FN_OPCLK,
+               WM8962_GPIO_FN_DMICCLK,
+               0,
+               0x8000 | WM8962_GPIO_FN_DMICDAT,
+               WM8962_GPIO_FN_IRQ,    /* Open drain mode */
+       },
+       .irq_active_low = true,
+};
+
+static struct wm9081_pdata wm9081_pdata __initdata = {
+       .irq_high = false,
+       .irq_cmos = false,
+};
+
+static const struct i2c_board_info wm1254_devs[] = {
+       { I2C_BOARD_INFO("wm8996", 0x1a),
+         .platform_data = &wm8996_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+       { I2C_BOARD_INFO("wm9081", 0x6c),
+         .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1255_devs[] = {
+       { I2C_BOARD_INFO("wm5100", 0x1a),
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+       { I2C_BOARD_INFO("wm9081", 0x6c),
+         .platform_data = &wm9081_pdata, },
+};
+
+static const struct i2c_board_info wm1259_devs[] = {
+       { I2C_BOARD_INFO("wm8962", 0x1a),
+         .platform_data = &wm8962_pdata,
+         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
+       },
+};
+
+
+static __devinitdata const struct {
+       u8 id;
+       const char *name;
+       const struct i2c_board_info *i2c_devs;
+       int num_i2c_devs;
+} gf_mods[] = {
+       { .id = 0x01, .name = "1250-EV1 Springbank" },
+       { .id = 0x02, .name = "1251-EV1 Jura" },
+       { .id = 0x03, .name = "1252-EV1 Glenlivet" },
+       { .id = 0x11, .name = "6249-EV2 Glenfarclas", },
+       { .id = 0x21, .name = "1275-EV1 Mortlach" },
+       { .id = 0x25, .name = "1274-EV1 Glencadam" },
+       { .id = 0x31, .name = "1253-EV1 Tomatin", },
+       { .id = 0x39, .name = "1254-EV1 Dallas Dhu",
+         .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
+       { .id = 0x3a, .name = "1259-EV1 Tobermory",
+         .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
+       { .id = 0x3b, .name = "1255-EV1 Kilchoman",
+         .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
+       { .id = 0x3c, .name = "1273-EV1 Longmorn" },
+};
+
+static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
+                                        const struct i2c_device_id *i2c_id)
+{
+       int ret, i, j, id, rev;
+
+       ret = i2c_smbus_read_byte_data(i2c, 0);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
+               return ret;
+       }
+
+       id = (ret & 0xfe) >> 2;
+       rev = ret & 0x3;
+       for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
+               if (id == gf_mods[i].id)
+                       break;
+
+       if (i < ARRAY_SIZE(gf_mods)) {
+               dev_info(&i2c->dev, "%s revision %d\n",
+                        gf_mods[i].name, rev + 1);
+               for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
+                       if (!i2c_new_device(i2c->adapter,
+                                           &(gf_mods[i].i2c_devs[j])))
+                               dev_err(&i2c->dev,
+                                       "Failed to register dev: %d\n", ret);
+               }
+       } else {
+               dev_warn(&i2c->dev, "Unknown module ID %d revision %d\n",
+                        id, rev);
+       }
+
+       return 0;
+}
+
+static const struct i2c_device_id wlf_gf_module_id[] = {
+       { "wlf-gf-module", 0 },
+       { }
+};
+
+static struct i2c_driver wlf_gf_module_driver = {
+       .driver = {
+               .name = "wlf-gf-module",
+               .owner = THIS_MODULE,
+       },
+       .probe = wlf_gf_module_probe,
+       .id_table = wlf_gf_module_id,
+};
+
+static int __init wlf_gf_module_register(void)
+{
+       return i2c_add_driver(&wlf_gf_module_driver);
+}
+module_init(wlf_gf_module_register);
index 806580388f30df20154245328c469b8fc3b6a779..d04b6544851031bf2800ebea7768e00e803fb67c 100644 (file)
 #include <mach/hardware.h>
 #include <mach/map.h>
 
-#include <mach/s3c6410.h>
 #include <mach/regs-sys.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-modem.h>
+#include <mach/crag6410.h>
 
 #include <mach/regs-gpio-memport.h>
 
+#include <plat/s3c6410.h>
 #include <plat/regs-serial.h>
 #include <plat/regs-fb-v4.h>
 #include <plat/fb.h>
 #include <plat/iic.h>
 #include <plat/pm.h>
 
-#include <sound/wm8996.h>
-#include <sound/wm8962.h>
-#include <sound/wm9081.h>
-
-#define BANFF_PMIC_IRQ_BASE            IRQ_BOARD_START
-#define GLENFARCLAS_PMIC_IRQ_BASE      (IRQ_BOARD_START + 64)
-
-#define PCA935X_GPIO_BASE              GPIO_BOARD_START
-#define CODEC_GPIO_BASE                (GPIO_BOARD_START + 8)
-#define GLENFARCLAS_PMIC_GPIO_BASE     (GPIO_BOARD_START + 16)
-
 /* serial port setup */
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
@@ -287,6 +277,11 @@ static struct platform_device speyside_device = {
        .id             = -1,
 };
 
+static struct platform_device lowland_device = {
+       .name           = "lowland",
+       .id             = -1,
+};
+
 static struct platform_device speyside_wm8962_device = {
        .name           = "speyside-wm8962",
        .id             = -1,
@@ -295,6 +290,8 @@ static struct platform_device speyside_wm8962_device = {
 static struct regulator_consumer_supply wallvdd_consumers[] = {
        REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
        REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+       REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
+       REGULATOR_SUPPLY("SPKVDDR", "1-001a"),
 };
 
 static struct regulator_init_data wallvdd_data = {
@@ -342,6 +339,7 @@ static struct platform_device *crag6410_devices[] __initdata = {
        &crag6410_backlight_device,
        &speyside_device,
        &speyside_wm8962_device,
+       &lowland_device,
        &wallvdd_device,
 };
 
@@ -350,6 +348,12 @@ static struct pca953x_platform_data crag6410_pca_data = {
        .irq_base       = 0,
 };
 
+/* VDDARM is controlled by DVS1 connected to GPK(0) */
+static struct wm831x_buckv_pdata vddarm_pdata = {
+       .dvs_control_src = 1,
+       .dvs_gpio = S3C64XX_GPK(0),
+};
+
 static struct regulator_consumer_supply vddarm_consumers[] __initdata = {
        REGULATOR_SUPPLY("vddarm", NULL),
 };
@@ -365,6 +369,7 @@ static struct regulator_init_data vddarm __initdata = {
        .num_consumer_supplies = ARRAY_SIZE(vddarm_consumers),
        .consumer_supplies = vddarm_consumers,
        .supply_regulator = "WALLVDD",
+       .driver_data = &vddarm_pdata,
 };
 
 static struct regulator_init_data vddint __initdata = {
@@ -500,6 +505,8 @@ static struct wm831x_pdata crag_pmic_pdata __initdata = {
        .backup = &banff_backup_pdata,
 
        .gpio_defaults = {
+               /* GPIO5: DVS1_REQ - CMOS, DBVDD, active high */
+               [4] = WM831X_GPN_DIR | WM831X_GPN_POL | WM831X_GPN_ENA | 0x8,
                /* GPIO11: Touchscreen data - CMOS, DBVDD, active high*/
                [10] = WM831X_GPN_POL | WM831X_GPN_ENA | 0x6,
                /* GPIO12: Touchscreen pen down - CMOS, DBVDD, active high*/
@@ -557,8 +564,12 @@ static struct regulator_init_data pvdd_1v2 __initdata = {
 };
 
 static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
+       REGULATOR_SUPPLY("LDOVDD", "1-001a"),
        REGULATOR_SUPPLY("PLLVDD", "1-001a"),
        REGULATOR_SUPPLY("DBVDD", "1-001a"),
+       REGULATOR_SUPPLY("DBVDD1", "1-001a"),
+       REGULATOR_SUPPLY("DBVDD2", "1-001a"),
+       REGULATOR_SUPPLY("DBVDD3", "1-001a"),
        REGULATOR_SUPPLY("CPVDD", "1-001a"),
        REGULATOR_SUPPLY("AVDD2", "1-001a"),
        REGULATOR_SUPPLY("DCVDD", "1-001a"),
@@ -611,81 +622,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
        .disable_touch = true,
 };
 
-static struct wm8996_retune_mobile_config wm8996_retune[] = {
-       {
-               .name = "Sub LPF",
-               .rate = 48000,
-               .regs = {
-                       0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
-                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
-                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
-               },
-       },
-       {
-               .name = "Sub HPF",
-               .rate = 48000,
-               .regs = {
-                       0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
-                       0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
-                       0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
-               },
-       },
-};
-
-static struct wm8996_pdata wm8996_pdata __initdata = {
-       .ldo_ena = S3C64XX_GPN(7),
-       .gpio_base = CODEC_GPIO_BASE,
-       .micdet_def = 1,
-       .inl_mode = WM8996_DIFFERRENTIAL_1,
-       .inr_mode = WM8996_DIFFERRENTIAL_1,
-
-       .irq_flags = IRQF_TRIGGER_RISING,
-
-       .gpio_default = {
-               0x8001, /* GPIO1 == ADCLRCLK1 */
-               0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
-               0x0141, /* GPIO3 == HP_SEL */
-               0x0002, /* GPIO4 == IRQ */
-               0x020e, /* GPIO5 == CLKOUT */
-       },
-
-       .retune_mobile_cfgs = wm8996_retune,
-       .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
-};
-
-static struct wm8962_pdata wm8962_pdata __initdata = {
-       .gpio_init = {
-               0,
-               WM8962_GPIO_FN_OPCLK,
-               WM8962_GPIO_FN_DMICCLK,
-               0,
-               0x8000 | WM8962_GPIO_FN_DMICDAT,
-               WM8962_GPIO_FN_IRQ,    /* Open drain mode */
-       },
-       .irq_active_low = true,
-};
-
-static struct wm9081_pdata wm9081_pdata __initdata = {
-       .irq_high = false,
-       .irq_cmos = false,
-};
-
 static struct i2c_board_info i2c_devs1[] __initdata = {
        { I2C_BOARD_INFO("wm8311", 0x34),
          .irq = S3C_EINT(0),
          .platform_data = &glenfarclas_pmic_pdata },
 
+       { I2C_BOARD_INFO("wlf-gf-module", 0x24) },
+       { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
+       { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
+
        { I2C_BOARD_INFO("wm1250-ev1", 0x27) },
-       { I2C_BOARD_INFO("wm8996", 0x1a),
-         .platform_data = &wm8996_pdata,
-         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
-       },
-       { I2C_BOARD_INFO("wm9081", 0x6c),
-         .platform_data = &wm9081_pdata, },
-       { I2C_BOARD_INFO("wm8962", 0x1a),
-         .platform_data = &wm8962_pdata,
-         .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
-       },
 };
 
 static void __init crag6410_map_io(void)
index 19a0887e1c1e980c657f193e5ab7f6e7a509b2b2..952f75ff5debaa245e0cac3ac638067a9463958c 100644 (file)
@@ -37,7 +37,7 @@
 #include <plat/fb.h>
 #include <plat/nand.h>
 
-#include <mach/s3c6410.h>
+#include <plat/s3c6410.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index fb8969aa412e057e3ae60ef39baf613003784b14..1bc85c35949894e7eff7607d572df777c604fcf0 100644 (file)
@@ -32,8 +32,8 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-modem.h>
 #include <mach/regs-srom.h>
-#include <mach/s3c6410.h>
 
+#include <plat/s3c6410.h>
 #include <plat/adc.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
index c30f2e5e0d85ba01bf0e98a083dba3458832043a..cb13cba98b3d00fba0c0c7a73795a597288153ce 100644 (file)
@@ -39,7 +39,7 @@
 #include <plat/iic.h>
 #include <plat/fb.h>
 
-#include <mach/s3c6410.h>
+#include <plat/s3c6410.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 93170d4834e7dd2bc45e6dd33581816ed3ecd2f7..87281e4b847134da27b461c2d05bec07063ee759 100644 (file)
@@ -33,8 +33,8 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-modem.h>
 #include <mach/regs-srom.h>
-#include <mach/s3c6410.h>
 
+#include <plat/s3c6410.h>
 #include <plat/adc.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
index cbb57ded3d95b72e4a4bd099a06ea21286ef14bf..94c831d8836502165477cda3c1e3124b318bd37f 100644 (file)
@@ -22,8 +22,8 @@
 
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
-#include <mach/s3c6410.h>
 
+#include <plat/s3c6410.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/fb.h>
index 04f914b85fdffcb7b1cad45550dcecdcd767ddaa..f112547ce80a123fdf9f495624ebe031abf28bd5 100644 (file)
@@ -22,8 +22,8 @@
 
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
-#include <mach/s3c6410.h>
 
+#include <plat/s3c6410.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/fb.h>
index 6fd5e95f8f757cfdd8e66ef27b3532e9ee2794d4..73450c2b530a661b131bf9e9e3824f7423ee94ba 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <plat/regs-serial.h>
 
-#include <mach/s3c6400.h>
+#include <plat/s3c6400.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 5f147c33edad718db0eb0ae216863190b093fa49..8bc8edd85e5a33418c6b50438037cc3878f82bca 100644 (file)
@@ -63,7 +63,7 @@
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
 
-#include <mach/s3c6410.h>
+#include <plat/s3c6410.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 055e2858b0dd9a31c027ecd8d7032d6ecefbddc7..b375cd5c47cb2ebe9f7b28ce2f7d0b6c0624ddc8 100644 (file)
@@ -29,6 +29,7 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-syscon-power.h>
 #include <mach/regs-gpio-memport.h>
+#include <mach/regs-modem.h>
 
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
 void s3c_pm_debug_smdkled(u32 set, u32 clear)
@@ -85,6 +86,9 @@ static struct sleep_save misc_save[] = {
        SAVE_ITEM(S3C64XX_MEM0CONSLP0),
        SAVE_ITEM(S3C64XX_MEM0CONSLP1),
        SAVE_ITEM(S3C64XX_MEM1CONSLP),
+
+       SAVE_ITEM(S3C64XX_SDMA_SEL),
+       SAVE_ITEM(S3C64XX_MODEM_MIFPCON),
 };
 
 void s3c_pm_configure_extint(void)
index 5e93fe3f3f409a16f4232d8e0fb5326de99652c3..51c00f2453c6c62ef9537143c0f31ad8ea416424 100644 (file)
@@ -38,7 +38,7 @@
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
 #include <plat/onenand-core.h>
-#include <mach/s3c6400.h>
+#include <plat/s3c6400.h>
 
 void __init s3c6400_map_io(void)
 {
@@ -70,7 +70,7 @@ void __init s3c6400_init_irq(void)
        s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
 }
 
-struct sysdev_class s3c6400_sysclass = {
+static struct sysdev_class s3c6400_sysclass = {
        .name   = "s3c6400-core",
 };
 
index 312aa6b115e8ee84a170f965d6a4b1f27e557407..4117003464ada5f505732d994b2292364d4be79b 100644 (file)
@@ -41,8 +41,8 @@
 #include <plat/adc-core.h>
 #include <plat/iic-core.h>
 #include <plat/onenand-core.h>
-#include <mach/s3c6400.h>
-#include <mach/s3c6410.h>
+#include <plat/s3c6400.h>
+#include <plat/s3c6410.h>
 
 void __init s3c6410_map_io(void)
 {
index 83d2afb79e9f88370fbced458f6ffbf9a5b1b1c8..2cf80026c58d470c5f328da8b6df696fa4514bae 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
 
-extern void s3c64xx_fb_gpio_setup_24bpp(void)
+void s3c64xx_fb_gpio_setup_24bpp(void)
 {
        s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
        s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
index f344a222bc84965b1ddc000ff4eb931af71886fe..c75a71b2116566415484eedb08c2db735a82e4b9 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
@@ -32,41 +22,3 @@ char *s3c64xx_hsmmc_clksrcs[4] = {
        [2] = "mmc_bus",
        /* [3] = "48m", - note not successfully used yet */
 };
-
-void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
-                                 void __iomem *r,
-                                 struct mmc_ios *ios,
-                                 struct mmc_card *card)
-{
-       u32 ctrl2, ctrl3;
-
-       ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-                 S3C_SDHCI_CTRL2_ENFBCLKRX |
-                 S3C_SDHCI_CTRL2_DFCNT_NONE |
-                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-       if (ios->clock < 25 * 1000000)
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-                        S3C_SDHCI_CTRL3_FCSEL2 |
-                        S3C_SDHCI_CTRL3_FCSEL1 |
-                        S3C_SDHCI_CTRL3_FCSEL0);
-       else
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-       pr_debug("%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
-       writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-       writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
-
-void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
-                                 void __iomem *r,
-                                 struct mmc_ios *ios,
-                                 struct mmc_card *card)
-{
-       writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
-
-       s3c6400_setup_sdhci_cfg_card(dev, r, ios, card);
-}
index 9527ed24dbff92f3c6d004db95c85c7613efea49..18690c5f99e638c88487d7d53d48be6b943b8f7e 100644 (file)
@@ -11,6 +11,8 @@ config CPU_S5P6440
        bool
        select SAMSUNG_DMADEV
        select S5P_HRT
+       select S5P_SLEEP if PM
+       select SAMSUNG_WAKEMASK if PM
        help
          Enable S5P6440 CPU support
 
@@ -18,9 +20,17 @@ config CPU_S5P6450
        bool
        select SAMSUNG_DMADEV
        select S5P_HRT
+       select S5P_SLEEP if PM
+       select SAMSUNG_WAKEMASK if PM
        help
          Enable S5P6450 CPU support
 
+config S5P64X0_SETUP_FB_24BPP
+       bool
+       help
+         Common setup code for S5P64X0 based boards with a LCD display
+         through RGB interface.
+
 config S5P64X0_SETUP_I2C1
        bool
        help
@@ -31,6 +41,7 @@ config S5P64X0_SETUP_I2C1
 config MACH_SMDK6440
        bool "SMDK6440"
        select CPU_S5P6440
+       select S3C_DEV_FB
        select S3C_DEV_I2C1
        select S3C_DEV_RTC
        select S3C_DEV_WDT
@@ -39,6 +50,7 @@ config MACH_SMDK6440
        select SAMSUNG_DEV_BACKLIGHT
        select SAMSUNG_DEV_PWM
        select SAMSUNG_DEV_TS
+       select S5P64X0_SETUP_FB_24BPP
        select S5P64X0_SETUP_I2C1
        help
          Machine support for the Samsung SMDK6440
@@ -46,6 +58,7 @@ config MACH_SMDK6440
 config MACH_SMDK6450
        bool "SMDK6450"
        select CPU_S5P6450
+       select S3C_DEV_FB
        select S3C_DEV_I2C1
        select S3C_DEV_RTC
        select S3C_DEV_WDT
@@ -54,6 +67,7 @@ config MACH_SMDK6450
        select SAMSUNG_DEV_BACKLIGHT
        select SAMSUNG_DEV_PWM
        select SAMSUNG_DEV_TS
+       select S5P64X0_SETUP_FB_24BPP
        select S5P64X0_SETUP_I2C1
        help
          Machine support for the Samsung SMDK6450
index 5f6afdf067eda5f4ae6379b661f676c10ae26b75..a1324d8dc4e06dece93c89b38459c1e962e17690 100644 (file)
@@ -12,10 +12,11 @@ obj-                                :=
 
 # Core support for S5P64X0 system
 
-obj-$(CONFIG_ARCH_S5P64X0)     += cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_ARCH_S5P64X0)     += cpu.o init.o clock.o dma.o
 obj-$(CONFIG_ARCH_S5P64X0)     += setup-i2c0.o irq-eint.o
 obj-$(CONFIG_CPU_S5P6440)      += clock-s5p6440.o
 obj-$(CONFIG_CPU_S5P6450)      += clock-s5p6450.o
+obj-$(CONFIG_PM)               += pm.o irq-pm.o
 
 # machine support
 
@@ -28,3 +29,4 @@ obj-y                         += dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
 
 obj-$(CONFIG_S5P64X0_SETUP_I2C1)       += setup-i2c1.o
+obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP)   += setup-fb-24bpp.o
index c1f548f69a0d93e30d0c1d3b099218c87a0ac11a..c54c65d511f04cb67b9a5bfa930257188a2a1a7d 100644 (file)
@@ -147,6 +147,7 @@ static struct clk init_clocks_off[] = {
                .ctrlbit        = (1 << 8),
        }, {
                .name           = "dma",
+               .devname        = "dma-pl330",
                .parent         = &clk_hclk_low.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 12),
index 3d9b6097557066ae32a7fc5f13f9db2fa0f92f72..2d04abfba12ecfcaed6cfd5988984f0128681935 100644 (file)
@@ -180,6 +180,7 @@ static struct clk init_clocks_off[] = {
                .ctrlbit        = (1 << 3),
        }, {
                .name           = "dma",
+               .devname        = "dma-pl330",
                .parent         = &clk_hclk_low.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 12),
index 8a938542c54d0f8a64ea66250dcb3a901df724ae..ecab40cf19ab15b906576131d3f829f62f52f1a8 100644 (file)
@@ -39,6 +39,7 @@
 #include <plat/s5p6440.h>
 #include <plat/s5p6450.h>
 #include <plat/adc-core.h>
+#include <plat/fb-core.h>
 
 /* Initial IO mappings */
 
@@ -109,6 +110,7 @@ void __init s5p6440_map_io(void)
 {
        /* initialize any device information early */
        s3c_adc_setname("s3c64xx-adc");
+       s3c_fb_setname("s5p64x0-fb");
 
        iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
        iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
@@ -119,6 +121,7 @@ void __init s5p6450_map_io(void)
 {
        /* initialize any device information early */
        s3c_adc_setname("s3c64xx-adc");
+       s3c_fb_setname("s5p64x0-fb");
 
        iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
        iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
diff --git a/arch/arm/mach-s5p64x0/include/mach/clkdev.h b/arch/arm/mach-s5p64x0/include/mach/clkdev.h
deleted file mode 100644 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#endif
index 5837a36ece8d6d9a7baec682a242923442666fe5..53982db9d25989d27c09d822b0c595a061c41874 100644 (file)
 
 #define IRQ_I2S0               IRQ_I2SV40
 
+#define IRQ_LCD_FIFO           IRQ_DISPCON0
+#define IRQ_LCD_VSYNC          IRQ_DISPCON1
+#define IRQ_LCD_SYSTEM         IRQ_DISPCON2
+
 /* S5P6450 EINT feature will be added */
 
 /*
index 95c91257c7caf22b0d05ed5ad1c2828443e6da99..4d3ac8a3709df918dd7d829cca09e4a6ca6f7421 100644 (file)
@@ -47,6 +47,8 @@
 
 #define S5P64X0_PA_HSMMC(x)    (0xED800000 + ((x) * 0x100000))
 
+#define S5P64X0_PA_FB          0xEE000000
+
 #define S5P64X0_PA_I2S         0xF2000000
 #define S5P6450_PA_I2S1                0xF2800000
 #define S5P6450_PA_I2S2                0xF2900000
@@ -64,6 +66,7 @@
 #define S3C_PA_IIC1            S5P6440_PA_IIC1
 #define S3C_PA_RTC             S5P64X0_PA_RTC
 #define S3C_PA_WDT             S5P64X0_PA_WDT
+#define S3C_PA_FB              S5P64X0_PA_FB
 
 #define S5P_PA_CHIPID          S5P64X0_PA_CHIPID
 #define S5P_PA_SROMC           S5P64X0_PA_SROMC
@@ -85,5 +88,6 @@
 #define S5P_PA_UART5           S5P6450_PA_UART(5)
 
 #define S5P_SZ_UART            SZ_256
+#define S3C_VA_UARTx(x)                (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 
 #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 (file)
index 0000000..e52f754
--- /dev/null
@@ -0,0 +1,117 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/pm-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - PM core support for arch/arm/plat-samsung/pm.c
+ *
+ * Based on PM core support for S3C64XX by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+       u32 tmp = __raw_readl(S5P64X0_CLK_GATE_PCLK);
+
+       /*
+        * As a note, since the S5P64X0 UARTs generally have multiple
+        * clock sources, we simply enable PCLK at the moment and hope
+        * that the resume settings for the UART are suitable for the
+        * use with PCLK.
+        */
+       tmp |= S5P64X0_CLK_GATE_PCLK_UART0;
+       tmp |= S5P64X0_CLK_GATE_PCLK_UART1;
+       tmp |= S5P64X0_CLK_GATE_PCLK_UART2;
+       tmp |= S5P64X0_CLK_GATE_PCLK_UART3;
+
+       __raw_writel(tmp, S5P64X0_CLK_GATE_PCLK);
+       udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+       /* VIC should have already been taken care of */
+
+       /* clear any pending EINT0 interrupts */
+       __raw_writel(__raw_readl(S5P64X0_EINT0PEND), S5P64X0_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void) { }
+static inline void s3c_pm_arch_show_resume_irqs(void) { }
+
+/*
+ * make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on
+ */
+#define s3c_irqwake_eintallow  ((1 << 16) - 1)
+#define s3c_irqwake_intallow   (~0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+                                       struct pm_uart_save *save)
+{
+       u32 ucon = __raw_readl(regs + S3C2410_UCON);
+       u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+       u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+       u32 new_ucon;
+       u32 delta;
+
+       /*
+        * S5P64X0 UART blocks only support level interrupts, so ensure that
+        * when we restore unused UART blocks we force the level interrupt
+        * settings.
+        */
+       save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+       /*
+        * We have a constraint on changing the clock type of the UART
+        * between UCLKx and PCLK, so ensure that when we restore UCON
+        * that the CLK field is correctly modified if the bootloader
+        * has changed anything.
+        */
+       if (ucon_clk != save_clk) {
+               new_ucon = save->ucon;
+               delta = ucon_clk ^ save_clk;
+
+               /*
+                * change from UCLKx => wrong PCLK,
+                * either UCLK can be tested for by a bit-test
+                * with UCLK0
+                */
+               if (ucon_clk & S3C6400_UCON_UCLK0 &&
+               !(save_clk & S3C6400_UCON_UCLK0) &&
+               delta & S3C6400_UCON_PCLK2) {
+                       new_ucon &= ~S3C6400_UCON_UCLK0;
+               } else if (delta == S3C6400_UCON_PCLK2) {
+                       /*
+                        * as a precaution, don't change from
+                        * PCLK2 => PCLK or vice-versa
+                        */
+                       new_ucon ^= S3C6400_UCON_PCLK2;
+               }
+
+               S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+                       ucon, new_ucon, save->ucon);
+               save->ucon = new_ucon;
+       }
+}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+       /* ensure sleep mode has been cleared from the system */
+       __raw_writel(0, S5P64X0_SLPEN);
+}
+
+static inline void samsung_pm_saved_gpios(void)
+{
+       /*
+        * turn on the sleep mode and keep it there, as it seems that during
+        * suspend the xCON registers get re-set and thus you can end up with
+        * problems between going to sleep and resuming.
+        */
+       __raw_writel(S5P64X0_SLPEN_USE_xSLP, S5P64X0_SLPEN);
+}
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 (file)
index 19fff8b..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S5P64X0 - pwm clock and timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_PWMCLK_H
-#define __ASM_ARCH_PWMCLK_H __FILE__
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return 0;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK 0
-
-#endif /* __ASM_ARCH_PWMCLK_H */
index a133f22fa155f38edf2e91711c893defd120eee0..bd91112c813ce93bb0ce1fcfd75899b9d50d932d 100644 (file)
 #define S5P6450_DPLL_CON               S5P_CLKREG(0x50)
 #define S5P6450_DPLL_CON_K             S5P_CLKREG(0x54)
 
+#define S5P64X0_AHB_CON0               S5P_CLKREG(0x100)
 #define S5P64X0_CLK_SRC1               S5P_CLKREG(0x10C)
 
 #define S5P64X0_SYS_ID                 S5P_CLKREG(0x118)
 #define S5P64X0_SYS_OTHERS             S5P_CLKREG(0x11C)
 
 #define S5P64X0_PWR_CFG                        S5P_CLKREG(0x804)
+#define S5P64X0_EINT_WAKEUP_MASK       S5P_CLKREG(0x808)
+#define S5P64X0_SLEEP_CFG              S5P_CLKREG(0x818)
+#define S5P64X0_PWR_STABLE             S5P_CLKREG(0x828)
+
 #define S5P64X0_OTHERS                 S5P_CLKREG(0x900)
+#define S5P64X0_WAKEUP_STAT            S5P_CLKREG(0x908)
+
+#define S5P64X0_INFORM0                        S5P_CLKREG(0xA00)
 
 #define S5P64X0_CLKDIV0_HCLK_SHIFT     (8)
 #define S5P64X0_CLKDIV0_HCLK_MASK      (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
 
+/* HCLK GATE Registers */
+#define S5P64X0_CLK_GATE_HCLK1_FIMGVG  (1 << 2)
+#define S5P64X0_CLK_GATE_SCLK1_FIMGVG  (1 << 2)
+
+/* PCLK GATE Registers */
+#define S5P64X0_CLK_GATE_PCLK_UART3    (1 << 4)
+#define S5P64X0_CLK_GATE_PCLK_UART2    (1 << 3)
+#define S5P64X0_CLK_GATE_PCLK_UART1    (1 << 2)
+#define S5P64X0_CLK_GATE_PCLK_UART0    (1 << 1)
+
+#define S5P64X0_PWR_CFG_MMC1_DISABLE           (1 << 15)
+#define S5P64X0_PWR_CFG_MMC0_DISABLE           (1 << 14)
+#define S5P64X0_PWR_CFG_RTC_TICK_DISABLE       (1 << 11)
+#define S5P64X0_PWR_CFG_RTC_ALRM_DISABLE       (1 << 10)
+#define S5P64X0_PWR_CFG_WFI_MASK               (3 << 5)
+#define S5P64X0_PWR_CFG_WFI_SLEEP              (3 << 5)
+
+#define S5P64X0_SLEEP_CFG_OSC_EN       (1 << 0)
+
+#define S5P64X0_PWR_STABLE_PWR_CNT_VAL4        (4 << 0)
+
+#define S5P6450_OTHERS_DISABLE_INT     (1 << 31)
+#define S5P64X0_OTHERS_RET_UART                (1 << 26)
+#define S5P64X0_OTHERS_RET_MMC1                (1 << 25)
+#define S5P64X0_OTHERS_RET_MMC0                (1 << 24)
 #define S5P64X0_OTHERS_USB_SIG_MASK    (1 << 16)
 
 /* Compatibility defines */
index 6ce254729f3baaa51b13ea8c09b1046ba21f4938..cfdfa4fdadf2b60f5ba4019fb0ff2a0716208b06 100644 (file)
 #define S5P6450_GPQ_BASE               (S5P_VA_GPIO + 0x0180)
 #define S5P6450_GPS_BASE               (S5P_VA_GPIO + 0x0300)
 
+#define S5P64X0_SPCON0                 (S5P_VA_GPIO + 0x1A0)
+#define S5P64X0_SPCON0_LCD_SEL_MASK    (0x3 << 0)
+#define S5P64X0_SPCON0_LCD_SEL_RGB     (0x1 << 0)
+#define S5P64X0_SPCON1                 (S5P_VA_GPIO + 0x2B0)
+
+#define S5P64X0_MEM0CONSLP0            (S5P_VA_GPIO + 0x1C0)
+#define S5P64X0_MEM0CONSLP1            (S5P_VA_GPIO + 0x1C4)
+#define S5P64X0_MEM0DRVCON             (S5P_VA_GPIO + 0x1D0)
+#define S5P64X0_MEM1DRVCON             (S5P_VA_GPIO + 0x1D4)
+
+#define S5P64X0_EINT12CON              (S5P_VA_GPIO + 0x200)
+#define S5P64X0_EINT12FLTCON           (S5P_VA_GPIO + 0x220)
+#define S5P64X0_EINT12MASK             (S5P_VA_GPIO + 0x240)
+
 /* External interrupt control registers for group0 */
 
 #define EINT0CON0_OFFSET               (0x900)
+#define EINT0FLTCON0_OFFSET            (0x910)
+#define EINT0FLTCON1_OFFSET            (0x914)
 #define EINT0MASK_OFFSET               (0x920)
 #define EINT0PEND_OFFSET               (0x924)
 
 #define S5P64X0_EINT0CON0              (S5P_VA_GPIO + EINT0CON0_OFFSET)
+#define S5P64X0_EINT0FLTCON0           (S5P_VA_GPIO + EINT0FLTCON0_OFFSET)
+#define S5P64X0_EINT0FLTCON1           (S5P_VA_GPIO + EINT0FLTCON1_OFFSET)
 #define S5P64X0_EINT0MASK              (S5P_VA_GPIO + EINT0MASK_OFFSET)
 #define S5P64X0_EINT0PEND              (S5P_VA_GPIO + EINT0PEND_OFFSET)
 
+#define S5P64X0_SLPEN                  (S5P_VA_GPIO + 0x930)
+#define S5P64X0_SLPEN_USE_xSLP         (1 << 0)
+
 #endif /* __ASM_ARCH_REGS_GPIO_H */
index 494e1a8f6f6d68a0613c63a6e5618ad162458d50..275dc74f4a7b4cc1013e623a2a6c1904590b93c4 100644 (file)
@@ -20,6 +20,7 @@
 #include <plat/cpu.h>
 #include <plat/regs-irqtype.h>
 #include <plat/gpio-cfg.h>
+#include <plat/pm.h>
 
 #include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
@@ -134,6 +135,7 @@ static int s5p64x0_alloc_gc(void)
        ct->chip.irq_mask = irq_gc_mask_set_bit;
        ct->chip.irq_unmask = irq_gc_mask_clr_bit;
        ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
+       ct->chip.irq_set_wake = s3c_irqext_wake;
        ct->regs.ack = EINT0PEND_OFFSET;
        ct->regs.mask = EINT0MASK_OFFSET;
        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 (file)
index 0000000..3e6f245
--- /dev/null
@@ -0,0 +1,92 @@
+/* linux/arch/arm/mach-s5p64x0/irq-pm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 - Interrupt handling Power Management
+ *
+ * Based on arch/arm/mach-s3c64xx/irq-pm.c by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <plat/regs-serial.h>
+#include <plat/pm.h>
+
+#include <mach/regs-gpio.h>
+
+static struct sleep_save irq_save[] = {
+       SAVE_ITEM(S5P64X0_EINT0CON0),
+       SAVE_ITEM(S5P64X0_EINT0FLTCON0),
+       SAVE_ITEM(S5P64X0_EINT0FLTCON1),
+       SAVE_ITEM(S5P64X0_EINT0MASK),
+};
+
+static struct irq_grp_save {
+       u32     con;
+       u32     fltcon;
+       u32     mask;
+} eint_grp_save[4];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s5p64x0_irq_pm_suspend(void)
+{
+       struct irq_grp_save *grp = eint_grp_save;
+       int i;
+
+       S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+       s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+       for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+               irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+       for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+               grp->con = __raw_readl(S5P64X0_EINT12CON + (i * 4));
+               grp->mask = __raw_readl(S5P64X0_EINT12MASK + (i * 4));
+               grp->fltcon = __raw_readl(S5P64X0_EINT12FLTCON + (i * 4));
+       }
+
+       return 0;
+}
+
+static void s5p64x0_irq_pm_resume(void)
+{
+       struct irq_grp_save *grp = eint_grp_save;
+       int i;
+
+       S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+       s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+       for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+               __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+       for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+               __raw_writel(grp->con, S5P64X0_EINT12CON + (i * 4));
+               __raw_writel(grp->mask, S5P64X0_EINT12MASK + (i * 4));
+               __raw_writel(grp->fltcon, S5P64X0_EINT12FLTCON + (i * 4));
+       }
+
+       S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+}
+
+static struct syscore_ops s5p64x0_irq_syscore_ops = {
+       .suspend = s5p64x0_irq_pm_suspend,
+       .resume  = s5p64x0_irq_pm_resume,
+};
+
+static int __init s5p64x0_syscore_init(void)
+{
+       register_syscore_ops(&s5p64x0_irq_syscore_ops);
+
+       return 0;
+}
+core_initcall(s5p64x0_syscore_init);
index 88857f5a49f7141d14c29519c605a993a8101202..4a1250cd1356b364c5a4c38160610caadccf3292 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/pwm_backlight.h>
+#include <linux/fb.h>
+
+#include <video/platform_lcd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -47,6 +50,8 @@
 #include <plat/ts.h>
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
+#include <plat/fb.h>
+#include <plat/regs-fb.h>
 
 #define SMDK6440_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
                                S3C2410_UCON_RXILEVEL |         \
@@ -92,6 +97,59 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
        },
 };
 
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdk6440_fb_win0 = {
+       .win_mode = {
+               .left_margin    = 8,
+               .right_margin   = 13,
+               .upper_margin   = 7,
+               .lower_margin   = 5,
+               .hsync_len      = 3,
+               .vsync_len      = 1,
+               .xres           = 800,
+               .yres           = 480,
+       },
+       .max_bpp        = 32,
+       .default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdk6440_lcd_pdata __initdata = {
+       .win[0]         = &smdk6440_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = s5p64x0_fb_gpio_setup_24bpp,
+};
+
+/* LCD power controller */
+static void smdk6440_lte480_reset_power(struct plat_lcd_data *pd,
+                                        unsigned int power)
+{
+       int err;
+
+       if (power) {
+               err = gpio_request(S5P6440_GPN(5), "GPN");
+               if (err) {
+                       printk(KERN_ERR "failed to request GPN for lcd reset\n");
+                       return;
+               }
+
+               gpio_direction_output(S5P6440_GPN(5), 1);
+               gpio_set_value(S5P6440_GPN(5), 0);
+               gpio_set_value(S5P6440_GPN(5), 1);
+               gpio_free(S5P6440_GPN(5));
+       }
+}
+
+static struct plat_lcd_data smdk6440_lcd_power_data = {
+       .set_power      = smdk6440_lte480_reset_power,
+};
+
+static struct platform_device smdk6440_lcd_lte480wv = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s3c_device_fb.dev,
+       .dev.platform_data      = &smdk6440_lcd_power_data,
+};
+
 static struct platform_device *smdk6440_devices[] __initdata = {
        &s3c_device_adc,
        &s3c_device_rtc,
@@ -101,6 +159,8 @@ static struct platform_device *smdk6440_devices[] __initdata = {
        &s3c_device_wdt,
        &samsung_asoc_dma,
        &s5p6440_device_iis,
+       &s3c_device_fb,
+       &smdk6440_lcd_lte480wv,
 };
 
 static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -147,6 +207,17 @@ static void __init smdk6440_map_io(void)
        s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
 }
 
+static void s5p6440_set_lcd_interface(void)
+{
+       unsigned int cfg;
+
+       /* select TFT LCD type (RGB I/F) */
+       cfg = __raw_readl(S5P64X0_SPCON0);
+       cfg &= ~S5P64X0_SPCON0_LCD_SEL_MASK;
+       cfg |= S5P64X0_SPCON0_LCD_SEL_RGB;
+       __raw_writel(cfg, S5P64X0_SPCON0);
+}
+
 static void __init smdk6440_machine_init(void)
 {
        s3c24xx_ts_set_platdata(NULL);
@@ -160,6 +231,9 @@ static void __init smdk6440_machine_init(void)
 
        samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
 
+       s5p6440_set_lcd_interface();
+       s3c_fb_set_platdata(&smdk6440_lcd_pdata);
+
        platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
 }
 
index e1b277b94610826ed2452afc054e234db0418ed4..0ab129ecf00956decaab6e1b60b55d71e7a841fa 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/clk.h>
 #include <linux/gpio.h>
 #include <linux/pwm_backlight.h>
+#include <linux/fb.h>
+
+#include <video/platform_lcd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -47,6 +50,8 @@
 #include <plat/ts.h>
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
+#include <plat/fb.h>
+#include <plat/regs-fb.h>
 
 #define SMDK6450_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
                                S3C2410_UCON_RXILEVEL |         \
@@ -110,6 +115,59 @@ static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
 #endif
 };
 
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdk6450_fb_win0 = {
+       .win_mode       = {
+               .left_margin    = 8,
+               .right_margin   = 13,
+               .upper_margin   = 7,
+               .lower_margin   = 5,
+               .hsync_len      = 3,
+               .vsync_len      = 1,
+               .xres           = 800,
+               .yres           = 480,
+       },
+       .max_bpp        = 32,
+       .default_bpp    = 24,
+};
+
+static struct s3c_fb_platdata smdk6450_lcd_pdata __initdata = {
+       .win[0]         = &smdk6450_fb_win0,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+       .setup_gpio     = s5p64x0_fb_gpio_setup_24bpp,
+};
+
+/* LCD power controller */
+static void smdk6450_lte480_reset_power(struct plat_lcd_data *pd,
+                                        unsigned int power)
+{
+       int err;
+
+       if (power) {
+               err = gpio_request(S5P6450_GPN(5), "GPN");
+               if (err) {
+                       printk(KERN_ERR "failed to request GPN for lcd reset\n");
+                       return;
+               }
+
+               gpio_direction_output(S5P6450_GPN(5), 1);
+               gpio_set_value(S5P6450_GPN(5), 0);
+               gpio_set_value(S5P6450_GPN(5), 1);
+               gpio_free(S5P6450_GPN(5));
+       }
+}
+
+static struct plat_lcd_data smdk6450_lcd_power_data = {
+       .set_power      = smdk6450_lte480_reset_power,
+};
+
+static struct platform_device smdk6450_lcd_lte480wv = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s3c_device_fb.dev,
+       .dev.platform_data      = &smdk6450_lcd_power_data,
+};
+
 static struct platform_device *smdk6450_devices[] __initdata = {
        &s3c_device_adc,
        &s3c_device_rtc,
@@ -119,6 +177,9 @@ static struct platform_device *smdk6450_devices[] __initdata = {
        &s3c_device_wdt,
        &samsung_asoc_dma,
        &s5p6450_device_iis0,
+       &s3c_device_fb,
+       &smdk6450_lcd_lte480wv,
+
        /* s5p6450_device_spi0 will be added */
 };
 
@@ -166,6 +227,17 @@ static void __init smdk6450_map_io(void)
        s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
 }
 
+static void s5p6450_set_lcd_interface(void)
+{
+       unsigned int cfg;
+
+       /* select TFT LCD type (RGB I/F) */
+       cfg = __raw_readl(S5P64X0_SPCON0);
+       cfg &= ~S5P64X0_SPCON0_LCD_SEL_MASK;
+       cfg |= S5P64X0_SPCON0_LCD_SEL_RGB;
+       __raw_writel(cfg, S5P64X0_SPCON0);
+}
+
 static void __init smdk6450_machine_init(void)
 {
        s3c24xx_ts_set_platdata(NULL);
@@ -179,6 +251,9 @@ static void __init smdk6450_machine_init(void)
 
        samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
 
+       s5p6450_set_lcd_interface();
+       s3c_fb_set_platdata(&smdk6450_lcd_pdata);
+
        platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
 }
 
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
new file mode 100644 (file)
index 0000000..6992724
--- /dev/null
@@ -0,0 +1,204 @@
+/* linux/arch/arm/mach-s5p64x0/pm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P64X0 Power Management Support
+ *
+ * Based on arch/arm/mach-s3c64xx/pm.c by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-timer.h>
+#include <plat/wakeup-mask.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+static struct sleep_save s5p64x0_core_save[] = {
+       SAVE_ITEM(S5P64X0_APLL_CON),
+       SAVE_ITEM(S5P64X0_MPLL_CON),
+       SAVE_ITEM(S5P64X0_EPLL_CON),
+       SAVE_ITEM(S5P64X0_EPLL_CON_K),
+       SAVE_ITEM(S5P64X0_CLK_SRC0),
+       SAVE_ITEM(S5P64X0_CLK_SRC1),
+       SAVE_ITEM(S5P64X0_CLK_DIV0),
+       SAVE_ITEM(S5P64X0_CLK_DIV1),
+       SAVE_ITEM(S5P64X0_CLK_DIV2),
+       SAVE_ITEM(S5P64X0_CLK_DIV3),
+       SAVE_ITEM(S5P64X0_CLK_GATE_MEM0),
+       SAVE_ITEM(S5P64X0_CLK_GATE_HCLK1),
+       SAVE_ITEM(S5P64X0_CLK_GATE_SCLK1),
+};
+
+static struct sleep_save s5p64x0_misc_save[] = {
+       SAVE_ITEM(S5P64X0_AHB_CON0),
+       SAVE_ITEM(S5P64X0_SPCON0),
+       SAVE_ITEM(S5P64X0_SPCON1),
+       SAVE_ITEM(S5P64X0_MEM0CONSLP0),
+       SAVE_ITEM(S5P64X0_MEM0CONSLP1),
+       SAVE_ITEM(S5P64X0_MEM0DRVCON),
+       SAVE_ITEM(S5P64X0_MEM1DRVCON),
+
+       SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+/* DPLL is present only in S5P6450 */
+static struct sleep_save s5p6450_core_save[] = {
+       SAVE_ITEM(S5P6450_DPLL_CON),
+       SAVE_ITEM(S5P6450_DPLL_CON_K),
+};
+
+void s3c_pm_configure_extint(void)
+{
+       __raw_writel(s3c_irqwake_eintmask, S5P64X0_EINT_WAKEUP_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+       __raw_writel(0, S5P64X0_EINT_WAKEUP_MASK);
+
+       s3c_pm_do_restore_core(s5p64x0_core_save,
+                               ARRAY_SIZE(s5p64x0_core_save));
+
+       if (soc_is_s5p6450())
+               s3c_pm_do_restore_core(s5p6450_core_save,
+                               ARRAY_SIZE(s5p6450_core_save));
+
+       s3c_pm_do_restore(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+       s3c_pm_do_save(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
+
+       if (soc_is_s5p6450())
+               s3c_pm_do_save(s5p6450_core_save,
+                               ARRAY_SIZE(s5p6450_core_save));
+
+       s3c_pm_do_save(s5p64x0_core_save, ARRAY_SIZE(s5p64x0_core_save));
+}
+
+static int s5p64x0_cpu_suspend(unsigned long arg)
+{
+       unsigned long tmp = 0;
+
+       /*
+        * Issue the standby signal into the pm unit. Note, we
+        * issue a write-buffer drain just in case.
+        */
+       asm("b 1f\n\t"
+           ".align 5\n\t"
+           "1:\n\t"
+           "mcr p15, 0, %0, c7, c10, 5\n\t"
+           "mcr p15, 0, %0, c7, c10, 4\n\t"
+           "mcr p15, 0, %0, c7, c0, 4" : : "r" (tmp));
+
+       /* we should never get past here */
+       panic("sleep resumed to originator?");
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static struct samsung_wakeup_mask s5p64x0_wake_irqs[] = {
+       { .irq = IRQ_RTC_ALARM, .bit = S5P64X0_PWR_CFG_RTC_ALRM_DISABLE, },
+       { .irq = IRQ_RTC_TIC,   .bit = S5P64X0_PWR_CFG_RTC_TICK_DISABLE, },
+       { .irq = IRQ_HSMMC0,    .bit = S5P64X0_PWR_CFG_MMC0_DISABLE, },
+       { .irq = IRQ_HSMMC1,    .bit = S5P64X0_PWR_CFG_MMC1_DISABLE, },
+};
+
+static void s5p64x0_pm_prepare(void)
+{
+       u32 tmp;
+
+       samsung_sync_wakemask(S5P64X0_PWR_CFG,
+                       s5p64x0_wake_irqs, ARRAY_SIZE(s5p64x0_wake_irqs));
+
+       /* store the resume address in INFORM0 register */
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S5P64X0_INFORM0);
+
+       /* setup clock gating for FIMGVG block */
+       __raw_writel((__raw_readl(S5P64X0_CLK_GATE_HCLK1) | \
+               (S5P64X0_CLK_GATE_HCLK1_FIMGVG)), S5P64X0_CLK_GATE_HCLK1);
+       __raw_writel((__raw_readl(S5P64X0_CLK_GATE_SCLK1) | \
+               (S5P64X0_CLK_GATE_SCLK1_FIMGVG)), S5P64X0_CLK_GATE_SCLK1);
+
+       /* Configure the stabilization counter with wait time required */
+       __raw_writel(S5P64X0_PWR_STABLE_PWR_CNT_VAL4, S5P64X0_PWR_STABLE);
+
+       /* set WFI to SLEEP mode configuration */
+       tmp = __raw_readl(S5P64X0_SLEEP_CFG);
+       tmp &= ~(S5P64X0_SLEEP_CFG_OSC_EN);
+       __raw_writel(tmp, S5P64X0_SLEEP_CFG);
+
+       tmp = __raw_readl(S5P64X0_PWR_CFG);
+       tmp &= ~(S5P64X0_PWR_CFG_WFI_MASK);
+       tmp |= S5P64X0_PWR_CFG_WFI_SLEEP;
+       __raw_writel(tmp, S5P64X0_PWR_CFG);
+
+       /*
+        * set OTHERS register to disable interrupt before going to
+        * sleep. This bit is present only in S5P6450, it is reserved
+        * in S5P6440.
+        */
+       if (soc_is_s5p6450()) {
+               tmp = __raw_readl(S5P64X0_OTHERS);
+               tmp |= S5P6450_OTHERS_DISABLE_INT;
+               __raw_writel(tmp, S5P64X0_OTHERS);
+       }
+
+       /* ensure previous wakeup state is cleared before sleeping */
+       __raw_writel(__raw_readl(S5P64X0_WAKEUP_STAT), S5P64X0_WAKEUP_STAT);
+
+}
+
+static int s5p64x0_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = s5p64x0_pm_prepare;
+       pm_cpu_sleep = s5p64x0_cpu_suspend;
+       pm_uart_udivslot = 1;
+
+       return 0;
+}
+
+static struct sysdev_driver s5p64x0_pm_driver = {
+       .add            = s5p64x0_pm_add,
+};
+
+static __init int s5p64x0_pm_drvinit(void)
+{
+       s3c_pm_init();
+
+       return sysdev_driver_register(&s5p64x0_sysclass, &s5p64x0_pm_driver);
+}
+arch_initcall(s5p64x0_pm_drvinit);
+
+static void s5p64x0_pm_resume(void)
+{
+       u32 tmp;
+
+       tmp = __raw_readl(S5P64X0_OTHERS);
+       tmp |= (S5P64X0_OTHERS_RET_MMC0 | S5P64X0_OTHERS_RET_MMC1 | \
+                       S5P64X0_OTHERS_RET_UART);
+       __raw_writel(tmp , S5P64X0_OTHERS);
+}
+
+static struct syscore_ops s5p64x0_pm_syscore_ops = {
+       .resume         = s5p64x0_pm_resume,
+};
+
+static __init int s5p64x0_pm_syscore_init(void)
+{
+       register_syscore_ops(&s5p64x0_pm_syscore_ops);
+
+       return 0;
+}
+arch_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 (file)
index 0000000..f346ee4
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5p64x0/setup-fb-24bpp.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Base S5P64X0 GPIO setup information for LCD framebuffer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+void s5p64x0_fb_gpio_setup_24bpp(void)
+{
+       if (soc_is_s5p6440()) {
+               s3c_gpio_cfgrange_nopull(S5P6440_GPI(0), 16, S3C_GPIO_SFN(2));
+               s3c_gpio_cfgrange_nopull(S5P6440_GPJ(0), 12, S3C_GPIO_SFN(2));
+       } else if (soc_is_s5p6450()) {
+               s3c_gpio_cfgrange_nopull(S5P6450_GPI(0), 16, S3C_GPIO_SFN(2));
+               s3c_gpio_cfgrange_nopull(S5P6450_GPJ(0), 12, S3C_GPIO_SFN(2));
+       }
+}
index 6527c05c5fa101ac6b85b2b1506ee60e002692b5..8d47709da713f22001622b90d67595d3ae0dd7c3 100644 (file)
@@ -460,13 +460,13 @@ static struct clk init_clocks_off[] = {
                .ctrlbit        = (1 << 2),
        }, {
                .name           = "dma",
-               .devname        = "s3c-pl330.1",
+               .devname        = "dma-pl330.1",
                .parent         = &clk_div_d1_bus.clk,
                .enable         = s5pc100_d1_0_ctrl,
                .ctrlbit        = (1 << 1),
        }, {
                .name           = "dma",
-               .devname        = "s3c-pl330.0",
+               .devname        = "dma-pl330.0",
                .parent         = &clk_div_d1_bus.clk,
                .enable         = s5pc100_d1_0_ctrl,
                .ctrlbit        = (1 << 0),
index ef803e92d35dca237122f6834c59038a8ba4453f..065a087f5a8bf4edbfb197589f482635d340e55d 100644 (file)
@@ -260,6 +260,7 @@ struct amba_device s5pc100_device_pdma1 = {
 static int __init s5pc100_dma_init(void)
 {
        amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
+       amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
 
        return 0;
 }
diff --git a/arch/arm/mach-s5pc100/include/mach/clkdev.h b/arch/arm/mach-s5pc100/include/mach/clkdev.h
deleted file mode 100644 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#endif
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 (file)
index b34d2f7..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *      Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - pwm clock and timer support
- *
- * Based on mach-s3c6400/include/mach/pwm-clock.h
- */
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
index be25879bb2eeee6de46d9d3f76fc78d075388978..6418c6e8a7b77238b7f3072de2fd447bc7722bb9 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
@@ -31,35 +21,3 @@ char *s5pc100_hsmmc_clksrcs[4] = {
        [2] = "sclk_mmc",       /* mmc_bus */
        /* [3] = "48m",         - note not successfully used yet */
 };
-
-
-void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
-                                   void __iomem *r,
-                                   struct mmc_ios *ios,
-                                   struct mmc_card *card)
-{
-       u32 ctrl2, ctrl3;
-
-       /* don't need to alter anything according to card-type */
-
-       writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
-
-       ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-                 S3C_SDHCI_CTRL2_ENFBCLKRX |
-                 S3C_SDHCI_CTRL2_DFCNT_NONE |
-                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-       if (ios->clock < 25 * 1000000)
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-                        S3C_SDHCI_CTRL3_FCSEL2 |
-                        S3C_SDHCI_CTRL3_FCSEL1 |
-                        S3C_SDHCI_CTRL3_FCSEL0);
-       else
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-       writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-       writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
index e3ebe96923c8c2954570e7b3993c20d56295b9df..646057ab2e4ca41a6b1385b3cad88b1cacdeebe6 100644 (file)
@@ -14,6 +14,8 @@ config CPU_S5PV210
        select SAMSUNG_DMADEV
        select S5P_EXT_INT
        select S5P_HRT
+       select S5P_PM if PM
+       select S5P_SLEEP if PM
        help
          Enable S5PV210 CPU support
 
@@ -93,11 +95,13 @@ config MACH_GONI
        select S3C_DEV_USB_HSOTG
        select S5P_DEV_ONENAND
        select SAMSUNG_DEV_KEYPAD
+       select S5P_DEV_TV
        select S5PV210_SETUP_FB_24BPP
        select S5PV210_SETUP_I2C1
        select S5PV210_SETUP_I2C2
        select S5PV210_SETUP_KEYPAD
        select S5PV210_SETUP_SDHCI
+       select S5PV210_SETUP_FIMC
        help
          Machine support for Samsung GONI board
          S5PC110(MCP) is one of package option of S5PV210
index ef7e4668d6706169219b2822fcf8e3ce04fad62d..009fbe53df96031f462cf92357630345482e1bb7 100644 (file)
@@ -14,7 +14,7 @@ obj-                          :=
 
 obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o dma.o
 obj-$(CONFIG_CPU_S5PV210)      += setup-i2c0.o
-obj-$(CONFIG_PM)               += pm.o sleep.o
+obj-$(CONFIG_PM)               += pm.o
 
 # machine support
 
index 1ab34000cc7eeb5f36879e5f1c3f38316ef996e2..4c5ac7a69e9e1b75fb7640d698f9ba0116122a0a 100644 (file)
@@ -174,6 +174,16 @@ static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
 }
 
+static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
+}
+
 static struct clk clk_sclk_hdmi27m = {
        .name           = "sclk_hdmi27m",
        .rate           = 27000000,
@@ -295,13 +305,13 @@ static struct clk_ops clk_fout_apll_ops = {
 static struct clk init_clocks_off[] = {
        {
                .name           = "dma",
-               .devname        = "s3c-pl330.0",
+               .devname        = "dma-pl330.0",
                .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1 << 3),
        }, {
                .name           = "dma",
-               .devname        = "s3c-pl330.1",
+               .devname        = "dma-pl330.1",
                .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1 << 4),
@@ -334,6 +344,40 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "dac",
+               .devname        = "s5p-sdo",
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "mixer",
+               .devname        = "s5p-mixer",
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "vp",
+               .devname        = "s5p-mixer",
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "hdmi",
+               .devname        = "s5pv210-hdmi",
+               .parent         = &clk_hclk_dsys.clk,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "hdmiphy",
+               .devname        = "s5pv210-hdmi",
+               .enable         = exynos4_clk_hdmiphy_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "dacphy",
+               .devname        = "s5p-sdo",
+               .enable         = exynos4_clk_dac_ctrl,
+               .ctrlbit        = (1 << 0),
        }, {
                .name           = "otg",
                .parent         = &clk_hclk_psys.clk,
@@ -411,6 +455,12 @@ static struct clk init_clocks_off[] = {
                .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<9),
+       }, {
+               .name           = "i2c",
+               .devname        = "s3c2440-hdmiphy-i2c",
+               .parent         = &clk_pclk_psys.clk,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 11),
        }, {
                .name           = "spi",
                .devname        = "s3c64xx-spi.0",
@@ -599,6 +649,23 @@ static struct clksrc_sources clkset_sclk_mixer = {
        .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
 };
 
+static struct clksrc_clk clk_sclk_mixer = {
+       .clk            = {
+               .name           = "sclk_mixer",
+               .enable         = s5pv210_clk_mask0_ctrl,
+               .ctrlbit        = (1 << 1),
+       },
+       .sources = &clkset_sclk_mixer,
+       .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk *sclk_tv[] = {
+       &clk_sclk_dac,
+       &clk_sclk_pixel,
+       &clk_sclk_hdmi,
+       &clk_sclk_mixer,
+};
+
 static struct clk *clkset_sclk_audio0_list[] = {
        [0] = &clk_ext_xtal_mux,
        [1] = &clk_pcmcdclk0,
@@ -780,14 +847,6 @@ static struct clksrc_clk clksrcs[] = {
                .sources = &clkset_uart,
                .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
                .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_mixer",
-                       .enable         = s5pv210_clk_mask0_ctrl,
-                       .ctrlbit        = (1 << 1),
-               },
-               .sources = &clkset_sclk_mixer,
-               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
        }, {
                .clk    = {
                        .name           = "sclk_fimc",
@@ -978,9 +1037,6 @@ static struct clksrc_clk *sysclks[] = {
        &clk_pclk_psys,
        &clk_vpllsrc,
        &clk_sclk_vpll,
-       &clk_sclk_dac,
-       &clk_sclk_pixel,
-       &clk_sclk_hdmi,
        &clk_mout_dmc0,
        &clk_sclk_dmc0,
        &clk_sclk_audio0,
@@ -1065,6 +1121,61 @@ static struct clk_ops s5pv210_epll_ops = {
        .get_rate = s5p_epll_get_rate,
 };
 
+static u32 vpll_div[][5] = {
+       {  54000000, 3, 53, 3, 0 },
+       { 108000000, 3, 53, 2, 0 },
+};
+
+static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int vpll_con;
+       unsigned int i;
+
+       /* Return if nothing changed */
+       if (clk->rate == rate)
+               return 0;
+
+       vpll_con = __raw_readl(S5P_VPLL_CON);
+       vpll_con &= ~(0x1 << 27 |                                       \
+                       PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |       \
+                       PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |       \
+                       PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
+
+       for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
+               if (vpll_div[i][0] == rate) {
+                       vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
+                       vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
+                       vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
+                       vpll_con |= vpll_div[i][4] << 27;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(vpll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+                               __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(vpll_con, S5P_VPLL_CON);
+
+       /* Wait for VPLL lock */
+       while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
+               continue;
+
+       clk->rate = rate;
+       return 0;
+}
+static struct clk_ops s5pv210_vpll_ops = {
+       .get_rate = s5pv210_vpll_get_rate,
+       .set_rate = s5pv210_vpll_set_rate,
+};
+
 void __init_or_cpufreq s5pv210_setup_clocks(void)
 {
        struct clk *xtal_clk;
@@ -1113,6 +1224,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        clk_fout_apll.ops = &clk_fout_apll_ops;
        clk_fout_mpll.rate = mpll;
        clk_fout_epll.rate = epll;
+       clk_fout_vpll.ops = &s5pv210_vpll_ops;
        clk_fout_vpll.rate = vpll;
 
        printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
@@ -1158,6 +1270,9 @@ void __init s5pv210_register_clocks(void)
        for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
                s3c_register_clksrc(sysclks[ptr], 1);
 
+       for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
+               s3c_register_clksrc(sclk_tv[ptr], 1);
+
        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
index 91145720822c09f5f85b3018d4648681f62e1bea..84ec746332328d0cfd5b5f81ed1e338c7399d428 100644 (file)
@@ -42,6 +42,7 @@
 #include <plat/keypad-core.h>
 #include <plat/sdhci.h>
 #include <plat/reset.h>
+#include <plat/tv-core.h>
 
 /* Initial IO mappings */
 
@@ -145,6 +146,9 @@ void __init s5pv210_map_io(void)
 
        /* Use s5pv210-keypad instead of samsung-keypad */
        samsung_keypad_setname("s5pv210-keypad");
+
+       /* setup TV devices */
+       s5p_hdmi_setname("s5pv210-hdmi");
 }
 
 void __init s5pv210_init_clocks(int xtal)
index f79d0b06cbf98fae4e36cef8733fa5e9618b6668..86b749c18b77cfdb0da3215cd2528b44f7429e56 100644 (file)
@@ -254,6 +254,7 @@ struct amba_device s5pv210_device_pdma1 = {
 static int __init s5pv210_dma_init(void)
 {
        amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
+       amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
 
        return 0;
 }
diff --git a/arch/arm/mach-s5pv210/include/mach/clkdev.h b/arch/arm/mach-s5pv210/include/mach/clkdev.h
deleted file mode 100644 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#endif
index b9f9ec33384d6cecc1633a90e9aabb3492d556b0..5e0de3a31f3d7f621f32eba0d6e5a448ccdad559 100644 (file)
@@ -56,7 +56,7 @@
 #define IRQ_SPI2               S5P_IRQ_VIC1(17)
 #define IRQ_IRDA               S5P_IRQ_VIC1(18)
 #define IRQ_IIC2               S5P_IRQ_VIC1(19)
-#define IRQ_IIC3               S5P_IRQ_VIC1(20)
+#define IRQ_IIC_HDMIPHY                S5P_IRQ_VIC1(20)
 #define IRQ_HSIRX              S5P_IRQ_VIC1(21)
 #define IRQ_HSITX              S5P_IRQ_VIC1(22)
 #define IRQ_UHOST              S5P_IRQ_VIC1(23)
@@ -86,7 +86,7 @@
 #define IRQ_HDMI               S5P_IRQ_VIC2(12)
 #define IRQ_IIC1               S5P_IRQ_VIC2(13)
 #define IRQ_MFC                        S5P_IRQ_VIC2(14)
-#define IRQ_TVENC              S5P_IRQ_VIC2(15)
+#define IRQ_SDO                        S5P_IRQ_VIC2(15)
 #define IRQ_I2S0               S5P_IRQ_VIC2(16)
 #define IRQ_I2S1               S5P_IRQ_VIC2(17)
 #define IRQ_I2S2               S5P_IRQ_VIC2(18)
index aac343c180b2cffb7bb757248d15286a56bee58a..7ff609f1568b10b4d71b9fd7aca0218248b48235 100644 (file)
 #define S5PV210_PA_FIMC1               0xFB300000
 #define S5PV210_PA_FIMC2               0xFB400000
 
+#define S5PV210_PA_SDO                 0xF9000000
+#define S5PV210_PA_VP                  0xF9100000
+#define S5PV210_PA_MIXER               0xF9200000
+#define S5PV210_PA_HDMI                        0xFA100000
+#define S5PV210_PA_IIC_HDMIPHY         0xFA900000
+
 /* Compatibiltiy Defines */
 
 #define S3C_PA_FB                      S5PV210_PA_FB
 #define S5P_PA_FIMC2                   S5PV210_PA_FIMC2
 #define S5P_PA_MIPI_CSIS0              S5PV210_PA_MIPI_CSIS
 #define S5P_PA_MFC                     S5PV210_PA_MFC
+#define S5P_PA_IIC_HDMIPHY             S5PV210_PA_IIC_HDMIPHY
+
+#define S5P_PA_SDO                     S5PV210_PA_SDO
+#define S5P_PA_VP                      S5PV210_PA_VP
+#define S5P_PA_MIXER                   S5PV210_PA_MIXER
+#define S5P_PA_HDMI                    S5PV210_PA_HDMI
+
 #define S5P_PA_ONENAND                 S5PC110_PA_ONENAND
 #define S5P_PA_ONENAND_DMA             S5PC110_PA_ONENAND_DMA
 #define S5P_PA_SDRAM                   S5PV210_PA_SDRAM
index 3e22109e1b7b4e851f890cb19cffd4d49c89314e..eba8aea63ed8f928b09f9d56a8486d666e31e302 100644 (file)
@@ -43,4 +43,4 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
 }
 
 static inline void s3c_pm_restored_gpios(void) { }
-static inline void s3c_pm_saved_gpios(void) { }
+static 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 (file)
index f8a9f1b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
- *
- * S5PV210 - pwm clock and timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_PWMCLK_H
-#define __ASM_ARCH_PWMCLK_H __FILE__
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div);
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
-
-#endif /* __ASM_ARCH_PWMCLK_H */
index 78925c5163469f380d7c057625285c5c21570da9..032de66fb8be2817496da9c431a2f5fef69d66f9 100644 (file)
 
 #define S5P_OTHERS             S5P_CLKREG(0xE000)
 #define S5P_OM_STAT            S5P_CLKREG(0xE100)
+#define S5P_HDMI_PHY_CONTROL   S5P_CLKREG(0xE804)
 #define S5P_USB_PHY_CONTROL    S5P_CLKREG(0xE80C)
-#define S5P_DAC_CONTROL                S5P_CLKREG(0xE810)
+#define S5P_DAC_PHY_CONTROL    S5P_CLKREG(0xE810)
 #define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
 #define S5P_MIPI_DPHY_ENABLE   (1 << 0)
 #define S5P_MIPI_DPHY_SRESETN  (1 << 1)
index 061cc7e4f48c1fcd750bf99315d5d837153821fb..15edcae448b9a81411dda546d48803875eb239b1 100644 (file)
 #include <plat/s5p-time.h>
 #include <plat/mfc.h>
 #include <plat/regs-fb-v4.h>
+#include <plat/camport.h>
+
+#include <media/v4l2-mediabus.h>
+#include <media/s5p_fimc.h>
+#include <media/noon010pc30.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define GONI_UCON_DEFAULT      (S3C2410_UCON_TXILEVEL |        \
@@ -272,6 +277,14 @@ static void __init goni_tsp_init(void)
        i2c2_devs[0].irq = gpio_to_irq(gpio);
 }
 
+static void goni_camera_init(void)
+{
+       s5pv210_fimc_setup_gpio(S5P_CAMPORT_A);
+
+       /* Set max driver strength on CAM_A_CLKOUT pin. */
+       s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4);
+}
+
 /* MAX8998 regulators */
 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
 
@@ -285,6 +298,7 @@ static struct regulator_consumer_supply goni_ldo5_consumers[] = {
 
 static struct regulator_consumer_supply goni_ldo8_consumers[] = {
        REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"),
+       REGULATOR_SUPPLY("vdd33a_dac", "s5p-sdo"),
 };
 
 static struct regulator_consumer_supply goni_ldo11_consumers[] = {
@@ -475,6 +489,10 @@ static struct regulator_consumer_supply buck1_consumer =
 static struct regulator_consumer_supply buck2_consumer =
        REGULATOR_SUPPLY("vddint", NULL);
 
+static struct regulator_consumer_supply buck3_consumer =
+       REGULATOR_SUPPLY("vdet", "s5p-sdo");
+
+
 static struct regulator_init_data goni_buck1_data = {
        .constraints    = {
                .name           = "VARM_1.2V",
@@ -511,6 +529,8 @@ static struct regulator_init_data goni_buck3_data = {
                        .enabled = 1,
                },
        },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &buck3_consumer,
 };
 
 static struct regulator_init_data goni_buck4_data = {
@@ -801,6 +821,34 @@ static void goni_setup_sdhci(void)
        s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
 };
 
+static struct noon010pc30_platform_data noon010pc30_pldata = {
+       .clk_rate       = 16000000UL,
+       .gpio_nreset    = S5PV210_GPB(2), /* CAM_CIF_NRST */
+       .gpio_nstby     = S5PV210_GPB(0), /* CAM_CIF_NSTBY */
+};
+
+static struct i2c_board_info noon010pc30_board_info = {
+       I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1),
+       .platform_data = &noon010pc30_pldata,
+};
+
+static struct s5p_fimc_isp_info goni_camera_sensors[] = {
+       {
+               .mux_id         = 0,
+               .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+                                 V4L2_MBUS_VSYNC_ACTIVE_LOW,
+               .bus_type       = FIMC_ITU_601,
+               .board_info     = &noon010pc30_board_info,
+               .i2c_bus_num    = 0,
+               .clk_frequency  = 16000000UL,
+       },
+};
+
+struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
+       .isp_info       = goni_camera_sensors,
+       .num_clients    = ARRAY_SIZE(goni_camera_sensors),
+};
+
 static struct platform_device *goni_devices[] __initdata = {
        &s3c_device_fb,
        &s5p_device_onenand,
@@ -812,10 +860,13 @@ static struct platform_device *goni_devices[] __initdata = {
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
+       &s5p_device_mixer,
+       &s5p_device_sdo,
        &s3c_device_i2c0,
        &s5p_device_fimc0,
        &s5p_device_fimc1,
        &s5p_device_fimc2,
+       &s5p_device_fimc_md,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
        &s3c_device_hsmmc2,
@@ -884,6 +935,12 @@ static void __init goni_machine_init(void)
        /* FB */
        s3c_fb_set_platdata(&goni_lcd_pdata);
 
+       /* FIMC */
+       s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata),
+                        &s5p_device_fimc_md);
+
+       goni_camera_init();
+
        /* SPI */
        spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 
index a83b6c909f6b16a3fc371428dffc82619fa63d84..6b8ccc4d35fd41cef548687ec344df44580943b0 100644 (file)
  * published by the Free Software Foundation.
 */
 
-#include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
@@ -30,34 +20,3 @@ char *s5pv210_hsmmc_clksrcs[4] = {
        [2] = "sclk_mmc",       /* mmc_bus */
        /* [3] = NULL,          - reserved */
 };
-
-void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
-                                   void __iomem *r,
-                                   struct mmc_ios *ios,
-                                   struct mmc_card *card)
-{
-       u32 ctrl2, ctrl3;
-
-       /* don't need to alter anything according to card-type */
-
-       writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
-
-       ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
-       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
-       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
-                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
-                 S3C_SDHCI_CTRL2_ENFBCLKRX |
-                 S3C_SDHCI_CTRL2_DFCNT_NONE |
-                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
-
-       if (ios->clock < 25 * 1000000)
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
-                        S3C_SDHCI_CTRL3_FCSEL2 |
-                        S3C_SDHCI_CTRL3_FCSEL1 |
-                        S3C_SDHCI_CTRL3_FCSEL0);
-       else
-               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
-
-       writel(ctrl2, r + S3C_SDHCI_CONTROL2);
-       writel(ctrl3, r + S3C_SDHCI_CONTROL3);
-}
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
deleted file mode 100644 (file)
index e3452cc..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/arch/arm/plat-s5p/sleep.S
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * S5PV210 power Manager (Suspend-To-RAM) support
- * Based on S3C2410 sleep code by:
- *     Ben Dooks, (c) 2004 Simtec Electronics
- *
- * Based on PXA/SA1100 sleep code by:
- *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- *     Cliff Brake, (c) 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/memory.h>
-
-       .text
-
-       /* sleep magic, to allow the bootloader to check for an valid
-        * image to resume to. Must be the first word before the
-        * s3c_cpu_resume entry.
-       */
-
-       .word   0x2bedf00d
-
-       /* s3c_cpu_resume
-        *
-        * resume code entry for bootloader to call
-        *
-        * we must put this code here in the data segment as we have no
-        * other way of restoring the stack pointer after sleep, and we
-        * must not write to the code segment (code is read-only)
-       */
-
-ENTRY(s3c_cpu_resume)
-       b       cpu_resume
index 5a616f6e56120c850c9afa93af19513a4b80ef1c..f7951aa0456287eadb4356ef5d1a3ecd3266abba 100644 (file)
@@ -1,5 +1,5 @@
-ifeq ($(CONFIG_ARCH_SA1100),y)
-   zreladdr-$(CONFIG_SA1111)           += 0xc0208000
+ifeq ($(CONFIG_SA1111),y)
+   zreladdr-y  += 0xc0208000
 else
    zreladdr-y  += 0xc0008000
 endif
index bd3e1bfdd6aa7b9e0e71de6a5ae37b28eda58fcf..2965cc9d424ee5dc9f504930052bec9ddcc0504f 100644 (file)
@@ -31,6 +31,7 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
+#include <asm/page.h>
 #include <asm/setup.h>
 #include <mach/collie.h>
 
index 0bb520d48ed0909c8876809572832c0a58fe59a8..77198fe02bc5ad2e8e4fc69bafe7881e21663c7a 100644 (file)
@@ -26,6 +26,7 @@
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/irq.h>
+#include <asm/page.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 #include <asm/mach/arch.h>
index 0c8f6cf3e948270f55c55b3f3f61cca77e3f8a80..0828fab2b65c7aa910dcfbcd73e712a1c56f0b61 100644 (file)
@@ -26,6 +26,7 @@ config ARCH_SH73A0
        select SH_CLK_CPG
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select ARM_GIC
+       select I2C
 
 comment "SH-Mobile Board Type"
 
@@ -69,6 +70,11 @@ config MACH_MACKEREL
        depends on ARCH_SH7372
        select ARCH_REQUIRE_GPIOLIB
 
+config MACH_KOTA2
+       bool "KOTA2 board"
+       select ARCH_REQUIRE_GPIOLIB
+       depends on ARCH_SH73A0
+
 comment "SH-Mobile System Configuration"
 
 menu "Memory configuration"
@@ -78,6 +84,7 @@ config MEMORY_START
        default "0x50000000" if MACH_G3EVM
        default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
                                MACH_MACKEREL
+       default "0x41000000" if MACH_KOTA2
        default "0x00000000"
        ---help---
          Tweak this only when porting to a new machine which does not
@@ -89,6 +96,7 @@ config MEMORY_SIZE
        default "0x08000000" if MACH_G3EVM
        default "0x08000000" if MACH_G4EVM
        default "0x20000000" if MACH_AG5EVM
+       default "0x1e000000" if MACH_KOTA2
        default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
        default "0x04000000"
        help
index 612b27000c3e3863cd50e5aa3b4b15fc1bfc2586..737bdc631b0dba4d292057bd0393840880b3a2e7 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common objects
-obj-y                          := timer.o console.o clock.o pm_runtime.o
+obj-y                          := timer.o console.o clock.o
 
 # CPU objects
 obj-$(CONFIG_ARCH_SH7367)      += setup-sh7367.o clock-sh7367.o intc-sh7367.o
@@ -41,6 +41,7 @@ obj-$(CONFIG_MACH_G4EVM)      += board-g4evm.o
 obj-$(CONFIG_MACH_AP4EVB)      += board-ap4evb.o
 obj-$(CONFIG_MACH_AG5EVM)      += board-ag5evm.o
 obj-$(CONFIG_MACH_MACKEREL)    += board-mackerel.o
+obj-$(CONFIG_MACH_KOTA2)       += board-kota2.o
 
 # Framework support
 obj-$(CONFIG_SMP)              += $(smp-y)
index 475342bcc95c36356291d866776d6a498678e952..b862e9f81e3e557935f13df5ec6fa29128b4d86c 100644 (file)
@@ -59,7 +59,7 @@ static struct resource smsc9220_resources[] = {
                .flags          = IORESOURCE_MEM,
        },
        [1] = {
-               .start          = gic_spi(33), /* PINT1 */
+               .start          = SH73A0_PINT0_IRQ(2), /* PINTA2 */
                .flags          = IORESOURCE_IRQ,
        },
 };
@@ -339,6 +339,18 @@ static struct platform_device mipidsi0_device = {
        },
 };
 
+/* SDHI0 */
+static irqreturn_t ag5evm_sdhi0_gpio_cd(int irq, void *arg)
+{
+       struct device *dev = arg;
+       struct sh_mobile_sdhi_info *info = dev->platform_data;
+       struct tmio_mmc_data *pdata = info->pdata;
+
+       tmio_mmc_cd_wakeup(pdata);
+
+       return IRQ_HANDLED;
+}
+
 static struct sh_mobile_sdhi_info sdhi0_info = {
        .dma_slave_tx   = SHDMA_SLAVE_SDHI0_TX,
        .dma_slave_rx   = SHDMA_SLAVE_SDHI0_RX,
@@ -462,19 +474,6 @@ static void __init ag5evm_map_io(void)
        shmobile_setup_console();
 }
 
-#define PINTC_ADDR     0xe6900000
-#define PINTER0A       (PINTC_ADDR + 0xa0)
-#define PINTCR0A       (PINTC_ADDR + 0xb0)
-
-void __init ag5evm_init_irq(void)
-{
-       sh73a0_init_irq();
-
-       /* setup PINT: enable PINTA2 as active low */
-       __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A);
-       __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
-}
-
 #define DSI0PHYCR      0xe615006c
 
 static void __init ag5evm_init(void)
@@ -516,14 +515,14 @@ static void __init ag5evm_init(void)
        /* enable MMCIF */
        gpio_request(GPIO_FN_MMCCLK0, NULL);
        gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
-       gpio_request(GPIO_FN_MMCD0_0, NULL);
-       gpio_request(GPIO_FN_MMCD0_1, NULL);
-       gpio_request(GPIO_FN_MMCD0_2, NULL);
-       gpio_request(GPIO_FN_MMCD0_3, NULL);
-       gpio_request(GPIO_FN_MMCD0_4, NULL);
-       gpio_request(GPIO_FN_MMCD0_5, NULL);
-       gpio_request(GPIO_FN_MMCD0_6, NULL);
-       gpio_request(GPIO_FN_MMCD0_7, NULL);
+       gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
+       gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
        gpio_request(GPIO_PORT208, NULL); /* Reset */
        gpio_direction_output(GPIO_PORT208, 1);
 
@@ -570,6 +569,13 @@ static void __init ag5evm_init(void)
        gpio_request(GPIO_FN_SDHID0_1, NULL);
        gpio_request(GPIO_FN_SDHID0_0, NULL);
 
+       if (!request_irq(intcs_evt2irq(0x3c0), ag5evm_sdhi0_gpio_cd,
+                        IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+                        "sdhi0 cd", &sdhi0_device.dev))
+               sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
+       else
+               pr_warn("Unable to setup SDHI0 GPIO IRQ\n");
+
        /* enable SDHI1 on CN4 [WLAN I/F] */
        gpio_request(GPIO_FN_SDHICLK1, NULL);
        gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
@@ -601,7 +607,7 @@ struct sys_timer ag5evm_timer = {
 
 MACHINE_START(AG5EVM, "ag5evm")
        .map_io         = ag5evm_map_io,
-       .init_irq       = ag5evm_init_irq,
+       .init_irq       = sh73a0_init_irq,
        .handle_irq     = shmobile_handle_irq_gic,
        .init_machine   = ag5evm_init,
        .timer          = &ag5evm_timer,
index f9f66c20c9f19224952c43ca06f4883fb6b8f139..4c865ece9ac4e9dc14aa4612ce7a780e59fed690 100644 (file)
@@ -200,8 +200,8 @@ static struct physmap_flash_data nor_flash_data = {
 
 static struct resource nor_flash_resources[] = {
        [0]     = {
-               .start  = 0x00000000,
-               .end    = 0x08000000 - 1,
+               .start  = 0x20000000, /* CS0 shadow instead of regular CS0 */
+               .end    = 0x28000000 - 1, /* needed by USB MASK ROM boot */
                .flags  = IORESOURCE_MEM,
        }
 };
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
new file mode 100644 (file)
index 0000000..bd9a784
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * kota2 board support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ * Copyright (C) 2010  Takashi Yoshii <yoshii.takashi.zj@renesas.com>
+ * Copyright (C) 2009  Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <mach/hardware.h>
+#include <mach/sh73a0.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/traps.h>
+
+/* SMSC 9220 */
+static struct resource smsc9220_resources[] = {
+       [0] = {
+               .start          = 0x14000000, /* CS5A */
+               .end            = 0x140000ff, /* A1->A7 */
+               .flags          = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start          = gic_spi(33), /* PINTA2 @ PORT144 */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct smsc911x_platform_config smsc9220_platdata = {
+       .flags          = SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+       .name           = "smsc911x",
+       .id             = 0,
+       .dev  = {
+               .platform_data = &smsc9220_platdata,
+       },
+       .resource       = smsc9220_resources,
+       .num_resources  = ARRAY_SIZE(smsc9220_resources),
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_platdata = {
+       .mode           = SH_KEYSC_MODE_6,
+       .scan_timing    = 3,
+       .delay          = 100,
+       .keycodes       = {
+               KEY_NUMERIC_STAR, KEY_NUMERIC_0, KEY_NUMERIC_POUND,
+               0, 0, 0, 0, 0,
+               KEY_NUMERIC_7, KEY_NUMERIC_8, KEY_NUMERIC_9,
+               0, KEY_DOWN, 0, 0, 0,
+               KEY_NUMERIC_4, KEY_NUMERIC_5, KEY_NUMERIC_6,
+               KEY_LEFT, KEY_ENTER, KEY_RIGHT, 0, 0,
+               KEY_NUMERIC_1, KEY_NUMERIC_2, KEY_NUMERIC_3,
+               0, KEY_UP, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+       },
+};
+
+static struct resource keysc_resources[] = {
+       [0] = {
+               .name   = "KEYSC",
+               .start  = 0xe61b0000,
+               .end    = 0xe61b0098 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gic_spi(71),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device keysc_device = {
+       .name           = "sh_keysc",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(keysc_resources),
+       .resource       = keysc_resources,
+       .dev            = {
+               .platform_data  = &keysc_platdata,
+       },
+};
+
+/* GPIO KEY */
+#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+static struct gpio_keys_button gpio_buttons[] = {
+       GPIO_KEY(KEY_VOLUMEUP, GPIO_PORT56, "+"), /* S2: VOL+ [IRQ9] */
+       GPIO_KEY(KEY_VOLUMEDOWN, GPIO_PORT54, "-"), /* S3: VOL- [IRQ10] */
+       GPIO_KEY(KEY_MENU, GPIO_PORT27, "Menu"), /* S4: MENU [IRQ30] */
+       GPIO_KEY(KEY_HOMEPAGE, GPIO_PORT26, "Home"), /* S5: HOME [IRQ31] */
+       GPIO_KEY(KEY_BACK, GPIO_PORT11, "Back"), /* S6: BACK [IRQ0] */
+       GPIO_KEY(KEY_PHONE, GPIO_PORT238, "Tel"), /* S7: TEL [IRQ11] */
+       GPIO_KEY(KEY_POWER, GPIO_PORT239, "C1"), /* S8: CAM [IRQ13] */
+       GPIO_KEY(KEY_MAIL, GPIO_PORT224, "Mail"), /* S9: MAIL [IRQ3] */
+       /* Omitted button "C3?": GPIO_PORT223 - S10: CUST [IRQ8] */
+       GPIO_KEY(KEY_CAMERA, GPIO_PORT164, "C2"), /* S11: CAM_HALF [IRQ25] */
+       /* Omitted button "?": GPIO_PORT152 - S12: CAM_FULL [No IRQ] */
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+       .buttons        = gpio_buttons,
+       .nbuttons       = ARRAY_SIZE(gpio_buttons),
+       .poll_interval  = 250, /* polled for now */
+};
+
+static struct platform_device gpio_keys_device = {
+       .name   = "gpio-keys-polled", /* polled for now */
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_key_info,
+       },
+};
+
+/* GPIO LED */
+#define GPIO_LED(n, g) { .name = n, .gpio = g }
+
+static struct gpio_led gpio_leds[] = {
+       GPIO_LED("V2513", GPIO_PORT153), /* PORT153 [TPU1T02] -> V2513 */
+       GPIO_LED("V2514", GPIO_PORT199), /* PORT199 [TPU4TO1] -> V2514 */
+       GPIO_LED("V2515", GPIO_PORT197), /* PORT197 [TPU2TO1] -> V2515 */
+       GPIO_LED("KEYLED", GPIO_PORT163), /* PORT163 [TPU3TO0] -> KEYLED */
+       GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */
+       GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */
+       GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */
+};
+
+static struct gpio_led_platform_data gpio_leds_info = {
+       .leds           = gpio_leds,
+       .num_leds       = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_leds_info,
+       },
+};
+
+/* MMCIF */
+static struct resource mmcif_resources[] = {
+       [0] = {
+               .name   = "MMCIF",
+               .start  = 0xe6bd0000,
+               .end    = 0xe6bd00ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gic_spi(140),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = gic_spi(141),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct sh_mmcif_plat_data mmcif_info = {
+       .ocr            = MMC_VDD_165_195,
+       .caps           = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+};
+
+static struct platform_device mmcif_device = {
+       .name           = "sh_mmcif",
+       .id             = 0,
+       .dev            = {
+               .platform_data          = &mmcif_info,
+       },
+       .num_resources  = ARRAY_SIZE(mmcif_resources),
+       .resource       = mmcif_resources,
+};
+
+/* SDHI0 */
+static struct sh_mobile_sdhi_info sdhi0_info = {
+       .tmio_caps      = MMC_CAP_SD_HIGHSPEED,
+       .tmio_flags     = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi0_resources[] = {
+       [0] = {
+               .name   = "SDHI0",
+               .start  = 0xee100000,
+               .end    = 0xee1000ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gic_spi(83),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = gic_spi(84),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = gic_spi(85),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device sdhi0_device = {
+       .name           = "sh_mobile_sdhi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(sdhi0_resources),
+       .resource       = sdhi0_resources,
+       .dev    = {
+               .platform_data  = &sdhi0_info,
+       },
+};
+
+/* SDHI1 */
+static struct sh_mobile_sdhi_info sdhi1_info = {
+       .tmio_caps      = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
+       .tmio_flags     = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct resource sdhi1_resources[] = {
+       [0] = {
+               .name   = "SDHI1",
+               .start  = 0xee120000,
+               .end    = 0xee1200ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gic_spi(87),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = gic_spi(88),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = gic_spi(89),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device sdhi1_device = {
+       .name           = "sh_mobile_sdhi",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(sdhi1_resources),
+       .resource       = sdhi1_resources,
+       .dev    = {
+               .platform_data  = &sdhi1_info,
+       },
+};
+
+static struct platform_device *kota2_devices[] __initdata = {
+       &eth_device,
+       &keysc_device,
+       &gpio_keys_device,
+       &gpio_leds_device,
+       &mmcif_device,
+       &sdhi0_device,
+       &sdhi1_device,
+};
+
+static struct map_desc kota2_io_desc[] __initdata = {
+       /* create a 1:1 entity map for 0xe6xxxxxx
+        * used by CPGA, INTC and PFC.
+        */
+       {
+               .virtual        = 0xe6000000,
+               .pfn            = __phys_to_pfn(0xe6000000),
+               .length         = 256 << 20,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+static void __init kota2_map_io(void)
+{
+       iotable_init(kota2_io_desc, ARRAY_SIZE(kota2_io_desc));
+
+       /* setup early devices and console here as well */
+       sh73a0_add_early_devices();
+       shmobile_setup_console();
+}
+
+#define PINTER0A       0xe69000a0
+#define PINTCR0A       0xe69000b0
+
+void __init kota2_init_irq(void)
+{
+       sh73a0_init_irq();
+
+       /* setup PINT: enable PINTA2 as active low */
+       __raw_writel(1 << 29, PINTER0A);
+       __raw_writew(2 << 10, PINTCR0A);
+}
+
+static void __init kota2_init(void)
+{
+       sh73a0_pinmux_init();
+
+       /* SCIFA2 (UART2) */
+       gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
+       gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
+       gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
+       gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
+
+       /* SCIFA4 (UART1) */
+       gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
+       gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
+       gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
+       gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
+
+       /* SMSC911X */
+       gpio_request(GPIO_FN_D0_NAF0, NULL);
+       gpio_request(GPIO_FN_D1_NAF1, NULL);
+       gpio_request(GPIO_FN_D2_NAF2, NULL);
+       gpio_request(GPIO_FN_D3_NAF3, NULL);
+       gpio_request(GPIO_FN_D4_NAF4, NULL);
+       gpio_request(GPIO_FN_D5_NAF5, NULL);
+       gpio_request(GPIO_FN_D6_NAF6, NULL);
+       gpio_request(GPIO_FN_D7_NAF7, NULL);
+       gpio_request(GPIO_FN_D8_NAF8, NULL);
+       gpio_request(GPIO_FN_D9_NAF9, NULL);
+       gpio_request(GPIO_FN_D10_NAF10, NULL);
+       gpio_request(GPIO_FN_D11_NAF11, NULL);
+       gpio_request(GPIO_FN_D12_NAF12, NULL);
+       gpio_request(GPIO_FN_D13_NAF13, NULL);
+       gpio_request(GPIO_FN_D14_NAF14, NULL);
+       gpio_request(GPIO_FN_D15_NAF15, NULL);
+       gpio_request(GPIO_FN_CS5A_, NULL);
+       gpio_request(GPIO_FN_WE0__FWE, NULL);
+       gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
+       gpio_direction_input(GPIO_PORT144);
+       gpio_request(GPIO_PORT145, NULL); /* RESET */
+       gpio_direction_output(GPIO_PORT145, 1);
+
+       /* KEYSC */
+       gpio_request(GPIO_FN_KEYIN0_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN1_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN2_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN3_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN4_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN5_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN6_PU, NULL);
+       gpio_request(GPIO_FN_KEYIN7_PU, NULL);
+       gpio_request(GPIO_FN_KEYOUT0, NULL);
+       gpio_request(GPIO_FN_KEYOUT1, NULL);
+       gpio_request(GPIO_FN_KEYOUT2, NULL);
+       gpio_request(GPIO_FN_KEYOUT3, NULL);
+       gpio_request(GPIO_FN_KEYOUT4, NULL);
+       gpio_request(GPIO_FN_KEYOUT5, NULL);
+       gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
+       gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
+       gpio_request(GPIO_FN_KEYOUT8, NULL);
+
+       /* MMCIF */
+       gpio_request(GPIO_FN_MMCCLK0, NULL);
+       gpio_request(GPIO_FN_MMCD0_0, NULL);
+       gpio_request(GPIO_FN_MMCD0_1, NULL);
+       gpio_request(GPIO_FN_MMCD0_2, NULL);
+       gpio_request(GPIO_FN_MMCD0_3, NULL);
+       gpio_request(GPIO_FN_MMCD0_4, NULL);
+       gpio_request(GPIO_FN_MMCD0_5, NULL);
+       gpio_request(GPIO_FN_MMCD0_6, NULL);
+       gpio_request(GPIO_FN_MMCD0_7, NULL);
+       gpio_request(GPIO_FN_MMCCMD0, NULL);
+       gpio_request(GPIO_PORT208, NULL); /* Reset */
+       gpio_direction_output(GPIO_PORT208, 1);
+
+       /* SDHI0 (microSD) */
+       gpio_request(GPIO_FN_SDHICD0_PU, NULL);
+       gpio_request(GPIO_FN_SDHICMD0_PU, NULL);
+       gpio_request(GPIO_FN_SDHICLK0, NULL);
+       gpio_request(GPIO_FN_SDHID0_3_PU, NULL);
+       gpio_request(GPIO_FN_SDHID0_2_PU, NULL);
+       gpio_request(GPIO_FN_SDHID0_1_PU, NULL);
+       gpio_request(GPIO_FN_SDHID0_0_PU, NULL);
+
+       /* SCIFB (BT) */
+       gpio_request(GPIO_FN_PORT159_SCIFB_SCK, NULL);
+       gpio_request(GPIO_FN_PORT160_SCIFB_TXD, NULL);
+       gpio_request(GPIO_FN_PORT161_SCIFB_CTS_, NULL);
+       gpio_request(GPIO_FN_PORT162_SCIFB_RXD, NULL);
+       gpio_request(GPIO_FN_PORT163_SCIFB_RTS_, NULL);
+
+       /* SDHI1 (BCM4330) */
+       gpio_request(GPIO_FN_SDHICLK1, NULL);
+       gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
+       gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
+       gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
+       gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
+       gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
+
+#ifdef CONFIG_CACHE_L2X0
+       /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+       l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+#endif
+       sh73a0_add_standard_devices();
+       platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices));
+}
+
+static void __init kota2_timer_init(void)
+{
+       sh73a0_clock_init();
+       shmobile_timer.init();
+       return;
+}
+
+struct sys_timer kota2_timer = {
+       .init   = kota2_timer_init,
+};
+
+MACHINE_START(KOTA2, "kota2")
+       .map_io         = kota2_map_io,
+       .init_irq       = kota2_init_irq,
+       .handle_irq     = shmobile_handle_irq_gic,
+       .init_machine   = kota2_init,
+       .timer          = &kota2_timer,
+MACHINE_END
index 682042306ea2e22066d7c2913d83996465cb319c..9c5e598e0e3d69f1aa5c36d29f7a416f301b38fe 100644 (file)
@@ -273,8 +273,8 @@ static struct physmap_flash_data nor_flash_data = {
 
 static struct resource nor_flash_resources[] = {
        [0]     = {
-               .start  = 0x00000000,
-               .end    = 0x08000000 - 1,
+               .start  = 0x20000000, /* CS0 shadow instead of regular CS0 */
+               .end    = 0x28000000 - 1, /* needed by USB MASK ROM boot */
                .flags  = IORESOURCE_MEM,
        }
 };
index 66975921e6467b363e037ca355c82952a17a300a..995a9c3aec8fbe60da9c78f3dba9835d20db9003 100644 (file)
@@ -476,7 +476,7 @@ static struct clk_ops fsidiv_clk_ops = {
        .disable        = fsidiv_disable,
 };
 
-static struct clk_mapping sh7372_fsidiva_clk_mapping = {
+static struct clk_mapping fsidiva_clk_mapping = {
        .phys   = FSIDIVA,
        .len    = 8,
 };
@@ -484,10 +484,10 @@ static struct clk_mapping sh7372_fsidiva_clk_mapping = {
 struct clk sh7372_fsidiva_clk = {
        .ops            = &fsidiv_clk_ops,
        .parent         = &div6_reparent_clks[DIV6_FSIA], /* late install */
-       .mapping        = &sh7372_fsidiva_clk_mapping,
+       .mapping        = &fsidiva_clk_mapping,
 };
 
-static struct clk_mapping sh7372_fsidivb_clk_mapping = {
+static struct clk_mapping fsidivb_clk_mapping = {
        .phys   = FSIDIVB,
        .len    = 8,
 };
@@ -495,7 +495,7 @@ static struct clk_mapping sh7372_fsidivb_clk_mapping = {
 struct clk sh7372_fsidivb_clk = {
        .ops            = &fsidiv_clk_ops,
        .parent         = &div6_reparent_clks[DIV6_FSIB],  /* late install */
-       .mapping        = &sh7372_fsidivb_clk_mapping,
+       .mapping        = &fsidivb_clk_mapping,
 };
 
 static struct clk *late_main_clks[] = {
index 6b7c7c42bc8fc529678fe7e77d01878299d049c4..31654d78b96b6331b8edaaf3a6576f043de408ae 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sh_clk.h>
+#include <linux/export.h>
 
 int __init clk_init(void)
 {
index 2e44f11f592e6979f8f0dc759c84fe6d3a4dfe7c..1b2334277e85d5cbad17a126698fdbc39aaefd7b 100644 (file)
@@ -26,65 +26,59 @@ void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
 };
 
 static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
-                                 struct cpuidle_state *state)
+                                 struct cpuidle_driver *drv,
+                                 int index)
 {
        ktime_t before, after;
-       int requested_state = state - &dev->states[0];
 
-       dev->last_state = &dev->states[requested_state];
        before = ktime_get();
 
        local_irq_disable();
        local_fiq_disable();
 
-       shmobile_cpuidle_modes[requested_state]();
+       shmobile_cpuidle_modes[index]();
 
        local_irq_enable();
        local_fiq_enable();
 
        after = ktime_get();
-       return ktime_to_ns(ktime_sub(after, before)) >> 10;
+       dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10;
+
+       return index;
 }
 
 static struct cpuidle_device shmobile_cpuidle_dev;
 static struct cpuidle_driver shmobile_cpuidle_driver = {
        .name =         "shmobile_cpuidle",
        .owner =        THIS_MODULE,
+       .states[0] = {
+               .name = "C1",
+               .desc = "WFI",
+               .exit_latency = 1,
+               .target_residency = 1 * 2,
+               .flags = CPUIDLE_FLAG_TIME_VALID,
+       },
+       .safe_state_index = 0, /* C1 */
+       .state_count = 1,
 };
 
-void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
 
 static int shmobile_cpuidle_init(void)
 {
        struct cpuidle_device *dev = &shmobile_cpuidle_dev;
-       struct cpuidle_state *state;
+       struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
        int i;
 
-       cpuidle_register_driver(&shmobile_cpuidle_driver);
-
-       for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
-               dev->states[i].name[0] = '\0';
-               dev->states[i].desc[0] = '\0';
-               dev->states[i].enter = shmobile_cpuidle_enter;
-       }
-
-       i = CPUIDLE_DRIVER_STATE_START;
-
-       state = &dev->states[i++];
-       snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
-       strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
-       state->exit_latency = 1;
-       state->target_residency = 1 * 2;
-       state->power_usage = 3;
-       state->flags = 0;
-       state->flags |= CPUIDLE_FLAG_TIME_VALID;
-
-       dev->safe_state = state;
-       dev->state_count = i;
+       for (i = 0; i < CPUIDLE_STATE_MAX; i++)
+               drv->states[i].enter = shmobile_cpuidle_enter;
 
        if (shmobile_cpuidle_setup)
-               shmobile_cpuidle_setup(dev);
+               shmobile_cpuidle_setup(drv);
+
+       cpuidle_register_driver(drv);
 
+       dev->state_count = drv->state_count;
        cpuidle_register_device(dev);
 
        return 0;
index c0cdbf997c919ad6e22cd9044d4683807917908e..834bd6cd508f1f75625fb1f1126507ca9acf25d4 100644 (file)
@@ -9,9 +9,9 @@ extern int clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
 extern void shmobile_handle_irq_gic(struct pt_regs *);
 extern struct platform_suspend_ops shmobile_suspend_ops;
-struct cpuidle_device;
+struct cpuidle_driver;
 extern void (*shmobile_cpuidle_modes[])(void);
-extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
 
 extern void sh7367_init_irq(void);
 extern void sh7367_add_early_devices(void);
diff --git a/arch/arm/mach-shmobile/include/mach/intc.h b/arch/arm/mach-shmobile/include/mach/intc.h
new file mode 100644 (file)
index 0000000..8b22258
--- /dev/null
@@ -0,0 +1,246 @@
+#ifndef __ASM_MACH_INTC_H
+#define __ASM_MACH_INTC_H
+#include <linux/sh_intc.h>
+
+#define INTC_IRQ_PINS_ENUM_16L(p)                              \
+       p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,         \
+       p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7,         \
+       p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,       \
+       p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15
+
+#define INTC_IRQ_PINS_ENUM_16H(p)                              \
+       p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,     \
+       p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23,     \
+       p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,     \
+       p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31
+
+#define INTC_IRQ_PINS_VECT_16L(p, vect)                                \
+       vect(p ## _IRQ0, 0x0200), vect(p ## _IRQ1, 0x0220),     \
+       vect(p ## _IRQ2, 0x0240), vect(p ## _IRQ3, 0x0260),     \
+       vect(p ## _IRQ4, 0x0280), vect(p ## _IRQ5, 0x02a0),     \
+       vect(p ## _IRQ6, 0x02c0), vect(p ## _IRQ7, 0x02e0),     \
+       vect(p ## _IRQ8, 0x0300), vect(p ## _IRQ9, 0x0320),     \
+       vect(p ## _IRQ10, 0x0340), vect(p ## _IRQ11, 0x0360),   \
+       vect(p ## _IRQ12, 0x0380), vect(p ## _IRQ13, 0x03a0),   \
+       vect(p ## _IRQ14, 0x03c0), vect(p ## _IRQ15, 0x03e0)
+
+#define INTC_IRQ_PINS_VECT_16H(p, vect)                                \
+       vect(p ## _IRQ16, 0x3200), vect(p ## _IRQ17, 0x3220),   \
+       vect(p ## _IRQ18, 0x3240), vect(p ## _IRQ19, 0x3260),   \
+       vect(p ## _IRQ20, 0x3280), vect(p ## _IRQ21, 0x32a0),   \
+       vect(p ## _IRQ22, 0x32c0), vect(p ## _IRQ23, 0x32e0),   \
+       vect(p ## _IRQ24, 0x3300), vect(p ## _IRQ25, 0x3320),   \
+       vect(p ## _IRQ26, 0x3340), vect(p ## _IRQ27, 0x3360),   \
+       vect(p ## _IRQ28, 0x3380), vect(p ## _IRQ29, 0x33a0),   \
+       vect(p ## _IRQ30, 0x33c0), vect(p ## _IRQ31, 0x33e0)
+
+#define INTC_IRQ_PINS_MASK_16L(p, base)                                        \
+       { base + 0x40, base + 0x60, 8, /* INTMSK00A / INTMSKCLR00A */   \
+         { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,             \
+           p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },         \
+       { base + 0x44, base + 0x64, 8, /* INTMSK10A / INTMSKCLR10A */   \
+         { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,           \
+           p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_MASK_16H(p, base)                                        \
+       { base + 0x48, base + 0x68, 8, /* INTMSK20A / INTMSKCLR20A */   \
+         { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,         \
+           p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },     \
+       { base + 0x4c, base + 0x6c, 8, /* INTMSK30A / INTMSKCLR30A */   \
+         { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,         \
+           p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_PRIO_16L(p, base)                                        \
+       { base + 0x10, 0, 32, 4, /* INTPRI00A */                        \
+         { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,             \
+           p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },         \
+       { base + 0x14, 0, 32, 4, /* INTPRI10A */                        \
+         { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,           \
+           p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_PRIO_16H(p, base)                                        \
+       { base + 0x18, 0, 32, 4, /* INTPRI20A */                        \
+         { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,         \
+           p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },     \
+       { base + 0x1c, 0, 32, 4, /* INTPRI30A */                        \
+         { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,         \
+           p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_SENSE_16L(p, base)                               \
+       { base + 0x00, 32, 4, /* ICR1A */                               \
+         { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,             \
+           p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },         \
+       { base + 0x04, 32, 4, /* ICR2A */                               \
+         { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,           \
+           p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_SENSE_16H(p, base)                               \
+       { base + 0x08, 32, 4, /* ICR3A */                               \
+         { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,         \
+           p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },     \
+       { base + 0x0c, 32, 4, /* ICR4A */                               \
+         { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,         \
+           p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_ACK_16L(p, base)                                 \
+       { base + 0x20, 0, 8, /* INTREQ00A */                            \
+         { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,             \
+           p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },         \
+       { base + 0x24, 0, 8, /* INTREQ10A */                            \
+         { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,           \
+           p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
+
+#define INTC_IRQ_PINS_ACK_16H(p, base)                                 \
+       { base + 0x28, 0, 8, /* INTREQ20A */                            \
+         { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,         \
+           p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },     \
+       { base + 0x2c, 0, 8, /* INTREQ30A */                            \
+         { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,         \
+           p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
+
+#define INTC_IRQ_PINS_16(p, base, vect, str)                           \
+                                                                       \
+static struct resource p ## _resources[] __initdata = {                        \
+       [0] = {                                                         \
+               .start  = base,                                         \
+               .end    = base + 0x64,                                  \
+               .flags  = IORESOURCE_MEM,                               \
+       },                                                              \
+};                                                                     \
+                                                                       \
+enum {                                                                 \
+       p ## _UNUSED = 0,                                               \
+       INTC_IRQ_PINS_ENUM_16L(p),                                      \
+};                                                                     \
+                                                                       \
+static struct intc_vect p ## _vectors[] __initdata = {                 \
+       INTC_IRQ_PINS_VECT_16L(p, vect),                                \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = {      \
+       INTC_IRQ_PINS_MASK_16L(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = {      \
+       INTC_IRQ_PINS_PRIO_16L(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = {    \
+       INTC_IRQ_PINS_SENSE_16L(p, base),                               \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = {       \
+       INTC_IRQ_PINS_ACK_16L(p, base),                                 \
+};                                                                     \
+                                                                       \
+static struct intc_desc p ## _desc __initdata = {                      \
+       .name = str,                                                    \
+       .resource = p ## _resources,                                    \
+       .num_resources = ARRAY_SIZE(p ## _resources),                   \
+       .hw = INTC_HW_DESC(p ## _vectors, NULL,                         \
+                            p ## _mask_registers, p ## _prio_registers, \
+                            p ## _sense_registers, p ## _ack_registers) \
+}
+
+#define INTC_IRQ_PINS_32(p, base, vect, str)                           \
+                                                                       \
+static struct resource p ## _resources[] __initdata = {                        \
+       [0] = {                                                         \
+               .start  = base,                                         \
+               .end    = base + 0x6c,                                  \
+               .flags  = IORESOURCE_MEM,                               \
+       },                                                              \
+};                                                                     \
+                                                                       \
+enum {                                                                 \
+       p ## _UNUSED = 0,                                               \
+       INTC_IRQ_PINS_ENUM_16L(p),                                      \
+       INTC_IRQ_PINS_ENUM_16H(p),                                      \
+};                                                                     \
+                                                                       \
+static struct intc_vect p ## _vectors[] __initdata = {                 \
+       INTC_IRQ_PINS_VECT_16L(p, vect),                                \
+       INTC_IRQ_PINS_VECT_16H(p, vect),                                \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = {      \
+       INTC_IRQ_PINS_MASK_16L(p, base),                                \
+       INTC_IRQ_PINS_MASK_16H(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = {      \
+       INTC_IRQ_PINS_PRIO_16L(p, base),                                \
+       INTC_IRQ_PINS_PRIO_16H(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = {    \
+       INTC_IRQ_PINS_SENSE_16L(p, base),                               \
+       INTC_IRQ_PINS_SENSE_16H(p, base),                               \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = {       \
+       INTC_IRQ_PINS_ACK_16L(p, base),                                 \
+       INTC_IRQ_PINS_ACK_16H(p, base),                                 \
+};                                                                     \
+                                                                       \
+static struct intc_desc p ## _desc __initdata = {                      \
+       .name = str,                                                    \
+       .resource = p ## _resources,                                    \
+       .num_resources = ARRAY_SIZE(p ## _resources),                   \
+       .hw = INTC_HW_DESC(p ## _vectors, NULL,                         \
+                            p ## _mask_registers, p ## _prio_registers, \
+                            p ## _sense_registers, p ## _ack_registers) \
+}
+
+#define INTC_PINT_E_EMPTY
+#define INTC_PINT_E_NONE 0, 0, 0, 0, 0, 0, 0, 0,
+#define INTC_PINT_E(p)                                                 \
+       PINT ## p ## 0, PINT ## p ## 1, PINT ## p ## 2, PINT ## p ## 3, \
+       PINT ## p ## 4, PINT ## p ## 5, PINT ## p ## 6, PINT ## p ## 7,
+
+#define INTC_PINT_V_NONE
+#define INTC_PINT_V(p, vect)                                   \
+       vect(PINT ## p ## 0, 0), vect(PINT ## p ## 1, 1),       \
+       vect(PINT ## p ## 2, 2), vect(PINT ## p ## 3, 3),       \
+       vect(PINT ## p ## 4, 4), vect(PINT ## p ## 5, 5),       \
+       vect(PINT ## p ## 6, 6), vect(PINT ## p ## 7, 7),
+
+#define INTC_PINT(p, mask_reg, sense_base, str,                                \
+       enums_1, enums_2, enums_3, enums_4,                             \
+       vect_1, vect_2, vect_3, vect_4,                                 \
+       mask_a, mask_b, mask_c, mask_d,                                 \
+       sense_a, sense_b, sense_c, sense_d)                             \
+                                                                       \
+enum {                                                                 \
+       PINT ## p ## _UNUSED = 0,                                       \
+       enums_1 enums_2 enums_3 enums_4                                 \
+};                                                                     \
+                                                                       \
+static struct intc_vect p ## _vectors[] __initdata = {                 \
+       vect_1 vect_2 vect_3 vect_4                                     \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = {      \
+       { mask_reg, 0, 32, /* PINTER */                                 \
+         { mask_a mask_b mask_c mask_d } }                             \
+};                                                                     \
+                                                                       \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = {    \
+       { sense_base + 0x00, 16, 2, /* PINTCR */                        \
+         { sense_a } },                                                \
+       { sense_base + 0x04, 16, 2, /* PINTCR */                        \
+         { sense_b } },                                                \
+       { sense_base + 0x08, 16, 2, /* PINTCR */                        \
+         { sense_c } },                                                \
+       { sense_base + 0x0c, 16, 2, /* PINTCR */                        \
+         { sense_d } },                                                \
+};                                                                     \
+                                                                       \
+static struct intc_desc p ## _desc __initdata = {                      \
+       .name = str,                                                    \
+       .hw = INTC_HW_DESC(p ## _vectors, NULL,                         \
+                            p ## _mask_registers, NULL,                \
+                            p ## _sense_registers, NULL),              \
+}
+
+#endif  /* __ASM_MACH_INTC_H */
index 216c3d695ef177f36f131f47bbee51be3b9be877..881d515a9686f3786179003b2f5d4c5816fe6ac7 100644 (file)
@@ -451,18 +451,39 @@ enum {
        GPIO_FN_KEYIN5_PU,
        GPIO_FN_KEYIN6_PU,
        GPIO_FN_KEYIN7_PU,
+       GPIO_FN_SDHICD0_PU,
+       GPIO_FN_SDHID0_0_PU,
+       GPIO_FN_SDHID0_1_PU,
+       GPIO_FN_SDHID0_2_PU,
+       GPIO_FN_SDHID0_3_PU,
+       GPIO_FN_SDHICMD0_PU,
+       GPIO_FN_SDHIWP0_PU,
        GPIO_FN_SDHID1_0_PU,
        GPIO_FN_SDHID1_1_PU,
        GPIO_FN_SDHID1_2_PU,
        GPIO_FN_SDHID1_3_PU,
        GPIO_FN_SDHICMD1_PU,
+       GPIO_FN_SDHID2_0_PU,
+       GPIO_FN_SDHID2_1_PU,
+       GPIO_FN_SDHID2_2_PU,
+       GPIO_FN_SDHID2_3_PU,
+       GPIO_FN_SDHICMD2_PU,
        GPIO_FN_MMCCMD0_PU,
        GPIO_FN_MMCCMD1_PU,
+       GPIO_FN_MMCD0_0_PU,
+       GPIO_FN_MMCD0_1_PU,
+       GPIO_FN_MMCD0_2_PU,
+       GPIO_FN_MMCD0_3_PU,
+       GPIO_FN_MMCD0_4_PU,
+       GPIO_FN_MMCD0_5_PU,
+       GPIO_FN_MMCD0_6_PU,
+       GPIO_FN_MMCD0_7_PU,
        GPIO_FN_FSIACK_PU,
        GPIO_FN_FSIAILR_PU,
        GPIO_FN_FSIAIBT_PU,
        GPIO_FN_FSIAISLD_PU,
 };
+
 /* DMA slave IDs */
 enum {
        SHDMA_SLAVE_INVALID,
@@ -494,4 +515,8 @@ enum {
        SHDMA_SLAVE_MMCIF_RX,
 };
 
+/* PINT interrupts are located at Linux IRQ 768 and up */
+#define SH73A0_PINT0_IRQ(irq) ((irq) + 768)
+#define SH73A0_PINT1_IRQ(irq) ((irq) + 800)
+
 #endif /* __ASM_SH73A0_H__ */
index cc442d198cdc302b907e731233fcbef8186e16e2..cfde9bfc36699dec881fa738f2d19aec58075955 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
+#include <mach/intc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -31,8 +32,6 @@ enum {
        DISABLED,
 
        /* interrupt sources INTCA */
-       IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
-       IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
        DIRC,
        CRYPT1_ERR, CRYPT2_STD,
        IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
@@ -76,14 +75,6 @@ enum {
 };
 
 static struct intc_vect intca_vectors[] __initdata = {
-       INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
-       INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
-       INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
-       INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
-       INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
-       INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
-       INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
-       INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
        INTC_VECT(DIRC, 0x0560),
        INTC_VECT(CRYPT1_ERR, 0x05e0),
        INTC_VECT(CRYPT2_STD, 0x0700),
@@ -163,10 +154,6 @@ static struct intc_group intca_groups[] __initdata = {
 };
 
 static struct intc_mask_reg intca_mask_registers[] __initdata = {
-       { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
        { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
          { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
            ARM11_IRQPMU, 0, ARM11_COMMTX, ARM11_COMMRX } },
@@ -212,11 +199,6 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
 };
 
 static struct intc_prio_reg intca_prio_registers[] __initdata = {
-       { 0xe6900010, 0, 32, 4, /* INTPRI00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900014, 0, 32, 4, /* INTPRI10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-
        { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
        { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, ETM11, BBIF1, BBIF2 } },
        { 0xe6940008, 0, 16, 4, /* IPRCA */ { CRYPT1_ERR, CRYPT2_STD,
@@ -240,29 +222,18 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
        { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
 };
 
-static struct intc_sense_reg intca_sense_registers[] __initdata = {
-       { 0xe6900000, 16, 2, /* ICR1A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900004, 16, 2, /* ICR2A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-};
-
-static struct intc_mask_reg intca_ack_registers[] __initdata = {
-       { 0xe6900020, 0, 8, /* INTREQ00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900024, 0, 8, /* INTREQ10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-};
-
 static struct intc_desc intca_desc __initdata = {
        .name = "sh7367-intca",
        .force_enable = ENABLED,
        .force_disable = DISABLED,
        .hw = INTC_HW_DESC(intca_vectors, intca_groups,
                           intca_mask_registers, intca_prio_registers,
-                          intca_sense_registers, intca_ack_registers),
+                          NULL, NULL),
 };
 
+INTC_IRQ_PINS_16(intca_irq_pins, 0xe6900000,
+                INTC_VECT, "sh7367-intca-irq-pins");
+
 enum {
        UNUSED_INTCS = 0,
 
@@ -432,6 +403,7 @@ void __init sh7367_init_irq(void)
        void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
 
        register_intc_controller(&intca_desc);
+       register_intc_controller(&intca_irq_pins_desc);
        register_intc_controller(&intcs_desc);
 
        /* demux using INTEVTSA */
index 29cdc0522d9ca9a463a624f8a4019838a36e5fd5..2d8856df80e2796c7d100a84e419a8d47a515490 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
+#include <mach/intc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -29,10 +30,6 @@ enum {
        UNUSED_INTCA = 0,
 
        /* interrupt sources INTCA */
-       IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
-       IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
-       IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
-       IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
        DIRC,
        CRYPT_STD,
        IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
@@ -86,22 +83,6 @@ enum {
 };
 
 static struct intc_vect intca_vectors[] __initdata = {
-       INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
-       INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
-       INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
-       INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
-       INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
-       INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
-       INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
-       INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
-       INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
-       INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
-       INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0),
-       INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
-       INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
-       INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
-       INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
-       INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
        INTC_VECT(DIRC, 0x0560),
        INTC_VECT(CRYPT_STD, 0x0700),
        INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
@@ -203,15 +184,6 @@ static struct intc_group intca_groups[] __initdata = {
 };
 
 static struct intc_mask_reg intca_mask_registers[] __initdata = {
-       { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-
        { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
          { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
            AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
@@ -282,15 +254,6 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
 };
 
 static struct intc_prio_reg intca_prio_registers[] __initdata = {
-       { 0xe6900010, 0, 32, 4, /* INTPRI00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900014, 0, 32, 4, /* INTPRI10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900018, 0, 32, 4, /* INTPRI20A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690001c, 0, 32, 4, /* INTPRI30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-
        { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, 0 } },
        { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
        { 0xe6940008, 0, 16, 4, /* IPRCA */ { 0, CRYPT_STD,
@@ -336,33 +299,13 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
        { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
 };
 
-static struct intc_sense_reg intca_sense_registers[] __initdata = {
-       { 0xe6900000, 32, 4, /* ICR1A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900004, 32, 4, /* ICR2A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900008, 32, 4, /* ICR3A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690000c, 32, 4, /* ICR4A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-};
-
-static struct intc_mask_reg intca_ack_registers[] __initdata = {
-       { 0xe6900020, 0, 8, /* INTREQ00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900024, 0, 8, /* INTREQ10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900028, 0, 8, /* INTREQ20A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690002c, 0, 8, /* INTREQ30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-};
-
-static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
-                            intca_vectors, intca_groups,
-                            intca_mask_registers, intca_prio_registers,
-                            intca_sense_registers, intca_ack_registers);
+static DECLARE_INTC_DESC(intca_desc, "sh7372-intca",
+                        intca_vectors, intca_groups,
+                        intca_mask_registers, intca_prio_registers,
+                        NULL);
 
+INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
+                INTC_VECT, "sh7372-intca-irq-pins");
 enum {
        UNUSED_INTCS = 0,
        ENABLED_INTCS,
@@ -618,6 +561,7 @@ void __init sh7372_init_irq(void)
        intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);
 
        register_intc_controller(&intca_desc);
+       register_intc_controller(&intca_irq_pins_desc);
        register_intc_controller(&intcs_desc);
 
        /* demux using INTEVTSA */
index fe45154ce660a420d55bf0b31b73c3f684a0f886..2af4e6e9bc5b3a852070367d80ba9e3b3e27c370 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
+#include <mach/intc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -31,10 +32,6 @@ enum {
        DISABLED,
 
        /* interrupt sources INTCA */
-       IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
-       IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
-       IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
-       IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
        DIRC,
        _2DG,
        CRYPT_STD,
@@ -91,22 +88,6 @@ enum {
 };
 
 static struct intc_vect intca_vectors[] __initdata = {
-       INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
-       INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
-       INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
-       INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
-       INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
-       INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
-       INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
-       INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
-       INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
-       INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
-       INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
-       INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
-       INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
-       INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
-       INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
-       INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
        INTC_VECT(DIRC, 0x0560),
        INTC_VECT(_2DG, 0x05e0),
        INTC_VECT(CRYPT_STD, 0x0700),
@@ -203,15 +184,6 @@ static struct intc_group intca_groups[] __initdata = {
 };
 
 static struct intc_mask_reg intca_mask_registers[] __initdata = {
-       { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-
        { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
          { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
            AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
@@ -273,15 +245,6 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
 };
 
 static struct intc_prio_reg intca_prio_registers[] __initdata = {
-       { 0xe6900010, 0, 32, 4, /* INTPRI00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900014, 0, 32, 4, /* INTPRI10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900018, 0, 32, 4, /* INTPRI10A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690001c, 0, 32, 4, /* INTPRI30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-
        { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
        { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
        { 0xe6940008, 0, 16, 4, /* IPRCA */ { _2DG, CRYPT_STD,
@@ -315,37 +278,18 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
        { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
 };
 
-static struct intc_sense_reg intca_sense_registers[] __initdata = {
-       { 0xe6900000, 16, 2, /* ICR1A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900004, 16, 2, /* ICR2A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900008, 16, 2, /* ICR3A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690000c, 16, 2, /* ICR4A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-};
-
-static struct intc_mask_reg intca_ack_registers[] __initdata = {
-       { 0xe6900020, 0, 8, /* INTREQ00A */
-         { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
-       { 0xe6900024, 0, 8, /* INTREQ10A */
-         { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
-       { 0xe6900028, 0, 8, /* INTREQ20A */
-         { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
-       { 0xe690002c, 0, 8, /* INTREQ30A */
-         { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
-};
-
 static struct intc_desc intca_desc __initdata = {
        .name = "sh7377-intca",
        .force_enable = ENABLED,
        .force_disable = DISABLED,
        .hw = INTC_HW_DESC(intca_vectors, intca_groups,
                           intca_mask_registers, intca_prio_registers,
-                          intca_sense_registers, intca_ack_registers),
+                          NULL, NULL),
 };
 
+INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
+                INTC_VECT, "sh7377-intca-irq-pins");
+
 /* this macro ignore entry which is also in INTCA */
 #define __IGNORE(a...)
 #define __IGNORE0(a...) 0
@@ -638,6 +582,7 @@ void __init sh7377_init_irq(void)
        void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE);
 
        register_intc_controller(&intca_desc);
+       register_intc_controller(&intca_irq_pins_desc);
        register_intc_controller(&intcs_desc);
 
        /* demux using INTEVTSA */
index a911a60e7719a1e0fa040f5798b0e7174b060fa1..1eda6b0b69e308d24df75285cf10ba07d1f8e4b3 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
+#include <mach/intc.h>
+#include <mach/sh73a0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -255,20 +257,205 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
        return 0; /* always allow wakeup */
 }
 
+#define RELOC_BASE 0x1000
+
+/* INTCA IRQ pins at INTCS + 0x1000 to make space for GIC+INTC handling */
+#define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE)
+
+INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
+                INTCS_VECT_RELOC, "sh73a0-intca-irq-pins");
+
+static int to_gic_irq(struct irq_data *data)
+{
+       unsigned int vect = irq2evt(data->irq) - INTCS_VECT_BASE;
+
+       if (vect >= 0x3200)
+               vect -= 0x3000;
+       else
+               vect -= 0x0200;
+
+       return gic_spi((vect >> 5) + 1);
+}
+
+static int to_intca_reloc_irq(struct irq_data *data)
+{
+       return data->irq + (RELOC_BASE >> 5);
+}
+
+#define irq_cb(cb, irq) irq_get_chip(irq)->cb(irq_get_irq_data(irq))
+#define irq_cbp(cb, irq, p...) irq_get_chip(irq)->cb(irq_get_irq_data(irq), p)
+
+static void intca_gic_enable(struct irq_data *data)
+{
+       irq_cb(irq_unmask, to_intca_reloc_irq(data));
+       irq_cb(irq_unmask, to_gic_irq(data));
+}
+
+static void intca_gic_disable(struct irq_data *data)
+{
+       irq_cb(irq_mask, to_gic_irq(data));
+       irq_cb(irq_mask, to_intca_reloc_irq(data));
+}
+
+static void intca_gic_mask_ack(struct irq_data *data)
+{
+       irq_cb(irq_mask, to_gic_irq(data));
+       irq_cb(irq_mask_ack, to_intca_reloc_irq(data));
+}
+
+static void intca_gic_eoi(struct irq_data *data)
+{
+       irq_cb(irq_eoi, to_gic_irq(data));
+}
+
+static int intca_gic_set_type(struct irq_data *data, unsigned int type)
+{
+       return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type);
+}
+
+static int intca_gic_set_wake(struct irq_data *data, unsigned int on)
+{
+       return irq_cbp(irq_set_wake, to_intca_reloc_irq(data), on);
+}
+
+#ifdef CONFIG_SMP
+static int intca_gic_set_affinity(struct irq_data *data,
+                                 const struct cpumask *cpumask,
+                                 bool force)
+{
+       return irq_cbp(irq_set_affinity, to_gic_irq(data), cpumask, force);
+}
+#endif
+
+struct irq_chip intca_gic_irq_chip = {
+       .name                   = "INTCA-GIC",
+       .irq_mask               = intca_gic_disable,
+       .irq_unmask             = intca_gic_enable,
+       .irq_mask_ack           = intca_gic_mask_ack,
+       .irq_eoi                = intca_gic_eoi,
+       .irq_enable             = intca_gic_enable,
+       .irq_disable            = intca_gic_disable,
+       .irq_shutdown           = intca_gic_disable,
+       .irq_set_type           = intca_gic_set_type,
+       .irq_set_wake           = intca_gic_set_wake,
+#ifdef CONFIG_SMP
+       .irq_set_affinity       = intca_gic_set_affinity,
+#endif
+};
+
+static int to_intc_vect(int irq)
+{
+       unsigned int irq_pin = irq - gic_spi(1);
+       unsigned int offs;
+
+       if (irq_pin < 16)
+               offs = 0x0200;
+       else
+               offs = 0x3000;
+
+       return offs + (irq_pin << 5);
+}
+
+static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id)
+{
+       generic_handle_irq(intcs_evt2irq(to_intc_vect(irq)));
+       return IRQ_HANDLED;
+}
+
+static struct irqaction sh73a0_irq_pin_cascade[32];
+
+#define PINTER0 0xe69000a0
+#define PINTER1 0xe69000a4
+#define PINTRR0 0xe69000d0
+#define PINTRR1 0xe69000d4
+
+#define PINT0A_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq))
+#define PINT0B_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 8))
+#define PINT0C_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 16))
+#define PINT0D_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 24))
+#define PINT1E_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT1_IRQ(irq))
+
+INTC_PINT(intc_pint0, PINTER0, 0xe69000b0, "sh73a0-pint0",             \
+  INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D),      \
+  INTC_PINT_V(A, PINT0A_IRQ), INTC_PINT_V(B, PINT0B_IRQ),              \
+  INTC_PINT_V(C, PINT0C_IRQ), INTC_PINT_V(D, PINT0D_IRQ),              \
+  INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D),      \
+  INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D));
+
+INTC_PINT(intc_pint1, PINTER1, 0xe69000c0, "sh73a0-pint1",             \
+  INTC_PINT_E(E), INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, \
+  INTC_PINT_V(E, PINT1E_IRQ), INTC_PINT_V_NONE,                                \
+  INTC_PINT_V_NONE, INTC_PINT_V_NONE,                                  \
+  INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E(E), \
+  INTC_PINT_E(E), INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE);
+
+static struct irqaction sh73a0_pint0_cascade;
+static struct irqaction sh73a0_pint1_cascade;
+
+static void pint_demux(unsigned long rr, unsigned long er, int base_irq)
+{
+       unsigned long value =  ioread32(rr) & ioread32(er);
+       int k;
+
+       for (k = 0; k < 32; k++) {
+               if (value & (1 << (31 - k))) {
+                       generic_handle_irq(base_irq + k);
+                       iowrite32(~(1 << (31 - k)), rr);
+               }
+       }
+}
+
+static irqreturn_t sh73a0_pint0_demux(int irq, void *dev_id)
+{
+       pint_demux(PINTRR0, PINTER0, SH73A0_PINT0_IRQ(0));
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id)
+{
+       pint_demux(PINTRR1, PINTER1, SH73A0_PINT1_IRQ(0));
+       return IRQ_HANDLED;
+}
+
 void __init sh73a0_init_irq(void)
 {
        void __iomem *gic_dist_base = __io(0xf0001000);
        void __iomem *gic_cpu_base = __io(0xf0000100);
        void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+       int k, n;
 
        gic_init(0, 29, gic_dist_base, gic_cpu_base);
        gic_arch_extn.irq_set_wake = sh73a0_set_wake;
 
        register_intc_controller(&intcs_desc);
+       register_intc_controller(&intca_irq_pins_desc);
+       register_intc_controller(&intc_pint0_desc);
+       register_intc_controller(&intc_pint1_desc);
 
        /* demux using INTEVTSA */
        sh73a0_intcs_cascade.name = "INTCS cascade";
        sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
        sh73a0_intcs_cascade.dev_id = intevtsa;
        setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
+
+       /* IRQ pins require special handling through INTCA and GIC */
+       for (k = 0; k < 32; k++) {
+               sh73a0_irq_pin_cascade[k].name = "INTCA-GIC cascade";
+               sh73a0_irq_pin_cascade[k].handler = sh73a0_irq_pin_demux;
+               setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
+
+               n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
+               irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
+                                             handle_level_irq, "level");
+               set_irq_flags(n, IRQF_VALID); /* yuck */
+       }
+
+       /* PINT pins are sanely tied to the GIC as SPI */
+       sh73a0_pint0_cascade.name = "PINT0 cascade";
+       sh73a0_pint0_cascade.handler = sh73a0_pint0_demux;
+       setup_irq(gic_spi(33), &sh73a0_pint0_cascade);
+
+       sh73a0_pint1_cascade.name = "PINT1 cascade";
+       sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
+       setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
 }
index 128555e76e430fb41d4313a6e2dea46fbdd73146..e6e524654e676e270d702de51005ffcabc0557e2 100644 (file)
 #include <linux/gpio.h>
 #include <mach/sh7367.h>
 
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx)                              \
-       _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),       \
-       _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),       \
-       _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),       \
-       _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),       \
-       _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _90(fn, pfx, sfx)                              \
-       _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx),     \
-       _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx),     \
-       _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx),     \
-       _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx),     \
-       _10(fn, pfx##9, sfx)
-
-#define _273(fn, pfx, sfx)             \
-       _10(fn, pfx, sfx), _90(fn, pfx, sfx),           \
-       _10(fn, pfx##10, sfx), _90(fn, pfx##1, sfx),    \
-       _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx),   \
-       _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx),   \
-       _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx),   \
-       _10(fn, pfx##26, sfx), _1(fn, pfx##270, sfx),   \
-       _1(fn, pfx##271, sfx), _1(fn, pfx##272, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_273(str) _273(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx)                             \
+       PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx),           \
+       PORT_10(fn, pfx##10, sfx), PORT_90(fn, pfx##1, sfx),    \
+       PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx),   \
+       PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx),   \
+       PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx),   \
+       PORT_10(fn, pfx##26, sfx), PORT_1(fn, pfx##270, sfx),   \
+       PORT_1(fn, pfx##271, sfx), PORT_1(fn, pfx##272, sfx)
 
 enum {
        PINMUX_RESERVED = 0,
 
        PINMUX_DATA_BEGIN,
-       PORT_273(DATA), /* PORT0_DATA -> PORT272_DATA */
+       PORT_ALL(DATA), /* PORT0_DATA -> PORT272_DATA */
        PINMUX_DATA_END,
 
        PINMUX_INPUT_BEGIN,
-       PORT_273(IN), /* PORT0_IN -> PORT272_IN */
+       PORT_ALL(IN), /* PORT0_IN -> PORT272_IN */
        PINMUX_INPUT_END,
 
        PINMUX_INPUT_PULLUP_BEGIN,
-       PORT_273(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
+       PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
        PINMUX_INPUT_PULLUP_END,
 
        PINMUX_INPUT_PULLDOWN_BEGIN,
-       PORT_273(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
+       PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
        PINMUX_INPUT_PULLDOWN_END,
 
        PINMUX_OUTPUT_BEGIN,
-       PORT_273(OUT), /* PORT0_OUT -> PORT272_OUT */
+       PORT_ALL(OUT), /* PORT0_OUT -> PORT272_OUT */
        PINMUX_OUTPUT_END,
 
        PINMUX_FUNCTION_BEGIN,
-       PORT_273(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
-       PORT_273(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
-       PORT_273(FN0), /* PORT0_FN0 -> PORT272_FN0 */
-       PORT_273(FN1), /* PORT0_FN1 -> PORT272_FN1 */
-       PORT_273(FN2), /* PORT0_FN2 -> PORT272_FN2 */
-       PORT_273(FN3), /* PORT0_FN3 -> PORT272_FN3 */
-       PORT_273(FN4), /* PORT0_FN4 -> PORT272_FN4 */
-       PORT_273(FN5), /* PORT0_FN5 -> PORT272_FN5 */
-       PORT_273(FN6), /* PORT0_FN6 -> PORT272_FN6 */
-       PORT_273(FN7), /* PORT0_FN7 -> PORT272_FN7 */
+       PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
+       PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
+       PORT_ALL(FN0), /* PORT0_FN0 -> PORT272_FN0 */
+       PORT_ALL(FN1), /* PORT0_FN1 -> PORT272_FN1 */
+       PORT_ALL(FN2), /* PORT0_FN2 -> PORT272_FN2 */
+       PORT_ALL(FN3), /* PORT0_FN3 -> PORT272_FN3 */
+       PORT_ALL(FN4), /* PORT0_FN4 -> PORT272_FN4 */
+       PORT_ALL(FN5), /* PORT0_FN5 -> PORT272_FN5 */
+       PORT_ALL(FN6), /* PORT0_FN6 -> PORT272_FN6 */
+       PORT_ALL(FN7), /* PORT0_FN7 -> PORT272_FN7 */
 
        MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
        PINMUX_FUNCTION_END,
@@ -327,41 +308,6 @@ enum {
        PINMUX_MARK_END,
 };
 
-#define PORT_DATA_I(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-
 static pinmux_enum_t pinmux_data[] = {
 
        /* specify valid pin states for each pin in GPIO mode */
@@ -1098,13 +1044,9 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
 };
 
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_273() _273(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
 static struct pinmux_gpio pinmux_gpios[] = {
        /* 49-1 -> 49-6 (GPIO) */
-       GPIO_PORT_273(),
+       GPIO_PORT_ALL(),
 
        /* Special Pull-up / Pull-down Functions */
        GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
@@ -1345,22 +1287,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
        GPIO_FN(DIVLOCK),
 };
 
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out)            \
-       0, (out), (in), 0,                      \
-       0, 0, 0, 0,                             \
-       0, 0, (in_pd), 0,                       \
-       0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg)                                                \
-       { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {           \
-               PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,           \
-                    PORT##nr##_IN_PU, PORT##nr##_OUT),         \
-               PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
-               PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
-               PORT##nr##_FN6, PORT##nr##_FN7 }                \
-       }
-
 static struct pinmux_cfg_reg pinmux_config_regs[] = {
        PORTCR(0, 0xe6050000), /* PORT0CR */
        PORTCR(1, 0xe6050001), /* PORT1CR */
index 9c265dae138a31c245c63fbaf2f87e3f5f147dbb..1bd6585a6acffd23a3094c90487a723fca5beb09 100644 (file)
 #include <linux/gpio.h>
 #include <mach/sh7372.h>
 
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx)                              \
-       _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),       \
-       _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),       \
-       _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),       \
-       _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),       \
-       _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _80(fn, pfx, sfx)                              \
-       _10(fn, pfx##1, sfx),   _10(fn, pfx##2, sfx),   \
-       _10(fn, pfx##3, sfx),   _10(fn, pfx##4, sfx),   \
-       _10(fn, pfx##5, sfx),   _10(fn, pfx##6, sfx),   \
-       _10(fn, pfx##7, sfx),   _10(fn, pfx##8, sfx)
-
-#define _190(fn, pfx, sfx) \
-       _10(fn, pfx, sfx), _80(fn, pfx, sfx), _10(fn, pfx##9, sfx), \
-       _10(fn, pfx##10, sfx), _80(fn, pfx##1, sfx), _1(fn, pfx##190, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_ALL(str) _190(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx) \
+       PORT_10(fn, pfx, sfx),          PORT_90(fn, pfx, sfx), \
+       PORT_10(fn, pfx##10, sfx),      PORT_10(fn, pfx##11, sfx), \
+       PORT_10(fn, pfx##12, sfx),      PORT_10(fn, pfx##13, sfx), \
+       PORT_10(fn, pfx##14, sfx),      PORT_10(fn, pfx##15, sfx), \
+       PORT_10(fn, pfx##16, sfx),      PORT_10(fn, pfx##17, sfx), \
+       PORT_10(fn, pfx##18, sfx),      PORT_1(fn, pfx##190, sfx)
 
 enum {
        PINMUX_RESERVED = 0,
@@ -381,108 +367,124 @@ enum {
        PINMUX_MARK_END,
 };
 
-/* PORT_DATA_I_PD(nr) */
-#define _I___D(nr)                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD)
-
-/* PORT_DATA_I_PU(nr) */
-#define _I__U_(nr)                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PU)
-
-/* PORT_DATA_I_PU_PD(nr) */
-#define _I__UD(nr)                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-/* PORT_DATA_O(nr) */
-#define __O___(nr)                                                     \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
-
-/* PORT_DATA_IO(nr) */
-#define _IO___(nr)                                  \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN)
-
-/* PORT_DATA_IO_PD(nr) */
-#define _IO__D(nr)                                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD)
-
-/* PORT_DATA_IO_PU(nr) */
-#define _IO_U_(nr)                                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PU)
-
-/* PORT_DATA_IO_PU_PD(nr) */
-#define _IO_UD(nr)                                          \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
-                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
-
 static pinmux_enum_t pinmux_data[] = {
 
        /* specify valid pin states for each pin in GPIO mode */
-
-       _IO__D(0), _IO__D(1), __O___(2), _I___D(3), _I___D(4),
-       _I___D(5), _IO_UD(6), _I___D(7), _IO__D(8), __O___(9),
-
-       __O___(10), __O___(11), _IO_UD(12), _IO__D(13), _IO__D(14),
-       __O___(15), _IO__D(16), _IO__D(17), _I___D(18), _IO___(19),
-
-       _IO___(20), _IO___(21), _IO___(22), _IO___(23), _IO___(24),
-       _IO___(25), _IO___(26), _IO___(27), _IO___(28), _IO___(29),
-
-       _IO___(30), _IO___(31), _IO___(32), _IO___(33), _IO___(34),
-       _IO___(35), _IO___(36), _IO___(37), _IO___(38), _IO___(39),
-
-       _IO___(40), _IO___(41), _IO___(42), _IO___(43), _IO___(44),
-       _IO___(45), _IO_U_(46), _IO_U_(47), _IO_U_(48), _IO_U_(49),
-
-       _IO_U_(50), _IO_U_(51), _IO_U_(52), _IO_U_(53), _IO_U_(54),
-       _IO_U_(55), _IO_U_(56), _IO_U_(57), _IO_U_(58), _IO_U_(59),
-
-       _IO_U_(60), _IO_U_(61), _IO___(62), __O___(63), __O___(64),
-       _IO_U_(65), __O___(66), _IO_U_(67), __O___(68), _IO___(69), /*66?*/
-
-       _IO___(70), _IO___(71), __O___(72), _I__U_(73), _I__UD(74),
-       _IO_UD(75), _IO_UD(76), _IO_UD(77), _IO_UD(78), _IO_UD(79),
-
-       _IO_UD(80), _IO_UD(81), _IO_UD(82), _IO_UD(83), _IO_UD(84),
-       _IO_UD(85), _IO_UD(86), _IO_UD(87), _IO_UD(88), _IO_UD(89),
-
-       _IO_UD(90), _IO_UD(91), _IO_UD(92), _IO_UD(93), _IO_UD(94),
-       _IO_UD(95), _IO_U_(96), _IO_UD(97), _IO_UD(98), __O___(99), /*99?*/
-
-       _IO__D(100), _IO__D(101), _IO__D(102), _IO__D(103), _IO__D(104),
-       _IO__D(105), _IO_U_(106), _IO_U_(107), _IO_U_(108), _IO_U_(109),
-
-       _IO_U_(110), _IO_U_(111), _IO__D(112), _IO__D(113), _IO_U_(114),
-       _IO_U_(115), _IO_U_(116), _IO_U_(117), _IO_U_(118), _IO_U_(119),
-
-       _IO_U_(120), _IO__D(121), _IO__D(122), _IO__D(123), _IO__D(124),
-       _IO__D(125), _IO__D(126), _IO__D(127), _IO__D(128), _IO_UD(129),
-
-       _IO_UD(130), _IO_UD(131), _IO_UD(132), _IO_UD(133), _IO_UD(134),
-       _IO_UD(135), _IO__D(136), _IO__D(137), _IO__D(138), _IO__D(139),
-
-       _IO__D(140), _IO__D(141), _IO__D(142), _IO_UD(143), _IO__D(144),
-       _IO__D(145), _IO__D(146), _IO__D(147), _IO__D(148), _IO__D(149),
-
-       _IO__D(150), _IO__D(151), _IO_UD(152), _I___D(153), _IO_UD(154),
-       _I___D(155), _IO__D(156), _IO__D(157), _I___D(158), _IO__D(159),
-
-       __O___(160), _IO__D(161), _IO__D(162), _IO__D(163), _I___D(164),
-       _IO__D(165), _I___D(166), _I___D(167), _I___D(168), _I___D(169),
-
-       _I___D(170), __O___(171), _IO_UD(172), _IO_UD(173), _IO_UD(174),
-       _IO_UD(175), _IO_UD(176), _IO_UD(177), _IO_UD(178), __O___(179),
-
-       _IO_UD(180), _IO_UD(181), _IO_UD(182), _IO_UD(183), _IO_UD(184),
-       __O___(185), _IO_UD(186), _IO_UD(187), _IO_UD(188), _IO_UD(189),
-
-       _IO_UD(190),
+       PORT_DATA_IO_PD(0),             PORT_DATA_IO_PD(1),
+       PORT_DATA_O(2),                 PORT_DATA_I_PD(3),
+       PORT_DATA_I_PD(4),              PORT_DATA_I_PD(5),
+       PORT_DATA_IO_PU_PD(6),          PORT_DATA_I_PD(7),
+       PORT_DATA_IO_PD(8),             PORT_DATA_O(9),
+
+       PORT_DATA_O(10),                PORT_DATA_O(11),
+       PORT_DATA_IO_PU_PD(12),         PORT_DATA_IO_PD(13),
+       PORT_DATA_IO_PD(14),            PORT_DATA_O(15),
+       PORT_DATA_IO_PD(16),            PORT_DATA_IO_PD(17),
+       PORT_DATA_I_PD(18),             PORT_DATA_IO(19),
+
+       PORT_DATA_IO(20),               PORT_DATA_IO(21),
+       PORT_DATA_IO(22),               PORT_DATA_IO(23),
+       PORT_DATA_IO(24),               PORT_DATA_IO(25),
+       PORT_DATA_IO(26),               PORT_DATA_IO(27),
+       PORT_DATA_IO(28),               PORT_DATA_IO(29),
+
+       PORT_DATA_IO(30),               PORT_DATA_IO(31),
+       PORT_DATA_IO(32),               PORT_DATA_IO(33),
+       PORT_DATA_IO(34),               PORT_DATA_IO(35),
+       PORT_DATA_IO(36),               PORT_DATA_IO(37),
+       PORT_DATA_IO(38),               PORT_DATA_IO(39),
+
+       PORT_DATA_IO(40),               PORT_DATA_IO(41),
+       PORT_DATA_IO(42),               PORT_DATA_IO(43),
+       PORT_DATA_IO(44),               PORT_DATA_IO(45),
+       PORT_DATA_IO_PU(46),            PORT_DATA_IO_PU(47),
+       PORT_DATA_IO_PU(48),            PORT_DATA_IO_PU(49),
+
+       PORT_DATA_IO_PU(50),            PORT_DATA_IO_PU(51),
+       PORT_DATA_IO_PU(52),            PORT_DATA_IO_PU(53),
+       PORT_DATA_IO_PU(54),            PORT_DATA_IO_PU(55),
+       PORT_DATA_IO_PU(56),            PORT_DATA_IO_PU(57),
+       PORT_DATA_IO_PU(58),            PORT_DATA_IO_PU(59),
+
+       PORT_DATA_IO_PU(60),            PORT_DATA_IO_PU(61),
+       PORT_DATA_IO(62),               PORT_DATA_O(63),
+       PORT_DATA_O(64),                PORT_DATA_IO_PU(65),
+       PORT_DATA_O(66),                PORT_DATA_IO_PU(67),  /*66?*/
+       PORT_DATA_O(68),                PORT_DATA_IO(69),
+
+       PORT_DATA_IO(70),               PORT_DATA_IO(71),
+       PORT_DATA_O(72),                PORT_DATA_I_PU(73),
+       PORT_DATA_I_PU_PD(74),          PORT_DATA_IO_PU_PD(75),
+       PORT_DATA_IO_PU_PD(76),         PORT_DATA_IO_PU_PD(77),
+       PORT_DATA_IO_PU_PD(78),         PORT_DATA_IO_PU_PD(79),
+
+       PORT_DATA_IO_PU_PD(80),         PORT_DATA_IO_PU_PD(81),
+       PORT_DATA_IO_PU_PD(82),         PORT_DATA_IO_PU_PD(83),
+       PORT_DATA_IO_PU_PD(84),         PORT_DATA_IO_PU_PD(85),
+       PORT_DATA_IO_PU_PD(86),         PORT_DATA_IO_PU_PD(87),
+       PORT_DATA_IO_PU_PD(88),         PORT_DATA_IO_PU_PD(89),
+
+       PORT_DATA_IO_PU_PD(90),         PORT_DATA_IO_PU_PD(91),
+       PORT_DATA_IO_PU_PD(92),         PORT_DATA_IO_PU_PD(93),
+       PORT_DATA_IO_PU_PD(94),         PORT_DATA_IO_PU_PD(95),
+       PORT_DATA_IO_PU(96),            PORT_DATA_IO_PU_PD(97),
+       PORT_DATA_IO_PU_PD(98),         PORT_DATA_O(99), /*99?*/
+
+       PORT_DATA_IO_PD(100),           PORT_DATA_IO_PD(101),
+       PORT_DATA_IO_PD(102),           PORT_DATA_IO_PD(103),
+       PORT_DATA_IO_PD(104),           PORT_DATA_IO_PD(105),
+       PORT_DATA_IO_PU(106),           PORT_DATA_IO_PU(107),
+       PORT_DATA_IO_PU(108),           PORT_DATA_IO_PU(109),
+
+       PORT_DATA_IO_PU(110),           PORT_DATA_IO_PU(111),
+       PORT_DATA_IO_PD(112),           PORT_DATA_IO_PD(113),
+       PORT_DATA_IO_PU(114),           PORT_DATA_IO_PU(115),
+       PORT_DATA_IO_PU(116),           PORT_DATA_IO_PU(117),
+       PORT_DATA_IO_PU(118),           PORT_DATA_IO_PU(119),
+
+       PORT_DATA_IO_PU(120),           PORT_DATA_IO_PD(121),
+       PORT_DATA_IO_PD(122),           PORT_DATA_IO_PD(123),
+       PORT_DATA_IO_PD(124),           PORT_DATA_IO_PD(125),
+       PORT_DATA_IO_PD(126),           PORT_DATA_IO_PD(127),
+       PORT_DATA_IO_PD(128),           PORT_DATA_IO_PU_PD(129),
+
+       PORT_DATA_IO_PU_PD(130),        PORT_DATA_IO_PU_PD(131),
+       PORT_DATA_IO_PU_PD(132),        PORT_DATA_IO_PU_PD(133),
+       PORT_DATA_IO_PU_PD(134),        PORT_DATA_IO_PU_PD(135),
+       PORT_DATA_IO_PD(136),           PORT_DATA_IO_PD(137),
+       PORT_DATA_IO_PD(138),           PORT_DATA_IO_PD(139),
+
+       PORT_DATA_IO_PD(140),           PORT_DATA_IO_PD(141),
+       PORT_DATA_IO_PD(142),           PORT_DATA_IO_PU_PD(143),
+       PORT_DATA_IO_PD(144),           PORT_DATA_IO_PD(145),
+       PORT_DATA_IO_PD(146),           PORT_DATA_IO_PD(147),
+       PORT_DATA_IO_PD(148),           PORT_DATA_IO_PD(149),
+
+       PORT_DATA_IO_PD(150),           PORT_DATA_IO_PD(151),
+       PORT_DATA_IO_PU_PD(152),        PORT_DATA_I_PD(153),
+       PORT_DATA_IO_PU_PD(154),        PORT_DATA_I_PD(155),
+       PORT_DATA_IO_PD(156),           PORT_DATA_IO_PD(157),
+       PORT_DATA_I_PD(158),            PORT_DATA_IO_PD(159),
+
+       PORT_DATA_O(160),               PORT_DATA_IO_PD(161),
+       PORT_DATA_IO_PD(162),           PORT_DATA_IO_PD(163),
+       PORT_DATA_I_PD(164),            PORT_DATA_IO_PD(165),
+       PORT_DATA_I_PD(166),            PORT_DATA_I_PD(167),
+       PORT_DATA_I_PD(168),            PORT_DATA_I_PD(169),
+
+       PORT_DATA_I_PD(170),            PORT_DATA_O(171),
+       PORT_DATA_IO_PU_PD(172),        PORT_DATA_IO_PU_PD(173),
+       PORT_DATA_IO_PU_PD(174),        PORT_DATA_IO_PU_PD(175),
+       PORT_DATA_IO_PU_PD(176),        PORT_DATA_IO_PU_PD(177),
+       PORT_DATA_IO_PU_PD(178),        PORT_DATA_O(179),
+
+       PORT_DATA_IO_PU_PD(180),        PORT_DATA_IO_PU_PD(181),
+       PORT_DATA_IO_PU_PD(182),        PORT_DATA_IO_PU_PD(183),
+       PORT_DATA_IO_PU_PD(184),        PORT_DATA_O(185),
+       PORT_DATA_IO_PU_PD(186),        PORT_DATA_IO_PU_PD(187),
+       PORT_DATA_IO_PU_PD(188),        PORT_DATA_IO_PU_PD(189),
+
+       PORT_DATA_IO_PU_PD(190),
 
        /* IRQ */
        PINMUX_DATA(IRQ0_6_MARK,        PORT6_FN0,      MSEL1CR_0_0),
@@ -926,10 +928,6 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(MFIv4_MARK,         MSEL4CR_6_1),
 };
 
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_ALL() _190(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
 static struct pinmux_gpio pinmux_gpios[] = {
 
        /* PORT */
@@ -1201,22 +1199,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
        GPIO_FN(SDENC_DV_CLKI),
 };
 
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out)            \
-       0, (out), (in), 0,                      \
-       0, 0, 0, 0,                             \
-       0, 0, (in_pd), 0,                       \
-       0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg)                                                \
-       { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {           \
-               PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,           \
-                    PORT##nr##_IN_PU, PORT##nr##_OUT),         \
-               PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
-               PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
-               PORT##nr##_FN6, PORT##nr##_FN7 }                \
-       }
-
 static struct pinmux_cfg_reg pinmux_config_regs[] = {
        PORTCR(0,       0xE6051000), /* PORT0CR */
        PORTCR(1,       0xE6051001), /* PORT1CR */
index 613e6842ad0521a6da29eb6262a3d1be48bf880e..2f10511946ad1a8a60287f02ef6b7c6fa58bc211 100644 (file)
 #include <linux/gpio.h>
 #include <mach/sh7377.h>
 
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx)                              \
-       _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),       \
-       _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),       \
-       _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),       \
-       _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),       \
-       _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _90(fn, pfx, sfx)                              \
-       _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx),     \
-       _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx),     \
-       _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx),     \
-       _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx),     \
-       _10(fn, pfx##9, sfx)
-
-#define _265(fn, pfx, sfx)                             \
-       _10(fn, pfx, sfx), _90(fn, pfx, sfx),           \
-       _10(fn, pfx##10, sfx),                          \
-       _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx),   \
-       _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx),   \
-       _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx),   \
-       _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx),   \
-       _1(fn, pfx##118, sfx),                          \
-       _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx),   \
-       _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx),   \
-       _10(fn, pfx##15, sfx),                          \
-       _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx),   \
-       _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx),   \
-       _1(fn, pfx##164, sfx),                          \
-       _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx),   \
-       _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx),   \
-       _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx),   \
-       _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx),   \
-       _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx),   \
-       _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx),   \
-       _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx),   \
-       _1(fn, pfx##260, sfx), _1(fn, pfx##261, sfx),   \
-       _1(fn, pfx##262, sfx), _1(fn, pfx##263, sfx),   \
-       _1(fn, pfx##264, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_265(str) _265(_PORT, PORT, str)
+#define CPU_ALL_PORT(fn, pfx, sfx)                             \
+       PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx),           \
+       PORT_10(fn, pfx##10, sfx),                              \
+       PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx),   \
+       PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx),   \
+       PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx),   \
+       PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx),   \
+       PORT_1(fn, pfx##118, sfx),                              \
+       PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx),   \
+       PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx),   \
+       PORT_10(fn, pfx##15, sfx),                              \
+       PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx),   \
+       PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx),   \
+       PORT_1(fn, pfx##164, sfx),                              \
+       PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx),   \
+       PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx),   \
+       PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx),   \
+       PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx),   \
+       PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx),   \
+       PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx),   \
+       PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx),   \
+       PORT_1(fn, pfx##260, sfx), PORT_1(fn, pfx##261, sfx),   \
+       PORT_1(fn, pfx##262, sfx), PORT_1(fn, pfx##263, sfx),   \
+       PORT_1(fn, pfx##264, sfx)
 
 enum {
        PINMUX_RESERVED = 0,
 
        PINMUX_DATA_BEGIN,
-       PORT_265(DATA), /* PORT0_DATA -> PORT264_DATA */
+       PORT_ALL(DATA), /* PORT0_DATA -> PORT264_DATA */
        PINMUX_DATA_END,
 
        PINMUX_INPUT_BEGIN,
-       PORT_265(IN), /* PORT0_IN -> PORT264_IN */
+       PORT_ALL(IN), /* PORT0_IN -> PORT264_IN */
        PINMUX_INPUT_END,
 
        PINMUX_INPUT_PULLUP_BEGIN,
-       PORT_265(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
+       PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
        PINMUX_INPUT_PULLUP_END,
 
        PINMUX_INPUT_PULLDOWN_BEGIN,
-       PORT_265(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
+       PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
        PINMUX_INPUT_PULLDOWN_END,
 
        PINMUX_OUTPUT_BEGIN,
-       PORT_265(OUT), /* PORT0_OUT -> PORT264_OUT */
+       PORT_ALL(OUT), /* PORT0_OUT -> PORT264_OUT */
        PINMUX_OUTPUT_END,
 
        PINMUX_FUNCTION_BEGIN,
-       PORT_265(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
-       PORT_265(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
-       PORT_265(FN0), /* PORT0_FN0 -> PORT264_FN0 */
-       PORT_265(FN1), /* PORT0_FN1 -> PORT264_FN1 */
-       PORT_265(FN2), /* PORT0_FN2 -> PORT264_FN2 */
-       PORT_265(FN3), /* PORT0_FN3 -> PORT264_FN3 */
-       PORT_265(FN4), /* PORT0_FN4 -> PORT264_FN4 */
-       PORT_265(FN5), /* PORT0_FN5 -> PORT264_FN5 */
-       PORT_265(FN6), /* PORT0_FN6 -> PORT264_FN6 */
-       PORT_265(FN7), /* PORT0_FN7 -> PORT264_FN7 */
+       PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
+       PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
+       PORT_ALL(FN0), /* PORT0_FN0 -> PORT264_FN0 */
+       PORT_ALL(FN1), /* PORT0_FN1 -> PORT264_FN1 */
+       PORT_ALL(FN2), /* PORT0_FN2 -> PORT264_FN2 */
+       PORT_ALL(FN3), /* PORT0_FN3 -> PORT264_FN3 */
+       PORT_ALL(FN4), /* PORT0_FN4 -> PORT264_FN4 */
+       PORT_ALL(FN5), /* PORT0_FN5 -> PORT264_FN5 */
+       PORT_ALL(FN6), /* PORT0_FN6 -> PORT264_FN6 */
+       PORT_ALL(FN7), /* PORT0_FN7 -> PORT264_FN7 */
 
        MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
        MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
@@ -360,45 +341,6 @@ enum {
        PINMUX_MARK_END,
 };
 
-#define PORT_DATA_I(nr)        \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr)     \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr)     \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr)  \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PD,        \
-                               PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr)        \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr)       \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr)    \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr)    \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
 static pinmux_enum_t pinmux_data[] = {
        /* specify valid pin states for each pin in GPIO mode */
        /* 55-1 (GPIO) */
@@ -1078,13 +1020,9 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
 };
 
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_265() _265(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
 static struct pinmux_gpio pinmux_gpios[] = {
        /* 55-1 -> 55-5 (GPIO) */
-       GPIO_PORT_265(),
+       GPIO_PORT_ALL(),
 
        /* Special Pull-up / Pull-down Functions */
        GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
@@ -1362,23 +1300,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
        GPIO_FN(RESETOUTS),
 };
 
-/* helper for top 4 bits in PORTnCR */
-#define PCRH(in, in_pd, in_pu, out)    \
-       0, (out), (in), 0,      \
-               0, 0, 0, 0,     \
-               0, 0, (in_pd), 0,       \
-               0, 0, (in_pu), 0
-
-#define PORTCR(nr, reg)        \
-       { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {   \
-                       PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,   \
-                                PORT##nr##_IN_PU, PORT##nr##_OUT),     \
-                               PORT##nr##_FN0, PORT##nr##_FN1, \
-                               PORT##nr##_FN2, PORT##nr##_FN3, \
-                               PORT##nr##_FN4, PORT##nr##_FN5, \
-                               PORT##nr##_FN6, PORT##nr##_FN7 }        \
-       }
-
 static struct pinmux_cfg_reg pinmux_config_regs[] = {
        PORTCR(0, 0xe6050000), /* PORT0CR */
        PORTCR(1, 0xe6050001), /* PORT1CR */
index 3eed44eb98b4367719a0c7a65cee78f72996d65a..e05634ce2e0d60e8831b4c083f53a9e25ae70111 100644 (file)
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 #include <mach/sh73a0.h>
-
-#define _1(fn, pfx, sfx) fn(pfx, sfx)
-
-#define _10(fn, pfx, sfx)                              \
-       _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx),       \
-       _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx),       \
-       _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx),       \
-       _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx),       \
-       _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
-
-#define _310(fn, pfx, sfx)                             \
-       _10(fn, pfx,    sfx), _10(fn, pfx##1, sfx),     \
-       _10(fn, pfx##2, sfx), _10(fn, pfx##3, sfx),     \
-       _10(fn, pfx##4, sfx), _10(fn, pfx##5, sfx),     \
-       _10(fn, pfx##6, sfx), _10(fn, pfx##7, sfx),     \
-       _10(fn, pfx##8, sfx), _10(fn, pfx##9, sfx),     \
-       _10(fn, pfx##10, sfx),                          \
-       _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx),   \
-       _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx),   \
-       _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx),   \
-       _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx),   \
-       _1(fn, pfx##118, sfx),                          \
-       _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx),   \
-       _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx),   \
-       _10(fn, pfx##15, sfx),                          \
-       _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx),   \
-       _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx),   \
-       _1(fn, pfx##164, sfx),                          \
-       _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx),   \
-       _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx),   \
-       _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx),   \
-       _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx),   \
-       _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx),   \
-       _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx),   \
-       _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx),   \
-       _10(fn, pfx##26, sfx), _10(fn, pfx##27, sfx),   \
-       _1(fn, pfx##280, sfx), _1(fn, pfx##281, sfx),   \
-       _1(fn, pfx##282, sfx),                          \
-       _1(fn, pfx##288, sfx), _1(fn, pfx##289, sfx),   \
-       _10(fn, pfx##29, sfx), _10(fn, pfx##30, sfx)
-
-#define _PORT(pfx, sfx) pfx##_##sfx
-#define PORT_310(str) _310(_PORT, PORT, str)
+#include <mach/irqs.h>
+
+#define CPU_ALL_PORT(fn, pfx, sfx)                             \
+       PORT_10(fn, pfx,    sfx), PORT_10(fn, pfx##1, sfx),     \
+       PORT_10(fn, pfx##2, sfx), PORT_10(fn, pfx##3, sfx),     \
+       PORT_10(fn, pfx##4, sfx), PORT_10(fn, pfx##5, sfx),     \
+       PORT_10(fn, pfx##6, sfx), PORT_10(fn, pfx##7, sfx),     \
+       PORT_10(fn, pfx##8, sfx), PORT_10(fn, pfx##9, sfx),     \
+       PORT_10(fn, pfx##10, sfx),                              \
+       PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx),   \
+       PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx),   \
+       PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx),   \
+       PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx),   \
+       PORT_1(fn, pfx##118, sfx),                              \
+       PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx),   \
+       PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx),   \
+       PORT_10(fn, pfx##15, sfx),                              \
+       PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx),   \
+       PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx),   \
+       PORT_1(fn, pfx##164, sfx),                              \
+       PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx),   \
+       PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx),   \
+       PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx),   \
+       PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx),   \
+       PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx),   \
+       PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx),   \
+       PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx),   \
+       PORT_10(fn, pfx##26, sfx), PORT_10(fn, pfx##27, sfx),   \
+       PORT_1(fn, pfx##280, sfx), PORT_1(fn, pfx##281, sfx),   \
+       PORT_1(fn, pfx##282, sfx),                              \
+       PORT_1(fn, pfx##288, sfx), PORT_1(fn, pfx##289, sfx),   \
+       PORT_10(fn, pfx##29, sfx), PORT_10(fn, pfx##30, sfx)
 
 enum {
        PINMUX_RESERVED = 0,
 
        PINMUX_DATA_BEGIN,
-       PORT_310(DATA),                 /* PORT0_DATA -> PORT309_DATA */
+       PORT_ALL(DATA),                 /* PORT0_DATA -> PORT309_DATA */
        PINMUX_DATA_END,
 
        PINMUX_INPUT_BEGIN,
-       PORT_310(IN),                   /* PORT0_IN -> PORT309_IN */
+       PORT_ALL(IN),                   /* PORT0_IN -> PORT309_IN */
        PINMUX_INPUT_END,
 
        PINMUX_INPUT_PULLUP_BEGIN,
-       PORT_310(IN_PU),                /* PORT0_IN_PU -> PORT309_IN_PU */
+       PORT_ALL(IN_PU),                /* PORT0_IN_PU -> PORT309_IN_PU */
        PINMUX_INPUT_PULLUP_END,
 
        PINMUX_INPUT_PULLDOWN_BEGIN,
-       PORT_310(IN_PD),                /* PORT0_IN_PD -> PORT309_IN_PD */
+       PORT_ALL(IN_PD),                /* PORT0_IN_PD -> PORT309_IN_PD */
        PINMUX_INPUT_PULLDOWN_END,
 
        PINMUX_OUTPUT_BEGIN,
-       PORT_310(OUT),                  /* PORT0_OUT -> PORT309_OUT */
+       PORT_ALL(OUT),                  /* PORT0_OUT -> PORT309_OUT */
        PINMUX_OUTPUT_END,
 
        PINMUX_FUNCTION_BEGIN,
-       PORT_310(FN_IN),                /* PORT0_FN_IN -> PORT309_FN_IN */
-       PORT_310(FN_OUT),               /* PORT0_FN_OUT -> PORT309_FN_OUT */
-       PORT_310(FN0),                  /* PORT0_FN0 -> PORT309_FN0 */
-       PORT_310(FN1),                  /* PORT0_FN1 -> PORT309_FN1 */
-       PORT_310(FN2),                  /* PORT0_FN2 -> PORT309_FN2 */
-       PORT_310(FN3),                  /* PORT0_FN3 -> PORT309_FN3 */
-       PORT_310(FN4),                  /* PORT0_FN4 -> PORT309_FN4 */
-       PORT_310(FN5),                  /* PORT0_FN5 -> PORT309_FN5 */
-       PORT_310(FN6),                  /* PORT0_FN6 -> PORT309_FN6 */
-       PORT_310(FN7),                  /* PORT0_FN7 -> PORT309_FN7 */
+       PORT_ALL(FN_IN),                /* PORT0_FN_IN -> PORT309_FN_IN */
+       PORT_ALL(FN_OUT),               /* PORT0_FN_OUT -> PORT309_FN_OUT */
+       PORT_ALL(FN0),                  /* PORT0_FN0 -> PORT309_FN0 */
+       PORT_ALL(FN1),                  /* PORT0_FN1 -> PORT309_FN1 */
+       PORT_ALL(FN2),                  /* PORT0_FN2 -> PORT309_FN2 */
+       PORT_ALL(FN3),                  /* PORT0_FN3 -> PORT309_FN3 */
+       PORT_ALL(FN4),                  /* PORT0_FN4 -> PORT309_FN4 */
+       PORT_ALL(FN5),                  /* PORT0_FN5 -> PORT309_FN5 */
+       PORT_ALL(FN6),                  /* PORT0_FN6 -> PORT309_FN6 */
+       PORT_ALL(FN7),                  /* PORT0_FN7 -> PORT309_FN7 */
 
        MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
        MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
@@ -488,13 +477,34 @@ enum {
        KEYIN5_PU_MARK,
        KEYIN6_PU_MARK,
        KEYIN7_PU_MARK,
+       SDHICD0_PU_MARK,
+       SDHID0_0_PU_MARK,
+       SDHID0_1_PU_MARK,
+       SDHID0_2_PU_MARK,
+       SDHID0_3_PU_MARK,
+       SDHICMD0_PU_MARK,
+       SDHIWP0_PU_MARK,
        SDHID1_0_PU_MARK,
        SDHID1_1_PU_MARK,
        SDHID1_2_PU_MARK,
        SDHID1_3_PU_MARK,
        SDHICMD1_PU_MARK,
+       SDHID2_0_PU_MARK,
+       SDHID2_1_PU_MARK,
+       SDHID2_2_PU_MARK,
+       SDHID2_3_PU_MARK,
+       SDHICMD2_PU_MARK,
        MMCCMD0_PU_MARK,
        MMCCMD1_PU_MARK,
+       MMCD0_0_PU_MARK,
+       MMCD0_1_PU_MARK,
+       MMCD0_2_PU_MARK,
+       MMCD0_3_PU_MARK,
+       MMCD0_4_PU_MARK,
+       MMCD0_5_PU_MARK,
+       MMCD0_6_PU_MARK,
+       MMCD0_7_PU_MARK,
+       FSIBISLD_PU_MARK,
        FSIACK_PU_MARK,
        FSIAILR_PU_MARK,
        FSIAIBT_PU_MARK,
@@ -503,45 +513,6 @@ enum {
        PINMUX_MARK_END,
 };
 
-#define PORT_DATA_I(nr)        \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
-
-#define PORT_DATA_I_PD(nr)     \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PD)
-
-#define PORT_DATA_I_PU(nr)     \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PU)
-
-#define PORT_DATA_I_PU_PD(nr)  \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_IN, PORT##nr##_IN_PD,        \
-                               PORT##nr##_IN_PU)
-
-#define PORT_DATA_O(nr)        \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT)
-
-#define PORT_DATA_IO(nr)       \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN)
-
-#define PORT_DATA_IO_PD(nr)    \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PD)
-
-#define PORT_DATA_IO_PU(nr)    \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PU)
-
-#define PORT_DATA_IO_PU_PD(nr) \
-       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
-                               PORT##nr##_OUT, PORT##nr##_IN,          \
-                               PORT##nr##_IN_PD, PORT##nr##_IN_PU)
-
 static pinmux_enum_t pinmux_data[] = {
        /* specify valid pin states for each pin in GPIO mode */
 
@@ -1387,19 +1358,28 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3),
        PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1),
        PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), \
+       PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, PORT271_IN_PU,
+               MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, PORT272_IN_PU,
+               MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, PORT273_IN_PU,
+               MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, PORT274_IN_PU,
+               MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, PORT275_IN_PU,
+               MSEL4CR_MSEL15_0), \
        PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3),
-       PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), \
+       PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, PORT276_IN_PU,
+               MSEL4CR_MSEL15_0), \
        PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3),
-       PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), \
+       PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, PORT277_IN_PU,
+               MSEL4CR_MSEL15_0), \
        PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3),
-       PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), \
+       PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, PORT278_IN_PU,
+               MSEL4CR_MSEL15_0), \
        PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3),
-       PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, PORT279_IN_PU,
+               MSEL4CR_MSEL15_0),
        PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \
        PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2),
        PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1),
@@ -1516,28 +1496,55 @@ static pinmux_enum_t pinmux_data[] = {
        PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU),
        PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU),
 
-       PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_IN_PU, PORT259_FN1),
-       PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_IN_PU, PORT260_FN1),
-       PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_IN_PU, PORT261_FN1),
-       PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_IN_PU, PORT262_FN1),
-       PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_IN_PU, PORT263_FN1),
+       PINMUX_DATA(SDHICD0_PU_MARK,  PORT251_FN1, PORT251_IN_PU),
+       PINMUX_DATA(SDHID0_0_PU_MARK, PORT252_FN1, PORT252_IN_PU),
+       PINMUX_DATA(SDHID0_1_PU_MARK, PORT253_FN1, PORT253_IN_PU),
+       PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU),
+       PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU),
+       PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU),
+       PINMUX_DATA(SDHIWP0_PU_MARK,  PORT257_FN1, PORT256_IN_PU),
+       PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU),
+       PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU),
+       PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU),
+       PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_FN1, PORT262_IN_PU),
+       PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_FN1, PORT263_IN_PU),
+       PINMUX_DATA(SDHID2_0_PU_MARK, PORT265_FN1, PORT265_IN_PU),
+       PINMUX_DATA(SDHID2_1_PU_MARK, PORT266_FN1, PORT266_IN_PU),
+       PINMUX_DATA(SDHID2_2_PU_MARK, PORT267_FN1, PORT267_IN_PU),
+       PINMUX_DATA(SDHID2_3_PU_MARK, PORT268_FN1, PORT268_IN_PU),
+       PINMUX_DATA(SDHICMD2_PU_MARK, PORT269_FN1, PORT269_IN_PU),
 
        PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU,
                MSEL4CR_MSEL15_0),
-       PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT279_IN_PU,
+       PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU,
                MSEL4CR_MSEL15_1),
+
+       PINMUX_DATA(MMCD0_0_PU_MARK,
+                   PORT271_FN1, PORT271_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_1_PU_MARK,
+                   PORT272_FN1, PORT272_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_2_PU_MARK,
+                   PORT273_FN1, PORT273_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_3_PU_MARK,
+                   PORT274_FN1, PORT274_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_4_PU_MARK,
+                   PORT275_FN1, PORT275_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_5_PU_MARK,
+                   PORT276_FN1, PORT276_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_6_PU_MARK,
+                   PORT277_FN1, PORT277_IN_PU, MSEL4CR_MSEL15_0),
+       PINMUX_DATA(MMCD0_7_PU_MARK,
+                   PORT278_FN1, PORT278_IN_PU, MSEL4CR_MSEL15_0),
+
+       PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU),
        PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
        PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
        PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU),
        PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU),
 };
 
-#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
-#define GPIO_PORT_310() _310(_GPIO_PORT, , unused)
-#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
-
 static struct pinmux_gpio pinmux_gpios[] = {
-       GPIO_PORT_310(),
+       GPIO_PORT_ALL(),
 
        /* Table 25-1 (Functions 0-7) */
        GPIO_FN(VBUS_0),
@@ -2181,31 +2188,39 @@ static struct pinmux_gpio pinmux_gpios[] = {
        GPIO_FN(KEYIN5_PU),
        GPIO_FN(KEYIN6_PU),
        GPIO_FN(KEYIN7_PU),
+       GPIO_FN(SDHICD0_PU),
+       GPIO_FN(SDHID0_0_PU),
+       GPIO_FN(SDHID0_1_PU),
+       GPIO_FN(SDHID0_2_PU),
+       GPIO_FN(SDHID0_3_PU),
+       GPIO_FN(SDHICMD0_PU),
+       GPIO_FN(SDHIWP0_PU),
        GPIO_FN(SDHID1_0_PU),
        GPIO_FN(SDHID1_1_PU),
        GPIO_FN(SDHID1_2_PU),
        GPIO_FN(SDHID1_3_PU),
        GPIO_FN(SDHICMD1_PU),
+       GPIO_FN(SDHID2_0_PU),
+       GPIO_FN(SDHID2_1_PU),
+       GPIO_FN(SDHID2_2_PU),
+       GPIO_FN(SDHID2_3_PU),
+       GPIO_FN(SDHICMD2_PU),
        GPIO_FN(MMCCMD0_PU),
        GPIO_FN(MMCCMD1_PU),
+       GPIO_FN(MMCD0_0_PU),
+       GPIO_FN(MMCD0_1_PU),
+       GPIO_FN(MMCD0_2_PU),
+       GPIO_FN(MMCD0_3_PU),
+       GPIO_FN(MMCD0_4_PU),
+       GPIO_FN(MMCD0_5_PU),
+       GPIO_FN(MMCD0_6_PU),
+       GPIO_FN(MMCD0_7_PU),
        GPIO_FN(FSIACK_PU),
        GPIO_FN(FSIAILR_PU),
        GPIO_FN(FSIAIBT_PU),
        GPIO_FN(FSIAISLD_PU),
 };
 
-#define PORTCR(nr, reg)        \
-       { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
-               0, \
-               /*0001*/ PORT##nr##_OUT , \
-               /*0010*/ PORT##nr##_IN , 0, 0, 0, 0, 0, 0, 0, \
-               /*1010*/ PORT##nr##_IN_PD, 0, 0, 0, \
-               /*1110*/ PORT##nr##_IN_PU, 0, \
-               PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
-               PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
-               PORT##nr##_FN6, PORT##nr##_FN7, 0, 0, 0, 0, 0, 0, 0, 0 } \
-       }
-
 static struct pinmux_cfg_reg pinmux_config_regs[] = {
        PORTCR(0, 0xe6050000), /* PORT0CR */
        PORTCR(1, 0xe6050001), /* PORT1CR */
@@ -2718,6 +2733,45 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
        { },
 };
 
+/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */
+#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5))
+#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5))
+
+static struct pinmux_irq pinmux_irqs[] = {
+       PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(1), PORT10_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(0), PORT11_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(18), PORT13_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(20), PORT14_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(21), PORT15_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(31), PORT26_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(30), PORT27_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(29), PORT28_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(22), PORT40_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(23), PORT53_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(10), PORT54_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(9), PORT56_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(26), PORT115_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(27), PORT116_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(28), PORT117_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(24), PORT118_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(6), PORT147_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(2), PORT149_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(7), PORT150_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(12), PORT156_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(4), PORT159_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(25), PORT164_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(8), PORT223_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(3), PORT224_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(5), PORT227_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(17), PORT234_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(11), PORT238_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(13), PORT239_FN0),
+       PINMUX_IRQ(EXT_IRQ16H(16), PORT249_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(14), PORT251_FN0),
+       PINMUX_IRQ(EXT_IRQ16L(9), PORT308_FN0),
+};
+
 static struct pinmux_info sh73a0_pinmux_info = {
        .name = "sh73a0_pfc",
        .reserved_id = PINMUX_RESERVED,
@@ -2738,6 +2792,9 @@ static struct pinmux_info sh73a0_pinmux_info = {
 
        .gpio_data = pinmux_data,
        .gpio_data_size = ARRAY_SIZE(pinmux_data),
+
+       .gpio_irq = pinmux_irqs,
+       .gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
 };
 
 void sh73a0_pinmux_init(void)
index e4e485fa2532b56d21a56e53f4b0815d07230274..c49a833bf9bbf123d0313390b65ba85c9a9f669c 100644 (file)
 #include <asm/mach-types.h>
 #include <mach/common.h>
 
+#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2())
+
 static unsigned int __init shmobile_smp_get_core_count(void)
 {
-       if (machine_is_ag5evm())
+       if (is_sh73a0())
                return sh73a0_get_core_count();
 
        return 1;
@@ -31,7 +33,7 @@ static unsigned int __init shmobile_smp_get_core_count(void)
 
 static void __init shmobile_smp_prepare_cpus(void)
 {
-       if (machine_is_ag5evm())
+       if (is_sh73a0())
                sh73a0_smp_prepare_cpus();
 }
 
@@ -39,13 +41,13 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
 {
        trace_hardirqs_off();
 
-       if (machine_is_ag5evm())
+       if (is_sh73a0())
                sh73a0_secondary_init(cpu);
 }
 
 int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       if (machine_is_ag5evm())
+       if (is_sh73a0())
                return sh73a0_boot_secondary(cpu);
 
        return -ENOSYS;
index 79612737c5b231867b06d809b5c54ec5d92aadf7..34bbcbfb1706f1b74d4d5c92965e491d32204e21 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/bitrev.h>
+#include <linux/console.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/tlbflush.h>
@@ -106,9 +107,8 @@ static int pd_power_down(struct generic_pm_domain *genpd)
        return 0;
 }
 
-static int pd_power_up(struct generic_pm_domain *genpd)
+static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume)
 {
-       struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
        unsigned int mask = 1 << sh7372_pd->bit_shift;
        unsigned int retry_count;
        int ret = 0;
@@ -123,13 +123,13 @@ static int pd_power_up(struct generic_pm_domain *genpd)
 
        for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
                if (!(__raw_readl(SWUCR) & mask))
-                       goto out;
+                       break;
                if (retry_count > PSTR_RETRIES)
                        udelay(PSTR_DELAY_US);
                else
                        cpu_relax();
        }
-       if (__raw_readl(SWUCR) & mask)
+       if (!retry_count)
                ret = -EIO;
 
        if (!sh7372_pd->no_debug)
@@ -137,12 +137,17 @@ static int pd_power_up(struct generic_pm_domain *genpd)
                         mask, __raw_readl(PSTR));
 
  out:
-       if (ret == 0 && sh7372_pd->resume)
+       if (ret == 0 && sh7372_pd->resume && do_resume)
                sh7372_pd->resume();
 
        return ret;
 }
 
+static int pd_power_up(struct generic_pm_domain *genpd)
+{
+        return __pd_power_up(to_sh7372_pd(genpd), true);
+}
+
 static void sh7372_a4r_suspend(void)
 {
        sh7372_intcs_suspend();
@@ -174,7 +179,7 @@ void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
        genpd->active_wakeup = pd_active_wakeup;
        genpd->power_off = pd_power_down;
        genpd->power_on = pd_power_up;
-       genpd->power_on(&sh7372_pd->genpd);
+       __pd_power_up(sh7372_pd, false);
 }
 
 void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
@@ -227,11 +232,23 @@ struct sh7372_pm_domain sh7372_a3sp = {
        .no_debug = true,
 };
 
+static void sh7372_a3sp_init(void)
+{
+       /* serial consoles make use of SCIF hardware located in A3SP,
+        * keep such power domain on if "no_console_suspend" is set.
+        */
+       sh7372_a3sp.stay_on = !console_suspend_enabled;
+}
+
 struct sh7372_pm_domain sh7372_a3sg = {
        .bit_shift = 13,
 };
 
-#endif /* CONFIG_PM */
+#else /* !CONFIG_PM */
+
+static inline void sh7372_a3sp_init(void) {}
+
+#endif /* !CONFIG_PM */
 
 #if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE)
 static int sh7372_do_idle_core_standby(unsigned long unused)
@@ -402,22 +419,18 @@ static void sh7372_setup_a3sm(unsigned long msk, unsigned long msk2)
 
 #ifdef CONFIG_CPU_IDLE
 
-static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
+static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
 {
-       struct cpuidle_state *state;
-       int i = dev->state_count;
+       struct cpuidle_state *state = &drv->states[drv->state_count];
 
-       state = &dev->states[i];
        snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
        strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
        state->exit_latency = 10;
        state->target_residency = 20 + 10;
-       state->power_usage = 1; /* perhaps not */
-       state->flags = 0;
-       state->flags |= CPUIDLE_FLAG_TIME_VALID;
-       shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
+       state->flags = CPUIDLE_FLAG_TIME_VALID;
+       shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
 
-       dev->state_count = i + 1;
+       drv->state_count++;
 }
 
 static void sh7372_cpuidle_init(void)
@@ -469,6 +482,8 @@ void __init sh7372_pm_init(void)
        /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
        __raw_writel(0, PDNSEL);
 
+       sh7372_a3sp_init();
+
        sh7372_suspend_init();
        sh7372_cpuidle_init();
 }
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c
deleted file mode 100644 (file)
index bd5c6a3..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * arch/arm/mach-shmobile/pm_runtime.c
- *
- * Runtime PM support code for SuperH Mobile ARM
- *
- *  Copyright (C) 2009-2010 Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/pm_domain.h>
-#include <linux/pm_clock.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/sh_clk.h>
-#include <linux/bitmap.h>
-#include <linux/slab.h>
-
-#ifdef CONFIG_PM_RUNTIME
-
-static int default_platform_runtime_idle(struct device *dev)
-{
-       /* suspend synchronously to disable clocks immediately */
-       return pm_runtime_suspend(dev);
-}
-
-static struct dev_pm_domain default_pm_domain = {
-       .ops = {
-               .runtime_suspend = pm_clk_suspend,
-               .runtime_resume = pm_clk_resume,
-               .runtime_idle = default_platform_runtime_idle,
-               USE_PLATFORM_PM_SLEEP_OPS
-       },
-};
-
-#define DEFAULT_PM_DOMAIN_PTR  (&default_pm_domain)
-
-#else
-
-#define DEFAULT_PM_DOMAIN_PTR  NULL
-
-#endif /* CONFIG_PM_RUNTIME */
-
-static struct pm_clk_notifier_block platform_bus_notifier = {
-       .pm_domain = DEFAULT_PM_DOMAIN_PTR,
-       .con_ids = { NULL, },
-};
-
-static int __init sh_pm_runtime_init(void)
-{
-       pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
-       return 0;
-}
-core_initcall(sh_pm_runtime_init);
-
-static int __init sh_pm_runtime_late_init(void)
-{
-       pm_genpd_poweroff_unused();
-       return 0;
-}
-late_initcall(sh_pm_runtime_late_init);
index d368f8dafcfd916fe215637fd3cdd84e8d56c1a3..74743ad3d2d356b90908529dfa57b15ccd168dd5 100644 (file)
@@ -101,6 +101,13 @@ static void __init tegra_dt_init(void)
 
        tegra_clk_init_from_table(tegra_dt_clk_init_table);
 
+       /*
+        * Finished with the static registrations now; fill in the missing
+        * devices
+        */
+       of_platform_populate(NULL, tegra_dt_match_table,
+                               tegra20_auxdata_lookup, NULL);
+
        for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) {
                if (of_machine_is_compatible(pinmux_configs[i].machine)) {
                        pinmux_configs[i].init();
@@ -110,12 +117,6 @@ static void __init tegra_dt_init(void)
 
        WARN(i == ARRAY_SIZE(pinmux_configs),
                "Unknown platform! Pinmuxing not initialized\n");
-
-       /*
-        * Finished with the static registrations now; fill in the missing
-        * devices
-        */
-       of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL);
 }
 
 static const char * tegra_dt_board_compat[] = {
index e99b45618cd0d5f9c840cfac84fcb85207d2dcef..7a4a26d5174c33f4c1667725becd986f6f57dff2 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+
 #include <mach/pinmux.h>
 
 #include "gpio-names.h"
@@ -161,7 +163,9 @@ static struct tegra_gpio_table gpio_table[] = {
 
 void harmony_pinmux_init(void)
 {
-       platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+       if (!of_machine_is_compatible("nvidia,tegra20"))
+               platform_add_devices(pinmux_devices,
+                                       ARRAY_SIZE(pinmux_devices));
 
        tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
 
index fb20894862b0c94bac143b93e039bc0d52d1925d..be30e215f4b73ba15daefb2030c8d86afc4e1637 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+
 #include <mach/pinmux.h>
 
 #include "gpio-names.h"
@@ -158,7 +160,9 @@ static struct tegra_gpio_table gpio_table[] = {
 
 void paz00_pinmux_init(void)
 {
-       platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+       if (!of_machine_is_compatible("nvidia,tegra20"))
+               platform_add_devices(pinmux_devices,
+                                       ARRAY_SIZE(pinmux_devices));
 
        tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
 
index fbce31daa3c9fd65760fc8d6fcc2b0cbdc92db8e..b1c2972f62fe4622eedff53761cce68340959b03 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 
 #include <mach/pinmux.h>
 #include <mach/pinmux-t2.h>
@@ -191,6 +192,7 @@ static struct tegra_gpio_table common_gpio_table[] = {
        { .gpio = TEGRA_GPIO_SD2_POWER,         .enable = true },
        { .gpio = TEGRA_GPIO_LIDSWITCH,         .enable = true },
        { .gpio = TEGRA_GPIO_POWERKEY,          .enable = true },
+       { .gpio = TEGRA_GPIO_HP_DET,            .enable = true },
        { .gpio = TEGRA_GPIO_ISL29018_IRQ,      .enable = true },
        { .gpio = TEGRA_GPIO_CDC_IRQ,           .enable = true },
        { .gpio = TEGRA_GPIO_USB1,              .enable = true },
@@ -218,7 +220,9 @@ static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size)
 
 void __init seaboard_common_pinmux_init(void)
 {
-       platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+       if (!of_machine_is_compatible("nvidia,tegra20"))
+               platform_add_devices(pinmux_devices,
+                                       ARRAY_SIZE(pinmux_devices));
 
        tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
 
index 4969dd28a04ccf58e03850497fbdf368a3f21e8f..7ab719d46da0558f3b9b1ca4df751a2a05a71432 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/of.h>
 
 #include <mach/pinmux.h>
 
@@ -157,7 +158,9 @@ static struct tegra_gpio_table gpio_table[] = {
 
 void __init trimslice_pinmux_init(void)
 {
-       platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+       if (!of_machine_is_compatible("nvidia,tegra20"))
+               platform_add_devices(pinmux_devices,
+                                       ARRAY_SIZE(pinmux_devices));
        tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
        tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
 }
index f5aa173c26b320ac3a8b46688ab00ea2d51dd317..97ef3e55dfdf8503319abba74f6dbe68ebecb78e 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/irq.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include <asm/sizes.h>
 #include <asm/mach/pci.h>
index 7a1fa6adb7c32d5645b1f0e608b1e61794081afc..5b0c38abacc107a7eae8bd35ec8f03666f3422e7 100644 (file)
@@ -422,7 +422,7 @@ struct platform_device nuc900_device_kpi = {
 
 /* LCD controller*/
 
-static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
+static struct nuc900fb_display nuc900_lcd_info[] = {
        /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
        [0] = {
                .type           = LCM_DCCS_VA_SRC_RGB565,
@@ -445,7 +445,7 @@ static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
        },
 };
 
-static struct nuc900fb_mach_info nuc900_fb_info __initdata = {
+static struct nuc900fb_mach_info nuc900_fb_info = {
 #if defined(CONFIG_GPM1040A0_320X240)
        .displays               = &nuc900_lcd_info[0],
 #else
index 94c0e71617c6c3487aaf20a4f1b7bfd34023e580..23ef1f573abd3395ac872ab6b39be6bc29090a8d 100644 (file)
@@ -19,6 +19,7 @@
 extern void mfp_set_groupf(struct device *dev);
 extern void mfp_set_groupc(struct device *dev);
 extern void mfp_set_groupi(struct device *dev);
-extern void mfp_set_groupg(struct device *dev);
+extern void mfp_set_groupg(struct device *dev, const char *subname);
+extern void mfp_set_groupd(struct device *dev, const char *subname);
 
 #endif /* __ASM_ARCH_MFP_H */
index bd94819e314fed7f67173c016a00bbcfbacc38c6..2c4e0c1285010fdfee53bebeaff4cd638c50a56f 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __ASM_ARCH_SPI_H
 #define __ASM_ARCH_SPI_H
 
-extern void mfp_set_groupg(struct device *dev);
+extern void mfp_set_groupg(struct device *dev, const char *subname);
 
 struct nuc900_spi_info {
        unsigned int num_cs;
index fb7fb627b1a564ca920fdb747080988f3fb75551..9dd74612bb8707560abd06e6adc250f7ecd54bf2 100644 (file)
 #define REG_MFSEL      (W90X900_VA_GCR + 0xC)
 
 #define GPSELF         (0x01 << 1)
-
 #define GPSELC         (0x03 << 2)
-#define ENKPI          (0x02 << 2)
-#define ENNAND         (0x01 << 2)
+#define GPSELD         (0x0f << 4)
 
 #define GPSELEI0       (0x01 << 26)
 #define GPSELEI1       (0x01 << 27)
 #define GPIOG0TO1      (0x03 << 14)
 #define GPIOG2TO3      (0x03 << 16)
 #define GPIOG22TO23    (0x03 << 22)
+#define GPIOG18TO20    (0x07 << 18)
 
 #define ENSPI          (0x0a << 14)
 #define ENI2C0         (0x01 << 14)
 #define ENI2C1         (0x01 << 16)
 #define ENAC97         (0x02 << 22)
+#define ENSD1          (0x02 << 18)
+#define ENSD0          (0x0a << 4)
+#define ENKPI          (0x02 << 2)
+#define ENNAND         (0x01 << 2)
 
 static DEFINE_MUTEX(mfp_mutex);
 
@@ -127,16 +130,19 @@ void mfp_set_groupi(struct device *dev)
 }
 EXPORT_SYMBOL(mfp_set_groupi);
 
-void mfp_set_groupg(struct device *dev)
+void mfp_set_groupg(struct device *dev, const char *subname)
 {
        unsigned long mfpen;
        const char *dev_id;
 
-       BUG_ON(!dev);
+       BUG_ON((!dev) && (!subname));
 
        mutex_lock(&mfp_mutex);
 
-       dev_id = dev_name(dev);
+       if (subname != NULL)
+               dev_id = subname;
+       else
+               dev_id = dev_name(dev);
 
        mfpen = __raw_readl(REG_MFSEL);
 
@@ -152,6 +158,9 @@ void mfp_set_groupg(struct device *dev)
        } else if (strcmp(dev_id, "nuc900-audio") == 0) {
                mfpen &= ~(GPIOG22TO23);
                mfpen |= ENAC97;/*enable AC97*/
+       } else if (strcmp(dev_id, "nuc900-mmc-port1") == 0) {
+               mfpen &= ~(GPIOG18TO20);
+               mfpen |= (ENSD1 | 0x01);/*enable sd1*/
        } else {
                mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
        }
@@ -162,3 +171,30 @@ void mfp_set_groupg(struct device *dev)
 }
 EXPORT_SYMBOL(mfp_set_groupg);
 
+void mfp_set_groupd(struct device *dev, const char *subname)
+{
+       unsigned long mfpen;
+       const char *dev_id;
+
+       BUG_ON((!dev) && (!subname));
+
+       mutex_lock(&mfp_mutex);
+
+       if (subname != NULL)
+               dev_id = subname;
+       else
+               dev_id = dev_name(dev);
+
+       mfpen = __raw_readl(REG_MFSEL);
+
+       if (strcmp(dev_id, "nuc900-mmc-port0") == 0) {
+               mfpen &= ~GPSELD;/*enable sd0*/
+               mfpen |= ENSD0;
+       } else
+               mfpen &= (~GPSELD);
+
+       __raw_writel(mfpen, REG_MFSEL);
+
+       mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupd);
index 8ac9e9f84790bb946716016607478ad97711376d..b1e192ba8c2450cb75a8118f86f8b650be284c82 100644 (file)
@@ -61,7 +61,7 @@ static inline void cache_sync(void)
 {
        void __iomem *base = l2x0_base;
 
-#ifdef CONFIG_ARM_ERRATA_753970
+#ifdef CONFIG_PL310_ERRATA_753970
        /* write to an unmmapped register */
        writel_relaxed(0, base + L2X0_DUMMY_REG);
 #else
index e4e7f6cba1ab4823fdbf0fe7ab2109bf6df89ed7..1aa664a1999fce45c2548726b50b6fa924608ec2 100644 (file)
@@ -168,7 +168,7 @@ static int __init consistent_init(void)
        pte_t *pte;
        int i = 0;
        unsigned long base = consistent_base;
-       unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT;
+       unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
 
        consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
        if (!consistent_pte) {
@@ -332,6 +332,15 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
        struct page *page;
        void *addr;
 
+       /*
+        * Following is a work-around (a.k.a. hack) to prevent pages
+        * with __GFP_COMP being passed to split_page() which cannot
+        * handle them.  The real problem is that this flag probably
+        * should be 0 on ARM as it is not supported on this
+        * platform; see CONFIG_HUGETLBFS.
+        */
+       gfp &= ~(__GFP_COMP);
+
        *handle = ~0;
        size = PAGE_ALIGN(size);
 
index 7cab791794218b6c49917bf0471152ea810f9e55..7599e2625c7d021a9db22afbd5b4904e6b701b1d 100644 (file)
@@ -8,7 +8,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
index 04e9a92bb47ad602b866b35f77d90ae65493638d..fbdd12ea3a587a146497f9e560d28d86c52fca45 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/mman.h>
+#include <linux/export.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
index 74be05f3e03ac58be921aff208c6f6aa460ab683..44b628e4d6ea9c0121acf892ffbcfb30d0fc40ad 100644 (file)
@@ -9,8 +9,7 @@
 #include <linux/io.h>
 #include <linux/personality.h>
 #include <linux/random.h>
-#include <asm/cputype.h>
-#include <asm/system.h>
+#include <asm/cachetype.h>
 
 #define COLOUR_ALIGN(addr,pgoff)               \
        ((((addr)+SHMLBA-1)&~(SHMLBA-1)) +      \
@@ -32,25 +31,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        unsigned long start_addr;
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
-       unsigned int cache_type;
-       int do_align = 0, aliasing = 0;
+       int do_align = 0;
+       int aliasing = cache_is_vipt_aliasing();
 
        /*
         * We only need to do colour alignment if either the I or D
-        * caches alias.  This is indicated by bits 9 and 21 of the
-        * cache type register.
+        * caches alias.
         */
-       cache_type = read_cpuid_cachetype();
-       if (cache_type != read_cpuid_id()) {
-               aliasing = (cache_type | cache_type >> 12) & (1 << 11);
-               if (aliasing)
-                       do_align = filp || flags & MAP_SHARED;
-       }
-#else
-#define do_align 0
-#define aliasing 0
-#endif
+       if (aliasing)
+               do_align = filp || (flags & MAP_SHARED);
 
        /*
         * We enforce the MAP_FIXED case.
index 640e498c12efcc1c1bd6a5234b8de0756376a46b..e4de9be78feb1c857cd22d0b2e17918fc0dda8f8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 #include <asm/hardware/iop3xx.h>
 
 void gpio_line_config(int line, int direction)
index 7cdc5161ff2bda7e939c6ebcf1232bd91a964bb1..568dd0223d17462615534a6388017d1cb6934896 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/export.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/sched_clock.h>
index a08a95107a632f9b1c178c29a55388494d7286bd..b3a1f2b3ada3bcb2f699b7a1e86bda0a1e866acb 100644 (file)
@@ -10,7 +10,7 @@ choice
 
 config ARCH_IMX_V4_V5
        bool "i.MX1, i.MX21, i.MX25, i.MX27"
-       select AUTO_ZRELADDR
+       select AUTO_ZRELADDR if !ZBOOT_ROM
        select ARM_PATCH_PHYS_VIRT
        help
          This enables support for systems based on the Freescale i.MX ARMv4
@@ -26,7 +26,7 @@ config ARCH_IMX_V6_V7
 
 config ARCH_MX5
        bool "i.MX50, i.MX51, i.MX53"
-       select AUTO_ZRELADDR
+       select AUTO_ZRELADDR if !ZBOOT_ROM
        select ARM_PATCH_PHYS_VIRT
        help
          This enables support for machines using Freescale's i.MX50 and i.MX53
index 8875fb415f68f36990f0be4284b62dbb66fd32c4..55f15699a3835cba42c5509fc62b031db4e033d7 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <mach/common.h>
 #include <asm/mach/irq.h>
+#include <asm/exception.h>
 #include <mach/hardware.h>
 
 #include "irq-common.h"
index b3b8eed263b88e3c26765242b71184e981f9d28b..12f8f81090104726113716f82b4551080c5b0bb0 100644 (file)
@@ -28,21 +28,14 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
                if (irqnr == 1023)
                        break;
 
-               if (irqnr > 29 && irqnr < 1021)
+               if (irqnr > 15 && irqnr < 1021)
                        handle_IRQ(irqnr, regs);
 #ifdef CONFIG_SMP
-               else if (irqnr < 16) {
+               else {
                        writel_relaxed(irqstat, gic_cpu_base_addr +
                                                GIC_CPU_EOI);
                        handle_IPI(irqnr, regs);
                }
-#endif
-#ifdef CONFIG_LOCAL_TIMERS
-               else if (irqnr == 29) {
-                       writel_relaxed(irqstat, gic_cpu_base_addr +
-                                               GIC_CPU_EOI);
-                       handle_local_timer(regs);
-               }
 #endif
        } while (1);
 }
index 83b745a5e1b724e92ee87be633dc15b00edab968..c75f254abd857c07e6f8133716b51d5925f17581 100644 (file)
@@ -85,7 +85,6 @@ enum mxc_cpu_pwr_mode {
 };
 
 extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
-extern void (*imx_idle)(void);
 extern void imx_print_silicon_rev(const char *cpu, int srev);
 
 void avic_handle_irq(struct pt_regs *);
@@ -133,4 +132,5 @@ extern void imx53_qsb_common_init(void);
 extern void imx53_smd_common_init(void);
 extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
 extern void imx6q_pm_init(void);
+extern void imx6q_clock_map_io(void);
 #endif
index 9fe0dfcf4e7e02a85e0d4e944829d9f43305d74c..ca5cf26a04b1c9f16bf3e455afd4fa4098a7048e 100644 (file)
@@ -25,6 +25,3 @@
 
        .macro test_for_ipi, irqnr, irqstat, base, tmp
        .endm
-
-       .macro test_for_ltirq, irqnr, irqstat, base, tmp
-       .endm
index 00a78193c681ae16f5ed61f1b587f3ecf9e777f8..a4d36d601d55a5ed493f9191929850c6530f804f 100644 (file)
 #define IMX_CHIP_REVISION_3_3          0x33
 #define IMX_CHIP_REVISION_UNKNOWN      0xff
 
-#define IMX_CHIP_REVISION_1_0_STRING           "1.0"
-#define IMX_CHIP_REVISION_1_1_STRING           "1.1"
-#define IMX_CHIP_REVISION_1_2_STRING           "1.2"
-#define IMX_CHIP_REVISION_1_3_STRING           "1.3"
-#define IMX_CHIP_REVISION_2_0_STRING           "2.0"
-#define IMX_CHIP_REVISION_2_1_STRING           "2.1"
-#define IMX_CHIP_REVISION_2_2_STRING           "2.2"
-#define IMX_CHIP_REVISION_2_3_STRING           "2.3"
-#define IMX_CHIP_REVISION_3_0_STRING           "3.0"
-#define IMX_CHIP_REVISION_3_1_STRING           "3.1"
-#define IMX_CHIP_REVISION_3_2_STRING           "3.2"
-#define IMX_CHIP_REVISION_3_3_STRING           "3.3"
-#define IMX_CHIP_REVISION_UNKNOWN_STRING       "unknown"
-
 #ifndef __ASSEMBLY__
 extern unsigned int __mxc_cpu_type;
 #endif
index cf88b3593fba794d1a2de0c871f278ec03988da5..b9895d250167cf6b384d5cb1320e00e855537019 100644 (file)
 #ifndef __ASM_ARCH_MXC_SYSTEM_H__
 #define __ASM_ARCH_MXC_SYSTEM_H__
 
-extern void (*imx_idle)(void);
-
 static inline void arch_idle(void)
 {
-       if (imx_idle != NULL)
-               (imx_idle)();
-       else
-               cpu_do_idle();
+       cpu_do_idle();
 }
 
 void arch_reset(char mode, const char *cmd);
index 9dad8dcc2ea9dde822720e14c0c55ead52e8a420..d65fb31a55ca47ef350e38da864b6d34cf5295f9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
@@ -28,8 +29,8 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
-void (*imx_idle)(void) = NULL;
 void __iomem *(*imx_ioremap)(unsigned long, size_t, unsigned int) = NULL;
+EXPORT_SYMBOL_GPL(imx_ioremap);
 
 static void __iomem *wdog_base;
 
index e993a184189aa2c756a7ee8741fd7e096eb2da59..a3c164c7ba828a60c5bb2e3a94fb4055c318a9cd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 
 #include <asm/mach/irq.h>
+#include <asm/exception.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
index 3ba4d11ca73e25b53be83ccb883319d3f0560af7..567e4b54f245d9684d3525178eed385052d55d2d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/string.h>
 #include <linux/clk.h>
index 2def4e1990edca55e1fa67efd505f7efa7a25c33..af3b92be84593384f96c5c8c59f74d10c108e22d 100644 (file)
@@ -35,6 +35,7 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/err.h>
index 679cbd49c01945633b81b7c68cf25b0c38dfdc56..db071bc71c4d61d8e5bd5938eb3e438a06f2b449 100644 (file)
@@ -184,7 +184,7 @@ static inline int omap2_i2c_add_bus(int bus_id)
                        NULL, 0, 0);
        WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
 
-       return PTR_ERR(pdev);
+       return PTR_RET(pdev);
 }
 #else
 static inline int omap2_i2c_add_bus(int bus_id)
index 197ca03c3f7d8490a109a9b576b2e2f9c9c420e6..eb73ab40e9556ee03f36e63fa7c06b9e77b4b1d3 100644 (file)
@@ -165,8 +165,8 @@ struct dpll_data {
        u8                      auto_recal_bit;
        u8                      recal_en_bit;
        u8                      recal_st_bit;
-       u8                      flags;
 #  endif
+       u8                      flags;
 };
 
 #endif
index c50df4814f6f43935c7b021064c610f200ff0dc0..3ff3e36580f267df6890712efef55e8ee22bdbc7 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 
 #include <plat/i2c.h>
+#include <plat/omap_hwmod.h>
 
 struct sys_timer;
 
@@ -55,6 +56,8 @@ void am35xx_init_early(void);
 void ti816x_init_early(void);
 void omap4430_init_early(void);
 
+extern int omap_dss_reset(struct omap_hwmod *);
+
 void omap_sram_init(void);
 
 /*
index 2f90269422292d8ae8f854bbbead3751bfca784c..408a12f792051865c9adf21b0760b9b6871fe899 100644 (file)
@@ -399,6 +399,13 @@ void omap2_check_revision(void);
 
 /*
  * Runtime detection of OMAP3 features
+ *
+ * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip
+ *    family have OS-level control over the I/O chain clock.  This is
+ *    to avoid a window during which wakeups could potentially be lost
+ *    during powerdomain transitions.  If this bit is set, it
+ *    indicates that the chip does support OS-level control of this
+ *    feature.
  */
 extern u32 omap_features;
 
@@ -410,9 +417,10 @@ extern u32 omap_features;
 #define OMAP3_HAS_192MHZ_CLK           BIT(5)
 #define OMAP3_HAS_IO_WAKEUP            BIT(6)
 #define OMAP3_HAS_SDRC                 BIT(7)
-#define OMAP4_HAS_MPU_1GHZ             BIT(8)
-#define OMAP4_HAS_MPU_1_2GHZ           BIT(9)
-#define OMAP4_HAS_MPU_1_5GHZ           BIT(10)
+#define OMAP3_HAS_IO_CHAIN_CTRL                BIT(8)
+#define OMAP4_HAS_MPU_1GHZ             BIT(9)
+#define OMAP4_HAS_MPU_1_2GHZ           BIT(10)
+#define OMAP4_HAS_MPU_1_5GHZ           BIT(11)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)                   \
@@ -429,12 +437,11 @@ OMAP3_HAS_FEATURE(isp, ISP)
 OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
 
 /*
  * Runtime detection of OMAP4 features
  */
-extern u32 omap_features;
-
 #define OMAP4_HAS_FEATURE(feat, flag)                  \
 static inline unsigned int omap4_has_ ##feat(void)     \
 {                                                      \
index d11025e6e7a47df9921d252c46c64c087974132f..9418f00b6c381428fe32c61c95d8be42c455a2d4 100644 (file)
@@ -104,7 +104,7 @@ struct dmtimer_platform_data {
 
        bool loses_context;
 
-       u32 (*get_context_loss_count)(struct device *dev);
+       int (*get_context_loss_count)(struct device *dev);
 };
 
 struct omap_dm_timer *omap_dm_timer_request(void);
@@ -279,7 +279,7 @@ struct omap_dm_timer {
        struct platform_device *pdev;
        struct list_head node;
 
-       u32 (*get_context_loss_count)(struct device *dev);
+       int (*get_context_loss_count)(struct device *dev);
 };
 
 int omap_dm_timer_prepare(struct omap_dm_timer *timer);
diff --git a/arch/arm/plat-omap/include/plat/omap-alsa.h b/arch/arm/plat-omap/include/plat/omap-alsa.h
deleted file mode 100644 (file)
index b53055b..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/omap-alsa.h
- *
- * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
- *
- * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
- *
- * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
- * Written by Daniel Petrini, David Cohen, Anderson Briglia
- *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  History
- *  -------
- *
- *  2005/07/25 INdT-10LE Kernel Team -         Alsa driver for omap osk,
- *                                     original version based in sa1100 driver
- *                                     and omap oss driver.
- */
-
-#ifndef __OMAP_ALSA_H
-#define __OMAP_ALSA_H
-
-#include <plat/dma.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <plat/mcbsp.h>
-#include <linux/platform_device.h>
-
-#define DMA_BUF_SIZE   (1024 * 8)
-
-/*
- * Buffer management for alsa and dma
- */
-struct audio_stream {
-       char *id;               /* identification string */
-       int stream_id;          /* numeric identification */
-       int dma_dev;            /* dma number of that device */
-       int *lch;               /* Chain of channels this stream is linked to */
-       char started;           /* to store if the chain was started or not */
-       int dma_q_head;         /* DMA Channel Q Head */
-       int dma_q_tail;         /* DMA Channel Q Tail */
-       char dma_q_count;       /* DMA Channel Q Count */
-       int active:1;           /* we are using this stream for transfer now */
-       int period;             /* current transfer period */
-       int periods;            /* current count of periods registerd in the DMA engine */
-       spinlock_t dma_lock;    /* for locking in DMA operations */
-       struct snd_pcm_substream *stream;       /* the pcm stream */
-       unsigned linked:1;      /* dma channels linked */
-       int offset;             /* store start position of the last period in the alsa buffer */
-       int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
-       int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
-};
-
-/*
- * Alsa card structure for aic23
- */
-struct snd_card_omap_codec {
-       struct snd_card *card;
-       struct snd_pcm *pcm;
-       long samplerate;
-       struct audio_stream s[2];       /* playback & capture */
-};
-
-/* Codec specific information and function pointers.
- * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
- * are responsible for defining the function pointers.
- */
-struct omap_alsa_codec_config {
-       char    *name;
-       struct  omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
-       struct  snd_pcm_hw_constraint_list *hw_constraints_rates;
-       struct  snd_pcm_hardware *snd_omap_alsa_playback;
-       struct  snd_pcm_hardware *snd_omap_alsa_capture;
-       void    (*codec_configure_dev)(void);
-       void    (*codec_set_samplerate)(long);
-       void    (*codec_clock_setup)(void);
-       int     (*codec_clock_on)(void);
-       int     (*codec_clock_off)(void);
-       int     (*get_default_samplerate)(void);
-};
-
-/*********** Mixer function prototypes *************************/
-int snd_omap_mixer(struct snd_card_omap_codec *);
-void snd_omap_init_mixer(void);
-
-#ifdef CONFIG_PM
-void snd_omap_suspend_mixer(void);
-void snd_omap_resume_mixer(void);
-#endif
-
-int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
-int snd_omap_alsa_remove(struct platform_device *pdev);
-#ifdef CONFIG_PM
-int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
-int snd_omap_alsa_resume(struct platform_device *pdev);
-#else
-#define snd_omap_alsa_suspend  NULL
-#define snd_omap_alsa_resume   NULL
-#endif
-
-void callback_omap_alsa_sound_dma(void *);
-
-#endif
index 0840df813f4f15f4e5b0ecc1cfcd0b53269f0549..67faa7b8fe92fd932889b65d55adbe0c5a97e5de 100644 (file)
@@ -342,9 +342,9 @@ unsigned long omap_pm_cpu_get_freq(void);
  * driver must restore device context.   If the number of context losses
  * exceeds the maximum positive integer, the function will wrap to 0 and
  * continue counting.  Returns the number of context losses for this device,
- * or zero upon error.
+ * or negative value upon error.
  */
-u32 omap_pm_get_dev_context_loss_count(struct device *dev);
+int omap_pm_get_dev_context_loss_count(struct device *dev);
 
 void omap_pm_enable_off_mode(void);
 void omap_pm_disable_off_mode(void);
index 12c5b0c345bfdf93b1f6b7c83447b78f50c8454a..51423d2727a5f9b11ef886e1548905bc6a0e3ef4 100644 (file)
@@ -107,7 +107,7 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name);
 int omap_device_align_pm_lat(struct platform_device *pdev,
                             u32 new_wakeup_lat_limit);
 struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
-u32 omap_device_get_context_loss_count(struct platform_device *pdev);
+int omap_device_get_context_loss_count(struct platform_device *pdev);
 
 /* Other */
 
index 5419f1a2aaa432622ad377d6d56fb1438aa1b944..8b372ede17c167f90bd5b78495e4f3769d483a59 100644 (file)
@@ -600,7 +600,7 @@ int omap_hwmod_for_each_by_class(const char *classname,
                                 void *user);
 
 int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
-u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
 
index 69ddc9f76c13ebcdcad6b97b109e374f0b2960c4..ad80112c22751defaaa4cb5b9aefe11eac27e6be 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kfifo.h>
 #include <linux/err.h>
 #include <linux/notifier.h>
+#include <linux/module.h>
 
 #include <plat/mailbox.h>
 
index b0471bb2d47dda81c45447e381ada7ff294b502f..3dc3801aace4424c96722aa48139fc2b51197c63 100644 (file)
@@ -27,7 +27,7 @@
 #include <plat/omap_device.h>
 
 static bool off_mode_enabled;
-static u32 dummy_context_loss_counter;
+static int dummy_context_loss_counter;
 
 /*
  * Device-driver-originated constraints (via board-*.c files)
@@ -311,22 +311,32 @@ void omap_pm_disable_off_mode(void)
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
 
-u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+int omap_pm_get_dev_context_loss_count(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
-       u32 count;
+       int count;
 
        if (WARN_ON(!dev))
-               return 0;
+               return -ENODEV;
 
        if (dev->parent == &omap_device_parent) {
                count = omap_device_get_context_loss_count(pdev);
        } else {
                WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
                          dev_name(dev));
-               if (off_mode_enabled)
-                       dummy_context_loss_counter++;
+
                count = dummy_context_loss_counter;
+
+               if (off_mode_enabled) {
+                       count++;
+                       /*
+                        * Context loss count has to be a non-negative value.
+                        * Clear the sign bit to get a value range from 0 to
+                        * INT_MAX.
+                        */
+                       count &= INT_MAX;
+                       dummy_context_loss_counter = count;
+               }
        }
 
        pr_debug("OMAP PM: context loss count for dev %s = %d\n",
@@ -337,7 +347,7 @@ u32 omap_pm_get_dev_context_loss_count(struct device *dev)
 
 #else
 
-u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+int omap_pm_get_dev_context_loss_count(struct device *dev)
 {
        return dummy_context_loss_counter;
 }
index cd90bedd9306fb6389d5f9eef0d6061db1c02076..e8d98693d2dd1fd0ac11a175510738cae8419c72 100644 (file)
@@ -78,6 +78,7 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/err.h>
@@ -426,7 +427,7 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
  * return the context loss counter for that hwmod, otherwise return
  * zero.
  */
-u32 omap_device_get_context_loss_count(struct platform_device *pdev)
+int omap_device_get_context_loss_count(struct platform_device *pdev)
 {
        struct omap_device *od;
        u32 ret = 0;
index 442301fe48b4176d3403de8f535837317ec7213d..c42f39f20195374bf6f0f046b487bd8e8c4511a6 100644 (file)
@@ -41,6 +41,19 @@ struct pxa3xx_nand_flash {
        struct pxa3xx_nand_timing *timing;      /* NAND Flash timing */
 };
 
+/*
+ * Current pxa3xx_nand controller has two chip select which
+ * both be workable.
+ *
+ * Notice should be taken that:
+ * When you want to use this feature, you should not enable the
+ * keep configuration feature, for two chip select could be
+ * attached with different nand chip. The different page size
+ * and timing requirement make the keep configuration impossible.
+ */
+
+/* The max num of chip select current support */
+#define NUM_CHIP_SELECT                (2)
 struct pxa3xx_nand_platform_data {
 
        /* the data flash bus is shared between the Static Memory
@@ -52,8 +65,11 @@ struct pxa3xx_nand_platform_data {
        /* allow platform code to keep OBM/bootloader defined NFC config */
        int     keep_config;
 
-       const struct mtd_partition              *parts;
-       unsigned int                            nr_parts;
+       /* indicate how many chip selects will be used */
+       int     num_cs;
+
+       const struct mtd_partition              *parts[NUM_CHIP_SELECT];
+       unsigned int                            nr_parts[NUM_CHIP_SELECT];
 
        const struct pxa3xx_nand_flash *        flash;
        size_t                                  num_flash;
index 8c5b3029b39fca958703da3a73316daf85a212a7..d8973ac46bc4e909a9f04a6e43883197e8e4acec 100644 (file)
@@ -9,7 +9,6 @@ config PLAT_S3C24XX
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select S3C_DEV_NAND
-       select S3C_GPIO_CFG_S3C24XX
        help
          Base platform code for any Samsung S3C24XX device
 
index 0291bd6e236e832003986d6559eda8699740aba4..b2b01125de66ac24606cf6dbe71072a974e5e7cf 100644 (file)
@@ -14,9 +14,7 @@ obj-                          :=
 
 obj-y                          += cpu.o
 obj-y                          += irq.o
-obj-y                          += devs.o
-obj-y                          += gpio.o
-obj-y                          += gpiolib.o
+obj-y                          += dev-uart.o
 obj-y                          += clock.o
 obj-$(CONFIG_S3C24XX_DCLK)     += clock-dclk.o
 
index a9276667c2fb0e59c21e643aab28aef2debdee84..c7adad0e8de091ad42d021958bb1fc3b3c8cff03 100644 (file)
@@ -12,7 +12,7 @@
 */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
diff --git a/arch/arm/plat-s3c24xx/dev-uart.c b/arch/arm/plat-s3c24xx/dev-uart.c
new file mode 100644 (file)
index 0000000..9ab22e6
--- /dev/null
@@ -0,0 +1,100 @@
+/* linux/arch/arm/plat-s3c24xx/dev-uart.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX UART resource and platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/regs-serial.h>
+
+/* Serial port registrations */
+
+static struct resource s3c2410_uart0_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART0,
+               .end   = S3C2410_PA_UART0 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX0,
+               .end   = IRQ_S3CUART_ERR0,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART1,
+               .end   = S3C2410_PA_UART1 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX1,
+               .end   = IRQ_S3CUART_ERR1,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+       [0] = {
+               .start = S3C2410_PA_UART2,
+               .end   = S3C2410_PA_UART2 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX2,
+               .end   = IRQ_S3CUART_ERR2,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+static struct resource s3c2410_uart3_resource[] = {
+       [0] = {
+               .start = S3C2443_PA_UART3,
+               .end   = S3C2443_PA_UART3 + 0x3fff,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_S3CUART_RX3,
+               .end   = IRQ_S3CUART_ERR3,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+       [0] = {
+               .resources      = s3c2410_uart0_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart0_resource),
+       },
+       [1] = {
+               .resources      = s3c2410_uart1_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart1_resource),
+       },
+       [2] = {
+               .resources      = s3c2410_uart2_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart2_resource),
+       },
+       [3] = {
+               .resources      = s3c2410_uart3_resource,
+               .nr_resources   = ARRAY_SIZE(s3c2410_uart3_resource),
+       },
+};
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
deleted file mode 100644 (file)
index a76bf2d..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/devs.c
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Base S3C24XX platform device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <mach/fb.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-#include <asm/irq.h>
-
-#include <plat/regs-serial.h>
-#include <plat/udc.h>
-#include <plat/mci.h>
-
-#include <plat/devs.h>
-#include <plat/cpu.h>
-#include <plat/regs-spi.h>
-#include <plat/ts.h>
-
-/* Serial port registrations */
-
-static struct resource s3c2410_uart0_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART0,
-               .end   = S3C2410_PA_UART0 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX0,
-               .end   = IRQ_S3CUART_ERR0,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c2410_uart1_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART1,
-               .end   = S3C2410_PA_UART1 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX1,
-               .end   = IRQ_S3CUART_ERR1,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c2410_uart2_resource[] = {
-       [0] = {
-               .start = S3C2410_PA_UART2,
-               .end   = S3C2410_PA_UART2 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX2,
-               .end   = IRQ_S3CUART_ERR2,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct resource s3c2410_uart3_resource[] = {
-       [0] = {
-               .start = S3C2443_PA_UART3,
-               .end   = S3C2443_PA_UART3 + 0x3fff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3CUART_RX3,
-               .end   = IRQ_S3CUART_ERR3,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
-       [0] = {
-               .resources      = s3c2410_uart0_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart0_resource),
-       },
-       [1] = {
-               .resources      = s3c2410_uart1_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart1_resource),
-       },
-       [2] = {
-               .resources      = s3c2410_uart2_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart2_resource),
-       },
-       [3] = {
-               .resources      = s3c2410_uart3_resource,
-               .nr_resources   = ARRAY_SIZE(s3c2410_uart3_resource),
-       },
-};
-
-/* LCD Controller */
-
-static struct resource s3c_lcd_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_LCD,
-               .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_LCD,
-               .end   = IRQ_LCD,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_lcd = {
-       .name             = "s3c2410-lcd",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_lcd_resource),
-       .resource         = s3c_lcd_resource,
-       .dev              = {
-               .dma_mask               = &s3c_device_lcd_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_lcd);
-
-void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
-{
-       struct s3c2410fb_mach_info *npd;
-
-       npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
-       if (npd) {
-               npd->displays = kmemdup(pd->displays,
-                       sizeof(struct s3c2410fb_display) * npd->num_displays,
-                       GFP_KERNEL);
-               if (!npd->displays)
-                       printk(KERN_ERR "no memory for LCD display data\n");
-       } else {
-               printk(KERN_ERR "no memory for LCD platform data\n");
-       }
-}
-
-/* Touchscreen */
-
-static struct resource s3c_ts_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_ADC,
-               .end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-
-};
-
-struct platform_device s3c_device_ts = {
-       .name             = "s3c2410-ts",
-       .id               = -1,
-       .dev.parent     = &s3c_device_adc.dev,
-       .num_resources    = ARRAY_SIZE(s3c_ts_resource),
-       .resource         = s3c_ts_resource,
-};
-EXPORT_SYMBOL(s3c_device_ts);
-
-void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
-{
-       s3c_set_platdata(hard_s3c2410ts_info,
-                        sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
-}
-
-/* USB Device (Gadget)*/
-
-static struct resource s3c_usbgadget_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_USBDEV,
-               .end   = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBD,
-               .end   = IRQ_USBD,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_usbgadget = {
-       .name             = "s3c2410-usbgadget",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_usbgadget_resource),
-       .resource         = s3c_usbgadget_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_usbgadget);
-
-void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
-{
-       s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
-}
-
-/* USB High Speed 2.0 Device (Gadget) */
-static struct resource s3c_hsudc_resource[] = {
-       [0] = {
-               .start  = S3C2416_PA_HSUDC,
-               .end    = S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_USBD,
-               .end    = IRQ_USBD,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s3c_device_usb_hsudc = {
-       .name           = "s3c-hsudc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_hsudc_resource),
-       .resource       = s3c_hsudc_resource,
-       .dev            = {
-               .dma_mask               = &s3c_hsudc_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
-void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
-{
-       s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
-}
-
-/* IIS */
-
-static struct resource s3c_iis_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_IIS,
-               .end   = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static u64 s3c_device_iis_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_iis = {
-       .name             = "s3c24xx-iis",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_iis_resource),
-       .resource         = s3c_iis_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_iis_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_iis);
-
-/* RTC */
-
-static struct resource s3c_rtc_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_RTC,
-               .end   = S3C24XX_PA_RTC + 0xff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_RTC,
-               .end   = IRQ_RTC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_TICK,
-               .end   = IRQ_TICK,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-struct platform_device s3c_device_rtc = {
-       .name             = "s3c2410-rtc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
-       .resource         = s3c_rtc_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_rtc);
-
-/* ADC */
-
-static struct resource s3c_adc_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_ADC,
-               .end   = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_ADC,
-               .end   = IRQ_ADC,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_adc = {
-       .name             = "s3c24xx-adc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_adc_resource),
-       .resource         = s3c_adc_resource,
-};
-
-/* SDI */
-
-static struct resource s3c_sdi_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_SDI,
-               .end   = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SDI,
-               .end   = IRQ_SDI,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device s3c_device_sdi = {
-       .name             = "s3c2410-sdi",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_sdi_resource),
-       .resource         = s3c_sdi_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_sdi);
-
-void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
-{
-       s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
-                        &s3c_device_sdi);
-}
-
-
-/* SPI (0) */
-
-static struct resource s3c_spi0_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_SPI,
-               .end   = S3C24XX_PA_SPI + 0x1f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SPI0,
-               .end   = IRQ_SPI0,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_spi0 = {
-       .name             = "s3c2410-spi",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s3c_spi0_resource),
-       .resource         = s3c_spi0_resource,
-        .dev              = {
-                .dma_mask = &s3c_device_spi0_dmamask,
-                .coherent_dma_mask = 0xffffffffUL
-        }
-};
-
-EXPORT_SYMBOL(s3c_device_spi0);
-
-/* SPI (1) */
-
-static struct resource s3c_spi1_resource[] = {
-       [0] = {
-               .start = S3C24XX_PA_SPI + S3C2410_SPI1,
-               .end   = S3C24XX_PA_SPI + S3C2410_SPI1 + 0x1f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SPI1,
-               .end   = IRQ_SPI1,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_spi1 = {
-       .name             = "s3c2410-spi",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_spi1_resource),
-       .resource         = s3c_spi1_resource,
-        .dev              = {
-                .dma_mask = &s3c_device_spi1_dmamask,
-                .coherent_dma_mask = 0xffffffffUL
-        }
-};
-
-EXPORT_SYMBOL(s3c_device_spi1);
-
-#ifdef CONFIG_CPU_S3C2440
-
-/* Camif Controller */
-
-static struct resource s3c_camif_resource[] = {
-       [0] = {
-               .start = S3C2440_PA_CAMIF,
-               .end   = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_CAM,
-               .end   = IRQ_CAM,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-static u64 s3c_device_camif_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_camif = {
-       .name             = "s3c2440-camif",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_camif_resource),
-       .resource         = s3c_camif_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_camif_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_camif);
-
-/* AC97 */
-
-static struct resource s3c_ac97_resource[] = {
-       [0] = {
-               .start = S3C2440_PA_AC97,
-               .end   = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_S3C244x_AC97,
-               .end   = IRQ_S3C244x_AC97,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .name  = "PCM out",
-               .start = DMACH_PCM_OUT,
-               .end   = DMACH_PCM_OUT,
-               .flags = IORESOURCE_DMA,
-       },
-       [3] = {
-               .name  = "PCM in",
-               .start = DMACH_PCM_IN,
-               .end   = DMACH_PCM_IN,
-               .flags = IORESOURCE_DMA,
-       },
-       [4] = {
-               .name  = "Mic in",
-               .start = DMACH_MIC_IN,
-               .end   = DMACH_MIC_IN,
-               .flags = IORESOURCE_DMA,
-       },
-};
-
-static u64 s3c_device_audio_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_ac97 = {
-       .name             = "samsung-ac97",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_ac97_resource),
-       .resource         = s3c_ac97_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_audio_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_ac97);
-
-/* ASoC I2S */
-
-struct platform_device s3c2412_device_iis = {
-       .name             = "s3c2412-iis",
-       .id               = -1,
-       .dev              = {
-               .dma_mask = &s3c_device_audio_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c2412_device_iis);
-
-#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
deleted file mode 100644 (file)
index 2f3d7c0..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/gpio.c
- *
- * Copyright (c) 2004-2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX GPIO support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/gpio-fns.h>
-#include <asm/irq.h>
-
-#include <mach/regs-gpio.h>
-
-#include <plat/gpio-core.h>
-
-/* gpiolib wrappers until these are totally eliminated */
-
-void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
-{
-       int ret;
-
-       WARN_ON(to);    /* should be none of these left */
-
-       if (!to) {
-               /* if pull is enabled, try first with up, and if that
-                * fails, try using down */
-
-               ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
-               if (ret)
-                       s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
-       } else {
-               s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
-       }
-}
-EXPORT_SYMBOL(s3c2410_gpio_pullup);
-
-void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
-{
-       /* do this via gpiolib until all users removed */
-
-       gpio_request(pin, "temporary");
-       gpio_set_value(pin, to);
-       gpio_free(pin);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_setpin);
-
-unsigned int s3c2410_gpio_getpin(unsigned int pin)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned long offs = pin - chip->chip.base;
-
-       return __raw_readl(chip->base + 0x04) & (1<< offs);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getpin);
-
-unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
-{
-       unsigned long flags;
-       unsigned long misccr;
-
-       local_irq_save(flags);
-       misccr = __raw_readl(S3C24XX_MISCCR);
-       misccr &= ~clear;
-       misccr ^= change;
-       __raw_writel(misccr, S3C24XX_MISCCR);
-       local_irq_restore(flags);
-
-       return misccr;
-}
-
-EXPORT_SYMBOL(s3c2410_modify_misccr);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
deleted file mode 100644 (file)
index 243b641..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/gpiolib.c
- *
- * Copyright (c) 2008-2010 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/sysdev.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <plat/pm.h>
-
-#include <mach/regs-gpio.h>
-
-static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
-{
-       return -EINVAL;
-}
-
-static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
-                                       unsigned offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-       unsigned long con;
-
-       local_irq_save(flags);
-
-       con = __raw_readl(base + 0x00);
-       dat = __raw_readl(base + 0x04);
-
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-
-       __raw_writel(dat, base + 0x04);
-
-       con &= ~(1 << offset);
-
-       __raw_writel(con, base + 0x00);
-       __raw_writel(dat, base + 0x04);
-
-       local_irq_restore(flags);
-       return 0;
-}
-
-static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
-{
-       if (offset < 4)
-               return IRQ_EINT0 + offset;
-       
-       if (offset < 8)
-               return IRQ_EINT4 + offset - 4;
-       
-       return -EINVAL;
-}
-
-static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
-       .set_config     = s3c_gpio_setcfg_s3c24xx_a,
-       .get_config     = s3c_gpio_getcfg_s3c24xx_a,
-};
-
-struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
-       .set_config     = s3c_gpio_setcfg_s3c24xx,
-       .get_config     = s3c_gpio_getcfg_s3c24xx,
-};
-
-struct s3c_gpio_chip s3c24xx_gpios[] = {
-       [0] = {
-               .base   = S3C2410_GPACON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_1bit),
-               .config = &s3c24xx_gpiocfg_banka,
-               .chip   = {
-                       .base                   = S3C2410_GPA(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOA",
-                       .ngpio                  = 24,
-                       .direction_input        = s3c24xx_gpiolib_banka_input,
-                       .direction_output       = s3c24xx_gpiolib_banka_output,
-               },
-       },
-       [1] = {
-               .base   = S3C2410_GPBCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPB(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOB",
-                       .ngpio                  = 16,
-               },
-       },
-       [2] = {
-               .base   = S3C2410_GPCCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPC(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOC",
-                       .ngpio                  = 16,
-               },
-       },
-       [3] = {
-               .base   = S3C2410_GPDCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPD(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOD",
-                       .ngpio                  = 16,
-               },
-       },
-       [4] = {
-               .base   = S3C2410_GPECON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPE(0),
-                       .label                  = "GPIOE",
-                       .owner                  = THIS_MODULE,
-                       .ngpio                  = 16,
-               },
-       },
-       [5] = {
-               .base   = S3C2410_GPFCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPF(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOF",
-                       .ngpio                  = 8,
-                       .to_irq                 = s3c24xx_gpiolib_bankf_toirq,
-               },
-       },
-       [6] = {
-               .base   = S3C2410_GPGCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .irq_base = IRQ_EINT8,
-               .chip   = {
-                       .base                   = S3C2410_GPG(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOG",
-                       .ngpio                  = 16,
-                       .to_irq                 = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = S3C2410_GPHCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPH(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOH",
-                       .ngpio                  = 11,
-               },
-       },
-               /* GPIOS for the S3C2443 and later devices. */
-       {
-               .base   = S3C2440_GPJCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPJ(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOJ",
-                       .ngpio                  = 16,
-               },
-       }, {
-               .base   = S3C2443_GPKCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPK(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOK",
-                       .ngpio                  = 16,
-               },
-       }, {
-               .base   = S3C2443_GPLCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPL(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOL",
-                       .ngpio                  = 15,
-               },
-       }, {
-               .base   = S3C2443_GPMCON,
-               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
-               .chip   = {
-                       .base                   = S3C2410_GPM(0),
-                       .owner                  = THIS_MODULE,
-                       .label                  = "GPIOM",
-                       .ngpio                  = 2,
-               },
-       },
-};
-
-
-static __init int s3c24xx_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chip = s3c24xx_gpios;
-       int gpn;
-
-       for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
-               if (!chip->config)
-                       chip->config = &s3c24xx_gpiocfg_default;
-
-               s3c_gpiolib_add(chip);
-       }
-
-       return 0;
-}
-
-core_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 (file)
index 7dffa83..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MACH_CLKDEV_H__
-#define __MACH_CLKDEV_H__
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do {} while (0)
-
-#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 (file)
index a087de2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C24xx - pwm clock and timer support
- */
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-       return 1 << (1 + tcfg1);
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-       return 0;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-       return ilog2(div) - 1;
-}
-
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
diff --git a/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h b/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
deleted file mode 100644 (file)
index de5e88f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
- *
- * Copyright 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Simtec Audio support.
-*/
-
-/**
- * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
- * @use_mpllin: Select codec clock from MPLLin
- * @output_cdclk: Need to output CDCLK to the codec
- * @have_mic: Set if we have a MIC socket
- * @have_lout: Set if we have a LineOut socket
- * @amp_gpio: GPIO pin to enable the AMP
- * @amp_gain: Option GPIO to control AMP gain
- */
-struct s3c24xx_audio_simtec_pdata {
-       unsigned int    use_mpllin:1;
-       unsigned int    output_cdclk:1;
-
-       unsigned int    have_mic:1;
-       unsigned int    have_lout:1;
-
-       int             amp_gpio;
-       int             amp_gain[2];
-
-       void    (*startup)(void);
-};
-
-extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
-                           struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c24xx/include/plat/common-smdk.h b/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
deleted file mode 100644 (file)
index 58d9094..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Common code for SMDK2410 and SMDK2440 boards
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern void smdk_machine_init(void);
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
deleted file mode 100644 (file)
index d623235..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/cpu-freq.h
- *
- * Copyright (c) 2006-2009 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C CPU frequency scaling support - core support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/cpu-freq.h>
-
-struct seq_file;
-
-#define MAX_BANKS (8)
-#define S3C2412_MAX_IO (8)
-
-/**
- * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
- * @bankcon: The cached version of settings in this structure.
- * @tacp:
- * @tacs: Time from address valid to nCS asserted.
- * @tcos: Time from nCS asserted to nOE or nWE asserted.
- * @tacc: Time that nOE or nWE is asserted.
- * @tcoh: Time nCS is held after nOE or nWE are released.
- * @tcah: Time address is held for after
- * @nwait_en: Whether nWAIT is enabled for this bank.
- *
- * This structure represents the IO timings for a S3C2410 style IO bank
- * used by the CPU frequency support if it needs to change the settings
- * of the IO.
- */
-struct s3c2410_iobank_timing {
-       unsigned long   bankcon;
-       unsigned int    tacp;
-       unsigned int    tacs;
-       unsigned int    tcos;
-       unsigned int    tacc;
-       unsigned int    tcoh;           /* nCS hold afrer nOE/nWE */
-       unsigned int    tcah;           /* Address hold after nCS */
-       unsigned char   nwait_en;       /* nWait enabled for bank. */
-};
-
-/**
- * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
- * @idcy: The idle cycle time between transactions.
- * @wstrd: nCS release to end of read cycle.
- * @wstwr: nCS release to end of write cycle.
- * @wstoen: nCS assertion to nOE assertion time.
- * @wstwen: nCS assertion to nWE assertion time.
- * @wstbrd: Burst ready delay.
- * @smbidcyr: Register cache for smbidcyr value.
- * @smbwstrd: Register cache for smbwstrd value.
- * @smbwstwr: Register cache for smbwstwr value.
- * @smbwstoen: Register cache for smbwstoen value.
- * @smbwstwen: Register cache for smbwstwen value.
- * @smbwstbrd: Register cache for smbwstbrd value.
- *
- * Timing information for a IO bank on an S3C2412 or similar system which
- * uses a PL093 block.
- */
-struct s3c2412_iobank_timing {
-       unsigned int    idcy;
-       unsigned int    wstrd;
-       unsigned int    wstwr;
-       unsigned int    wstoen;
-       unsigned int    wstwen;
-       unsigned int    wstbrd;
-
-       /* register cache */
-       unsigned char   smbidcyr;
-       unsigned char   smbwstrd;
-       unsigned char   smbwstwr;
-       unsigned char   smbwstoen;
-       unsigned char   smbwstwen;
-       unsigned char   smbwstbrd;
-};
-
-union s3c_iobank {
-       struct s3c2410_iobank_timing    *io_2410;
-       struct s3c2412_iobank_timing    *io_2412;
-};
-
-/**
- * struct s3c_iotimings - Chip IO timings holder
- * @bank: The timings for each IO bank.
- */
-struct s3c_iotimings {
-       union s3c_iobank        bank[MAX_BANKS];
-};
-
-/**
- * struct s3c_plltab - PLL table information.
- * @vals: List of PLL values.
- * @size: Size of the PLL table @vals.
- */
-struct s3c_plltab {
-       struct s3c_pllval       *vals;
-       int                      size;
-};
-
-/**
- * struct s3c_cpufreq_config - current cpu frequency configuration
- * @freq: The current settings for the core clocks.
- * @max: Maxium settings, derived from core, board and user settings.
- * @pll: The PLL table entry for the current PLL settings.
- * @divs: The divisor settings for the core clocks.
- * @info: The current core driver information.
- * @board: The information for the board we are running on.
- * @lock_pll: Set if the PLL settings cannot be changed.
- *
- * This is for the core drivers that need to know information about
- * the current settings and values. It should not be needed by any
- * device drivers.
-*/
-struct s3c_cpufreq_config {
-       struct s3c_freq         freq;
-       struct s3c_freq         max;
-       struct cpufreq_frequency_table pll;
-       struct s3c_clkdivs      divs;
-       struct s3c_cpufreq_info *info;  /* for core, not drivers */
-       struct s3c_cpufreq_board *board;
-
-       unsigned int    lock_pll:1;
-};
-
-/**
- * struct s3c_cpufreq_info - Information for the CPU frequency driver.
- * @name: The name of this implementation.
- * @max: The maximum frequencies for the system.
- * @latency: Transition latency to give to cpufreq.
- * @locktime_m: The lock-time in uS for the MPLL.
- * @locktime_u: The lock-time in uS for the UPLL.
- * @locttime_bits: The number of bits each LOCKTIME field.
- * @need_pll: Set if this driver needs to change the PLL values to achieve
- *     any frequency changes. This is really only need by devices like the
- *     S3C2410 where there is no or limited divider between the PLL and the
- *     ARMCLK.
- * @resume_clocks: Update the clocks on resume.
- * @get_iotiming: Get the current IO timing data, mainly for use at start.
- * @set_iotiming: Update the IO timings from the cached copies calculated
- *     from the @calc_iotiming entry when changing the frequency.
- * @calc_iotiming: Calculate and update the cached copies of the IO timings
- *     from the newly calculated frequencies.
- * @calc_freqtable: Calculate (fill in) the given frequency table from the
- *     current frequency configuration. If the table passed in is NULL,
- *     then the return is the number of elements to be filled for allocation
- *     of the table.
- * @set_refresh: Set the memory refresh configuration.
- * @set_fvco: Set the PLL frequencies.
- * @set_divs: Update the clock divisors.
- * @calc_divs: Calculate the clock divisors.
- */
-struct s3c_cpufreq_info {
-       const char              *name;
-       struct s3c_freq         max;
-
-       unsigned int            latency;
-
-       unsigned int            locktime_m;
-       unsigned int            locktime_u;
-       unsigned char           locktime_bits;
-
-       unsigned int            need_pll:1;
-
-       /* driver routines */
-
-       void            (*resume_clocks)(void);
-
-       int             (*get_iotiming)(struct s3c_cpufreq_config *cfg,
-                                       struct s3c_iotimings *timings);
-
-       void            (*set_iotiming)(struct s3c_cpufreq_config *cfg,
-                                       struct s3c_iotimings *timings);
-
-       int             (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
-                                        struct s3c_iotimings *timings);
-
-       int             (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
-                                         struct cpufreq_frequency_table *t,
-                                         size_t table_size);
-
-       void            (*debug_io_show)(struct seq_file *seq,
-                                        struct s3c_cpufreq_config *cfg,
-                                        union s3c_iobank *iob);
-
-       void            (*set_refresh)(struct s3c_cpufreq_config *cfg);
-       void            (*set_fvco)(struct s3c_cpufreq_config *cfg);
-       void            (*set_divs)(struct s3c_cpufreq_config *cfg);
-       int             (*calc_divs)(struct s3c_cpufreq_config *cfg);
-};
-
-extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
-
-extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
-
-/* exports and utilities for debugfs */
-extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
-extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
-
-extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
-                                    struct s3c_cpufreq_config *cfg,
-                                    union s3c_iobank *iob);
-
-extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
-                                    struct s3c_cpufreq_config *cfg,
-                                    union s3c_iobank *iob);
-
-#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
-#define s3c_cpufreq_debugfs_call(x) x
-#else
-#define s3c_cpufreq_debugfs_call(x) NULL
-#endif
-
-/* Useful utility functions. */
-
-extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
-
-/* S3C2410 and compatible exported functions */
-
-extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
-extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
-
-#ifdef CONFIG_S3C2410_IOTIMING
-extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
-                                struct s3c_iotimings *iot);
-
-extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
-                               struct s3c_iotimings *timings);
-
-extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
-                                struct s3c_iotimings *iot);
-#else
-#define s3c2410_iotiming_calc NULL
-#define s3c2410_iotiming_get NULL
-#define s3c2410_iotiming_set NULL
-#endif /* CONFIG_S3C2410_IOTIMING */
-
-/* S3C2412 compatible routines */
-
-extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
-                               struct s3c_iotimings *timings);
-
-extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
-                               struct s3c_iotimings *timings);
-
-extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
-                                struct s3c_iotimings *iot);
-
-extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
-                                struct s3c_iotimings *iot);
-
-#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
-#define s3c_freq_dbg(x...) printk(KERN_INFO x)
-#else
-#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
-#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
-
-#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
-#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
-#else
-#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
-#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
-
-static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
-                                     int index, size_t table_size,
-                                     unsigned int freq)
-{
-       if (index < 0)
-               return index;
-
-       if (table) {
-               if (index >= table_size)
-                       return -ENOMEM;
-
-               s3c_freq_dbg("%s: { %d = %u kHz }\n",
-                            __func__, index, freq);
-
-               table[index].index = index;
-               table[index].frequency = freq;
-       }
-
-       return index + 1;
-}
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-s3c24xx/include/plat/fiq.h
deleted file mode 100644 (file)
index 8521b83..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/fiq.h
- *
- * Copyright (c) 2009 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU FIQ support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern int s3c24xx_set_fiq(unsigned int irq, bool on);
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
deleted file mode 100644 (file)
index ec087d6..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/irq.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU IRQ support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#define irqdbf(x...)
-#define irqdbf2(x...)
-
-#define EXTINT_OFF (IRQ_EINT4 - 4)
-
-/* these are exported for arch/arm/mach-* usage */
-extern struct irq_chip s3c_irq_level_chip;
-extern struct irq_chip s3c_irq_chip;
-
-static inline void
-s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
-               int subcheck)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
-
-       /* check to see if we need to mask the parent IRQ */
-
-       if ((submask  & subcheck) == subcheck) {
-               __raw_writel(mask | parentbit, S3C2410_INTMSK);
-       }
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-
-}
-
-static inline void
-s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
-       mask &= ~parentbit;
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-       __raw_writel(mask, S3C2410_INTMSK);
-}
-
-
-static inline void
-s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       s3c_irqsub_mask(irqno, parentmask, group);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-static inline void
-s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-/* exported for use in arch/arm/mach-s3c2410 */
-
-#ifdef CONFIG_PM
-extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
-#else
-#define s3c_irq_wake NULL
-#endif
-
-extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
deleted file mode 100644 (file)
index 2ac2b21..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _ARCH_MCI_H
-#define _ARCH_MCI_H
-
-/**
- * struct s3c24xx_mci_pdata - sd/mmc controller platform data
- * @no_wprotect: Set this to indicate there is no write-protect switch.
- * @no_detect: Set this if there is no detect switch.
- * @wprotect_invert: Invert the default sense of the write protect switch.
- * @detect_invert: Invert the default sense of the write protect switch.
- * @use_dma: Set to allow the use of DMA.
- * @gpio_detect: GPIO number for the card detect line.
- * @gpio_wprotect: GPIO number for the write protect line.
- * @ocr_avail: The mask of the available power states, non-zero to use.
- * @set_power: Callback to control the power mode.
- *
- * The @gpio_detect is used for card detection when @no_wprotect is unset,
- * and the default sense is that 0 returned from gpio_get_value() means
- * that a card is inserted. If @detect_invert is set, then the value from
- * gpio_get_value() is inverted, which makes 1 mean card inserted.
- *
- * The driver will use @gpio_wprotect to signal whether the card is write
- * protected if @no_wprotect is not set. A 0 returned from gpio_get_value()
- * means the card is read/write, and 1 means read-only. The @wprotect_invert
- * will invert the value returned from gpio_get_value().
- *
- * Card power is set by @ocr_availa, using MCC_VDD_ constants if it is set
- * to a non-zero value, otherwise the default of 3.2-3.4V is used.
- */
-struct s3c24xx_mci_pdata {
-       unsigned int    no_wprotect : 1;
-       unsigned int    no_detect : 1;
-       unsigned int    wprotect_invert : 1;
-       unsigned int    detect_invert : 1;   /* set => detect active high. */
-       unsigned int    use_dma : 1;
-
-       unsigned int    gpio_detect;
-       unsigned int    gpio_wprotect;
-       unsigned long   ocr_avail;
-       void            (*set_power)(unsigned char power_mode,
-                                    unsigned short vdd);
-};
-
-/**
- * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device
- * @pdata: The platform data
- *
- * Copy the platform data supplied by @pdata so that this can be marked
- * __initdata.
- */
-extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata);
-
-#endif /* _ARCH_NCI_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
deleted file mode 100644 (file)
index 005729a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
- *
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C24xx - common pll registers and code
- */
-
-#define S3C24XX_PLLCON_MDIVSHIFT       12
-#define S3C24XX_PLLCON_PDIVSHIFT       4
-#define S3C24XX_PLLCON_SDIVSHIFT       0
-#define S3C24XX_PLLCON_MDIVMASK                ((1<<(1+(19-12)))-1)
-#define S3C24XX_PLLCON_PDIVMASK                ((1<<5)-1)
-#define S3C24XX_PLLCON_SDIVMASK                3
-
-#include <asm/div64.h>
-
-static inline unsigned int
-s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
-{
-       unsigned int mdiv, pdiv, sdiv;
-       uint64_t fvco;
-
-       mdiv = pllval >> S3C24XX_PLLCON_MDIVSHIFT;
-       pdiv = pllval >> S3C24XX_PLLCON_PDIVSHIFT;
-       sdiv = pllval >> S3C24XX_PLLCON_SDIVSHIFT;
-
-       mdiv &= S3C24XX_PLLCON_MDIVMASK;
-       pdiv &= S3C24XX_PLLCON_PDIVMASK;
-       sdiv &= S3C24XX_PLLCON_SDIVMASK;
-
-       fvco = (uint64_t)baseclk * (mdiv + 8);
-       do_div(fvco, (pdiv + 2) << sdiv);
-
-       return (unsigned int)fvco;
-}
-
-#define S3C2416_PLL_M_SHIFT    (14)
-#define S3C2416_PLL_P_SHIFT    (5)
-#define S3C2416_PLL_S_MASK     (7)
-#define S3C2416_PLL_M_MASK     ((1 << 10) - 1)
-#define S3C2416_PLL_P_MASK     (63)
-
-static inline unsigned int
-s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
-{
-       unsigned int m, p, s;
-       uint64_t fvco;
-
-       m = pllval >> S3C2416_PLL_M_SHIFT;
-       p = pllval >> S3C2416_PLL_P_SHIFT;
-
-       s = pllval & S3C2416_PLL_S_MASK;
-       m &= S3C2416_PLL_M_MASK;
-       p &= S3C2416_PLL_P_MASK;
-
-       fvco = (uint64_t)baseclk * m;
-       do_div(fvco, (p << s));
-
-       return (unsigned int)fvco;
-}
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-dma.h b/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
deleted file mode 100644 (file)
index 1b0f4c3..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* DMA Register definitions */
-
-#define S3C2410_DMA_DISRC              (0x00)
-#define S3C2410_DMA_DISRCC             (0x04)
-#define S3C2410_DMA_DIDST              (0x08)
-#define S3C2410_DMA_DIDSTC             (0x0C)
-#define S3C2410_DMA_DCON               (0x10)
-#define S3C2410_DMA_DSTAT              (0x14)
-#define S3C2410_DMA_DCSRC              (0x18)
-#define S3C2410_DMA_DCDST              (0x1C)
-#define S3C2410_DMA_DMASKTRIG          (0x20)
-#define S3C2412_DMA_DMAREQSEL          (0x24)
-#define S3C2443_DMA_DMAREQSEL          (0x24)
-
-#define S3C2410_DISRCC_INC             (1<<0)
-#define S3C2410_DISRCC_APB             (1<<1)
-
-#define S3C2410_DMASKTRIG_STOP         (1<<2)
-#define S3C2410_DMASKTRIG_ON           (1<<1)
-#define S3C2410_DMASKTRIG_SWTRIG       (1<<0)
-
-#define S3C2410_DCON_DEMAND            (0<<31)
-#define S3C2410_DCON_HANDSHAKE         (1<<31)
-#define S3C2410_DCON_SYNC_PCLK         (0<<30)
-#define S3C2410_DCON_SYNC_HCLK         (1<<30)
-
-#define S3C2410_DCON_INTREQ            (1<<29)
-
-#define S3C2410_DCON_CH0_XDREQ0                (0<<24)
-#define S3C2410_DCON_CH0_UART0         (1<<24)
-#define S3C2410_DCON_CH0_SDI           (2<<24)
-#define S3C2410_DCON_CH0_TIMER         (3<<24)
-#define S3C2410_DCON_CH0_USBEP1                (4<<24)
-
-#define S3C2410_DCON_CH1_XDREQ1                (0<<24)
-#define S3C2410_DCON_CH1_UART1         (1<<24)
-#define S3C2410_DCON_CH1_I2SSDI                (2<<24)
-#define S3C2410_DCON_CH1_SPI           (3<<24)
-#define S3C2410_DCON_CH1_USBEP2                (4<<24)
-
-#define S3C2410_DCON_CH2_I2SSDO                (0<<24)
-#define S3C2410_DCON_CH2_I2SSDI                (1<<24)
-#define S3C2410_DCON_CH2_SDI           (2<<24)
-#define S3C2410_DCON_CH2_TIMER         (3<<24)
-#define S3C2410_DCON_CH2_USBEP3                (4<<24)
-
-#define S3C2410_DCON_CH3_UART2         (0<<24)
-#define S3C2410_DCON_CH3_SDI           (1<<24)
-#define S3C2410_DCON_CH3_SPI           (2<<24)
-#define S3C2410_DCON_CH3_TIMER         (3<<24)
-#define S3C2410_DCON_CH3_USBEP4                (4<<24)
-
-#define S3C2410_DCON_SRCSHIFT          (24)
-#define S3C2410_DCON_SRCMASK           (7<<24)
-
-#define S3C2410_DCON_BYTE              (0<<20)
-#define S3C2410_DCON_HALFWORD          (1<<20)
-#define S3C2410_DCON_WORD              (2<<20)
-
-#define S3C2410_DCON_AUTORELOAD                (0<<22)
-#define S3C2410_DCON_NORELOAD          (1<<22)
-#define S3C2410_DCON_HWTRIG            (1<<23)
-
-#ifdef CONFIG_CPU_S3C2440
-#define S3C2440_DIDSTC_CHKINT          (1<<2)
-
-#define S3C2440_DCON_CH0_I2SSDO                (5<<24)
-#define S3C2440_DCON_CH0_PCMIN         (6<<24)
-
-#define S3C2440_DCON_CH1_PCMOUT                (5<<24)
-#define S3C2440_DCON_CH1_SDI           (6<<24)
-
-#define S3C2440_DCON_CH2_PCMIN         (5<<24)
-#define S3C2440_DCON_CH2_MICIN         (6<<24)
-
-#define S3C2440_DCON_CH3_MICIN         (5<<24)
-#define S3C2440_DCON_CH3_PCMOUT                (6<<24)
-#endif
-
-#ifdef CONFIG_CPU_S3C2412
-
-#define S3C2412_DMAREQSEL_SRC(x)       ((x)<<1)
-
-#define S3C2412_DMAREQSEL_HW           (1)
-
-#define S3C2412_DMAREQSEL_SPI0TX       S3C2412_DMAREQSEL_SRC(0)
-#define S3C2412_DMAREQSEL_SPI0RX       S3C2412_DMAREQSEL_SRC(1)
-#define S3C2412_DMAREQSEL_SPI1TX       S3C2412_DMAREQSEL_SRC(2)
-#define S3C2412_DMAREQSEL_SPI1RX       S3C2412_DMAREQSEL_SRC(3)
-#define S3C2412_DMAREQSEL_I2STX                S3C2412_DMAREQSEL_SRC(4)
-#define S3C2412_DMAREQSEL_I2SRX                S3C2412_DMAREQSEL_SRC(5)
-#define S3C2412_DMAREQSEL_TIMER                S3C2412_DMAREQSEL_SRC(9)
-#define S3C2412_DMAREQSEL_SDI          S3C2412_DMAREQSEL_SRC(10)
-#define S3C2412_DMAREQSEL_USBEP1       S3C2412_DMAREQSEL_SRC(13)
-#define S3C2412_DMAREQSEL_USBEP2       S3C2412_DMAREQSEL_SRC(14)
-#define S3C2412_DMAREQSEL_USBEP3       S3C2412_DMAREQSEL_SRC(15)
-#define S3C2412_DMAREQSEL_USBEP4       S3C2412_DMAREQSEL_SRC(16)
-#define S3C2412_DMAREQSEL_XDREQ0       S3C2412_DMAREQSEL_SRC(17)
-#define S3C2412_DMAREQSEL_XDREQ1       S3C2412_DMAREQSEL_SRC(18)
-#define S3C2412_DMAREQSEL_UART0_0      S3C2412_DMAREQSEL_SRC(19)
-#define S3C2412_DMAREQSEL_UART0_1      S3C2412_DMAREQSEL_SRC(20)
-#define S3C2412_DMAREQSEL_UART1_0      S3C2412_DMAREQSEL_SRC(21)
-#define S3C2412_DMAREQSEL_UART1_1      S3C2412_DMAREQSEL_SRC(22)
-#define S3C2412_DMAREQSEL_UART2_0      S3C2412_DMAREQSEL_SRC(23)
-#define S3C2412_DMAREQSEL_UART2_1      S3C2412_DMAREQSEL_SRC(24)
-
-#endif
-
-#define S3C2443_DMAREQSEL_SRC(x)       ((x)<<1)
-
-#define S3C2443_DMAREQSEL_HW           (1)
-
-#define S3C2443_DMAREQSEL_SPI0TX       S3C2443_DMAREQSEL_SRC(0)
-#define S3C2443_DMAREQSEL_SPI0RX       S3C2443_DMAREQSEL_SRC(1)
-#define S3C2443_DMAREQSEL_SPI1TX       S3C2443_DMAREQSEL_SRC(2)
-#define S3C2443_DMAREQSEL_SPI1RX       S3C2443_DMAREQSEL_SRC(3)
-#define S3C2443_DMAREQSEL_I2STX                S3C2443_DMAREQSEL_SRC(4)
-#define S3C2443_DMAREQSEL_I2SRX                S3C2443_DMAREQSEL_SRC(5)
-#define S3C2443_DMAREQSEL_TIMER                S3C2443_DMAREQSEL_SRC(9)
-#define S3C2443_DMAREQSEL_SDI          S3C2443_DMAREQSEL_SRC(10)
-#define S3C2443_DMAREQSEL_XDREQ0       S3C2443_DMAREQSEL_SRC(17)
-#define S3C2443_DMAREQSEL_XDREQ1       S3C2443_DMAREQSEL_SRC(18)
-#define S3C2443_DMAREQSEL_UART0_0      S3C2443_DMAREQSEL_SRC(19)
-#define S3C2443_DMAREQSEL_UART0_1      S3C2443_DMAREQSEL_SRC(20)
-#define S3C2443_DMAREQSEL_UART1_0      S3C2443_DMAREQSEL_SRC(21)
-#define S3C2443_DMAREQSEL_UART1_1      S3C2443_DMAREQSEL_SRC(22)
-#define S3C2443_DMAREQSEL_UART2_0      S3C2443_DMAREQSEL_SRC(23)
-#define S3C2443_DMAREQSEL_UART2_1      S3C2443_DMAREQSEL_SRC(24)
-#define S3C2443_DMAREQSEL_UART3_0      S3C2443_DMAREQSEL_SRC(25)
-#define S3C2443_DMAREQSEL_UART3_1      S3C2443_DMAREQSEL_SRC(26)
-#define S3C2443_DMAREQSEL_PCMOUT       S3C2443_DMAREQSEL_SRC(27)
-#define S3C2443_DMAREQSEL_PCMIN        S3C2443_DMAREQSEL_SRC(28)
-#define S3C2443_DMAREQSEL_MICIN                S3C2443_DMAREQSEL_SRC(29)
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 (file)
index cc44e0e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-iis.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 IIS register definition
-*/
-
-#ifndef __ASM_ARCH_REGS_IIS_H
-#define __ASM_ARCH_REGS_IIS_H
-
-#define S3C2410_IISCON  (0x00)
-
-#define S3C2410_IISCON_LRINDEX   (1<<8)
-#define S3C2410_IISCON_TXFIFORDY  (1<<7)
-#define S3C2410_IISCON_RXFIFORDY  (1<<6)
-#define S3C2410_IISCON_TXDMAEN   (1<<5)
-#define S3C2410_IISCON_RXDMAEN   (1<<4)
-#define S3C2410_IISCON_TXIDLE    (1<<3)
-#define S3C2410_IISCON_RXIDLE    (1<<2)
-#define S3C2410_IISCON_PSCEN     (1<<1)
-#define S3C2410_IISCON_IISEN     (1<<0)
-
-#define S3C2410_IISMOD  (0x04)
-
-#define S3C2440_IISMOD_MPLL      (1<<9)
-#define S3C2410_IISMOD_SLAVE     (1<<8)
-#define S3C2410_IISMOD_NOXFER    (0<<6)
-#define S3C2410_IISMOD_RXMODE    (1<<6)
-#define S3C2410_IISMOD_TXMODE    (2<<6)
-#define S3C2410_IISMOD_TXRXMODE          (3<<6)
-#define S3C2410_IISMOD_LR_LLOW   (0<<5)
-#define S3C2410_IISMOD_LR_RLOW   (1<<5)
-#define S3C2410_IISMOD_IIS       (0<<4)
-#define S3C2410_IISMOD_MSB       (1<<4)
-#define S3C2410_IISMOD_8BIT      (0<<3)
-#define S3C2410_IISMOD_16BIT     (1<<3)
-#define S3C2410_IISMOD_BITMASK   (1<<3)
-#define S3C2410_IISMOD_256FS     (0<<2)
-#define S3C2410_IISMOD_384FS     (1<<2)
-#define S3C2410_IISMOD_16FS      (0<<0)
-#define S3C2410_IISMOD_32FS      (1<<0)
-#define S3C2410_IISMOD_48FS      (2<<0)
-#define S3C2410_IISMOD_FS_MASK   (3<<0)
-
-#define S3C2410_IISPSR         (0x08)
-#define S3C2410_IISPSR_INTMASK (31<<5)
-#define S3C2410_IISPSR_INTSHIFT        (5)
-#define S3C2410_IISPSR_EXTMASK (31<<0)
-#define S3C2410_IISPSR_EXTSHFIT        (0)
-
-#define S3C2410_IISFCON  (0x0c)
-
-#define S3C2410_IISFCON_TXDMA    (1<<15)
-#define S3C2410_IISFCON_RXDMA    (1<<14)
-#define S3C2410_IISFCON_TXENABLE  (1<<13)
-#define S3C2410_IISFCON_RXENABLE  (1<<12)
-#define S3C2410_IISFCON_TXMASK   (0x3f << 6)
-#define S3C2410_IISFCON_TXSHIFT          (6)
-#define S3C2410_IISFCON_RXMASK   (0x3f)
-#define S3C2410_IISFCON_RXSHIFT          (0)
-
-#define S3C2410_IISFIFO  (0x10)
-#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 (file)
index 892e2f6..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-spi.h
- *
- * Copyright (c) 2004 Fetron GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 SPI register definition
-*/
-
-#ifndef __ASM_ARCH_REGS_SPI_H
-#define __ASM_ARCH_REGS_SPI_H
-
-#define S3C2410_SPI1   (0x20)
-#define S3C2412_SPI1   (0x100)
-
-#define S3C2410_SPCON  (0x00)
-
-#define S3C2412_SPCON_RXFIFO_RB2       (0<<14)
-#define S3C2412_SPCON_RXFIFO_RB4       (1<<14)
-#define S3C2412_SPCON_RXFIFO_RB12      (2<<14)
-#define S3C2412_SPCON_RXFIFO_RB14      (3<<14)
-#define S3C2412_SPCON_TXFIFO_RB2       (0<<12)
-#define S3C2412_SPCON_TXFIFO_RB4       (1<<12)
-#define S3C2412_SPCON_TXFIFO_RB12      (2<<12)
-#define S3C2412_SPCON_TXFIFO_RB14      (3<<12)
-#define S3C2412_SPCON_RXFIFO_RESET     (1<<11) /* RxFIFO reset */
-#define S3C2412_SPCON_TXFIFO_RESET     (1<<10) /* TxFIFO reset */
-#define S3C2412_SPCON_RXFIFO_EN                (1<<9)  /* RxFIFO Enable */
-#define S3C2412_SPCON_TXFIFO_EN                (1<<8)  /* TxFIFO Enable */
-
-#define S3C2412_SPCON_DIRC_RX    (1<<7)
-
-#define S3C2410_SPCON_SMOD_DMA   (2<<5)        /* DMA mode */
-#define S3C2410_SPCON_SMOD_INT   (1<<5)        /* interrupt mode */
-#define S3C2410_SPCON_SMOD_POLL   (0<<5)       /* polling mode */
-#define S3C2410_SPCON_ENSCK      (1<<4)        /* Enable SCK */
-#define S3C2410_SPCON_MSTR       (1<<3)        /* Master/Slave select
-                                                  0: slave, 1: master */
-#define S3C2410_SPCON_CPOL_HIGH          (1<<2)        /* Clock polarity select */
-#define S3C2410_SPCON_CPOL_LOW   (0<<2)        /* Clock polarity select */
-
-#define S3C2410_SPCON_CPHA_FMTB          (1<<1)        /* Clock Phase Select */
-#define S3C2410_SPCON_CPHA_FMTA          (0<<1)        /* Clock Phase Select */
-
-#define S3C2410_SPCON_TAGD       (1<<0)        /* Tx auto garbage data mode */
-
-
-#define S3C2410_SPSTA   (0x04)
-
-#define S3C2412_SPSTA_RXFIFO_AE                (1<<11)
-#define S3C2412_SPSTA_TXFIFO_AE                (1<<10)
-#define S3C2412_SPSTA_RXFIFO_ERROR     (1<<9)
-#define S3C2412_SPSTA_TXFIFO_ERROR     (1<<8)
-#define S3C2412_SPSTA_RXFIFO_FIFO      (1<<7)
-#define S3C2412_SPSTA_RXFIFO_EMPTY     (1<<6)
-#define S3C2412_SPSTA_TXFIFO_NFULL     (1<<5)
-#define S3C2412_SPSTA_TXFIFO_EMPTY     (1<<4)
-
-#define S3C2410_SPSTA_DCOL       (1<<2)        /* Data Collision Error */
-#define S3C2410_SPSTA_MULD       (1<<1)        /* Multi Master Error */
-#define S3C2410_SPSTA_READY      (1<<0)        /* Data Tx/Rx ready */
-#define S3C2412_SPSTA_READY_ORG          (1<<3)
-
-#define S3C2410_SPPIN   (0x08)
-
-#define S3C2410_SPPIN_ENMUL      (1<<2)        /* Multi Master Error detect */
-#define S3C2410_SPPIN_RESERVED   (1<<1)
-#define S3C2410_SPPIN_KEEP       (1<<0)        /* Master Out keep */
-
-#define S3C2410_SPPRE   (0x0C)
-#define S3C2410_SPTDAT  (0x10)
-#define S3C2410_SPRDAT  (0x14)
-
-#define S3C2412_TXFIFO  (0x18)
-#define S3C2412_RXFIFO  (0x18)
-#define S3C2412_SPFIC   (0x24)
-
-
-#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-udc.h b/arch/arm/plat-s3c24xx/include/plat/regs-udc.h
deleted file mode 100644 (file)
index f0dd4a4..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-udc.h
- *
- * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
- *
- * This include file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
-*/
-
-#ifndef __ASM_ARCH_REGS_UDC_H
-#define __ASM_ARCH_REGS_UDC_H
-
-#define S3C2410_USBDREG(x) (x)
-
-#define S3C2410_UDC_FUNC_ADDR_REG      S3C2410_USBDREG(0x0140)
-#define S3C2410_UDC_PWR_REG            S3C2410_USBDREG(0x0144)
-#define S3C2410_UDC_EP_INT_REG         S3C2410_USBDREG(0x0148)
-
-#define S3C2410_UDC_USB_INT_REG                S3C2410_USBDREG(0x0158)
-#define S3C2410_UDC_EP_INT_EN_REG      S3C2410_USBDREG(0x015c)
-
-#define S3C2410_UDC_USB_INT_EN_REG     S3C2410_USBDREG(0x016c)
-
-#define S3C2410_UDC_FRAME_NUM1_REG     S3C2410_USBDREG(0x0170)
-#define S3C2410_UDC_FRAME_NUM2_REG     S3C2410_USBDREG(0x0174)
-
-#define S3C2410_UDC_EP0_FIFO_REG       S3C2410_USBDREG(0x01c0)
-#define S3C2410_UDC_EP1_FIFO_REG       S3C2410_USBDREG(0x01c4)
-#define S3C2410_UDC_EP2_FIFO_REG       S3C2410_USBDREG(0x01c8)
-#define S3C2410_UDC_EP3_FIFO_REG       S3C2410_USBDREG(0x01cc)
-#define S3C2410_UDC_EP4_FIFO_REG       S3C2410_USBDREG(0x01d0)
-
-#define S3C2410_UDC_EP1_DMA_CON                S3C2410_USBDREG(0x0200)
-#define S3C2410_UDC_EP1_DMA_UNIT       S3C2410_USBDREG(0x0204)
-#define S3C2410_UDC_EP1_DMA_FIFO       S3C2410_USBDREG(0x0208)
-#define S3C2410_UDC_EP1_DMA_TTC_L      S3C2410_USBDREG(0x020c)
-#define S3C2410_UDC_EP1_DMA_TTC_M      S3C2410_USBDREG(0x0210)
-#define S3C2410_UDC_EP1_DMA_TTC_H      S3C2410_USBDREG(0x0214)
-
-#define S3C2410_UDC_EP2_DMA_CON                S3C2410_USBDREG(0x0218)
-#define S3C2410_UDC_EP2_DMA_UNIT       S3C2410_USBDREG(0x021c)
-#define S3C2410_UDC_EP2_DMA_FIFO       S3C2410_USBDREG(0x0220)
-#define S3C2410_UDC_EP2_DMA_TTC_L      S3C2410_USBDREG(0x0224)
-#define S3C2410_UDC_EP2_DMA_TTC_M      S3C2410_USBDREG(0x0228)
-#define S3C2410_UDC_EP2_DMA_TTC_H      S3C2410_USBDREG(0x022c)
-
-#define S3C2410_UDC_EP3_DMA_CON                S3C2410_USBDREG(0x0240)
-#define S3C2410_UDC_EP3_DMA_UNIT       S3C2410_USBDREG(0x0244)
-#define S3C2410_UDC_EP3_DMA_FIFO       S3C2410_USBDREG(0x0248)
-#define S3C2410_UDC_EP3_DMA_TTC_L      S3C2410_USBDREG(0x024c)
-#define S3C2410_UDC_EP3_DMA_TTC_M      S3C2410_USBDREG(0x0250)
-#define S3C2410_UDC_EP3_DMA_TTC_H      S3C2410_USBDREG(0x0254)
-
-#define S3C2410_UDC_EP4_DMA_CON                S3C2410_USBDREG(0x0258)
-#define S3C2410_UDC_EP4_DMA_UNIT       S3C2410_USBDREG(0x025c)
-#define S3C2410_UDC_EP4_DMA_FIFO       S3C2410_USBDREG(0x0260)
-#define S3C2410_UDC_EP4_DMA_TTC_L      S3C2410_USBDREG(0x0264)
-#define S3C2410_UDC_EP4_DMA_TTC_M      S3C2410_USBDREG(0x0268)
-#define S3C2410_UDC_EP4_DMA_TTC_H      S3C2410_USBDREG(0x026c)
-
-#define S3C2410_UDC_INDEX_REG          S3C2410_USBDREG(0x0178)
-
-/* indexed registers */
-
-#define S3C2410_UDC_MAXP_REG           S3C2410_USBDREG(0x0180)
-
-#define S3C2410_UDC_EP0_CSR_REG                S3C2410_USBDREG(0x0184)
-
-#define S3C2410_UDC_IN_CSR1_REG                S3C2410_USBDREG(0x0184)
-#define S3C2410_UDC_IN_CSR2_REG                S3C2410_USBDREG(0x0188)
-
-#define S3C2410_UDC_OUT_CSR1_REG       S3C2410_USBDREG(0x0190)
-#define S3C2410_UDC_OUT_CSR2_REG       S3C2410_USBDREG(0x0194)
-#define S3C2410_UDC_OUT_FIFO_CNT1_REG  S3C2410_USBDREG(0x0198)
-#define S3C2410_UDC_OUT_FIFO_CNT2_REG  S3C2410_USBDREG(0x019c)
-
-#define S3C2410_UDC_FUNCADDR_UPDATE    (1<<7)
-
-#define S3C2410_UDC_PWR_ISOUP          (1<<7) // R/W
-#define S3C2410_UDC_PWR_RESET          (1<<3) // R
-#define S3C2410_UDC_PWR_RESUME         (1<<2) // R/W
-#define S3C2410_UDC_PWR_SUSPEND                (1<<1) // R
-#define S3C2410_UDC_PWR_ENSUSPEND      (1<<0) // R/W
-
-#define S3C2410_UDC_PWR_DEFAULT                0x00
-
-#define S3C2410_UDC_INT_EP4            (1<<4) // R/W (clear only)
-#define S3C2410_UDC_INT_EP3            (1<<3) // R/W (clear only)
-#define S3C2410_UDC_INT_EP2            (1<<2) // R/W (clear only)
-#define S3C2410_UDC_INT_EP1            (1<<1) // R/W (clear only)
-#define S3C2410_UDC_INT_EP0            (1<<0) // R/W (clear only)
-
-#define S3C2410_UDC_USBINT_RESET       (1<<2) // R/W (clear only)
-#define S3C2410_UDC_USBINT_RESUME      (1<<1) // R/W (clear only)
-#define S3C2410_UDC_USBINT_SUSPEND     (1<<0) // R/W (clear only)
-
-#define S3C2410_UDC_INTE_EP4           (1<<4) // R/W
-#define S3C2410_UDC_INTE_EP3           (1<<3) // R/W
-#define S3C2410_UDC_INTE_EP2           (1<<2) // R/W
-#define S3C2410_UDC_INTE_EP1           (1<<1) // R/W
-#define S3C2410_UDC_INTE_EP0           (1<<0) // R/W
-
-#define S3C2410_UDC_USBINTE_RESET      (1<<2) // R/W
-#define S3C2410_UDC_USBINTE_SUSPEND    (1<<0) // R/W
-
-
-#define S3C2410_UDC_INDEX_EP0          (0x00)
-#define S3C2410_UDC_INDEX_EP1          (0x01) // ??
-#define S3C2410_UDC_INDEX_EP2          (0x02) // ??
-#define S3C2410_UDC_INDEX_EP3          (0x03) // ??
-#define S3C2410_UDC_INDEX_EP4          (0x04) // ??
-
-#define S3C2410_UDC_ICSR1_CLRDT                (1<<6) // R/W
-#define S3C2410_UDC_ICSR1_SENTSTL      (1<<5) // R/W (clear only)
-#define S3C2410_UDC_ICSR1_SENDSTL      (1<<4) // R/W
-#define S3C2410_UDC_ICSR1_FFLUSH       (1<<3) // W   (set only)
-#define S3C2410_UDC_ICSR1_UNDRUN       (1<<2) // R/W (clear only)
-#define S3C2410_UDC_ICSR1_PKTRDY       (1<<0) // R/W (set only)
-
-#define S3C2410_UDC_ICSR2_AUTOSET      (1<<7) // R/W
-#define S3C2410_UDC_ICSR2_ISO          (1<<6) // R/W
-#define S3C2410_UDC_ICSR2_MODEIN       (1<<5) // R/W
-#define S3C2410_UDC_ICSR2_DMAIEN       (1<<4) // R/W
-
-#define S3C2410_UDC_OCSR1_CLRDT                (1<<7) // R/W
-#define S3C2410_UDC_OCSR1_SENTSTL      (1<<6) // R/W (clear only)
-#define S3C2410_UDC_OCSR1_SENDSTL      (1<<5) // R/W
-#define S3C2410_UDC_OCSR1_FFLUSH       (1<<4) // R/W
-#define S3C2410_UDC_OCSR1_DERROR       (1<<3) // R
-#define S3C2410_UDC_OCSR1_OVRRUN       (1<<2) // R/W (clear only)
-#define S3C2410_UDC_OCSR1_PKTRDY       (1<<0) // R/W (clear only)
-
-#define S3C2410_UDC_OCSR2_AUTOCLR      (1<<7) // R/W
-#define S3C2410_UDC_OCSR2_ISO          (1<<6) // R/W
-#define S3C2410_UDC_OCSR2_DMAIEN       (1<<5) // R/W
-
-#define S3C2410_UDC_EP0_CSR_OPKRDY     (1<<0)
-#define S3C2410_UDC_EP0_CSR_IPKRDY     (1<<1)
-#define S3C2410_UDC_EP0_CSR_SENTSTL    (1<<2)
-#define S3C2410_UDC_EP0_CSR_DE         (1<<3)
-#define S3C2410_UDC_EP0_CSR_SE         (1<<4)
-#define S3C2410_UDC_EP0_CSR_SENDSTL    (1<<5)
-#define S3C2410_UDC_EP0_CSR_SOPKTRDY   (1<<6)
-#define S3C2410_UDC_EP0_CSR_SSE        (1<<7)
-
-#define S3C2410_UDC_MAXP_8             (1<<0)
-#define S3C2410_UDC_MAXP_16            (1<<1)
-#define S3C2410_UDC_MAXP_32            (1<<2)
-#define S3C2410_UDC_MAXP_64            (1<<3)
-
-
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
deleted file mode 100644 (file)
index 82ab4aa..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 machine directory
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#ifdef CONFIG_CPU_S3C2410
-
-extern  int s3c2410_init(void);
-extern  int s3c2410a_init(void);
-
-extern void s3c2410_map_io(void);
-
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2410_init_clocks(int xtal);
-
-#else
-#define s3c2410_init_clocks NULL
-#define s3c2410_init_uarts NULL
-#define s3c2410_map_io NULL
-#define s3c2410_init NULL
-#define s3c2410a_init NULL
-#endif
-
-extern int s3c2410_baseclk_add(void);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2412.h b/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
deleted file mode 100644 (file)
index bb15d3b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2412 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C2412
-
-extern  int s3c2412_init(void);
-
-extern void s3c2412_map_io(void);
-
-extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2412_init_clocks(int xtal);
-
-extern  int s3c2412_baseclk_add(void);
-#else
-#define s3c2412_init_clocks NULL
-#define s3c2412_init_uarts NULL
-#define s3c2412_map_io NULL
-#define s3c2412_init NULL
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
deleted file mode 100644 (file)
index dc3c090..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
- *
- * Header file for s3c2416 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C2416
-
-struct s3c2410_uartcfg;
-
-extern  int s3c2416_init(void);
-
-extern void s3c2416_map_io(void);
-
-extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2416_init_clocks(int xtal);
-
-extern  int s3c2416_baseclk_add(void);
-
-#else
-#define s3c2416_init_clocks NULL
-#define s3c2416_init_uarts NULL
-#define s3c2416_map_io NULL
-#define s3c2416_init NULL
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
deleted file mode 100644 (file)
index a19715f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2443 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifdef CONFIG_CPU_S3C2443
-
-struct s3c2410_uartcfg;
-
-extern  int s3c2443_init(void);
-
-extern void s3c2443_map_io(void);
-
-extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2443_init_clocks(int xtal);
-
-extern  int s3c2443_baseclk_add(void);
-
-#else
-#define s3c2443_init_clocks NULL
-#define s3c2443_init_uarts NULL
-#define s3c2443_map_io NULL
-#define s3c2443_init NULL
-#endif
-
-/* common code used by s3c2443 and others.
- * note, not to be used outside of arch/arm/mach-s3c* */
-
-struct clk;    /* some files don't need clk.h otherwise */
-
-typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
-typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
-
-extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
-extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
-
-extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
-extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
-extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
-
-extern struct clksrc_clk clk_epllref;
-extern struct clksrc_clk clk_esysclk;
-extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
deleted file mode 100644 (file)
index 89e8d0a..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2440 and S3C2442 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-extern void s3c244x_map_io(void);
-
-extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c244x_init_clocks(int xtal);
-
-#else
-#define s3c244x_init_clocks NULL
-#define s3c244x_init_uarts NULL
-#endif
-
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-
-extern void s3c2440_map_io(void);
-#else
-#define s3c2440_init NULL
-#define s3c2440_map_io NULL
-#endif
-
-#ifdef CONFIG_CPU_S3C2442
-extern  int s3c2442_init(void);
-
-extern void s3c2442_map_io(void);
-#else
-#define s3c2442_init NULL
-#define s3c2442_map_io NULL
-#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h
deleted file mode 100644 (file)
index f638842..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/udc.h
- *
- * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *
- *  Changelog:
- *     14-Mar-2005     RTP     Created file
- *     02-Aug-2005     RTP     File rename
- *     07-Sep-2005     BJD     Minor cleanups, changed cmd to enum
- *     18-Jan-2007     HMW     Add per-platform vbus_draw function
-*/
-
-#ifndef __ASM_ARM_ARCH_UDC_H
-#define __ASM_ARM_ARCH_UDC_H
-
-enum s3c2410_udc_cmd_e {
-       S3C2410_UDC_P_ENABLE    = 1,    /* Pull-up enable        */
-       S3C2410_UDC_P_DISABLE   = 2,    /* Pull-up disable       */
-       S3C2410_UDC_P_RESET     = 3,    /* UDC reset, in case of */
-};
-
-struct s3c2410_udc_mach_info {
-       void    (*udc_command)(enum s3c2410_udc_cmd_e);
-       void    (*vbus_draw)(unsigned int ma);
-
-       unsigned int pullup_pin;
-       unsigned int pullup_pin_inverted;
-
-       unsigned int vbus_pin;
-       unsigned char vbus_pin_inverted;
-};
-
-extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
-
-/**
- * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
- * @epnum: Number of endpoints to be instantiated by the controller driver.
- * @gpio_init: Platform specific USB related GPIO initialization.
- * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
- *
- * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
- * controllers.
- */
-struct s3c24xx_hsudc_platdata {
-       unsigned int    epnum;
-       void            (*gpio_init)(void);
-       void            (*gpio_uninit)(void);
-};
-
-extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
-
-#endif /* __ASM_ARM_ARCH_UDC_H */
index 59552c0ea5fb3efe6feaaa17a42b39a8cfd05685..5a21b15b2a978e01b016b7309a4e5585a6ee995a 100644 (file)
@@ -160,6 +160,124 @@ static struct clk clk_prediv = {
        },
 };
 
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
+static unsigned int *armdiv;
+static int nr_armdiv;
+static int armdivmask;
+
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+                                             unsigned long rate)
+{
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned best = 256; /* bigger than any value */
+       unsigned div;
+       int ptr;
+
+       if (!nr_armdiv)
+               return -EINVAL;
+
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best)
+                               best = div;
+               }
+       }
+
+       return parent / best;
+}
+
+static unsigned long s3c2443_armclk_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkcon0;
+       int val;
+
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+
+       clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+       clkcon0 &= armdivmask;
+       val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+       return rate / armdiv[val];
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
+{
+       unsigned long parent = clk_get_rate(clk->parent);
+       unsigned long calc;
+       unsigned div;
+       unsigned best = 256; /* bigger than any value */
+       int ptr;
+       int val = -1;
+
+       if (!nr_armdiv || !armdivmask)
+               return -EINVAL;
+
+       for (ptr = 0; ptr < nr_armdiv; ptr++) {
+               div = armdiv[ptr];
+               if (div) {
+                       /* cpufreq provides 266mhz as 266666000 not 266666666 */
+                       calc = (parent / div / 1000) * 1000;
+                       if (calc <= rate && div < best) {
+                               best = div;
+                               val = ptr;
+                       }
+               }
+       }
+
+       if (val >= 0) {
+               unsigned long clkcon0;
+
+               clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+               clkcon0 &= ~armdivmask;
+               clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+               __raw_writel(clkcon0, S3C2443_CLKDIV0);
+       }
+
+       return (val == -1) ? -EINVAL : 0;
+}
+
+static struct clk clk_armdiv = {
+       .name           = "armdiv",
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .round_rate = s3c2443_armclk_roundrate,
+               .get_rate = s3c2443_armclk_getrate,
+               .set_rate = s3c2443_armclk_setrate,
+       },
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
+
+static struct clk *clk_arm_sources[] = {
+       [0] = &clk_armdiv,
+       [1] = &clk_h,
+};
+
+static struct clksrc_clk clk_arm = {
+       .clk    = {
+               .name           = "armclk",
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_arm_sources,
+               .nr_sources = ARRAY_SIZE(clk_arm_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
+
 /* usbhost
  *
  * usb host bus-clock, usually 48MHz to provide USB bus clock timing
@@ -205,9 +323,64 @@ static struct clksrc_clk clksrc_clks[] = {
        },
 };
 
+static struct clk clk_i2s_ext = {
+       .name           = "i2s-ext",
+};
+
+/* i2s_eplldiv
+ *
+ * This clock is the output from the I2S divisor of ESYSCLK, and is separate
+ * from the mux that comes after it (cannot merge into one single clock)
+*/
+
+static struct clksrc_clk clk_i2s_eplldiv = {
+       .clk    = {
+               .name           = "i2s-eplldiv",
+               .parent         = &clk_esysclk.clk,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+ *
+ * Note, this used to be two clocks, but was compressed into one.
+*/
+
+static struct clk *clk_i2s_srclist[] = {
+       [0] = &clk_i2s_eplldiv.clk,
+       [1] = &clk_i2s_ext,
+       [2] = &clk_epllref.clk,
+       [3] = &clk_epllref.clk,
+};
+
+static struct clksrc_clk clk_i2s = {
+       .clk    = {
+               .name           = "i2s-if",
+               .ctrlbit        = S3C2443_SCLKCON_I2SCLK,
+               .enable         = s3c2443_clkcon_enable_s,
+
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_i2s_srclist,
+               .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
+};
 
 static struct clk init_clocks_off[] = {
        {
+               .name           = "iis",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIS,
+       }, {
+               .name           = "hsspi",
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_HSSPI,
+       }, {
                .name           = "adc",
                .parent         = &clk_p,
                .enable         = s3c2443_clkcon_enable_p,
@@ -253,6 +426,7 @@ static struct clk init_clocks[] = {
                .ctrlbit        = S3C2443_HCLKCON_DMA5,
        }, {
                .name           = "hsmmc",
+               .devname        = "s3c-sdhci.1",
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_HSMMC,
@@ -347,8 +521,7 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
 
 /* EPLLCON compatible enough to get on/off information */
 
-void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
-                                                  fdiv_fn get_fdiv)
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
 {
        unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
        unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
@@ -368,7 +541,7 @@ void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
        pll = get_mpll(mpllcon, xtal);
        clk_msysclk.clk.rate = pll;
 
-       fclk = pll / get_fdiv(clkdiv0);
+       fclk = clk_get_rate(&clk_armdiv);
        hclk = s3c2443_prediv_getrate(&clk_prediv);
        hclk /= s3c2443_get_hdiv(clkdiv0);
        pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
@@ -403,20 +576,29 @@ static struct clk *clks[] __initdata = {
        &clk_ext,
        &clk_epll,
        &clk_usb_bus,
+       &clk_armdiv,
 };
 
 static struct clksrc_clk *clksrcs[] __initdata = {
+       &clk_i2s_eplldiv,
+       &clk_i2s,
        &clk_usb_bus_host,
        &clk_epllref,
        &clk_esysclk,
        &clk_msysclk,
+       &clk_arm,
 };
 
 void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
-                                      fdiv_fn get_fdiv)
+                                      unsigned int *divs, int nr_divs,
+                                      int divmask)
 {
        int ptr;
 
+       armdiv = divs;
+       nr_armdiv = nr_divs;
+       armdivmask = divmask;
+
        /* s3c2443 parents h and p clocks from prediv */
        clk_h.parent = &clk_prediv;
        clk_p.parent = &clk_prediv;
@@ -437,5 +619,5 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
        s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
        s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
-       s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+       s3c2443_common_setup_clocks(get_mpll);
 }
index 9a197e55f66955c5e55521edc22e5c857a4af590..9b9968fa8695b05b0fa4edb3784dc90fd000126f 100644 (file)
@@ -7,7 +7,7 @@
 
 config PLAT_S5P
        bool
-       depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
+       depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
        default y
        select ARM_VIC if !ARCH_EXYNOS4
        select ARM_GIC if ARCH_EXYNOS4
@@ -16,9 +16,6 @@ config PLAT_S5P
        select S3C_GPIO_TRACK
        select S5P_GPIO_DRVSTR
        select SAMSUNG_GPIOLIB_4BIT
-       select S3C_GPIO_CFG_S3C64XX
-       select S3C_GPIO_PULL_UPDOWN
-       select S3C_GPIO_CFG_S3C24XX
        select PLAT_SAMSUNG
        select SAMSUNG_CLKSRC
        select SAMSUNG_IRQ_VIC_TIMER
@@ -42,6 +39,12 @@ config S5P_HRT
        help
          Use the High Resolution timer support
 
+config S5P_PM
+       bool
+       help
+         Common code for power management support on S5P and newer SoCs
+         Note: Do not select this for S5P6440 and S5P6450.
+
 comment "System MMU"
 
 config S5P_SYSTEM_MMU
@@ -50,6 +53,12 @@ config S5P_SYSTEM_MMU
        help
          Say Y here if you want to enable System MMU
 
+config S5P_SLEEP
+       bool
+       help
+         Internal config node to apply common S5P sleep management code.
+         Can be selected by S5P and newer SoCs with similar sleep procedure.
+
 config S5P_DEV_FIMC0
        bool
        help
@@ -75,6 +84,11 @@ config S5P_DEV_FIMD0
        help
          Compile in platform device definitions for FIMD controller 0
 
+config S5P_DEV_I2C_HDMIPHY
+       bool
+       help
+         Compile in platform device definitions for I2C HDMIPHY controller
+
 config S5P_DEV_MFC
        bool
        help
@@ -95,6 +109,11 @@ config S5P_DEV_CSIS1
        help
          Compile in platform device definitions for MIPI-CSIS channel 1
 
+config S5P_DEV_TV
+       bool
+       help
+         Compile in platform device definition for TV interface
+
 config S5P_DEV_USB_EHCI
        bool
        help
index 4b53e04eeca465266ec5faa2cc61147120e2a311..876344038b8d9ab556447f3133629f85ab3fb4cd 100644 (file)
@@ -12,7 +12,6 @@ obj-                          :=
 
 # Core files
 
-obj-y                          += dev-pmu.o
 obj-y                          += dev-uart.o
 obj-y                          += cpu.o
 obj-y                          += clock.o
@@ -20,19 +19,10 @@ obj-y                               += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
 obj-$(CONFIG_S5P_GPIO_INT)     += irq-gpioint.o
 obj-$(CONFIG_S5P_SYSTEM_MMU)   += sysmmu.o
-obj-$(CONFIG_PM)               += pm.o
-obj-$(CONFIG_PM)               += irq-pm.o
+obj-$(CONFIG_S5P_PM)           += pm.o irq-pm.o
+obj-$(CONFIG_S5P_SLEEP)                += sleep.o
 obj-$(CONFIG_S5P_HRT)          += s5p-time.o
 
 # devices
 obj-$(CONFIG_S5P_DEV_MFC)      += dev-mfc.o
-obj-$(CONFIG_S5P_DEV_FIMC0)    += dev-fimc0.o
-obj-$(CONFIG_S5P_DEV_FIMC1)    += dev-fimc1.o
-obj-$(CONFIG_S5P_DEV_FIMC2)    += dev-fimc2.o
-obj-$(CONFIG_S5P_DEV_FIMC3)    += dev-fimc3.o
-obj-$(CONFIG_S5P_DEV_FIMD0)    += dev-fimd0.o
-obj-$(CONFIG_S5P_DEV_ONENAND)  += dev-onenand.o
-obj-$(CONFIG_S5P_DEV_CSIS0)    += dev-csis0.o
-obj-$(CONFIG_S5P_DEV_CSIS1)    += dev-csis1.o
-obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)        += setup-mipiphy.o
index 7b0a28f73a68a2f47601d6ece39edac6547827b6..a56959e83516706a4fc016888813ec2feb9ad70c 100644 (file)
@@ -75,7 +75,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
-               .init           = exynos4_init,
+               .init           = exynos_init,
                .name           = name_exynos4210,
        }, {
                .idcode         = EXYNOS4212_CPU_ID,
@@ -83,7 +83,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
-               .init           = exynos4_init,
+               .init           = exynos_init,
                .name           = name_exynos4212,
        }, {
                .idcode         = EXYNOS4412_CPU_ID,
@@ -91,7 +91,7 @@ static struct cpu_table cpu_ids[] __initdata = {
                .map_io         = exynos4_map_io,
                .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
-               .init           = exynos4_init,
+               .init           = exynos_init,
                .name           = name_exynos4412,
        },
 };
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
deleted file mode 100644 (file)
index e3aabef..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * S5P series device definition for MIPI-CSIS channel 0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <mach/map.h>
-
-static struct resource s5p_mipi_csis0_resource[] = {
-       [0] = {
-               .start = S5P_PA_MIPI_CSIS0,
-               .end   = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_MIPI_CSIS0,
-               .end   = IRQ_MIPI_CSIS0,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-struct platform_device s5p_device_mipi_csis0 = {
-       .name             = "s5p-mipi-csis",
-       .id               = 0,
-       .num_resources    = ARRAY_SIZE(s5p_mipi_csis0_resource),
-       .resource         = s5p_mipi_csis0_resource,
-};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
deleted file mode 100644 (file)
index 08b91b5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * S5P series device definition for MIPI-CSIS channel 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <mach/map.h>
-
-static struct resource s5p_mipi_csis1_resource[] = {
-       [0] = {
-               .start = S5P_PA_MIPI_CSIS1,
-               .end   = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_MIPI_CSIS1,
-               .end   = IRQ_MIPI_CSIS1,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s5p_device_mipi_csis1 = {
-       .name             = "s5p-mipi-csis",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s5p_mipi_csis1_resource),
-       .resource         = s5p_mipi_csis1_resource,
-};
diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c
deleted file mode 100644 (file)
index 94080ff..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/platform_device.h>
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/ehci.h>
-#include <plat/usb-phy.h>
-
-/* USB EHCI Host Controller registration */
-static struct resource s5p_ehci_resource[] = {
-       [0] = {
-               .start  = S5P_PA_EHCI,
-               .end    = S5P_PA_EHCI + SZ_256 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_USB_HOST,
-               .end    = IRQ_USB_HOST,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s5p_device_ehci_dmamask = 0xffffffffUL;
-
-struct platform_device s5p_device_ehci = {
-       .name           = "s5p-ehci",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s5p_ehci_resource),
-       .resource       = s5p_ehci_resource,
-       .dev            = {
-               .dma_mask = &s5p_device_ehci_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
-{
-       struct s5p_ehci_platdata *npd;
-
-       npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
-                       &s5p_device_ehci);
-
-       if (!npd->phy_init)
-               npd->phy_init = s5p_usb_phy_init;
-       if (!npd->phy_exit)
-               npd->phy_exit = s5p_usb_phy_exit;
-}
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
deleted file mode 100644 (file)
index 608770f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-fimc0.c
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * Base S5P FIMC0 resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <mach/map.h>
-
-static struct resource s5p_fimc0_resource[] = {
-       [0] = {
-               .start  = S5P_PA_FIMC0,
-               .end    = S5P_PA_FIMC0 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_FIMC0,
-               .end    = IRQ_FIMC0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_fimc0 = {
-       .name           = "s5p-fimc",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(s5p_fimc0_resource),
-       .resource       = s5p_fimc0_resource,
-       .dev            = {
-               .dma_mask               = &s5p_fimc0_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
deleted file mode 100644 (file)
index 76e3a97..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-fimc1.c
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * Base S5P FIMC1 resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <mach/map.h>
-
-static struct resource s5p_fimc1_resource[] = {
-       [0] = {
-               .start  = S5P_PA_FIMC1,
-               .end    = S5P_PA_FIMC1 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_FIMC1,
-               .end    = IRQ_FIMC1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_fimc1 = {
-       .name           = "s5p-fimc",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(s5p_fimc1_resource),
-       .resource       = s5p_fimc1_resource,
-       .dev            = {
-               .dma_mask               = &s5p_fimc1_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
deleted file mode 100644 (file)
index 24d2981..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-fimc2.c
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * Base S5P FIMC2 resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <mach/map.h>
-
-static struct resource s5p_fimc2_resource[] = {
-       [0] = {
-               .start  = S5P_PA_FIMC2,
-               .end    = S5P_PA_FIMC2 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_FIMC2,
-               .end    = IRQ_FIMC2,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_fimc2 = {
-       .name           = "s5p-fimc",
-       .id             = 2,
-       .num_resources  = ARRAY_SIZE(s5p_fimc2_resource),
-       .resource       = s5p_fimc2_resource,
-       .dev            = {
-               .dma_mask               = &s5p_fimc2_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c
deleted file mode 100644 (file)
index ef31bec..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-fimc3.c
- *
- * Copyright (c) 2010 Samsung Electronics
- *
- * Base S5P FIMC3 resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <mach/map.h>
-
-static struct resource s5p_fimc3_resource[] = {
-       [0] = {
-               .start  = S5P_PA_FIMC3,
-               .end    = S5P_PA_FIMC3 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_FIMC3,
-               .end    = IRQ_FIMC3,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 s5p_fimc3_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_fimc3 = {
-       .name           = "s5p-fimc",
-       .id             = 3,
-       .num_resources  = ARRAY_SIZE(s5p_fimc3_resource),
-       .resource       = s5p_fimc3_resource,
-       .dev            = {
-               .dma_mask               = &s5p_fimc3_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
deleted file mode 100644 (file)
index f728bb5..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-fimd0.c
- *
- * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Core file for Samsung Display Controller (FIMD) driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/gfp.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/fb.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s5p_fimd0_resource[] = {
-       [0] = {
-               .start  = S5P_PA_FIMD0,
-               .end    = S5P_PA_FIMD0 + SZ_32K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_FIMD0_VSYNC,
-               .end    = IRQ_FIMD0_VSYNC,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = IRQ_FIMD0_FIFO,
-               .end    = IRQ_FIMD0_FIFO,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [3] = {
-               .start  = IRQ_FIMD0_SYSTEM,
-               .end    = IRQ_FIMD0_SYSTEM,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 fimd0_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_fimd0 = {
-       .name           = "s5p-fb",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(s5p_fimd0_resource),
-       .resource       = s5p_fimd0_resource,
-       .dev            = {
-               .dma_mask               = &fimd0_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
-void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
-{
-       s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
-                       &s5p_device_fimd0);
-}
index 94226a0010f704b0d5aaa854e53ea4c9277be146..a30d36b7f61bb62c41124ba4ba9e7441e30b9d9f 100644 (file)
 #include <plat/irqs.h>
 #include <plat/mfc.h>
 
-static struct resource s5p_mfc_resource[] = {
-       [0] = {
-               .start  = S5P_PA_MFC,
-               .end    = S5P_PA_MFC + SZ_64K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_MFC,
-               .end    = IRQ_MFC,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-struct platform_device s5p_device_mfc = {
-       .name           = "s5p-mfc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s5p_mfc_resource),
-       .resource       = s5p_mfc_resource,
-};
-
-/*
- * MFC hardware has 2 memory interfaces which are modelled as two separate
- * platform devices to let dma-mapping distinguish between them.
- *
- * MFC parent device (s5p_device_mfc) must be registered before memory
- * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
- */
-
-static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device s5p_device_mfc_l = {
-       .name           = "s5p-mfc-l",
-       .id             = -1,
-       .dev            = {
-               .parent                 = &s5p_device_mfc.dev,
-               .dma_mask               = &s5p_mfc_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
-struct platform_device s5p_device_mfc_r = {
-       .name           = "s5p-mfc-r",
-       .id             = -1,
-       .dev            = {
-               .parent                 = &s5p_device_mfc.dev,
-               .dma_mask               = &s5p_mfc_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
 struct s5p_mfc_reserved_mem {
        phys_addr_t     base;
        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 (file)
index 20336c8..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-onenand.c
- *
- * Copyright 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- *  Copyright (c) 2008-2010 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S5P series device definition for OneNAND devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-static struct resource s5p_onenand_resources[] = {
-       [0] = {
-               .start  = S5P_PA_ONENAND,
-               .end    = S5P_PA_ONENAND + SZ_128K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = S5P_PA_ONENAND_DMA,
-               .end    = S5P_PA_ONENAND_DMA + SZ_8K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start  = IRQ_ONENAND_AUDI,
-               .end    = IRQ_ONENAND_AUDI,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s5p_device_onenand = {
-       .name           = "s5pc110-onenand",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s5p_onenand_resources),
-       .resource       = s5p_onenand_resources,
-};
diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c
deleted file mode 100644 (file)
index a08576d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * linux/arch/arm/plat-s5p/dev-pmu.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/platform_device.h>
-#include <asm/pmu.h>
-#include <mach/irqs.h>
-
-static struct resource s5p_pmu_resource = {
-       .start  = IRQ_PMU,
-       .end    = IRQ_PMU,
-       .flags  = IORESOURCE_IRQ,
-};
-
-struct platform_device s5p_device_pmu = {
-       .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
-       .num_resources  = 1,
-       .resource       = &s5p_pmu_resource,
-};
-
-static int __init s5p_pmu_init(void)
-{
-       platform_device_register(&s5p_device_pmu);
-       return 0;
-}
-arch_initcall(s5p_pmu_init);
diff --git a/arch/arm/plat-s5p/include/plat/camport.h b/arch/arm/plat-s5p/include/plat/camport.h
deleted file mode 100644 (file)
index 71688c8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * S5P series camera interface helper functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef PLAT_S5P_CAMPORT_H_
-#define PLAT_S5P_CAMPORT_H_ __FILE__
-
-enum s5p_camport_id {
-       S5P_CAMPORT_A,
-       S5P_CAMPORT_B,
-};
-
-/*
- * The helper functions to configure GPIO for the camera parallel bus.
- * The camera port can be multiplexed with any FIMC entity, even multiple
- * FIMC entities are allowed to be attached to a single port simultaneously.
- * These functions are to be used in the board setup code.
- */
-int s5pv210_fimc_setup_gpio(enum s5p_camport_id id);
-int exynos4_fimc_setup_gpio(enum s5p_camport_id id);
-
-#endif
diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h
deleted file mode 100644 (file)
index 6ae6810..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_EHCI_H
-#define __PLAT_S5P_EHCI_H
-
-struct s5p_ehci_platdata {
-       int (*phy_init)(struct platform_device *pdev, int type);
-       int (*phy_exit)(struct platform_device *pdev, int type);
-};
-
-extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
-
-#endif /* __PLAT_S5P_EHCI_H */
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h
deleted file mode 100644 (file)
index f680a14..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/exynos4.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for exynos4 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for EXYNOS4 related SoCs */
-
-extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void exynos4_register_clocks(void);
-extern void exynos4210_register_clocks(void);
-extern void exynos4212_register_clocks(void);
-extern void exynos4_setup_clocks(void);
-
-#ifdef CONFIG_ARCH_EXYNOS4
-extern  int exynos4_init(void);
-extern void exynos4_init_irq(void);
-extern void exynos4_map_io(void);
-extern void exynos4_init_clocks(int xtal);
-extern struct sys_timer exynos4_timer;
-
-#define exynos4_init_uarts exynos4_common_init_uarts
-
-#else
-#define exynos4_init_clocks NULL
-#define exynos4_init_uarts NULL
-#define exynos4_map_io NULL
-#define exynos4_init NULL
-#endif
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
deleted file mode 100644 (file)
index 144dbfc..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/irqs.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P Common IRQ support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_IRQS_H
-#define __ASM_PLAT_S5P_IRQS_H __FILE__
-
-/* we keep the first set of CPU IRQs out of the range of
- * the ISA space, so that the PC104 has them to itself
- * and we don't end up having to do horrible things to the
- * standard ISA drivers....
- *
- * note, since we're using the VICs, our start must be a
- * mulitple of 32 to allow the common code to work
- */
-
-#define S5P_IRQ_OFFSET         (32)
-
-#define S5P_IRQ(x)             ((x) + S5P_IRQ_OFFSET)
-
-#define S5P_VIC0_BASE          S5P_IRQ(0)
-#define S5P_VIC1_BASE          S5P_IRQ(32)
-#define S5P_VIC2_BASE          S5P_IRQ(64)
-#define S5P_VIC3_BASE          S5P_IRQ(96)
-
-#define VIC_BASE(x)            (S5P_VIC0_BASE + ((x)*32))
-
-#define IRQ_VIC0_BASE          S5P_VIC0_BASE
-#define IRQ_VIC1_BASE          S5P_VIC1_BASE
-#define IRQ_VIC2_BASE          S5P_VIC2_BASE
-
-/* VIC based IRQs */
-
-#define S5P_IRQ_VIC0(x)                (S5P_VIC0_BASE + (x))
-#define S5P_IRQ_VIC1(x)                (S5P_VIC1_BASE + (x))
-#define S5P_IRQ_VIC2(x)                (S5P_VIC2_BASE + (x))
-#define S5P_IRQ_VIC3(x)                (S5P_VIC3_BASE + (x))
-
-#define S5P_TIMER_IRQ(x)       (11 + (x))
-
-#define IRQ_TIMER0             S5P_TIMER_IRQ(0)
-#define IRQ_TIMER1             S5P_TIMER_IRQ(1)
-#define IRQ_TIMER2             S5P_TIMER_IRQ(2)
-#define IRQ_TIMER3             S5P_TIMER_IRQ(3)
-#define IRQ_TIMER4             S5P_TIMER_IRQ(4)
-
-#define IRQ_EINT(x)            ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
-                                       : ((x) - 16 + S5P_EINT_BASE2))
-
-#define EINT_OFFSET(irq)       ((irq) < S5P_EINT_BASE2 ? \
-                                               ((irq) - S5P_EINT_BASE1) : \
-                                               ((irq) + 16 - S5P_EINT_BASE2))
-
-#define IRQ_EINT_BIT(x)                EINT_OFFSET(x)
-
-/* Typically only a few gpio chips require gpio interrupt support.
-   To avoid memory waste irq descriptors are allocated only for
-   S5P_GPIOINT_GROUP_COUNT chips, each with total number of
-   S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
-   to any gpio chip with the s5p_register_gpio_interrupt() function */
-#define S5P_GPIOINT_GROUP_COUNT 4
-#define S5P_GPIOINT_GROUP_SIZE 8
-#define S5P_GPIOINT_COUNT      (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
-
-/* IRQ types common for all s5p platforms */
-#define S5P_IRQ_TYPE_LEVEL_LOW         (0x00)
-#define S5P_IRQ_TYPE_LEVEL_HIGH                (0x01)
-#define S5P_IRQ_TYPE_EDGE_FALLING      (0x02)
-#define S5P_IRQ_TYPE_EDGE_RISING       (0x03)
-#define S5P_IRQ_TYPE_EDGE_BOTH         (0x04)
-
-#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/mfc.h b/arch/arm/plat-s5p/include/plat/mfc.h
deleted file mode 100644 (file)
index 6697f8c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_MFC_H
-#define __PLAT_S5P_MFC_H
-
-/**
- * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
- * @rbase:     base address for MFC 'right' memory interface
- * @rsize:     size of the memory reserved for MFC 'right' interface
- * @lbase:     base address for MFC 'left' memory interface
- * @lsize:     size of the memory reserved for MFC 'left' interface
- *
- * This function reserves system memory for both MFC device memory
- * interfaces and registers it to respective struct device entries as
- * coherent memory.
- */
-void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
-                               phys_addr_t lbase, unsigned int lsize);
-
-#endif /* __PLAT_S5P_MFC_H */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-s5p/include/plat/mipi_csis.h
deleted file mode 100644 (file)
index 9bd254c..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
- *
- * S5P series MIPI CSI slave device support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef PLAT_S5P_MIPI_CSIS_H_
-#define PLAT_S5P_MIPI_CSIS_H_ __FILE__
-
-struct platform_device;
-
-/**
- * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver
- * @clk_rate: bus clock frequency
- * @lanes: number of data lanes used
- * @alignment: data alignment in bits
- * @hs_settle: HS-RX settle time
- * @fixed_phy_vdd: false to enable external D-PHY regulator management in the
- *                driver or true in case this regulator has no enable function
- * @phy_enable: pointer to a callback controlling D-PHY enable/reset
- */
-struct s5p_platform_mipi_csis {
-       unsigned long clk_rate;
-       u8 lanes;
-       u8 alignment;
-       u8 hs_settle;
-       bool fixed_phy_vdd;
-       int (*phy_enable)(struct platform_device *pdev, bool on);
-};
-
-/**
- * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
- * @pdev: MIPI-CSIS platform device
- * @on: true to enable D-PHY and deassert its reset
- *     false to disable D-PHY
- */
-int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
-
-#endif /* PLAT_S5P_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
deleted file mode 100644 (file)
index 3e21b94..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/* arch/arm/plat-s5p/include/plat/pll.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P PLL code
- *
- * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <asm/div64.h>
-
-#define PLL35XX_MDIV_MASK      (0x3FF)
-#define PLL35XX_PDIV_MASK      (0x3F)
-#define PLL35XX_SDIV_MASK      (0x7)
-#define PLL35XX_MDIV_SHIFT     (16)
-#define PLL35XX_PDIV_SHIFT     (8)
-#define PLL35XX_SDIV_SHIFT     (0)
-
-static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
-{
-       u32 mdiv, pdiv, sdiv;
-       u64 fvco = baseclk;
-
-       mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
-       pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
-       sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
-
-       fvco *= mdiv;
-       do_div(fvco, (pdiv << sdiv));
-
-       return (unsigned long)fvco;
-}
-
-#define PLL36XX_KDIV_MASK      (0xFFFF)
-#define PLL36XX_MDIV_MASK      (0x1FF)
-#define PLL36XX_PDIV_MASK      (0x3F)
-#define PLL36XX_SDIV_MASK      (0x7)
-#define PLL36XX_MDIV_SHIFT     (16)
-#define PLL36XX_PDIV_SHIFT     (8)
-#define PLL36XX_SDIV_SHIFT     (0)
-
-static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
-                                           u32 pll_con0, u32 pll_con1)
-{
-       unsigned long result;
-       u32 mdiv, pdiv, sdiv, kdiv;
-       u64 tmp;
-
-       mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
-       pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
-       sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
-       kdiv = pll_con1 & PLL36XX_KDIV_MASK;
-
-       tmp = baseclk;
-
-       tmp *= (mdiv << 16) + kdiv;
-       do_div(tmp, (pdiv << sdiv));
-       result = tmp >> 16;
-
-       return result;
-}
-
-#define PLL45XX_MDIV_MASK      (0x3FF)
-#define PLL45XX_PDIV_MASK      (0x3F)
-#define PLL45XX_SDIV_MASK      (0x7)
-#define PLL45XX_MDIV_SHIFT     (16)
-#define PLL45XX_PDIV_SHIFT     (8)
-#define PLL45XX_SDIV_SHIFT     (0)
-
-enum pll45xx_type_t {
-       pll_4500,
-       pll_4502,
-       pll_4508
-};
-
-static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
-                                           enum pll45xx_type_t pll_type)
-{
-       u32 mdiv, pdiv, sdiv;
-       u64 fvco = baseclk;
-
-       mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
-       pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
-       sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
-
-       if (pll_type == pll_4508)
-               sdiv = sdiv - 1;
-
-       fvco *= mdiv;
-       do_div(fvco, (pdiv << sdiv));
-
-       return (unsigned long)fvco;
-}
-
-#define PLL46XX_KDIV_MASK      (0xFFFF)
-#define PLL4650C_KDIV_MASK     (0xFFF)
-#define PLL46XX_MDIV_MASK      (0x1FF)
-#define PLL46XX_PDIV_MASK      (0x3F)
-#define PLL46XX_SDIV_MASK      (0x7)
-#define PLL46XX_MDIV_SHIFT     (16)
-#define PLL46XX_PDIV_SHIFT     (8)
-#define PLL46XX_SDIV_SHIFT     (0)
-
-enum pll46xx_type_t {
-       pll_4600,
-       pll_4650,
-       pll_4650c,
-};
-
-static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
-                                           u32 pll_con0, u32 pll_con1,
-                                           enum pll46xx_type_t pll_type)
-{
-       unsigned long result;
-       u32 mdiv, pdiv, sdiv, kdiv;
-       u64 tmp;
-
-       mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
-       pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
-       sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
-
-       if (pll_type == pll_4650c)
-               kdiv = pll_con1 & PLL4650C_KDIV_MASK;
-       else
-               kdiv = pll_con1 & PLL46XX_KDIV_MASK;
-
-       tmp = baseclk;
-
-       if (pll_type == pll_4600) {
-               tmp *= (mdiv << 16) + kdiv;
-               do_div(tmp, (pdiv << sdiv));
-               result = tmp >> 16;
-       } else {
-               tmp *= (mdiv << 10) + kdiv;
-               do_div(tmp, (pdiv << sdiv));
-               result = tmp >> 10;
-       }
-
-       return result;
-}
-
-#define PLL90XX_MDIV_MASK      (0xFF)
-#define PLL90XX_PDIV_MASK      (0x3F)
-#define PLL90XX_SDIV_MASK      (0x7)
-#define PLL90XX_KDIV_MASK      (0xffff)
-#define PLL90XX_MDIV_SHIFT     (16)
-#define PLL90XX_PDIV_SHIFT     (8)
-#define PLL90XX_SDIV_SHIFT     (0)
-#define PLL90XX_KDIV_SHIFT     (0)
-
-static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
-                                           u32 pll_con, u32 pll_conk)
-{
-       unsigned long result;
-       u32 mdiv, pdiv, sdiv, kdiv;
-       u64 tmp;
-
-       mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
-       pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
-       sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
-       kdiv = pll_conk & PLL90XX_KDIV_MASK;
-
-       /* We need to multiple baseclk by mdiv (the integer part) and kdiv
-        * which is in 2^16ths, so shift mdiv up (does not overflow) and
-        * add kdiv before multiplying. The use of tmp is to avoid any
-        * overflows before shifting bac down into result when multipling
-        * by the mdiv and kdiv pair.
-        */
-
-       tmp = baseclk;
-       tmp *= (mdiv << 16) + kdiv;
-       do_div(tmp, (pdiv << sdiv));
-       result = tmp >> 16;
-
-       return result;
-}
-
-#define PLL65XX_MDIV_MASK      (0x3FF)
-#define PLL65XX_PDIV_MASK      (0x3F)
-#define PLL65XX_SDIV_MASK      (0x7)
-#define PLL65XX_MDIV_SHIFT     (16)
-#define PLL65XX_PDIV_SHIFT     (8)
-#define PLL65XX_SDIV_SHIFT     (0)
-
-static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
-{
-       u32 mdiv, pdiv, sdiv;
-       u64 fvco = baseclk;
-
-       mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
-       pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
-       sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
-
-       fvco *= mdiv;
-       do_div(fvco, (pdiv << sdiv));
-
-       return (unsigned long)fvco;
-}
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
deleted file mode 100644 (file)
index f121ab5..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * S5P SROMC register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_REGS_SROM_H
-#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_SROMREG(x)         (S5P_VA_SROMC + (x))
-
-#define S5P_SROM_BW            S5P_SROMREG(0x0)
-#define S5P_SROM_BC0           S5P_SROMREG(0x4)
-#define S5P_SROM_BC1           S5P_SROMREG(0x8)
-#define S5P_SROM_BC2           S5P_SROMREG(0xc)
-#define S5P_SROM_BC3           S5P_SROMREG(0x10)
-#define S5P_SROM_BC4           S5P_SROMREG(0x14)
-#define S5P_SROM_BC5           S5P_SROMREG(0x18)
-
-/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
-
-#define S5P_SROM_BW__DATAWIDTH__SHIFT          0
-#define S5P_SROM_BW__ADDRMODE__SHIFT           1
-#define S5P_SROM_BW__WAITENABLE__SHIFT         2
-#define S5P_SROM_BW__BYTEENABLE__SHIFT         3
-
-#define S5P_SROM_BW__CS_MASK                   0xf
-
-#define S5P_SROM_BW__NCS0__SHIFT               0
-#define S5P_SROM_BW__NCS1__SHIFT               4
-#define S5P_SROM_BW__NCS2__SHIFT               8
-#define S5P_SROM_BW__NCS3__SHIFT               12
-#define S5P_SROM_BW__NCS4__SHIFT               16
-#define S5P_SROM_BW__NCS5__SHIFT               20
-
-/* applies to same to BCS0 - BCS3 */
-
-#define S5P_SROM_BCX__PMC__SHIFT               0
-#define S5P_SROM_BCX__TACP__SHIFT              4
-#define S5P_SROM_BCX__TCAH__SHIFT              8
-#define S5P_SROM_BCX__TCOH__SHIFT              12
-#define S5P_SROM_BCX__TACC__SHIFT              16
-#define S5P_SROM_BCX__TCOS__SHIFT              24
-#define S5P_SROM_BCX__TACS__SHIFT              28
-
-#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/include/plat/reset.h b/arch/arm/plat-s5p/include/plat/reset.h
deleted file mode 100644 (file)
index 335e978..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/reset.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_RESET_H
-#define __ASM_PLAT_S5P_RESET_H __FILE__
-
-extern void (*s5p_reset_hook)(void);
-
-#endif /* __ASM_PLAT_S5P_RESET_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
deleted file mode 100644 (file)
index 769b5bd..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for s5p clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_CLOCK_H
-#define __ASM_PLAT_S5P_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
-#define clk_fin_apll clk_ext_xtal_mux
-#define clk_fin_mpll clk_ext_xtal_mux
-#define clk_fin_epll clk_ext_xtal_mux
-#define clk_fin_dpll clk_ext_xtal_mux
-#define clk_fin_vpll clk_ext_xtal_mux
-#define clk_fin_hpll clk_ext_xtal_mux
-
-extern struct clk clk_ext_xtal_mux;
-extern struct clk clk_xusbxti;
-extern struct clk clk_48m;
-extern struct clk s5p_clk_27m;
-extern struct clk clk_fout_apll;
-extern struct clk clk_fout_mpll;
-extern struct clk clk_fout_epll;
-extern struct clk clk_fout_dpll;
-extern struct clk clk_fout_vpll;
-extern struct clk clk_arm;
-extern struct clk clk_vpll;
-
-extern struct clksrc_sources clk_src_apll;
-extern struct clksrc_sources clk_src_mpll;
-extern struct clksrc_sources clk_src_epll;
-extern struct clksrc_sources clk_src_dpll;
-
-extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
-
-/* Common EPLL operations for S5P platform */
-extern int s5p_epll_enable(struct clk *clk, int enable);
-extern unsigned long s5p_epll_get_rate(struct clk *clk);
-
-/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */
-extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate);
-extern unsigned long s5p_spdif_get_rate(struct clk *clk);
-
-extern struct clk_ops s5p_sclk_spdif_ops;
-#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
deleted file mode 100644 (file)
index 575e881..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
- *
- * Copyright 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Header file for s5p time support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_S5P_TIME_H
-#define __ASM_PLAT_S5P_TIME_H __FILE__
-
-/* S5P HR-Timer Clock mode */
-enum s5p_timer_mode {
-       S5P_PWM0,
-       S5P_PWM1,
-       S5P_PWM2,
-       S5P_PWM3,
-       S5P_PWM4,
-};
-
-struct s5p_timer_source {
-       unsigned int event_id;
-       unsigned int source_id;
-};
-
-/* Be able to sleep for atleast 4 seconds (usually more) */
-#define S5PTIMER_MIN_RANGE     4
-
-#define TCNT_MAX               0xffffffff
-#define NON_PERIODIC           0
-#define PERIODIC               1
-
-extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
-                                       enum s5p_timer_mode source);
-extern struct sys_timer s5p_timer;
-#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
deleted file mode 100644 (file)
index 528585d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/plat-s5p/include/plat/s5p6440.h
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Header file for s5p6440 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
- /* Common init code for S5P6440 related SoCs */
-
-extern void s5p6440_register_clocks(void);
-extern void s5p6440_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S5P6440
-
-extern  int s5p64x0_init(void);
-extern void s5p6440_init_irq(void);
-extern void s5p6440_map_io(void);
-extern void s5p6440_init_clocks(int xtal);
-
-extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-#else
-#define s5p6440_init_clocks NULL
-#define s5p6440_init_uarts NULL
-#define s5p6440_map_io NULL
-#define s5p64x0_init NULL
-#endif
-
-/* S5P6440 timer */
-
-extern struct sys_timer s5p6440_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h
deleted file mode 100644 (file)
index 640a41c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/plat-s5p/include/plat/s5p6450.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for s5p6450 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for S5P6450 related SoCs */
-
-extern void s5p6450_register_clocks(void);
-extern void s5p6450_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S5P6450
-
-extern  int s5p64x0_init(void);
-extern void s5p6450_init_irq(void);
-extern void s5p6450_map_io(void);
-extern void s5p6450_init_clocks(int xtal);
-
-extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-#else
-#define s5p6450_init_clocks NULL
-#define s5p6450_init_uarts NULL
-#define s5p6450_map_io NULL
-#define s5p64x0_init NULL
-#endif
-
-/* S5P6450 timer */
-
-extern struct sys_timer s5p6450_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-s5p/include/plat/s5pc100.h
deleted file mode 100644 (file)
index 5f6099d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* arch/arm/plat-s5p/include/plat/s5pc100.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Header file for s5pc100 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for S5PC100 related SoCs */
-
-extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s5pc100_register_clocks(void);
-extern void s5pc100_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S5PC100
-
-extern  int s5pc100_init(void);
-extern void s5pc100_init_irq(void);
-extern void s5pc100_map_io(void);
-extern void s5pc100_init_clocks(int xtal);
-
-#define s5pc100_init_uarts s5pc100_common_init_uarts
-
-#else
-#define s5pc100_init_clocks NULL
-#define s5pc100_init_uarts NULL
-#define s5pc100_map_io NULL
-#define s5pc100_init NULL
-#endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
deleted file mode 100644 (file)
index 6c93a0c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Header file for s5pv210 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* Common init code for S5PV210 related SoCs */
-
-extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s5pv210_register_clocks(void);
-extern void s5pv210_setup_clocks(void);
-
-#ifdef CONFIG_CPU_S5PV210
-
-extern  int s5pv210_init(void);
-extern void s5pv210_init_irq(void);
-extern void s5pv210_map_io(void);
-extern void s5pv210_init_clocks(int xtal);
-
-#define s5pv210_init_uarts s5pv210_common_init_uarts
-
-#else
-#define s5pv210_init_clocks NULL
-#define s5pv210_init_uarts NULL
-#define s5pv210_map_io NULL
-#define s5pv210_init NULL
-#endif
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
deleted file mode 100644 (file)
index bf5283c..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Samsung System MMU driver for S5P platform
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM__PLAT_SYSMMU_H
-#define __ASM__PLAT_SYSMMU_H __FILE__
-
-enum S5P_SYSMMU_INTERRUPT_TYPE {
-       SYSMMU_PAGEFAULT,
-       SYSMMU_AR_MULTIHIT,
-       SYSMMU_AW_MULTIHIT,
-       SYSMMU_BUSERROR,
-       SYSMMU_AR_SECURITY,
-       SYSMMU_AR_ACCESS,
-       SYSMMU_AW_SECURITY,
-       SYSMMU_AW_PROTECTION, /* 7 */
-       SYSMMU_FAULTS_NUM
-};
-
-#ifdef CONFIG_S5P_SYSTEM_MMU
-
-#include <mach/sysmmu.h>
-
-/**
- * s5p_sysmmu_enable() - enable system mmu of ip
- * @ips: The ip connected system mmu.
- * #pgd: Base physical address of the 1st level page table
- *
- * This function enable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_disable() - disable sysmmu mmu of ip
- * @ips: The ip connected system mmu.
- *
- * This function disable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_disable(sysmmu_ips ips);
-
-/**
- * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
- * @ips: The ip connected system mmu.
- * @pgd: The page table base address.
- *
- * This function set page table base address
- * When system mmu transfer address from virtaul address to physical address,
- * system mmu refer address information from page table
- */
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
- * @ips: The ip connected system mmu.
- *
- * This function flush all TLB entry in system mmu
- */
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
-
-/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @ips is
- *               SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- *             translated. This is 0 if @ips is SYSMMU_BUSERROR.
- * Called when interrupt occurred by the System MMUs
- * The device drivers of peripheral devices that has a System MMU can implement
- * a fault handler to resolve address translation fault by System MMU.
- * The meanings of return value and parameters are described below.
-
- * return value: non-zero if the fault is correctly resolved.
- *         zero if the fault is not handled.
- */
-void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
-                       int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
-                                       unsigned long pgtable_base,
-                                       unsigned long fault_addr));
-#else
-#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
-#define s5p_sysmmu_disable(ips) do { } while (0)
-#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
-#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
-#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
-#endif
-#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-s5p/include/plat/system-reset.h
deleted file mode 100644 (file)
index f307f34..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/system-reset.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h
- *
- * S5P - System define for arch_reset()
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/watchdog-reset.h>
-
-void (*s5p_reset_hook)(void);
-
-static void arch_reset(char mode, const char *cmd)
-{
-       /* SWRESET support in s5p_reset_hook() */
-
-       if (s5p_reset_hook)
-               s5p_reset_hook();
-
-       /* Perform reset using Watchdog reset
-        * if there is no s5p_reset_hook()
-        */
-
-       arch_wdt_reset();
-}
diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h
deleted file mode 100644 (file)
index 6dd6bcf..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_USB_PHY_H
-#define __PLAT_S5P_USB_PHY_H
-
-enum s5p_usb_phy_type {
-       S5P_USB_PHY_DEVICE,
-       S5P_USB_PHY_HOST,
-};
-
-extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
-extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
-
-#endif /* __PLAT_S5P_REGS_USB_PHY_H */
index c65eb791d1bb6d68f4fdc2b60ee9e2b4b45ceae4..1fdfaa4599ced6465f647bc77578a92c9694b9bc 100644 (file)
@@ -37,7 +37,7 @@ struct s5p_gpioint_bank {
        int                     start;
        int                     nr_groups;
        int                     irq;
-       struct s3c_gpio_chip    **chips;
+       struct samsung_gpio_chip        **chips;
        void                    (*handler)(unsigned int, struct irq_desc *);
 };
 
@@ -87,7 +87,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
        chained_irq_enter(chip, desc);
 
        for (group = 0; group < bank->nr_groups; group++) {
-               struct s3c_gpio_chip *chip = bank->chips[group];
+               struct samsung_gpio_chip *chip = bank->chips[group];
                if (!chip)
                        continue;
 
@@ -110,7 +110,7 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
-static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
+static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip)
 {
        static int used_gpioint_groups = 0;
        int group = chip->group;
@@ -131,7 +131,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
                return -EINVAL;
 
        if (!bank->handler) {
-               bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
+               bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) *
                                      bank->nr_groups, GFP_KERNEL);
                if (!bank->chips)
                        return -ENOMEM;
@@ -174,7 +174,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
 
 int __init s5p_register_gpio_interrupt(int pin)
 {
-       struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
+       struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin);
        int offset, group;
        int ret;
 
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S
new file mode 100644 (file)
index 0000000..0fd591b
--- /dev/null
@@ -0,0 +1,49 @@
+/* linux/arch/arm/plat-s5p/sleep.S
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Common S5P Sleep Code
+ * Based on S3C64XX sleep code by:
+ *     Ben Dooks, (c) 2008 Simtec Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+       .text
+
+       /*
+        * sleep magic, to allow the bootloader to check for an valid
+        * image to resume to. Must be the first word before the
+        * s3c_cpu_resume entry.
+        */
+
+       .word   0x2bedf00d
+
+       /*
+        * s3c_cpu_resume
+        *
+        * resume code entry for bootloader to call
+        *
+        * we must put this code here in the data segment as we have no
+        * other way of restoring the stack pointer after sleep, and we
+        * must not write to the code segment (code is read-only)
+        */
+
+ENTRY(s3c_cpu_resume)
+       b       cpu_resume
index e1cbc728c7759b1e1f54923f11120b3ea4647cb2..c8bec9c7655d417ebbcb78096f16a7cbeddcf54d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 
 #include <asm/pgtable.h>
 
index 7a96198e3a7878d819c310facd78367e3c41cc00..313eb26cfa62cb6e953ef865ba260e6e5ee23393 100644 (file)
@@ -74,39 +74,12 @@ config SAMSUNG_GPIOLIB_4BIT
          configuration. GPIOlib shall be compiled only for S3C64XX and S5P
          series of processors.
 
-config S3C_GPIO_CFG_S3C24XX
-       bool
-       help
-         Internal configuration to enable S3C24XX style GPIO configuration
-         functions.
-
 config S3C_GPIO_CFG_S3C64XX
        bool
        help
          Internal configuration to enable S3C64XX style GPIO configuration
          functions.
 
-config S3C_GPIO_PULL_UPDOWN
-       bool
-       help
-         Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_S3C2443
-       bool
-       select S3C_GPIO_PULL_UPDOWN
-       help
-         Internal configuration to enable the correct GPIO pull helper for S3C2443-style GPIO
-
-config S3C_GPIO_PULL_DOWN
-       bool
-       help
-         Internal configuration to enable the correct GPIO pull helper
-
-config S3C_GPIO_PULL_UP
-       bool
-       help
-         Internal configuration to enable the correct GPIO pull helper
-
 config S5P_GPIO_DRVSTR
        bool
        help
index 3dd5dbad55c6db34d1c2c06f8bebb9cae1fcfc25..6012366f33cb5ebf42ed978a6e424059a4d62f26 100644 (file)
@@ -1,4 +1,4 @@
-# arch/arm/plat-s3c64xx/Makefile
+# arch/arm/plat-samsung/Makefile
 #
 # Copyright 2009 Simtec Electronics
 #
@@ -15,9 +15,6 @@ obj-y                         += init.o cpu.o
 obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET)   += time.o
 obj-y                          += clock.o
 obj-y                          += pwm-clock.o
-obj-y                          += gpio.o
-obj-y                          += gpio-config.o
-obj-y                          += dev-asocdma.o
 
 obj-$(CONFIG_SAMSUNG_CLKSRC)   += clock-clksrc.o
 
@@ -31,33 +28,9 @@ obj-$(CONFIG_S3C_ADC)        += adc.o
 
 obj-y                          += platformdata.o
 
-obj-$(CONFIG_S3C_DEV_HSMMC)    += dev-hsmmc.o
-obj-$(CONFIG_S3C_DEV_HSMMC1)   += dev-hsmmc1.o
-obj-$(CONFIG_S3C_DEV_HSMMC2)   += dev-hsmmc2.o
-obj-$(CONFIG_S3C_DEV_HSMMC3)   += dev-hsmmc3.o
-obj-$(CONFIG_S3C_DEV_HWMON)    += dev-hwmon.o
-obj-y                          += dev-i2c0.o
-obj-$(CONFIG_S3C_DEV_I2C1)     += dev-i2c1.o
-obj-$(CONFIG_S3C_DEV_I2C2)     += dev-i2c2.o
-obj-$(CONFIG_S3C_DEV_I2C3)     += dev-i2c3.o
-obj-$(CONFIG_S3C_DEV_I2C4)     += dev-i2c4.o
-obj-$(CONFIG_S3C_DEV_I2C5)     += dev-i2c5.o
-obj-$(CONFIG_S3C_DEV_I2C6)     += dev-i2c6.o
-obj-$(CONFIG_S3C_DEV_I2C7)     += dev-i2c7.o
-obj-$(CONFIG_S3C_DEV_FB)       += dev-fb.o
+obj-y                          += devs.o
 obj-y                          += dev-uart.o
-obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
-obj-$(CONFIG_S3C_DEV_USB_HSOTG)        += dev-usb-hsotg.o
-obj-$(CONFIG_S3C_DEV_WDT)      += dev-wdt.o
-obj-$(CONFIG_S3C_DEV_NAND)     += dev-nand.o
-obj-$(CONFIG_S3C_DEV_ONENAND)  += dev-onenand.o
-obj-$(CONFIG_S3C_DEV_RTC)      += dev-rtc.o
-
-obj-$(CONFIG_SAMSUNG_DEV_ADC)  += dev-adc.o
-obj-$(CONFIG_SAMSUNG_DEV_IDE)  += dev-ide.o
-obj-$(CONFIG_SAMSUNG_DEV_TS)   += dev-ts.o
-obj-$(CONFIG_SAMSUNG_DEV_KEYPAD)       += dev-keypad.o
-obj-$(CONFIG_SAMSUNG_DEV_PWM)  += dev-pwm.o
+
 obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT)    += dev-backlight.o
 
 # DMA support
index ee8deef1948156d02c01423ca1fc6b8f771451e2..33ecd0c9f0c3ecfdc63aaf44cab40a8deabd5f0c 100644 (file)
@@ -41,6 +41,8 @@
 
 enum s3c_cpu_type {
        TYPE_ADCV1, /* S3C24XX */
+       TYPE_ADCV11, /* S3C2443 */
+       TYPE_ADCV12, /* S3C2416, S3C2450 */
        TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */
        TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
 };
@@ -98,13 +100,17 @@ static inline void s3c_adc_select(struct adc_device *adc,
 
        client->select_cb(client, 1);
 
-       con &= ~S3C2410_ADCCON_MUXMASK;
+       if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV2)
+               con &= ~S3C2410_ADCCON_MUXMASK;
        con &= ~S3C2410_ADCCON_STDBM;
        con &= ~S3C2410_ADCCON_STARTMASK;
 
        if (!client->is_ts) {
                if (cpu == TYPE_ADCV3)
                        writel(client->channel & 0xf, adc->regs + S5P_ADCMUX);
+               else if (cpu == TYPE_ADCV11 || cpu == TYPE_ADCV12)
+                       writel(client->channel & 0xf,
+                                               adc->regs + S3C2443_ADCMUX);
                else
                        con |= S3C2410_ADCCON_SELMUX(client->channel);
        }
@@ -293,13 +299,13 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
 
        client->nr_samples--;
 
-       if (cpu != TYPE_ADCV1) {
-               /* S3C64XX/S5P ADC resolution is 12-bit */
-               data0 &= 0xfff;
-               data1 &= 0xfff;
-       } else {
+       if (cpu == TYPE_ADCV1 || cpu == TYPE_ADCV11) {
                data0 &= 0x3ff;
                data1 &= 0x3ff;
+       } else {
+               /* S3C2416/S3C64XX/S5P ADC resolution is 12-bit */
+               data0 &= 0xfff;
+               data1 &= 0xfff;
        }
 
        if (client->convert_cb)
@@ -320,7 +326,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
        }
 
 exit:
-       if (cpu != TYPE_ADCV1) {
+       if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3) {
                /* Clear ADC interrupt */
                writel(0, adc->regs + S3C64XX_ADCCLRINT);
        }
@@ -332,6 +338,7 @@ static int s3c_adc_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct adc_device *adc;
        struct resource *regs;
+       enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
        int ret;
        unsigned tmp;
 
@@ -394,10 +401,13 @@ static int s3c_adc_probe(struct platform_device *pdev)
        clk_enable(adc->clk);
 
        tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
-       if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1) {
-               /* Enable 12-bit ADC resolution */
+
+       /* Enable 12-bit ADC resolution */
+       if (cpu == TYPE_ADCV12)
+               tmp |= S3C2416_ADCCON_RESSEL;
+       if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
                tmp |= S3C64XX_ADCCON_RESSEL;
-       }
+
        writel(tmp, adc->regs + S3C2410_ADCCON);
 
        dev_info(dev, "attached adc driver\n");
@@ -464,6 +474,7 @@ static int s3c_adc_resume(struct device *dev)
        struct platform_device *pdev = container_of(dev,
                        struct platform_device, dev);
        struct adc_device *adc = platform_get_drvdata(pdev);
+       enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
        int ret;
        unsigned long tmp;
 
@@ -474,9 +485,13 @@ static int s3c_adc_resume(struct device *dev)
        enable_irq(adc->irq);
 
        tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+
        /* Enable 12-bit ADC resolution */
-       if (platform_get_device_id(pdev)->driver_data != TYPE_ADCV1)
+       if (cpu == TYPE_ADCV12)
+               tmp |= S3C2416_ADCCON_RESSEL;
+       if (cpu == TYPE_ADCV2 || cpu == TYPE_ADCV3)
                tmp |= S3C64XX_ADCCON_RESSEL;
+
        writel(tmp, adc->regs + S3C2410_ADCCON);
 
        return 0;
@@ -491,6 +506,12 @@ static struct platform_device_id s3c_adc_driver_ids[] = {
        {
                .name           = "s3c24xx-adc",
                .driver_data    = TYPE_ADCV1,
+       }, {
+               .name           = "s3c2443-adc",
+               .driver_data    = TYPE_ADCV11,
+       }, {
+               .name           = "s3c2416-adc",
+               .driver_data    = TYPE_ADCV12,
        }, {
                .name           = "s3c64xx-adc",
                .driver_data    = TYPE_ADCV2,
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
deleted file mode 100644 (file)
index 9d903d4..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-adc.c
- *
- * Copyright 2010 Maurus Cuelenaere
- *
- * S3C64xx series device definition for ADC device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/adc.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_adc_resource[] = {
-       [0] = {
-               .start = SAMSUNG_PA_ADC,
-               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_ADC,
-               .end   = IRQ_ADC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_adc = {
-       .name           = "samsung-adc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_adc_resource),
-       .resource       = s3c_adc_resource,
-};
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
deleted file mode 100644 (file)
index 97e35d3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-asocdma.c
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- *     Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <plat/devs.h>
-
-static u64 audio_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device samsung_asoc_dma = {
-       .name             = "samsung-audio",
-       .id               = -1,
-       .dev              = {
-               .dma_mask = &audio_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       }
-};
-EXPORT_SYMBOL(samsung_asoc_dma);
-
-struct platform_device samsung_asoc_idma = {
-       .name           = "samsung-idma",
-       .id             = -1,
-       .dev            = {
-               .dma_mask               = &audio_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       }
-};
-EXPORT_SYMBOL(samsung_asoc_idma);
index 3cedd4c407af193d6e563893c9e679045b7ca25f..e657305644cc27140f8c878d99e34ac2ea668ac0 100644 (file)
 
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/pwm_backlight.h>
+#include <linux/slab.h>
 
 #include <plat/devs.h>
 #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 (file)
index 49a1362..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-fb.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for framebuffer device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/gfp.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/fb.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_fb_resource[] = {
-       [0] = {
-               .start = S3C_PA_FB,
-               .end   = S3C_PA_FB + SZ_16K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_LCD_VSYNC,
-               .end   = IRQ_LCD_VSYNC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_LCD_FIFO,
-               .end   = IRQ_LCD_FIFO,
-               .flags = IORESOURCE_IRQ,
-       },
-       [3] = {
-               .start = IRQ_LCD_SYSTEM,
-               .end   = IRQ_LCD_SYSTEM,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_fb = {
-       .name             = "s3c-fb",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_fb_resource),
-       .resource         = s3c_fb_resource,
-       .dev.dma_mask     = &s3c_device_fb.dev.coherent_dma_mask,
-       .dev.coherent_dma_mask = 0xffffffffUL,
-};
-
-void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
-{
-       s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
-                        &s3c_device_fb);
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
deleted file mode 100644 (file)
index 06825c4..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC   (0x1000)
-
-static struct resource s3c_hsmmc_resource[] = {
-       [0] = {
-               .start = S3C_PA_HSMMC0,
-               .end   = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_HSMMC0,
-               .end   = IRQ_HSMMC0,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
-       .max_width      = 4,
-       .host_caps      = (MMC_CAP_4_BIT_DATA |
-                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
-};
-
-struct platform_device s3c_device_hsmmc0 = {
-       .name           = "s3c-sdhci",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(s3c_hsmmc_resource),
-       .resource       = s3c_hsmmc_resource,
-       .dev            = {
-               .dma_mask               = &s3c_device_hsmmc_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL,
-               .platform_data          = &s3c_hsmmc0_def_platdata,
-       },
-};
-
-void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-       s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
deleted file mode 100644 (file)
index 4524ef4..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC   (0x1000)
-
-static struct resource s3c_hsmmc1_resource[] = {
-       [0] = {
-               .start = S3C_PA_HSMMC1,
-               .end   = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_HSMMC1,
-               .end   = IRQ_HSMMC1,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
-       .max_width      = 4,
-       .host_caps      = (MMC_CAP_4_BIT_DATA |
-                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
-};
-
-struct platform_device s3c_device_hsmmc1 = {
-       .name           = "s3c-sdhci",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(s3c_hsmmc1_resource),
-       .resource       = s3c_hsmmc1_resource,
-       .dev            = {
-               .dma_mask               = &s3c_device_hsmmc1_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL,
-               .platform_data          = &s3c_hsmmc1_def_platdata,
-       },
-};
-
-void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-       s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
deleted file mode 100644 (file)
index 9cede96..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
- *
- * Copyright (c) 2009 Samsung Electronics
- * Copyright (c) 2009 Maurus Cuelenaere
- *
- * Based on arch/arm/plat-s3c/dev-hsmmc1.c
- * original file Copyright (c) 2008 Simtec Electronics
- *
- * S3C series device definition for hsmmc device 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC   (0x1000)
-
-static struct resource s3c_hsmmc2_resource[] = {
-       [0] = {
-               .start = S3C_PA_HSMMC2,
-               .end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_HSMMC2,
-               .end   = IRQ_HSMMC2,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
-       .max_width      = 4,
-       .host_caps      = (MMC_CAP_4_BIT_DATA |
-                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
-};
-
-struct platform_device s3c_device_hsmmc2 = {
-       .name           = "s3c-sdhci",
-       .id             = 2,
-       .num_resources  = ARRAY_SIZE(s3c_hsmmc2_resource),
-       .resource       = s3c_hsmmc2_resource,
-       .dev            = {
-               .dma_mask               = &s3c_device_hsmmc2_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL,
-               .platform_data          = &s3c_hsmmc2_def_platdata,
-       },
-};
-
-void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-       s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
deleted file mode 100644 (file)
index 0358ef4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/plat-samsung/dev-hsmmc1.c
- *
- * Samsung device definition for hsmmc device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC   (0x1000)
-
-static struct resource s3c_hsmmc3_resource[] = {
-       [0] = {
-               .start  = S3C_PA_HSMMC3,
-               .end    = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_HSMMC3,
-               .end    = IRQ_HSMMC3,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
-       .max_width      = 4,
-       .host_caps      = (MMC_CAP_4_BIT_DATA |
-                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
-};
-
-struct platform_device s3c_device_hsmmc3 = {
-       .name           = "s3c-sdhci",
-       .id             = 3,
-       .num_resources  = ARRAY_SIZE(s3c_hsmmc3_resource),
-       .resource       = s3c_hsmmc3_resource,
-       .dev            = {
-               .dma_mask               = &s3c_device_hsmmc3_dmamask,
-               .coherent_dma_mask      = 0xffffffffUL,
-               .platform_data          = &s3c_hsmmc3_def_platdata,
-       },
-};
-
-void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-       s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
-}
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
deleted file mode 100644 (file)
index c91a79c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-hwmon.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * Adapted for HWMON by Maurus Cuelenaere
- *
- * Samsung series device definition for HWMON
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <plat/devs.h>
-#include <plat/hwmon.h>
-
-struct platform_device s3c_device_hwmon = {
-       .name           = "s3c-hwmon",
-       .id             = -1,
-       .dev.parent     = &s3c_device_adc.dev,
-};
-
-void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
-{
-       s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
-                        &s3c_device_hwmon);
-}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
deleted file mode 100644 (file)
index f8251f5..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c0.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 0
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start = S3C_PA_IIC,
-               .end   = S3C_PA_IIC + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IIC,
-               .end   = IRQ_IIC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c0 = {
-       .name             = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
-       .id               = 0,
-#else
-       .id               = -1,
-#endif
-       .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
-       .resource         = s3c_i2c_resource,
-};
-
-struct s3c2410_platform_i2c default_i2c_data __initdata = {
-       .flags          = 0,
-       .slave_addr     = 0x10,
-       .frequency      = 100*1000,
-       .sda_delay      = 100,
-};
-
-void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd)
-               pd = &default_i2c_data;
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c0);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c0_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
deleted file mode 100644 (file)
index 3b7c7be..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c1.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start = S3C_PA_IIC1,
-               .end   = S3C_PA_IIC1 + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IIC1,
-               .end   = IRQ_IIC1,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c1 = {
-       .name             = "s3c2410-i2c",
-       .id               = 1,
-       .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
-       .resource         = s3c_i2c_resource,
-};
-
-void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 1;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c1);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c1_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
deleted file mode 100644 (file)
index 07e9fd0..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c2.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S3C series device definition for i2c device 2
- *
- * Based on plat-samsung/dev-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start = S3C_PA_IIC2,
-               .end   = S3C_PA_IIC2 + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IIC2,
-               .end   = IRQ_IIC2,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c2 = {
-       .name             = "s3c2410-i2c",
-       .id               = 2,
-       .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
-       .resource         = s3c_i2c_resource,
-};
-
-void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 2;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c2);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c2_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
deleted file mode 100644 (file)
index d48efa9..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-i2c3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P series device definition for i2c device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start  = S3C_PA_IIC3,
-               .end    = S3C_PA_IIC3 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IIC3,
-               .end    = IRQ_IIC3,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c3 = {
-       .name           = "s3c2440-i2c",
-       .id             = 3,
-       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
-       .resource       = s3c_i2c_resource,
-};
-
-void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 3;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c3);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c3_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
deleted file mode 100644 (file)
index 07e2644..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-i2c4.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P series device definition for i2c device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start  = S3C_PA_IIC4,
-               .end    = S3C_PA_IIC4 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IIC4,
-               .end    = IRQ_IIC4,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c4 = {
-       .name           = "s3c2440-i2c",
-       .id             = 4,
-       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
-       .resource       = s3c_i2c_resource,
-};
-
-void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 4;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c4);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c4_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
deleted file mode 100644 (file)
index f496557..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-i2c3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P series device definition for i2c device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start  = S3C_PA_IIC5,
-               .end    = S3C_PA_IIC5 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IIC5,
-               .end    = IRQ_IIC5,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c5 = {
-       .name           = "s3c2440-i2c",
-       .id             = 5,
-       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
-       .resource       = s3c_i2c_resource,
-};
-
-void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 5;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c5);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c5_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
deleted file mode 100644 (file)
index 141d799..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-i2c6.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P series device definition for i2c device 6
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start  = S3C_PA_IIC6,
-               .end    = S3C_PA_IIC6 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IIC6,
-               .end    = IRQ_IIC6,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c6 = {
-       .name           = "s3c2440-i2c",
-       .id             = 6,
-       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
-       .resource       = s3c_i2c_resource,
-};
-
-void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 6;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c6);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c6_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
deleted file mode 100644 (file)
index 9dddcd1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-i2c7.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P series device definition for i2c device 7
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-       [0] = {
-               .start  = S3C_PA_IIC7,
-               .end    = S3C_PA_IIC7 + SZ_4K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IIC7,
-               .end    = IRQ_IIC7,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_i2c7 = {
-       .name           = "s3c2440-i2c",
-       .id             = 7,
-       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
-       .resource       = s3c_i2c_resource,
-};
-
-void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-       struct s3c2410_platform_i2c *npd;
-
-       if (!pd) {
-               pd = &default_i2c_data;
-               pd->bus_num = 7;
-       }
-
-       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
-                              &s3c_device_i2c7);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = s3c_i2c7_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
deleted file mode 100644 (file)
index b497982..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-ide.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Samsung CF-ATA device definition.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <mach/map.h>
-#include <plat/ata.h>
-#include <plat/devs.h>
-
-static struct resource s3c_cfcon_resource[] = {
-       [0] = {
-               .start  = SAMSUNG_PA_CFCON,
-               .end    = SAMSUNG_PA_CFCON + SZ_16K - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_CFCON,
-               .end    = IRQ_CFCON,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_cfcon = {
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(s3c_cfcon_resource),
-       .resource       = s3c_cfcon_resource,
-};
-
-void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
-{
-       s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
-                        &s3c_device_cfcon);
-}
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c
deleted file mode 100644 (file)
index 677c2d7..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * linux/arch/arm/plat-samsung/dev-keypad.c
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/platform_device.h>
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/keypad.h>
-
-static struct resource samsung_keypad_resources[] = {
-       [0] = {
-               .start  = SAMSUNG_PA_KEYPAD,
-               .end    = SAMSUNG_PA_KEYPAD + 0x20 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_KEYPAD,
-               .end    = IRQ_KEYPAD,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device samsung_device_keypad = {
-       .name           = "samsung-keypad",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(samsung_keypad_resources),
-       .resource       = samsung_keypad_resources,
-};
-
-void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
-{
-       struct samsung_keypad_platdata *npd;
-
-       npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
-                       &samsung_device_keypad);
-
-       if (!npd->cfg_gpio)
-               npd->cfg_gpio = samsung_keypad_cfg_gpio;
-}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
deleted file mode 100644 (file)
index b8e30ec..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * S3C series device definition for nand device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/nand.h>
-
-static struct resource s3c_nand_resource[] = {
-       [0] = {
-               .start = S3C_PA_NAND,
-               .end   = S3C_PA_NAND + SZ_1M,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-struct platform_device s3c_device_nand = {
-       .name             = "s3c2410-nand",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_nand_resource),
-       .resource         = s3c_nand_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_nand);
-
-/**
- * s3c_nand_copy_set() - copy nand set data
- * @set: The new structure, directly copied from the old.
- *
- * Copy all the fields from the NAND set field from what is probably __initdata
- * to new kernel memory. The code returns 0 if the copy happened correctly or
- * an error code for the calling function to display.
- *
- * Note, we currently do not try and look to see if we've already copied the
- * data in a previous set.
- */
-static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
-{
-       void *ptr;
-       int size;
-
-       size = sizeof(struct mtd_partition) * set->nr_partitions;
-       if (size) {
-               ptr = kmemdup(set->partitions, size, GFP_KERNEL);
-               set->partitions = ptr;
-
-               if (!ptr)
-                       return -ENOMEM;
-       }
-       
-       if (set->nr_map && set->nr_chips) {
-               size = sizeof(int) * set->nr_chips;
-               ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
-               set->nr_map = ptr;
-
-               if (!ptr)
-                       return -ENOMEM;
-       }
-
-       if (set->ecc_layout) {
-               ptr = kmemdup(set->ecc_layout,
-                             sizeof(struct nand_ecclayout), GFP_KERNEL);
-               set->ecc_layout = ptr;
-
-               if (!ptr)
-                       return -ENOMEM;
-       }
-       
-       return 0;
-}
-
-void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
-{
-       struct s3c2410_platform_nand *npd;
-       int size;
-       int ret;
-
-       /* note, if we get a failure in allocation, we simply drop out of the
-        * function. If there is so little memory available at initialisation
-        * time then there is little chance the system is going to run.
-        */ 
-
-       npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
-                               &s3c_device_nand);
-       if (!npd)
-               return;
-
-       /* now see if we need to copy any of the nand set data */
-
-       size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
-       if (size) {
-               struct s3c2410_nand_set *from = npd->sets;
-               struct s3c2410_nand_set *to;
-               int i;
-
-               to = kmemdup(from, size, GFP_KERNEL);
-               npd->sets = to; /* set, even if we failed */
-
-               if (!to) {
-                       printk(KERN_ERR "%s: no memory for sets\n", __func__);
-                       return;
-               }
-               
-               for (i = 0; i < npd->nr_sets; i++) {
-                       ret = s3c_nand_copy_set(to);
-                       if (ret) {
-                               printk(KERN_ERR "%s: failed to copy set %d\n",
-                               __func__, i);
-                               return;
-                       }
-                       to++;
-               }
-       }
-}
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c
deleted file mode 100644 (file)
index f54ae71..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/arch/arm/plat-samsung/dev-onenand.c
- *
- *  Copyright (c) 2008-2010 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S3C64XX/S5PC100 series device definition for OneNAND devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-static struct resource s3c_onenand_resources[] = {
-       [0] = {
-               .start  = S3C_PA_ONENAND,
-               .end    = S3C_PA_ONENAND + 0x400 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = S3C_PA_ONENAND_BUF,
-               .end    = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [2] = {
-               .start  = IRQ_ONENAND,
-               .end    = IRQ_ONENAND,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_onenand = {
-       .name           = "samsung-onenand",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(s3c_onenand_resources),
-       .resource       = s3c_onenand_resources,
-};
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
deleted file mode 100644 (file)
index dab47b0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-pwm.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series device definition for the PWM timer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-
-#include <plat/devs.h>
-
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq)                     \
-       (struct resource [TIMER_RESOURCE_SIZE]) {       \
-               [0] = {                                 \
-                       .start  = _irq,                 \
-                       .end    = _irq,                 \
-                       .flags  = IORESOURCE_IRQ        \
-               }                                       \
-       }
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq)                        \
-       .name           = "s3c24xx-pwm",                \
-       .id             = _tmr_no,                      \
-       .num_resources  = TIMER_RESOURCE_SIZE,          \
-       .resource       = TIMER_RESOURCE(_tmr_no, _irq),        \
-
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
-       [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
-       [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
-       [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
-       [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
-       [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
-};
-EXPORT_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 (file)
index bf4e226..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-rtc.c
- *
- * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_rtc_resource[] = {
-       [0] = {
-               .start  = S3C_PA_RTC,
-               .end    = S3C_PA_RTC + 0xff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_RTC_ALARM,
-               .end    = IRQ_RTC_ALARM,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start  = IRQ_RTC_TIC,
-               .end    = IRQ_RTC_TIC,
-               .flags  = IORESOURCE_IRQ
-       }
-};
-
-struct platform_device s3c_device_rtc = {
-       .name           = "s3c64xx-rtc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
-       .resource       = s3c_rtc_resource,
-};
-EXPORT_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 (file)
index 5f3d46a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* linux/arch/arm/mach-s3c64xx/dev-ts.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *     http://armlinux.simtec.co.uk/
- *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * Adapted by Maurus Cuelenaere for s3c64xx
- *
- * S3C64XX series device definition for touchscreen device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/ts.h>
-
-static struct resource s3c_ts_resource[] = {
-       [0] = {
-               .start = SAMSUNG_PA_ADC,
-               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_ts = {
-       .name           = "s3c64xx-ts",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
-       .resource       = s3c_ts_resource,
-};
-
-static struct s3c2410_ts_mach_info default_ts_data __initdata = {
-       .delay                  = 10000,
-       .presc                  = 49,
-       .oversampling_shift     = 2,
-};
-
-void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
-{
-       if (!pd)
-               pd = &default_ts_data;
-
-       s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
-                        &s3c_device_ts);
-}
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c
deleted file mode 100644 (file)
index 33a844a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB high-speed UDC/OtG block
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_usb_hsotg_resources[] = {
-       [0] = {
-               .start  = S3C_PA_USB_HSOTG,
-               .end    = S3C_PA_USB_HSOTG + 0x10000 - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_OTG,
-               .end    = IRQ_OTG,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s3c_device_usb_hsotg = {
-       .name           = "s3c-hsotg",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
-       .resource       = s3c_usb_hsotg_resources,
-       .dev            = {
-               .dma_mask               = &s3c_hsotg_dmamask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
deleted file mode 100644 (file)
index 33fbaa9..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-usb.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for USB host
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/usb-control.h>
-
-static struct resource s3c_usb_resource[] = {
-       [0] = {
-               .start = S3C_PA_USBHOST,
-               .end   = S3C_PA_USBHOST + 0x100 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBH,
-               .end   = IRQ_USBH,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 s3c_device_usb_dmamask = 0xffffffffUL;
-
-struct platform_device s3c_device_ohci = {
-       .name             = "s3c2410-ohci",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_usb_resource),
-       .resource         = s3c_usb_resource,
-       .dev              = {
-               .dma_mask = &s3c_device_usb_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-EXPORT_SYMBOL(s3c_device_ohci);
-
-/**
- * s3c_ohci_set_platdata - initialise OHCI device platform data
- * @info: The platform data.
- *
- * This call copies the @info passed in and sets the device .platform_data
- * field to that copy. The @info is copied so that the original can be marked
- * __initdata.
- */
-void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
-{
-       s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
-                        &s3c_device_ohci);
-}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
deleted file mode 100644 (file)
index 019b5b8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-wdt.c
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * S3C series device definition for the watchdog timer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_wdt_resource[] = {
-       [0] = {
-               .start  = S3C_PA_WDT,
-               .end    = S3C_PA_WDT + SZ_1K,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_WDT,
-               .end    = IRQ_WDT,
-               .flags  = IORESOURCE_IRQ,
-       }
-};
-
-struct platform_device s3c_device_wdt = {
-       .name           = "s3c2410-wdt",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_wdt_resource),
-       .resource       = s3c_wdt_resource,
-};
-EXPORT_SYMBOL(s3c_device_wdt);
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
new file mode 100644 (file)
index 0000000..4ca8b57
--- /dev/null
@@ -0,0 +1,1463 @@
+/* linux/arch/arm/plat-samsung/devs.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Base SAMSUNG platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
+#include <linux/ioport.h>
+
+#include <asm/irq.h>
+#include <asm/pmu.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/adc.h>
+#include <plat/ata.h>
+#include <plat/ehci.h>
+#include <plat/fb.h>
+#include <plat/fb-s3c2410.h>
+#include <plat/hwmon.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
+#include <plat/mci.h>
+#include <plat/nand.h>
+#include <plat/sdhci.h>
+#include <plat/ts.h>
+#include <plat/udc.h>
+#include <plat/usb-control.h>
+#include <plat/usb-phy.h>
+#include <plat/regs-iic.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-spi.h>
+
+static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
+
+/* AC97 */
+#ifdef CONFIG_CPU_S3C2440
+static struct resource s3c_ac97_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
+       [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
+       [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
+       [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
+       [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
+};
+
+struct platform_device s3c_device_ac97 = {
+       .name           = "samsung-ac97",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_ac97_resource),
+       .resource       = s3c_ac97_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* ADC */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_adc_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
+       [1] = DEFINE_RES_IRQ(IRQ_TC),
+       [2] = DEFINE_RES_IRQ(IRQ_ADC),
+};
+
+struct platform_device s3c_device_adc = {
+       .name           = "s3c24xx-adc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_adc_resource),
+       .resource       = s3c_adc_resource,
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#if defined(CONFIG_SAMSUNG_DEV_ADC)
+static struct resource s3c_adc_resource[] = {
+       [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_TC),
+       [2] = DEFINE_RES_IRQ(IRQ_ADC),
+};
+
+struct platform_device s3c_device_adc = {
+       .name           = "samsung-adc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_adc_resource),
+       .resource       = s3c_adc_resource,
+};
+#endif /* CONFIG_SAMSUNG_DEV_ADC */
+
+/* Camif Controller */
+
+#ifdef CONFIG_CPU_S3C2440
+static struct resource s3c_camif_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF),
+       [1] = DEFINE_RES_IRQ(IRQ_CAM),
+};
+
+struct platform_device s3c_device_camif = {
+       .name           = "s3c2440-camif",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_camif_resource),
+       .resource       = s3c_camif_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* ASOC DMA */
+
+struct platform_device samsung_asoc_dma = {
+       .name           = "samsung-audio",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+struct platform_device samsung_asoc_idma = {
+       .name           = "samsung-idma",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+/* FB */
+
+#ifdef CONFIG_S3C_DEV_FB
+static struct resource s3c_fb_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K),
+       [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC),
+       [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO),
+       [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM),
+};
+
+struct platform_device s3c_device_fb = {
+       .name           = "s3c-fb",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_fb_resource),
+       .resource       = s3c_fb_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
+{
+       s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+                        &s3c_device_fb);
+}
+#endif /* CONFIG_S3C_DEV_FB */
+
+/* FIMC */
+
+#ifdef CONFIG_S5P_DEV_FIMC0
+static struct resource s5p_fimc0_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_FIMC0, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_FIMC0),
+};
+
+struct platform_device s5p_device_fimc0 = {
+       .name           = "s5p-fimc",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p_fimc0_resource),
+       .resource       = s5p_fimc0_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device s5p_device_fimc_md = {
+       .name   = "s5p-fimc-md",
+       .id     = -1,
+};
+#endif /* CONFIG_S5P_DEV_FIMC0 */
+
+#ifdef CONFIG_S5P_DEV_FIMC1
+static struct resource s5p_fimc1_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_FIMC1, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_FIMC1),
+};
+
+struct platform_device s5p_device_fimc1 = {
+       .name           = "s5p-fimc",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p_fimc1_resource),
+       .resource       = s5p_fimc1_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S5P_DEV_FIMC1 */
+
+#ifdef CONFIG_S5P_DEV_FIMC2
+static struct resource s5p_fimc2_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_FIMC2, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_FIMC2),
+};
+
+struct platform_device s5p_device_fimc2 = {
+       .name           = "s5p-fimc",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(s5p_fimc2_resource),
+       .resource       = s5p_fimc2_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S5P_DEV_FIMC2 */
+
+#ifdef CONFIG_S5P_DEV_FIMC3
+static struct resource s5p_fimc3_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_FIMC3, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_FIMC3),
+};
+
+struct platform_device s5p_device_fimc3 = {
+       .name           = "s5p-fimc",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(s5p_fimc3_resource),
+       .resource       = s5p_fimc3_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S5P_DEV_FIMC3 */
+
+/* FIMD0 */
+
+#ifdef CONFIG_S5P_DEV_FIMD0
+static struct resource s5p_fimd0_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_FIMD0, SZ_32K),
+       [1] = DEFINE_RES_IRQ(IRQ_FIMD0_VSYNC),
+       [2] = DEFINE_RES_IRQ(IRQ_FIMD0_FIFO),
+       [3] = DEFINE_RES_IRQ(IRQ_FIMD0_SYSTEM),
+};
+
+struct platform_device s5p_device_fimd0 = {
+       .name           = "s5p-fb",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p_fimd0_resource),
+       .resource       = s5p_fimd0_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+       s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+                        &s5p_device_fimd0);
+}
+#endif /* CONFIG_S5P_DEV_FIMD0 */
+
+/* HWMON */
+
+#ifdef CONFIG_S3C_DEV_HWMON
+struct platform_device s3c_device_hwmon = {
+       .name           = "s3c-hwmon",
+       .id             = -1,
+       .dev.parent     = &s3c_device_adc.dev,
+};
+
+void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
+{
+       s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
+                        &s3c_device_hwmon);
+}
+#endif /* CONFIG_S3C_DEV_HWMON */
+
+/* HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct resource s3c_hsmmc_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_HSMMC0),
+};
+
+struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
+       .max_width      = 4,
+       .host_caps      = (MMC_CAP_4_BIT_DATA |
+                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc0 = {
+       .name           = "s3c-sdhci",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c_hsmmc_resource),
+       .resource       = s3c_hsmmc_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &s3c_hsmmc0_def_platdata,
+       },
+};
+
+void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct resource s3c_hsmmc1_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_HSMMC1),
+};
+
+struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
+       .max_width      = 4,
+       .host_caps      = (MMC_CAP_4_BIT_DATA |
+                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc1 = {
+       .name           = "s3c-sdhci",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s3c_hsmmc1_resource),
+       .resource       = s3c_hsmmc1_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &s3c_hsmmc1_def_platdata,
+       },
+};
+
+void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+
+/* HSMMC2 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct resource s3c_hsmmc2_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_HSMMC2),
+};
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+       .max_width      = 4,
+       .host_caps      = (MMC_CAP_4_BIT_DATA |
+                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+       .name           = "s3c-sdhci",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(s3c_hsmmc2_resource),
+       .resource       = s3c_hsmmc2_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &s3c_hsmmc2_def_platdata,
+       },
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC2 */
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct resource s3c_hsmmc3_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_HSMMC3),
+};
+
+struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
+       .max_width      = 4,
+       .host_caps      = (MMC_CAP_4_BIT_DATA |
+                          MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc3 = {
+       .name           = "s3c-sdhci",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(s3c_hsmmc3_resource),
+       .resource       = s3c_hsmmc3_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .platform_data          = &s3c_hsmmc3_def_platdata,
+       },
+};
+
+void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+       s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata);
+}
+#endif /* CONFIG_S3C_DEV_HSMMC3 */
+
+/* I2C */
+
+static struct resource s3c_i2c0_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC),
+};
+
+struct platform_device s3c_device_i2c0 = {
+       .name           = "s3c2410-i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+       .id             = 0,
+#else
+       .id             = -1,
+#endif
+       .num_resources  = ARRAY_SIZE(s3c_i2c0_resource),
+       .resource       = s3c_i2c0_resource,
+};
+
+struct s3c2410_platform_i2c default_i2c_data __initdata = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data;
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c0);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+}
+
+#ifdef CONFIG_S3C_DEV_I2C1
+static struct resource s3c_i2c1_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC1),
+};
+
+struct platform_device s3c_device_i2c1 = {
+       .name           = "s3c2410-i2c",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s3c_i2c1_resource),
+       .resource       = s3c_i2c1_resource,
+};
+
+void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 1;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c1);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C1 */
+
+#ifdef CONFIG_S3C_DEV_I2C2
+static struct resource s3c_i2c2_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC2),
+};
+
+struct platform_device s3c_device_i2c2 = {
+       .name           = "s3c2410-i2c",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(s3c_i2c2_resource),
+       .resource       = s3c_i2c2_resource,
+};
+
+void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 2;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c2);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c2_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C2 */
+
+#ifdef CONFIG_S3C_DEV_I2C3
+static struct resource s3c_i2c3_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC3),
+};
+
+struct platform_device s3c_device_i2c3 = {
+       .name           = "s3c2440-i2c",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(s3c_i2c3_resource),
+       .resource       = s3c_i2c3_resource,
+};
+
+void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 3;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c3);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C3 */
+
+#ifdef CONFIG_S3C_DEV_I2C4
+static struct resource s3c_i2c4_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC4),
+};
+
+struct platform_device s3c_device_i2c4 = {
+       .name           = "s3c2440-i2c",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(s3c_i2c4_resource),
+       .resource       = s3c_i2c4_resource,
+};
+
+void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 4;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c4);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C4 */
+
+#ifdef CONFIG_S3C_DEV_I2C5
+static struct resource s3c_i2c5_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC5),
+};
+
+struct platform_device s3c_device_i2c5 = {
+       .name           = "s3c2440-i2c",
+       .id             = 5,
+       .num_resources  = ARRAY_SIZE(s3c_i2c5_resource),
+       .resource       = s3c_i2c5_resource,
+};
+
+void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 5;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c5);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+}
+#endif /*CONFIG_S3C_DEV_I2C5 */
+
+#ifdef CONFIG_S3C_DEV_I2C6
+static struct resource s3c_i2c6_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC6),
+};
+
+struct platform_device s3c_device_i2c6 = {
+       .name           = "s3c2440-i2c",
+       .id             = 6,
+       .num_resources  = ARRAY_SIZE(s3c_i2c6_resource),
+       .resource       = s3c_i2c6_resource,
+};
+
+void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 6;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c6);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C6 */
+
+#ifdef CONFIG_S3C_DEV_I2C7
+static struct resource s3c_i2c7_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC7),
+};
+
+struct platform_device s3c_device_i2c7 = {
+       .name           = "s3c2440-i2c",
+       .id             = 7,
+       .num_resources  = ARRAY_SIZE(s3c_i2c7_resource),
+       .resource       = s3c_i2c7_resource,
+};
+
+void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+               pd->bus_num = 7;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s3c_device_i2c7);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+}
+#endif /* CONFIG_S3C_DEV_I2C7 */
+
+/* I2C HDMIPHY */
+
+#ifdef CONFIG_S5P_DEV_I2C_HDMIPHY
+static struct resource s5p_i2c_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_IIC_HDMIPHY, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_IIC_HDMIPHY),
+};
+
+struct platform_device s5p_device_i2c_hdmiphy = {
+       .name           = "s3c2440-hdmiphy-i2c",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_i2c_resource),
+       .resource       = s5p_i2c_resource,
+};
+
+void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd) {
+               pd = &default_i2c_data;
+
+               if (soc_is_exynos4210())
+                       pd->bus_num = 8;
+               else if (soc_is_s5pv210())
+                       pd->bus_num = 3;
+               else
+                       pd->bus_num = 0;
+       }
+
+       npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+                              &s5p_device_i2c_hdmiphy);
+}
+#endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */
+
+/* I2S */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_iis_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
+};
+
+struct platform_device s3c_device_iis = {
+       .name           = "s3c24xx-iis",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_iis_resource),
+       .resource       = s3c_iis_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#ifdef CONFIG_CPU_S3C2440
+struct platform_device s3c2412_device_iis = {
+       .name           = "s3c2412-iis",
+       .id             = -1,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_CPU_S3C2440 */
+
+/* IDE CFCON */
+
+#ifdef CONFIG_SAMSUNG_DEV_IDE
+static struct resource s3c_cfcon_resource[] = {
+       [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K),
+       [1] = DEFINE_RES_IRQ(IRQ_CFCON),
+};
+
+struct platform_device s3c_device_cfcon = {
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c_cfcon_resource),
+       .resource       = s3c_cfcon_resource,
+};
+
+void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
+{
+       s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
+                        &s3c_device_cfcon);
+}
+#endif /* CONFIG_SAMSUNG_DEV_IDE */
+
+/* KEYPAD */
+
+#ifdef CONFIG_SAMSUNG_DEV_KEYPAD
+static struct resource samsung_keypad_resources[] = {
+       [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32),
+       [1] = DEFINE_RES_IRQ(IRQ_KEYPAD),
+};
+
+struct platform_device samsung_device_keypad = {
+       .name           = "samsung-keypad",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(samsung_keypad_resources),
+       .resource       = samsung_keypad_resources,
+};
+
+void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
+{
+       struct samsung_keypad_platdata *npd;
+
+       npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
+                       &samsung_device_keypad);
+
+       if (!npd->cfg_gpio)
+               npd->cfg_gpio = samsung_keypad_cfg_gpio;
+}
+#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */
+
+/* LCD Controller */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_lcd_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD),
+       [1] = DEFINE_RES_IRQ(IRQ_LCD),
+};
+
+struct platform_device s3c_device_lcd = {
+       .name           = "s3c2410-lcd",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_lcd_resource),
+       .resource       = s3c_lcd_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+{
+       struct s3c2410fb_mach_info *npd;
+
+       npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
+       if (npd) {
+               npd->displays = kmemdup(pd->displays,
+                       sizeof(struct s3c2410fb_display) * npd->num_displays,
+                       GFP_KERNEL);
+               if (!npd->displays)
+                       printk(KERN_ERR "no memory for LCD display data\n");
+       } else {
+               printk(KERN_ERR "no memory for LCD platform data\n");
+       }
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* MFC */
+
+#ifdef CONFIG_S5P_DEV_MFC
+static struct resource s5p_mfc_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_MFC, SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_MFC),
+};
+
+struct platform_device s5p_device_mfc = {
+       .name           = "s5p-mfc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_mfc_resource),
+       .resource       = s5p_mfc_resource,
+};
+
+/*
+ * MFC hardware has 2 memory interfaces which are modelled as two separate
+ * platform devices to let dma-mapping distinguish between them.
+ *
+ * MFC parent device (s5p_device_mfc) must be registered before memory
+ * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
+ */
+
+struct platform_device s5p_device_mfc_l = {
+       .name           = "s5p-mfc-l",
+       .id             = -1,
+       .dev            = {
+               .parent                 = &s5p_device_mfc.dev,
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device s5p_device_mfc_r = {
+       .name           = "s5p-mfc-r",
+       .id             = -1,
+       .dev            = {
+               .parent                 = &s5p_device_mfc.dev,
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S5P_DEV_MFC */
+
+/* MIPI CSIS */
+
+#ifdef CONFIG_S5P_DEV_CSIS0
+static struct resource s5p_mipi_csis0_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
+};
+
+struct platform_device s5p_device_mipi_csis0 = {
+       .name           = "s5p-mipi-csis",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s5p_mipi_csis0_resource),
+       .resource       = s5p_mipi_csis0_resource,
+};
+#endif /* CONFIG_S5P_DEV_CSIS0 */
+
+#ifdef CONFIG_S5P_DEV_CSIS1
+static struct resource s5p_mipi_csis1_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K),
+       [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
+};
+
+struct platform_device s5p_device_mipi_csis1 = {
+       .name           = "s5p-mipi-csis",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p_mipi_csis1_resource),
+       .resource       = s5p_mipi_csis1_resource,
+};
+#endif
+
+/* NAND */
+
+#ifdef CONFIG_S3C_DEV_NAND
+static struct resource s3c_nand_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),
+};
+
+struct platform_device s3c_device_nand = {
+       .name           = "s3c2410-nand",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_nand_resource),
+       .resource       = s3c_nand_resource,
+};
+
+/*
+ * s3c_nand_copy_set() - copy nand set data
+ * @set: The new structure, directly copied from the old.
+ *
+ * Copy all the fields from the NAND set field from what is probably __initdata
+ * to new kernel memory. The code returns 0 if the copy happened correctly or
+ * an error code for the calling function to display.
+ *
+ * Note, we currently do not try and look to see if we've already copied the
+ * data in a previous set.
+ */
+static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
+{
+       void *ptr;
+       int size;
+
+       size = sizeof(struct mtd_partition) * set->nr_partitions;
+       if (size) {
+               ptr = kmemdup(set->partitions, size, GFP_KERNEL);
+               set->partitions = ptr;
+
+               if (!ptr)
+                       return -ENOMEM;
+       }
+
+       if (set->nr_map && set->nr_chips) {
+               size = sizeof(int) * set->nr_chips;
+               ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
+               set->nr_map = ptr;
+
+               if (!ptr)
+                       return -ENOMEM;
+       }
+
+       if (set->ecc_layout) {
+               ptr = kmemdup(set->ecc_layout,
+                             sizeof(struct nand_ecclayout), GFP_KERNEL);
+               set->ecc_layout = ptr;
+
+               if (!ptr)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
+{
+       struct s3c2410_platform_nand *npd;
+       int size;
+       int ret;
+
+       /* note, if we get a failure in allocation, we simply drop out of the
+        * function. If there is so little memory available at initialisation
+        * time then there is little chance the system is going to run.
+        */
+
+       npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
+                               &s3c_device_nand);
+       if (!npd)
+               return;
+
+       /* now see if we need to copy any of the nand set data */
+
+       size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
+       if (size) {
+               struct s3c2410_nand_set *from = npd->sets;
+               struct s3c2410_nand_set *to;
+               int i;
+
+               to = kmemdup(from, size, GFP_KERNEL);
+               npd->sets = to; /* set, even if we failed */
+
+               if (!to) {
+                       printk(KERN_ERR "%s: no memory for sets\n", __func__);
+                       return;
+               }
+
+               for (i = 0; i < npd->nr_sets; i++) {
+                       ret = s3c_nand_copy_set(to);
+                       if (ret) {
+                               printk(KERN_ERR "%s: failed to copy set %d\n",
+                               __func__, i);
+                               return;
+                       }
+                       to++;
+               }
+       }
+}
+#endif /* CONFIG_S3C_DEV_NAND */
+
+/* ONENAND */
+
+#ifdef CONFIG_S3C_DEV_ONENAND
+static struct resource s3c_onenand_resources[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K),
+       [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF),
+       [2] = DEFINE_RES_IRQ(IRQ_ONENAND),
+};
+
+struct platform_device s3c_device_onenand = {
+       .name           = "samsung-onenand",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c_onenand_resources),
+       .resource       = s3c_onenand_resources,
+};
+#endif /* CONFIG_S3C_DEV_ONENAND */
+
+#ifdef CONFIG_S3C64XX_DEV_ONENAND1
+static struct resource s3c64xx_onenand1_resources[] = {
+       [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K),
+       [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF),
+       [2] = DEFINE_RES_IRQ(IRQ_ONENAND1),
+};
+
+struct platform_device s3c64xx_device_onenand1 = {
+       .name           = "samsung-onenand",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s3c64xx_onenand1_resources),
+       .resource       = s3c64xx_onenand1_resources,
+};
+
+void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
+{
+       s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
+                        &s3c64xx_device_onenand1);
+}
+#endif /* CONFIG_S3C64XX_DEV_ONENAND1 */
+
+#ifdef CONFIG_S5P_DEV_ONENAND
+static struct resource s5p_onenand_resources[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_ONENAND, SZ_128K),
+       [1] = DEFINE_RES_MEM(S5P_PA_ONENAND_DMA, SZ_8K),
+       [2] = DEFINE_RES_IRQ(IRQ_ONENAND_AUDI),
+};
+
+struct platform_device s5p_device_onenand = {
+       .name           = "s5pc110-onenand",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_onenand_resources),
+       .resource       = s5p_onenand_resources,
+};
+#endif /* CONFIG_S5P_DEV_ONENAND */
+
+/* PMU */
+
+#ifdef CONFIG_PLAT_S5P
+static struct resource s5p_pmu_resource[] = {
+       DEFINE_RES_IRQ(IRQ_PMU)
+};
+
+struct platform_device s5p_device_pmu = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .num_resources  = ARRAY_SIZE(s5p_pmu_resource),
+       .resource       = s5p_pmu_resource,
+};
+
+static int __init s5p_pmu_init(void)
+{
+       platform_device_register(&s5p_device_pmu);
+       return 0;
+}
+arch_initcall(s5p_pmu_init);
+#endif /* CONFIG_PLAT_S5P */
+
+/* PWM Timer */
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq)                     \
+       (struct resource [TIMER_RESOURCE_SIZE]) {       \
+               [0] = {                                 \
+                       .start  = _irq,                 \
+                       .end    = _irq,                 \
+                       .flags  = IORESOURCE_IRQ        \
+               }                                       \
+       }
+
+#define DEFINE_S3C_TIMER(_tmr_no, _irq)                        \
+       .name           = "s3c24xx-pwm",                \
+       .id             = _tmr_no,                      \
+       .num_resources  = TIMER_RESOURCE_SIZE,          \
+       .resource       = TIMER_RESOURCE(_tmr_no, _irq),        \
+
+/*
+ * since we already have an static mapping for the timer,
+ * we do not bother setting any IO resource for the base.
+ */
+
+struct platform_device s3c_device_timer[] = {
+       [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
+       [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
+       [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
+       [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
+       [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+};
+#endif /* CONFIG_SAMSUNG_DEV_PWM */
+
+/* RTC */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_rtc_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_RTC),
+       [2] = DEFINE_RES_IRQ(IRQ_TICK),
+};
+
+struct platform_device s3c_device_rtc = {
+       .name           = "s3c2410-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
+       .resource       = s3c_rtc_resource,
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#ifdef CONFIG_S3C_DEV_RTC
+static struct resource s3c_rtc_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM),
+       [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC),
+};
+
+struct platform_device s3c_device_rtc = {
+       .name           = "s3c64xx-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
+       .resource       = s3c_rtc_resource,
+};
+#endif /* CONFIG_S3C_DEV_RTC */
+
+/* SDI */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_sdi_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI),
+       [1] = DEFINE_RES_IRQ(IRQ_SDI),
+};
+
+struct platform_device s3c_device_sdi = {
+       .name           = "s3c2410-sdi",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_sdi_resource),
+       .resource       = s3c_sdi_resource,
+};
+
+void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+{
+       s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
+                        &s3c_device_sdi);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* SPI */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_spi0_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32),
+       [1] = DEFINE_RES_IRQ(IRQ_SPI0),
+};
+
+struct platform_device s3c_device_spi0 = {
+       .name           = "s3c2410-spi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(s3c_spi0_resource),
+       .resource       = s3c_spi0_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+static struct resource s3c_spi1_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32),
+       [1] = DEFINE_RES_IRQ(IRQ_SPI1),
+};
+
+struct platform_device s3c_device_spi1 = {
+       .name           = "s3c2410-spi",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s3c_spi1_resource),
+       .resource       = s3c_spi1_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* Touchscreen */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_ts_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC),
+       [1] = DEFINE_RES_IRQ(IRQ_TC),
+};
+
+struct platform_device s3c_device_ts = {
+       .name           = "s3c2410-ts",
+       .id             = -1,
+       .dev.parent     = &s3c_device_adc.dev,
+       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
+       .resource       = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
+{
+       s3c_set_platdata(hard_s3c2410ts_info,
+                        sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+#ifdef CONFIG_SAMSUNG_DEV_TS
+static struct resource s3c_ts_resource[] = {
+       [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_TC),
+};
+
+static struct s3c2410_ts_mach_info default_ts_data __initdata = {
+       .delay                  = 10000,
+       .presc                  = 49,
+       .oversampling_shift     = 2,
+};
+
+struct platform_device s3c_device_ts = {
+       .name           = "s3c64xx-ts",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
+       .resource       = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
+{
+       if (!pd)
+               pd = &default_ts_data;
+
+       s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
+                        &s3c_device_ts);
+}
+#endif /* CONFIG_SAMSUNG_DEV_TS */
+
+/* TV */
+
+#ifdef CONFIG_S5P_DEV_TV
+
+static struct resource s5p_hdmi_resources[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_HDMI, SZ_1M),
+       [1] = DEFINE_RES_IRQ(IRQ_HDMI),
+};
+
+struct platform_device s5p_device_hdmi = {
+       .name           = "s5p-hdmi",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_hdmi_resources),
+       .resource       = s5p_hdmi_resources,
+};
+
+static struct resource s5p_sdo_resources[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_SDO, SZ_64K),
+       [1] = DEFINE_RES_IRQ(IRQ_SDO),
+};
+
+struct platform_device s5p_device_sdo = {
+       .name           = "s5p-sdo",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_sdo_resources),
+       .resource       = s5p_sdo_resources,
+};
+
+static struct resource s5p_mixer_resources[] = {
+       [0] = DEFINE_RES_MEM_NAMED(S5P_PA_MIXER, SZ_64K, "mxr"),
+       [1] = DEFINE_RES_MEM_NAMED(S5P_PA_VP, SZ_64K, "vp"),
+       [2] = DEFINE_RES_IRQ_NAMED(IRQ_MIXER, "irq"),
+};
+
+struct platform_device s5p_device_mixer = {
+       .name           = "s5p-mixer",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_mixer_resources),
+       .resource       = s5p_mixer_resources,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+#endif /* CONFIG_S5P_DEV_TV */
+
+/* USB */
+
+#ifdef CONFIG_S3C_DEV_USB_HOST
+static struct resource s3c_usb_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_USBH),
+};
+
+struct platform_device s3c_device_ohci = {
+       .name           = "s3c2410-ohci",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_usb_resource),
+       .resource       = s3c_usb_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+/*
+ * s3c_ohci_set_platdata - initialise OHCI device platform data
+ * @info: The platform data.
+ *
+ * This call copies the @info passed in and sets the device .platform_data
+ * field to that copy. The @info is copied so that the original can be marked
+ * __initdata.
+ */
+
+void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
+{
+       s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
+                        &s3c_device_ohci);
+}
+#endif /* CONFIG_S3C_DEV_USB_HOST */
+
+/* USB Device (Gadget) */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_usbgadget_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV),
+       [1] = DEFINE_RES_IRQ(IRQ_USBD),
+};
+
+struct platform_device s3c_device_usbgadget = {
+       .name           = "s3c2410-usbgadget",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_usbgadget_resource),
+       .resource       = s3c_usbgadget_resource,
+};
+
+void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
+{
+       s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* USB EHCI Host Controller */
+
+#ifdef CONFIG_S5P_DEV_USB_EHCI
+static struct resource s5p_ehci_resource[] = {
+       [0] = DEFINE_RES_MEM(S5P_PA_EHCI, SZ_256),
+       [1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
+};
+
+struct platform_device s5p_device_ehci = {
+       .name           = "s5p-ehci",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5p_ehci_resource),
+       .resource       = s5p_ehci_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       }
+};
+
+void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
+{
+       struct s5p_ehci_platdata *npd;
+
+       npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
+                       &s5p_device_ehci);
+
+       if (!npd->phy_init)
+               npd->phy_init = s5p_usb_phy_init;
+       if (!npd->phy_exit)
+               npd->phy_exit = s5p_usb_phy_exit;
+}
+#endif /* CONFIG_S5P_DEV_USB_EHCI */
+
+/* USB HSOTG */
+
+#ifdef CONFIG_S3C_DEV_USB_HSOTG
+static struct resource s3c_usb_hsotg_resources[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_16K),
+       [1] = DEFINE_RES_IRQ(IRQ_OTG),
+};
+
+struct platform_device s3c_device_usb_hsotg = {
+       .name           = "s3c-hsotg",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_usb_hsotg_resources),
+       .resource       = s3c_usb_hsotg_resources,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+#endif /* CONFIG_S3C_DEV_USB_HSOTG */
+
+/* USB High Spped 2.0 Device (Gadget) */
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct resource s3c_hsudc_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC),
+       [1] = DEFINE_RES_IRQ(IRQ_USBD),
+};
+
+struct platform_device s3c_device_usb_hsudc = {
+       .name           = "s3c-hsudc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_hsudc_resource),
+       .resource       = s3c_hsudc_resource,
+       .dev            = {
+               .dma_mask               = &samsung_device_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
+{
+       s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
+}
+#endif /* CONFIG_PLAT_S3C24XX */
+
+/* WDT */
+
+#ifdef CONFIG_S3C_DEV_WDT
+static struct resource s3c_wdt_resource[] = {
+       [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K),
+       [1] = DEFINE_RES_IRQ(IRQ_WDT),
+};
+
+struct platform_device s3c_device_wdt = {
+       .name           = "s3c2410-wdt",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_wdt_resource),
+       .resource       = s3c_wdt_resource,
+};
+#endif /* CONFIG_S3C_DEV_WDT */
index 6e3d9abc9e2e856470e304c78f31794a4f715833..93a994a5dd8f546c53ea2d80af751336d0f84184 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/amba/pl330.h>
 #include <linux/scatterlist.h>
+#include <linux/export.h>
 
 #include <mach/dma.h>
 
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
deleted file mode 100644 (file)
index 1c0b040..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio-config.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008-2010 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO configuration core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset;
-       int ret;
-
-       if (!chip)
-               return -EINVAL;
-
-       offset = pin - chip->chip.base;
-
-       s3c_gpio_lock(chip, flags);
-       ret = s3c_gpio_do_setcfg(chip, offset, config);
-       s3c_gpio_unlock(chip, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_cfgpin);
-
-int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
-                         unsigned int cfg)
-{
-       int ret;
-
-       for (; nr > 0; nr--, start++) {
-               ret = s3c_gpio_cfgpin(start, cfg);
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
-
-int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
-                         unsigned int cfg, s3c_gpio_pull_t pull)
-{
-       int ret;
-
-       for (; nr > 0; nr--, start++) {
-               s3c_gpio_setpull(start, pull);
-               ret = s3c_gpio_cfgpin(start, cfg);
-               if (ret != 0)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
-
-unsigned s3c_gpio_getcfg(unsigned int pin)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned long flags;
-       unsigned ret = 0;
-       int offset;
-
-       if (chip) {
-               offset = pin - chip->chip.base;
-
-               s3c_gpio_lock(chip, flags);
-               ret = s3c_gpio_do_getcfg(chip, offset);
-               s3c_gpio_unlock(chip, flags);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_getcfg);
-
-
-int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset, ret;
-
-       if (!chip)
-               return -EINVAL;
-
-       offset = pin - chip->chip.base;
-
-       s3c_gpio_lock(chip, flags);
-       ret = s3c_gpio_do_setpull(chip, offset, pull);
-       s3c_gpio_unlock(chip, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(s3c_gpio_setpull);
-
-s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned long flags;
-       int offset;
-       u32 pup = 0;
-
-       if (chip) {
-               offset = pin - chip->chip.base;
-
-               s3c_gpio_lock(chip, flags);
-               pup = s3c_gpio_do_getpull(chip, offset);
-               s3c_gpio_unlock(chip, flags);
-       }
-
-       return (__force s3c_gpio_pull_t)pup;
-}
-EXPORT_SYMBOL(s3c_gpio_getpull);
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
-                             unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = off;
-       u32 con;
-
-       if (s3c_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-
-               /* Map output to 0, and SFN2 to 1 */
-               cfg -= 1;
-               if (cfg > 1)
-                       return -EINVAL;
-
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0x1 << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
-                                  unsigned int off)
-{
-       u32 con;
-
-       con = __raw_readl(chip->base);
-       con >>= off;
-       con &= 1;
-       con++;
-
-       return S3C_GPIO_SFN(con);
-}
-
-int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
-                           unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = off * 2;
-       u32 con;
-
-       if (s3c_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-               if (cfg > 3)
-                       return -EINVAL;
-
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0x3 << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
-                                    unsigned int off)
-{
-       u32 con;
-
-       con = __raw_readl(chip->base);
-       con >>= off * 2;
-       con &= 3;
-
-       /* this conversion works for IN and OUT as well as special mode */
-       return S3C_GPIO_SPECIAL(con);
-}
-#endif
-
-#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
-int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-                                unsigned int off, unsigned int cfg)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = (off & 7) * 4;
-       u32 con;
-
-       if (off < 8 && chip->chip.ngpio > 8)
-               reg -= 4;
-
-       if (s3c_gpio_is_cfg_special(cfg)) {
-               cfg &= 0xf;
-               cfg <<= shift;
-       }
-
-       con = __raw_readl(reg);
-       con &= ~(0xf << shift);
-       con |= cfg;
-       __raw_writel(con, reg);
-
-       return 0;
-}
-
-unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-                                     unsigned int off)
-{
-       void __iomem *reg = chip->base;
-       unsigned int shift = (off & 7) * 4;
-       u32 con;
-
-       if (off < 8 && chip->chip.ngpio > 8)
-               reg -= 4;
-
-       con = __raw_readl(reg);
-       con >>= shift;
-       con &= 0xf;
-
-       /* this conversion works for IN and OUT as well as special mode */
-       return S3C_GPIO_SPECIAL(con);
-}
-
-#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
-
-#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
-int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
-                           unsigned int off, s3c_gpio_pull_t pull)
-{
-       void __iomem *reg = chip->base + 0x08;
-       int shift = off * 2;
-       u32 pup;
-
-       pup = __raw_readl(reg);
-       pup &= ~(3 << shift);
-       pup |= pull << shift;
-       __raw_writel(pup, reg);
-
-       return 0;
-}
-
-s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
-                                       unsigned int off)
-{
-       void __iomem *reg = chip->base + 0x08;
-       int shift = off * 2;
-       u32 pup = __raw_readl(reg);
-
-       pup >>= shift;
-       pup &= 0x3;
-       return (__force s3c_gpio_pull_t)pup;
-}
-
-#ifdef CONFIG_S3C_GPIO_PULL_S3C2443
-int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
-                               unsigned int off, s3c_gpio_pull_t pull)
-{
-       switch (pull) {
-       case S3C_GPIO_PULL_NONE:
-               pull = 0x01;
-               break;
-       case S3C_GPIO_PULL_UP:
-               pull = 0x00;
-               break;
-       case S3C_GPIO_PULL_DOWN:
-               pull = 0x02;
-               break;
-       }
-       return s3c_gpio_setpull_updown(chip, off, pull);
-}
-
-s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
-                                       unsigned int off)
-{
-       s3c_gpio_pull_t pull;
-
-       pull = s3c_gpio_getpull_updown(chip, off);
-
-       switch (pull) {
-       case 0x00:
-               pull = S3C_GPIO_PULL_UP;
-               break;
-       case 0x01:
-       case 0x03:
-               pull = S3C_GPIO_PULL_NONE;
-               break;
-       case 0x02:
-               pull = S3C_GPIO_PULL_DOWN;
-               break;
-       }
-
-       return pull;
-}
-#endif
-#endif
-
-#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
-static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
-                        unsigned int off, s3c_gpio_pull_t pull,
-                        s3c_gpio_pull_t updown)
-{
-       void __iomem *reg = chip->base + 0x08;
-       u32 pup = __raw_readl(reg);
-
-       if (pull == updown)
-               pup &= ~(1 << off);
-       else if (pull == S3C_GPIO_PULL_NONE)
-               pup |= (1 << off);
-       else
-               return -EINVAL;
-
-       __raw_writel(pup, reg);
-       return 0;
-}
-
-static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
-                                    unsigned int off, s3c_gpio_pull_t updown)
-{
-       void __iomem *reg = chip->base + 0x08;
-       u32 pup = __raw_readl(reg);
-
-       pup &= (1 << off);
-       return pup ? S3C_GPIO_PULL_NONE : updown;
-}
-#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
-
-#ifdef CONFIG_S3C_GPIO_PULL_UP
-s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
-                                    unsigned int off)
-{
-       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
-}
-
-int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
-                        unsigned int off, s3c_gpio_pull_t pull)
-{
-       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
-}
-#endif /* CONFIG_S3C_GPIO_PULL_UP */
-
-#ifdef CONFIG_S3C_GPIO_PULL_DOWN
-s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
-                                    unsigned int off)
-{
-       return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
-}
-
-int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
-                        unsigned int off, s3c_gpio_pull_t pull)
-{
-       return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
-}
-#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
-
-#ifdef CONFIG_S5P_GPIO_DRVSTR
-s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned int off;
-       void __iomem *reg;
-       int shift;
-       u32 drvstr;
-
-       if (!chip)
-               return -EINVAL;
-
-       off = pin - chip->chip.base;
-       shift = off * 2;
-       reg = chip->base + 0x0C;
-
-       drvstr = __raw_readl(reg);
-       drvstr = drvstr >> shift;
-       drvstr &= 0x3;
-
-       return (__force s5p_gpio_drvstr_t)drvstr;
-}
-EXPORT_SYMBOL(s5p_gpio_get_drvstr);
-
-int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       unsigned int off;
-       void __iomem *reg;
-       int shift;
-       u32 tmp;
-
-       if (!chip)
-               return -EINVAL;
-
-       off = pin - chip->chip.base;
-       shift = off * 2;
-       reg = chip->base + 0x0C;
-
-       tmp = __raw_readl(reg);
-       tmp &= ~(0x3 << shift);
-       tmp |= drvstr << shift;
-
-       __raw_writel(tmp, reg);
-
-       return 0;
-}
-EXPORT_SYMBOL(s5p_gpio_set_drvstr);
-#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 (file)
index 7743c4b..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/* linux/arch/arm/plat-s3c/gpio.c
- *
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * S3C series GPIO core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-
-#include <plat/gpio-core.h>
-
-#ifdef CONFIG_S3C_GPIO_TRACK
-struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-
-static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
-{
-       unsigned int gpn;
-       int i;
-
-       gpn = chip->chip.base;
-       for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
-               BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
-               s3c_gpios[gpn] = chip;
-       }
-}
-#endif /* CONFIG_S3C_GPIO_TRACK */
-
-/* Default routines for controlling GPIO, based on the original S3C24XX
- * GPIO functions which deal with the case where each gpio bank of the
- * chip is as following:
- *
- * base + 0x00: Control register, 2 bits per gpio
- *             gpio n: 2 bits starting at (2*n)
- *             00 = input, 01 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *             bit n: data bit n
-*/
-
-static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long con;
-
-       s3c_gpio_lock(ourchip, flags);
-
-       con = __raw_readl(base + 0x00);
-       con &= ~(3 << (offset * 2));
-
-       __raw_writel(con, base + 0x00);
-
-       s3c_gpio_unlock(ourchip, flags);
-       return 0;
-}
-
-static int s3c_gpiolib_output(struct gpio_chip *chip,
-                             unsigned offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-       unsigned long con;
-
-       s3c_gpio_lock(ourchip, flags);
-
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-       __raw_writel(dat, base + 0x04);
-
-       con = __raw_readl(base + 0x00);
-       con &= ~(3 << (offset * 2));
-       con |= 1 << (offset * 2);
-
-       __raw_writel(con, base + 0x00);
-       __raw_writel(dat, base + 0x04);
-
-       s3c_gpio_unlock(ourchip, flags);
-       return 0;
-}
-
-static void s3c_gpiolib_set(struct gpio_chip *chip,
-                           unsigned offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long flags;
-       unsigned long dat;
-
-       s3c_gpio_lock(ourchip, flags);
-
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offset);
-       if (value)
-               dat |= 1 << offset;
-       __raw_writel(dat, base + 0x04);
-
-       s3c_gpio_unlock(ourchip, flags);
-}
-
-static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       unsigned long val;
-
-       val = __raw_readl(ourchip->base + 0x04);
-       val >>= offset;
-       val &= 1;
-
-       return val;
-}
-
-__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
-{
-       struct gpio_chip *gc = &chip->chip;
-       int ret;
-
-       BUG_ON(!chip->base);
-       BUG_ON(!gc->label);
-       BUG_ON(!gc->ngpio);
-
-       spin_lock_init(&chip->lock);
-
-       if (!gc->direction_input)
-               gc->direction_input = s3c_gpiolib_input;
-       if (!gc->direction_output)
-               gc->direction_output = s3c_gpiolib_output;
-       if (!gc->set)
-               gc->set = s3c_gpiolib_set;
-       if (!gc->get)
-               gc->get = s3c_gpiolib_get;
-
-#ifdef CONFIG_PM
-       if (chip->pm != NULL) {
-               if (!chip->pm->save || !chip->pm->resume)
-                       printk(KERN_ERR "gpio: %s has missing PM functions\n",
-                              gc->label);
-       } else
-               printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
-#endif
-
-       /* gpiochip_add() prints own failure message on error. */
-       ret = gpiochip_add(gc);
-       if (ret >= 0)
-               s3c_gpiolib_track(chip);
-}
-
-int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-       struct s3c_gpio_chip *s3c_chip = container_of(chip,
-                       struct s3c_gpio_chip, chip);
-
-       return s3c_chip->irq_base + offset;
-}
index a281568d5856083141d2123ca08febba0ea2916d..a927bee553593ca874da782f9fca0627a89dcf4c 100644 (file)
@@ -20,7 +20,7 @@
 /* re-define device name depending on support. */
 static inline void s3c_adc_setname(char *name)
 {
-#ifdef CONFIG_SAMSUNG_DEV_ADC
+#if defined(CONFIG_SAMSUNG_DEV_ADC) || defined(CONFIG_PLAT_S3C24XX)
        s3c_device_adc.name = name;
 #endif
 }
diff --git a/arch/arm/plat-samsung/include/plat/audio-simtec.h b/arch/arm/plat-samsung/include/plat/audio-simtec.h
new file mode 100644 (file)
index 0000000..5345364
--- /dev/null
@@ -0,0 +1,37 @@
+/* arch/arm/plat-samsung/include/plat/audio-simtec.h
+ *
+ * Copyright 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Simtec Audio support.
+*/
+
+/**
+ * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
+ * @use_mpllin: Select codec clock from MPLLin
+ * @output_cdclk: Need to output CDCLK to the codec
+ * @have_mic: Set if we have a MIC socket
+ * @have_lout: Set if we have a LineOut socket
+ * @amp_gpio: GPIO pin to enable the AMP
+ * @amp_gain: Option GPIO to control AMP gain
+ */
+struct s3c24xx_audio_simtec_pdata {
+       unsigned int    use_mpllin:1;
+       unsigned int    output_cdclk:1;
+
+       unsigned int    have_mic:1;
+       unsigned int    have_lout:1;
+
+       int             amp_gpio;
+       int             amp_gain[2];
+
+       void    (*startup)(void);
+};
+
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
+                           struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-samsung/include/plat/camport.h b/arch/arm/plat-samsung/include/plat/camport.h
new file mode 100644 (file)
index 0000000..a5708bf
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series camera interface helper functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_SAMSUNG_CAMPORT_H_
+#define __PLAT_SAMSUNG_CAMPORT_H_ __FILE__
+
+enum s5p_camport_id {
+       S5P_CAMPORT_A,
+       S5P_CAMPORT_B,
+};
+
+/*
+ * The helper functions to configure GPIO for the camera parallel bus.
+ * The camera port can be multiplexed with any FIMC entity, even multiple
+ * FIMC entities are allowed to be attached to a single port simultaneously.
+ * These functions are to be used in the board setup code.
+ */
+int s5pv210_fimc_setup_gpio(enum s5p_camport_id id);
+int exynos4_fimc_setup_gpio(enum s5p_camport_id id);
+
+#endif /* __PLAT_SAMSUNG_CAMPORT_H */
diff --git a/arch/arm/plat-samsung/include/plat/common-smdk.h b/arch/arm/plat-samsung/include/plat/common-smdk.h
new file mode 100644 (file)
index 0000000..ba028f1
--- /dev/null
@@ -0,0 +1,15 @@
+/* linux/arch/arm/plat-samsung/include/plat/common-smdk.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void smdk_machine_init(void);
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
new file mode 100644 (file)
index 0000000..dac4760
--- /dev/null
@@ -0,0 +1,288 @@
+/* arch/arm/plat-samsung/include/plat/cpu-freq-core.h
+ *
+ * Copyright (c) 2006-2009 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - core support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <plat/cpu-freq.h>
+
+struct seq_file;
+
+#define MAX_BANKS (8)
+#define S3C2412_MAX_IO (8)
+
+/**
+ * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
+ * @bankcon: The cached version of settings in this structure.
+ * @tacp:
+ * @tacs: Time from address valid to nCS asserted.
+ * @tcos: Time from nCS asserted to nOE or nWE asserted.
+ * @tacc: Time that nOE or nWE is asserted.
+ * @tcoh: Time nCS is held after nOE or nWE are released.
+ * @tcah: Time address is held for after
+ * @nwait_en: Whether nWAIT is enabled for this bank.
+ *
+ * This structure represents the IO timings for a S3C2410 style IO bank
+ * used by the CPU frequency support if it needs to change the settings
+ * of the IO.
+ */
+struct s3c2410_iobank_timing {
+       unsigned long   bankcon;
+       unsigned int    tacp;
+       unsigned int    tacs;
+       unsigned int    tcos;
+       unsigned int    tacc;
+       unsigned int    tcoh;           /* nCS hold afrer nOE/nWE */
+       unsigned int    tcah;           /* Address hold after nCS */
+       unsigned char   nwait_en;       /* nWait enabled for bank. */
+};
+
+/**
+ * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
+ * @idcy: The idle cycle time between transactions.
+ * @wstrd: nCS release to end of read cycle.
+ * @wstwr: nCS release to end of write cycle.
+ * @wstoen: nCS assertion to nOE assertion time.
+ * @wstwen: nCS assertion to nWE assertion time.
+ * @wstbrd: Burst ready delay.
+ * @smbidcyr: Register cache for smbidcyr value.
+ * @smbwstrd: Register cache for smbwstrd value.
+ * @smbwstwr: Register cache for smbwstwr value.
+ * @smbwstoen: Register cache for smbwstoen value.
+ * @smbwstwen: Register cache for smbwstwen value.
+ * @smbwstbrd: Register cache for smbwstbrd value.
+ *
+ * Timing information for a IO bank on an S3C2412 or similar system which
+ * uses a PL093 block.
+ */
+struct s3c2412_iobank_timing {
+       unsigned int    idcy;
+       unsigned int    wstrd;
+       unsigned int    wstwr;
+       unsigned int    wstoen;
+       unsigned int    wstwen;
+       unsigned int    wstbrd;
+
+       /* register cache */
+       unsigned char   smbidcyr;
+       unsigned char   smbwstrd;
+       unsigned char   smbwstwr;
+       unsigned char   smbwstoen;
+       unsigned char   smbwstwen;
+       unsigned char   smbwstbrd;
+};
+
+union s3c_iobank {
+       struct s3c2410_iobank_timing    *io_2410;
+       struct s3c2412_iobank_timing    *io_2412;
+};
+
+/**
+ * struct s3c_iotimings - Chip IO timings holder
+ * @bank: The timings for each IO bank.
+ */
+struct s3c_iotimings {
+       union s3c_iobank        bank[MAX_BANKS];
+};
+
+/**
+ * struct s3c_plltab - PLL table information.
+ * @vals: List of PLL values.
+ * @size: Size of the PLL table @vals.
+ */
+struct s3c_plltab {
+       struct s3c_pllval       *vals;
+       int                      size;
+};
+
+/**
+ * struct s3c_cpufreq_config - current cpu frequency configuration
+ * @freq: The current settings for the core clocks.
+ * @max: Maxium settings, derived from core, board and user settings.
+ * @pll: The PLL table entry for the current PLL settings.
+ * @divs: The divisor settings for the core clocks.
+ * @info: The current core driver information.
+ * @board: The information for the board we are running on.
+ * @lock_pll: Set if the PLL settings cannot be changed.
+ *
+ * This is for the core drivers that need to know information about
+ * the current settings and values. It should not be needed by any
+ * device drivers.
+*/
+struct s3c_cpufreq_config {
+       struct s3c_freq         freq;
+       struct s3c_freq         max;
+       struct cpufreq_frequency_table pll;
+       struct s3c_clkdivs      divs;
+       struct s3c_cpufreq_info *info;  /* for core, not drivers */
+       struct s3c_cpufreq_board *board;
+
+       unsigned int    lock_pll:1;
+};
+
+/**
+ * struct s3c_cpufreq_info - Information for the CPU frequency driver.
+ * @name: The name of this implementation.
+ * @max: The maximum frequencies for the system.
+ * @latency: Transition latency to give to cpufreq.
+ * @locktime_m: The lock-time in uS for the MPLL.
+ * @locktime_u: The lock-time in uS for the UPLL.
+ * @locttime_bits: The number of bits each LOCKTIME field.
+ * @need_pll: Set if this driver needs to change the PLL values to achieve
+ *     any frequency changes. This is really only need by devices like the
+ *     S3C2410 where there is no or limited divider between the PLL and the
+ *     ARMCLK.
+ * @resume_clocks: Update the clocks on resume.
+ * @get_iotiming: Get the current IO timing data, mainly for use at start.
+ * @set_iotiming: Update the IO timings from the cached copies calculated
+ *     from the @calc_iotiming entry when changing the frequency.
+ * @calc_iotiming: Calculate and update the cached copies of the IO timings
+ *     from the newly calculated frequencies.
+ * @calc_freqtable: Calculate (fill in) the given frequency table from the
+ *     current frequency configuration. If the table passed in is NULL,
+ *     then the return is the number of elements to be filled for allocation
+ *     of the table.
+ * @set_refresh: Set the memory refresh configuration.
+ * @set_fvco: Set the PLL frequencies.
+ * @set_divs: Update the clock divisors.
+ * @calc_divs: Calculate the clock divisors.
+ */
+struct s3c_cpufreq_info {
+       const char              *name;
+       struct s3c_freq         max;
+
+       unsigned int            latency;
+
+       unsigned int            locktime_m;
+       unsigned int            locktime_u;
+       unsigned char           locktime_bits;
+
+       unsigned int            need_pll:1;
+
+       /* driver routines */
+
+       void            (*resume_clocks)(void);
+
+       int             (*get_iotiming)(struct s3c_cpufreq_config *cfg,
+                                       struct s3c_iotimings *timings);
+
+       void            (*set_iotiming)(struct s3c_cpufreq_config *cfg,
+                                       struct s3c_iotimings *timings);
+
+       int             (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
+                                        struct s3c_iotimings *timings);
+
+       int             (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
+                                         struct cpufreq_frequency_table *t,
+                                         size_t table_size);
+
+       void            (*debug_io_show)(struct seq_file *seq,
+                                        struct s3c_cpufreq_config *cfg,
+                                        union s3c_iobank *iob);
+
+       void            (*set_refresh)(struct s3c_cpufreq_config *cfg);
+       void            (*set_fvco)(struct s3c_cpufreq_config *cfg);
+       void            (*set_divs)(struct s3c_cpufreq_config *cfg);
+       int             (*calc_divs)(struct s3c_cpufreq_config *cfg);
+};
+
+extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
+
+extern int s3c_plltab_register(struct cpufreq_frequency_table *plls,
+                              unsigned int plls_no);
+
+/* exports and utilities for debugfs */
+extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
+extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
+
+extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
+                                    struct s3c_cpufreq_config *cfg,
+                                    union s3c_iobank *iob);
+
+extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
+                                    struct s3c_cpufreq_config *cfg,
+                                    union s3c_iobank *iob);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+#define s3c_cpufreq_debugfs_call(x) x
+#else
+#define s3c_cpufreq_debugfs_call(x) NULL
+#endif
+
+/* Useful utility functions. */
+
+extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
+
+/* S3C2410 and compatible exported functions */
+
+extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
+extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
+
+#ifdef CONFIG_S3C2410_IOTIMING
+extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+                                struct s3c_iotimings *iot);
+
+extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+                               struct s3c_iotimings *timings);
+
+extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+                                struct s3c_iotimings *iot);
+#else
+#define s3c2410_iotiming_calc NULL
+#define s3c2410_iotiming_get NULL
+#define s3c2410_iotiming_set NULL
+#endif /* CONFIG_S3C2410_IOTIMING */
+
+/* S3C2412 compatible routines */
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+                               struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+                               struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+                                struct s3c_iotimings *iot);
+
+extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+                                struct s3c_iotimings *iot);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
+#define s3c_freq_dbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
+#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
+
+static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
+                                     int index, size_t table_size,
+                                     unsigned int freq)
+{
+       if (index < 0)
+               return index;
+
+       if (table) {
+               if (index >= table_size)
+                       return -ENOMEM;
+
+               s3c_freq_dbg("%s: { %d = %u kHz }\n",
+                            __func__, index, freq);
+
+               table[index].index = index;
+               table[index].frequency = freq;
+       }
+
+       return index + 1;
+}
index 54f370f0fc07f000b89681c92c3dec20ec48edad..40fd7b6b5e6605bf9a18825260b772ee1cf73ab8 100644 (file)
@@ -25,7 +25,6 @@ extern unsigned long samsung_cpu_id;
 
 #define S3C6400_CPU_ID         0x36400000
 #define S3C6410_CPU_ID         0x36410000
-#define S3C64XX_CPU_ID         (S3C6400_CPU_ID & S3C6410_CPU_ID)
 #define S3C64XX_CPU_MASK       0xFFFFF000
 
 #define S5P6440_CPU_ID         0x56440000
@@ -50,7 +49,8 @@ static inline int is_samsung_##name(void)     \
 }
 
 IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
-IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK)
 IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
 IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
 IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
@@ -69,7 +69,7 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
 #endif
 
 #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
-# define soc_is_s3c64xx()      is_samsung_s3c64xx()
+# define soc_is_s3c64xx()      (is_samsung_s3c6400() || is_samsung_s3c6410())
 #else
 # define soc_is_s3c64xx()      0
 #endif
index 24ebb1e1de413c4b1a5b47cdf3347c4275574558..ab633c9c2aec51666d69e86b71a2b84c38b98ebf 100644 (file)
@@ -30,30 +30,24 @@ extern struct s3c24xx_uart_resources s5p_uart_resources[];
 extern struct platform_device *s3c24xx_uart_devs[];
 extern struct platform_device *s3c24xx_uart_src[];
 
-extern struct platform_device s3c_device_timer[];
-
+extern struct platform_device s3c64xx_device_ac97;
 extern struct platform_device s3c64xx_device_iis0;
 extern struct platform_device s3c64xx_device_iis1;
 extern struct platform_device s3c64xx_device_iisv4;
-
-extern struct platform_device s3c64xx_device_spi0;
-extern struct platform_device s3c64xx_device_spi1;
-
-extern struct platform_device samsung_asoc_dma;
-extern struct platform_device samsung_asoc_idma;
-
+extern struct platform_device s3c64xx_device_onenand1;
 extern struct platform_device s3c64xx_device_pcm0;
 extern struct platform_device s3c64xx_device_pcm1;
+extern struct platform_device s3c64xx_device_spi0;
+extern struct platform_device s3c64xx_device_spi1;
 
-extern struct platform_device s3c64xx_device_ac97;
-
-extern struct platform_device s3c_device_ts;
-
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_cfcon;
 extern struct platform_device s3c_device_fb;
-extern struct platform_device s5p_device_fimd0;
-extern struct platform_device s3c_device_ohci;
-extern struct platform_device s3c_device_lcd;
-extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_hwmon;
+extern struct platform_device s3c_device_hsmmc0;
+extern struct platform_device s3c_device_hsmmc1;
+extern struct platform_device s3c_device_hsmmc2;
+extern struct platform_device s3c_device_hsmmc3;
 extern struct platform_device s3c_device_i2c0;
 extern struct platform_device s3c_device_i2c1;
 extern struct platform_device s3c_device_i2c2;
@@ -62,93 +56,90 @@ extern struct platform_device s3c_device_i2c4;
 extern struct platform_device s3c_device_i2c5;
 extern struct platform_device s3c_device_i2c6;
 extern struct platform_device s3c_device_i2c7;
+extern struct platform_device s3c_device_iis;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_nand;
+extern struct platform_device s3c_device_ohci;
+extern struct platform_device s3c_device_onenand;
 extern struct platform_device s3c_device_rtc;
-extern struct platform_device s3c_device_adc;
 extern struct platform_device s3c_device_sdi;
-extern struct platform_device s3c_device_iis;
-extern struct platform_device s3c_device_hwmon;
-extern struct platform_device s3c_device_hsmmc0;
-extern struct platform_device s3c_device_hsmmc1;
-extern struct platform_device s3c_device_hsmmc2;
-extern struct platform_device s3c_device_hsmmc3;
-extern struct platform_device s3c_device_cfcon;
-
 extern struct platform_device s3c_device_spi0;
 extern struct platform_device s3c_device_spi1;
-
-extern struct platform_device s5pc100_device_spi0;
-extern struct platform_device s5pc100_device_spi1;
-extern struct platform_device s5pc100_device_spi2;
-extern struct platform_device s5pv210_device_spi0;
-extern struct platform_device s5pv210_device_spi1;
-extern struct platform_device s5p64x0_device_spi0;
-extern struct platform_device s5p64x0_device_spi1;
-
-extern struct platform_device s3c_device_hwmon;
-
-extern struct platform_device s3c_device_nand;
-extern struct platform_device s3c_device_onenand;
-extern struct platform_device s3c64xx_device_onenand1;
-extern struct platform_device s5p_device_onenand;
-
+extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_timer[];
 extern struct platform_device s3c_device_usbgadget;
-extern struct platform_device s3c_device_usb_hsudc;
 extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s3c_device_usb_hsudc;
+extern struct platform_device s3c_device_wdt;
 
-extern struct platform_device s5pv210_device_ac97;
-extern struct platform_device s5pv210_device_pcm0;
-extern struct platform_device s5pv210_device_pcm1;
-extern struct platform_device s5pv210_device_pcm2;
-extern struct platform_device s5pv210_device_iis0;
-extern struct platform_device s5pv210_device_iis1;
-extern struct platform_device s5pv210_device_iis2;
-extern struct platform_device s5pv210_device_spdif;
-
-extern struct platform_device exynos4_device_ac97;
-extern struct platform_device exynos4_device_pcm0;
-extern struct platform_device exynos4_device_pcm1;
-extern struct platform_device exynos4_device_pcm2;
-extern struct platform_device exynos4_device_i2s0;
-extern struct platform_device exynos4_device_i2s1;
-extern struct platform_device exynos4_device_i2s2;
-extern struct platform_device exynos4_device_spdif;
-extern struct platform_device exynos4_device_pd[];
-extern struct platform_device exynos4_device_ahci;
-extern struct platform_device exynos4_device_dwmci;
+extern struct platform_device s5p_device_ehci;
+extern struct platform_device s5p_device_fimc0;
+extern struct platform_device s5p_device_fimc1;
+extern struct platform_device s5p_device_fimc2;
+extern struct platform_device s5p_device_fimc3;
+extern struct platform_device s5p_device_fimc_md;
+extern struct platform_device s5p_device_fimd0;
+extern struct platform_device s5p_device_hdmi;
+extern struct platform_device s5p_device_i2c_hdmiphy;
+extern struct platform_device s5p_device_mfc;
+extern struct platform_device s5p_device_mfc_l;
+extern struct platform_device s5p_device_mfc_r;
+extern struct platform_device s5p_device_mipi_csis0;
+extern struct platform_device s5p_device_mipi_csis1;
+extern struct platform_device s5p_device_mixer;
+extern struct platform_device s5p_device_onenand;
+extern struct platform_device s5p_device_sdo;
 
-extern struct platform_device s5p6440_device_pcm;
 extern struct platform_device s5p6440_device_iis;
+extern struct platform_device s5p6440_device_pcm;
 
 extern struct platform_device s5p6450_device_iis0;
 extern struct platform_device s5p6450_device_iis1;
 extern struct platform_device s5p6450_device_iis2;
 extern struct platform_device s5p6450_device_pcm0;
 
+extern struct platform_device s5p64x0_device_spi0;
+extern struct platform_device s5p64x0_device_spi1;
+
 extern struct platform_device s5pc100_device_ac97;
-extern struct platform_device s5pc100_device_pcm0;
-extern struct platform_device s5pc100_device_pcm1;
 extern struct platform_device s5pc100_device_iis0;
 extern struct platform_device s5pc100_device_iis1;
 extern struct platform_device s5pc100_device_iis2;
+extern struct platform_device s5pc100_device_pcm0;
+extern struct platform_device s5pc100_device_pcm1;
 extern struct platform_device s5pc100_device_spdif;
+extern struct platform_device s5pc100_device_spi0;
+extern struct platform_device s5pc100_device_spi1;
+extern struct platform_device s5pc100_device_spi2;
 
-extern struct platform_device samsung_device_keypad;
-
-extern struct platform_device s5p_device_fimc0;
-extern struct platform_device s5p_device_fimc1;
-extern struct platform_device s5p_device_fimc2;
-extern struct platform_device s5p_device_fimc3;
-
-extern struct platform_device s5p_device_mfc;
-extern struct platform_device s5p_device_mfc_l;
-extern struct platform_device s5p_device_mfc_r;
-extern struct platform_device s5p_device_mipi_csis0;
-extern struct platform_device s5p_device_mipi_csis1;
-
-extern struct platform_device s5p_device_ehci;
+extern struct platform_device s5pv210_device_ac97;
+extern struct platform_device s5pv210_device_iis0;
+extern struct platform_device s5pv210_device_iis1;
+extern struct platform_device s5pv210_device_iis2;
+extern struct platform_device s5pv210_device_pcm0;
+extern struct platform_device s5pv210_device_pcm1;
+extern struct platform_device s5pv210_device_pcm2;
+extern struct platform_device s5pv210_device_spdif;
+extern struct platform_device s5pv210_device_spi0;
+extern struct platform_device s5pv210_device_spi1;
 
+extern struct platform_device exynos4_device_ac97;
+extern struct platform_device exynos4_device_ahci;
+extern struct platform_device exynos4_device_dwmci;
+extern struct platform_device exynos4_device_i2s0;
+extern struct platform_device exynos4_device_i2s1;
+extern struct platform_device exynos4_device_i2s2;
+extern struct platform_device exynos4_device_pcm0;
+extern struct platform_device exynos4_device_pcm1;
+extern struct platform_device exynos4_device_pcm2;
+extern struct platform_device exynos4_device_pd[];
+extern struct platform_device exynos4_device_spdif;
 extern struct platform_device exynos4_device_sysmmu;
 
+extern struct platform_device samsung_asoc_dma;
+extern struct platform_device samsung_asoc_idma;
+extern struct platform_device samsung_device_keypad;
+
 /* s3c2440 specific devices */
 
 #ifdef CONFIG_CPU_S3C2440
diff --git a/arch/arm/plat-samsung/include/plat/ehci.h b/arch/arm/plat-samsung/include/plat/ehci.h
new file mode 100644 (file)
index 0000000..5f28cae
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_SAMSUNG_EHCI_H
+#define __PLAT_SAMSUNG_EHCI_H __FILE__
+
+struct s5p_ehci_platdata {
+       int (*phy_init)(struct platform_device *pdev, int type);
+       int (*phy_exit)(struct platform_device *pdev, int type);
+};
+
+extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+
+#endif /* __PLAT_SAMSUNG_EHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/exynos4.h b/arch/arm/plat-samsung/include/plat/exynos4.h
new file mode 100644 (file)
index 0000000..f546e88
--- /dev/null
@@ -0,0 +1,35 @@
+/* linux/arch/arm/plat-samsung/include/plat/exynos4.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for exynos4 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for EXYNOS4 related SoCs */
+
+extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void exynos4_register_clocks(void);
+extern void exynos4210_register_clocks(void);
+extern void exynos4212_register_clocks(void);
+extern void exynos4_setup_clocks(void);
+
+#ifdef CONFIG_ARCH_EXYNOS
+extern  int exynos_init(void);
+extern void exynos4_init_irq(void);
+extern void exynos4_map_io(void);
+extern void exynos4_init_clocks(int xtal);
+extern struct sys_timer exynos4_timer;
+
+#define exynos4_init_uarts exynos4_common_init_uarts
+
+#else
+#define exynos4_init_clocks NULL
+#define exynos4_init_uarts NULL
+#define exynos4_map_io NULL
+#define exynos_init NULL
+#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 (file)
index 0000000..4e5d958
--- /dev/null
@@ -0,0 +1,72 @@
+/* arch/arm/plat-samsung/include/plat/fb-s3c2410.h
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Inspired by pxafb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_FB_S3C2410_H
+#define __ASM_PLAT_FB_S3C2410_H __FILE__
+
+struct s3c2410fb_hw {
+       unsigned long   lcdcon1;
+       unsigned long   lcdcon2;
+       unsigned long   lcdcon3;
+       unsigned long   lcdcon4;
+       unsigned long   lcdcon5;
+};
+
+/* LCD description */
+struct s3c2410fb_display {
+       /* LCD type */
+       unsigned type;
+
+       /* Screen size */
+       unsigned short width;
+       unsigned short height;
+
+       /* Screen info */
+       unsigned short xres;
+       unsigned short yres;
+       unsigned short bpp;
+
+       unsigned pixclock;              /* pixclock in picoseconds */
+       unsigned short left_margin;  /* value in pixels (TFT) or HCLKs (STN) */
+       unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
+       unsigned short hsync_len;    /* value in pixels (TFT) or HCLKs (STN) */
+       unsigned short upper_margin;    /* value in lines (TFT) or 0 (STN) */
+       unsigned short lower_margin;    /* value in lines (TFT) or 0 (STN) */
+       unsigned short vsync_len;       /* value in lines (TFT) or 0 (STN) */
+
+       /* lcd configuration registers */
+       unsigned long   lcdcon5;
+};
+
+struct s3c2410fb_mach_info {
+
+       struct s3c2410fb_display *displays;     /* attached diplays info */
+       unsigned num_displays;                  /* number of defined displays */
+       unsigned default_display;
+
+       /* GPIOs */
+
+       unsigned long   gpcup;
+       unsigned long   gpcup_mask;
+       unsigned long   gpccon;
+       unsigned long   gpccon_mask;
+       unsigned long   gpdup;
+       unsigned long   gpdup_mask;
+       unsigned long   gpdcon;
+       unsigned long   gpdcon_mask;
+
+       /* lpc3600 control register */
+       unsigned long   lpcsel;
+};
+
+extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
+
+#endif /* __ASM_PLAT_FB_S3C2410_H */
index 01f10e4d00c71e5f799140bffbeaba650b212592..0fedf47fa502482a117dc9427d5067d11d8e3a3d 100644 (file)
@@ -109,4 +109,11 @@ extern void s5pv210_fb_gpio_setup_24bpp(void);
  */
 extern void exynos4_fimd0_gpio_setup_24bpp(void);
 
+/**
+ * s5p64x0_fb_gpio_setup_24bpp() - S5P6440/S5P6450 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5p64x0_fb_gpio_setup_24bpp(void);
+
 #endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-samsung/include/plat/fiq.h b/arch/arm/plat-samsung/include/plat/fiq.h
new file mode 100644 (file)
index 0000000..535d06a
--- /dev/null
@@ -0,0 +1,13 @@
+/* linux/arch/arm/plat-samsung/include/plat/fiq.h
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU FIQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern int s3c24xx_set_fiq(unsigned int irq, bool on);
index 9a4e53d5296747b35411b85ae8f5ae572fb4ea9a..a181d7ce81cff4f1bb560d919da8da31141864f3 100644 (file)
@@ -1,11 +1,11 @@
-/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
+/* linux/arch/arm/plat-samsung/include/plat/gpio-cfg-helper.h
  *
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *     http://armlinux.simtec.co.uk/
  *     Ben Dooks <ben@simtec.co.uk>
  *
- * S3C Platform - GPIO pin configuration helper definitions
+ * Samsung Platform - GPIO pin configuration helper definitions
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * by disabling interrupts.
 */
 
-static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
-                                    unsigned int off, unsigned int config)
+static inline int samsung_gpio_do_setcfg(struct samsung_gpio_chip *chip,
+                                        unsigned int off, unsigned int config)
 {
        return (chip->config->set_config)(chip, off, config);
 }
 
-static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
-                                         unsigned int off)
+static inline unsigned samsung_gpio_do_getcfg(struct samsung_gpio_chip *chip,
+                                             unsigned int off)
 {
        return (chip->config->get_config)(chip, off);
 }
 
-static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
-                                     unsigned int off, s3c_gpio_pull_t pull)
+static inline int samsung_gpio_do_setpull(struct samsung_gpio_chip *chip,
+                                         unsigned int off, samsung_gpio_pull_t pull)
 {
        return (chip->config->set_pull)(chip, off, pull);
 }
 
-static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
-                                                 unsigned int off)
+static inline samsung_gpio_pull_t samsung_gpio_do_getpull(struct samsung_gpio_chip *chip,
+                                                         unsigned int off)
 {
        return chip->config->get_pull(chip, off);
 }
 
-/**
- * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has two bits of configuration per gpio, which have the following
- * functions:
- *     00 = input
- *     01 = output
- *     1x = special function
-*/
-extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
-                                  unsigned int off, unsigned int cfg);
-
-/**
- * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
- * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
- * S3C_GPIO_SPECIAL() macro.
- */
-unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
-                                    unsigned int off);
-
-/**
- * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register
- * has one bit of configuration for the gpio, where setting the bit
- * means the pin is in special function mode and unset means output.
-*/
-extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
-                                    unsigned int off, unsigned int cfg);
-
-
-/**
- * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
- * GPIO configuration value.
- *
- * @sa s3c_gpio_getcfg_s3c24xx
- * @sa s3c_gpio_getcfg_s3c64xx_4bit
- */
-extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
-                                         unsigned int off);
-
-/**
- * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- * @cfg: The configuration value to set.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- *     0000 = Input
- *     0001 = Output
- *     others = Special functions (dependent on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a separate set of functions for
- * each case.
-*/
-extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-                                       unsigned int off, unsigned int cfg);
-
-
-/**
- * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
- * @chip: The gpio chip that is being configured.
- * @off: The offset for the GPIO being configured.
- *
- * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
- * register setting into a value the software can use, such as could be passed
- * to s3c_gpio_setcfg_s3c64xx_4bit().
- *
- * @sa s3c_gpio_getcfg_s3c24xx
- */
-extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
-                                            unsigned int off);
-
 /* Pull-{up,down} resistor controls.
  *
  * S3C2410,S3C2440 = Pull-UP,
@@ -147,7 +57,7 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
  */
 
 /**
- * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
+ * s3c24xx_gpio_setpull_1up() - Pull configuration for choice of up or none.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
  * @param: pull: The pull mode being requested.
@@ -155,11 +65,11 @@ extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
  * This is a helper function for the case where we have GPIOs with one
  * bit configuring the presence of a pull-up resistor.
  */
-extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
-                               unsigned int off, s3c_gpio_pull_t pull);
+extern int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
+                                   unsigned int off, samsung_gpio_pull_t pull);
 
 /**
- * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
+ * s3c24xx_gpio_setpull_1down() - Pull configuration for choice of down or none
  * @chip: The gpio chip that is being configured
  * @off: The offset for the GPIO being configured
  * @param: pull: The pull mode being requested
@@ -167,11 +77,13 @@ extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
  * This is a helper function for the case where we have GPIOs with one
  * bit configuring the presence of a pull-down resistor.
  */
-extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
-                                 unsigned int off, s3c_gpio_pull_t pull);
+extern int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
+                                     unsigned int off, samsung_gpio_pull_t pull);
 
 /**
- * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
+ * samsung_gpio_setpull_upown() - Pull configuration for choice of up,
+ * down or none
+ *
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
  * @param: pull: The pull mode being requested.
@@ -183,45 +95,46 @@ extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
  *     01 = Pull-up resistor connected
  *     10 = Pull-down resistor connected
  */
-extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
-                                  unsigned int off, s3c_gpio_pull_t pull);
-
+extern int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
+                                      unsigned int off, samsung_gpio_pull_t pull);
 
 /**
- * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
+ * samsung_gpio_getpull_updown() - Get configuration for choice of up,
+ * down or none
+ *
  * @chip: The gpio chip that the GPIO pin belongs to
  * @off: The offset to the pin to get the configuration of.
  *
- * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
+ * This helper function reads the state of the pull-{up,down} resistor
+ * for the given GPIO in the same case as samsung_gpio_setpull_upown.
 */
-extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
-                                              unsigned int off);
+extern samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
+                                                      unsigned int off);
 
 /**
- * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
+ * s3c24xx_gpio_getpull_1up() - Get configuration for choice of up or none
  * @chip: The gpio chip that the GPIO pin belongs to
  * @off: The offset to the pin to get the configuration of.
  *
  * This helper function reads the state of the pull-up resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_1up.
+ * given GPIO in the same case as s3c24xx_gpio_setpull_1up.
 */
-extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
-                                           unsigned int off);
+extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
+                                                   unsigned int off);
 
 /**
- * s3c_gpio_getpull_1down() - Get configuration for choice of down or none
+ * s3c24xx_gpio_getpull_1down() - Get configuration for choice of down or none
  * @chip: The gpio chip that the GPIO pin belongs to
  * @off: The offset to the pin to get the configuration of.
  *
  * This helper function reads the state of the pull-down resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_1down.
+ * given GPIO in the same case as s3c24xx_gpio_setpull_1down.
 */
-extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
-                                           unsigned int off);
+extern samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
+                                                     unsigned int off);
 
 /**
- * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
+ * s3c2443_gpio_setpull() - Pull configuration for s3c2443.
  * @chip: The gpio chip that is being configured.
  * @off: The offset for the GPIO being configured.
  * @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,
  *     10 = Pull-down resistor connected
  *     x1 = No pull up resistor
  */
-extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
-                                   unsigned int off, s3c_gpio_pull_t pull);
+extern int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
+                               unsigned int off, samsung_gpio_pull_t pull);
 
 /**
- * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
+ * s3c2443_gpio_getpull() - Get configuration for s3c2443 pull resistors
  * @chip: The gpio chip that the GPIO pin belongs to.
  * @off: The offset to the pin to get the configuration of.
  *
  * This helper function reads the state of the pull-{up,down} resistor for the
- * given GPIO in the same case as s3c_gpio_setpull_upown.
+ * given GPIO in the same case as samsung_gpio_setpull_upown.
 */
-extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
+extern samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
                                                unsigned int off);
 
 #endif /* __PLAT_GPIO_CFG_HELPERS_H */
-
index 1762dcb4cb9e96341c5d2a2c6d4181de1aade52d..df8155b9d4d19e550b881abf22df4dbbeab3315c 100644 (file)
 #ifndef __PLAT_GPIO_CFG_H
 #define __PLAT_GPIO_CFG_H __FILE__
 
-typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+#include<linux/types.h>
+
+typedef unsigned int __bitwise__ samsung_gpio_pull_t;
 typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
 
 /* forward declaration if gpio-core.h hasn't been included */
-struct s3c_gpio_chip;
+struct samsung_gpio_chip;
 
 /**
- * struct s3c_gpio_cfg GPIO configuration
+ * struct samsung_gpio_cfg GPIO configuration
  * @cfg_eint: Configuration setting when used for external interrupt source
  * @get_pull: Read the current pull configuration for the GPIO
  * @set_pull: Set the current pull configuraiton for the GPIO
@@ -44,20 +46,20 @@ struct s3c_gpio_chip;
  * per-bank configuration information that other systems such as the
  * external interrupt code will need.
  *
- * @sa s3c_gpio_cfgpin
+ * @sa samsung_gpio_cfgpin
  * @sa s3c_gpio_getcfg
  * @sa s3c_gpio_setpull
  * @sa s3c_gpio_getpull
  */
-struct s3c_gpio_cfg {
+struct samsung_gpio_cfg {
        unsigned int    cfg_eint;
 
-       s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
-       int             (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
-                                   s3c_gpio_pull_t pull);
+       samsung_gpio_pull_t     (*get_pull)(struct samsung_gpio_chip *chip, unsigned offs);
+       int             (*set_pull)(struct samsung_gpio_chip *chip, unsigned offs,
+                                   samsung_gpio_pull_t pull);
 
-       unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
-       int      (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
+       unsigned (*get_config)(struct samsung_gpio_chip *chip, unsigned offs);
+       int      (*set_config)(struct samsung_gpio_chip *chip, unsigned offs,
                               unsigned config);
 };
 
@@ -69,7 +71,7 @@ struct s3c_gpio_cfg {
 #define S3C_GPIO_OUTPUT        (S3C_GPIO_SPECIAL(1))
 #define S3C_GPIO_SFN(x)        (S3C_GPIO_SPECIAL(x))
 
-#define s3c_gpio_is_cfg_special(_cfg) \
+#define samsung_gpio_is_cfg_special(_cfg) \
        (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
 
 /**
@@ -128,9 +130,9 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
  * up or down settings, and it may be dependent on the chip that is being
  * used to whether the particular mode is available.
  */
-#define S3C_GPIO_PULL_NONE     ((__force s3c_gpio_pull_t)0x00)
-#define S3C_GPIO_PULL_DOWN     ((__force s3c_gpio_pull_t)0x01)
-#define S3C_GPIO_PULL_UP       ((__force s3c_gpio_pull_t)0x02)
+#define S3C_GPIO_PULL_NONE     ((__force samsung_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN     ((__force samsung_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP       ((__force samsung_gpio_pull_t)0x02)
 
 /**
  * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
@@ -143,7 +145,7 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
  *
  * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP.
 */
-extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
+extern int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull);
 
 /**
  * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
@@ -151,7 +153,7 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
  *
  * Read the pull resistor value for the specified pin.
 */
-extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
+extern samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
 
 /* configure `all` aspects of an gpio */
 
@@ -170,7 +172,7 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
  * @sa s3c_gpio_cfgpin_range
  */
 extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
-                                unsigned int cfg, s3c_gpio_pull_t pull);
+                                unsigned int cfg, samsung_gpio_pull_t pull);
 
 static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
                                           unsigned int cfg)
index 8cad4cf19c3c019bb81395ef2138359bad36e6d4..1fe6917f6a2a75e9f36cce7c28f46ef13228f113 100644 (file)
  * specific code.
 */
 
-struct s3c_gpio_chip;
+struct samsung_gpio_chip;
 
 /**
- * struct s3c_gpio_pm - power management (suspend/resume) information
+ * struct samsung_gpio_pm - power management (suspend/resume) information
  * @save: Routine to save the state of the GPIO block
  * @resume: Routine to resume the GPIO block.
  */
-struct s3c_gpio_pm {
-       void (*save)(struct s3c_gpio_chip *chip);
-       void (*resume)(struct s3c_gpio_chip *chip);
+struct samsung_gpio_pm {
+       void (*save)(struct samsung_gpio_chip *chip);
+       void (*resume)(struct samsung_gpio_chip *chip);
 };
 
-struct s3c_gpio_cfg;
+struct samsung_gpio_cfg;
 
 /**
- * struct s3c_gpio_chip - wrapper for specific implementation of gpio
+ * struct samsung_gpio_chip - wrapper for specific implementation of gpio
  * @chip: The chip structure to be exported via gpiolib.
  * @base: The base pointer to the gpio configuration registers.
  * @group: The group register number for gpio interrupt support.
@@ -60,10 +60,10 @@ struct s3c_gpio_cfg;
  * CPU cores trying to get one lock for different GPIO banks, where each
  * bank of GPIO has its own register space and configuration registers.
  */
-struct s3c_gpio_chip {
+struct samsung_gpio_chip {
        struct gpio_chip        chip;
-       struct s3c_gpio_cfg     *config;
-       struct s3c_gpio_pm      *pm;
+       struct samsung_gpio_cfg *config;
+       struct samsung_gpio_pm  *pm;
        void __iomem            *base;
        int                     irq_base;
        int                     group;
@@ -73,58 +73,11 @@ struct s3c_gpio_chip {
 #endif
 };
 
-static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
+static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
 {
-       return container_of(gpc, struct s3c_gpio_chip, chip);
+       return container_of(gpc, struct samsung_gpio_chip, chip);
 }
 
-/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
- * @chip: The chip to register
- *
- * This is a wrapper to gpiochip_add() that takes our specific gpio chip
- * information and makes the necessary alterations for the platform and
- * notes the information for use with the configuration systems and any
- * other parts of the system.
- */
-extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
-
-/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
- * for use with the configuration calls, and other parts of the s3c gpiolib
- * support code.
- *
- * Not all s3c support code will need this, as some configurations of cpu
- * may only support one or two different configuration options and have an
- * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
- * the machine support file should provide its own s3c_gpiolib_getchip()
- * and any other necessary functions.
- */
-
-/**
- * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
- * @chip: The gpio chip that is being configured.
- * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
- *
- * This helper deal with the GPIO cases where the control register has 4 bits
- * of control per GPIO, generally in the form of:
- * 0000 = Input
- * 0001 = Output
- * others = Special functions (dependent on bank)
- *
- * Note, since the code to deal with the case where there are two control
- * registers instead of one, we do not have a separate set of function
- * (samsung_gpiolib_add_4bit2_chips)for each case.
- */
-extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
-                                          int nr_chips);
-extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
-                                           int nr_chips);
-extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
-                                          int nr_chips);
-
-extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
-extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
-
-
 /**
  * samsung_gpiolib_to_irq - convert gpio pin to irq number
  * @chip: The gpio chip that the pin belongs to.
@@ -136,36 +89,36 @@ extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
 extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
 
 /* exported for core SoC support to change */
-extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+extern struct samsung_gpio_cfg s3c24xx_gpiocfg_default;
 
 #ifdef CONFIG_S3C_GPIO_TRACK
-extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
 
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip)
 {
        return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
 }
 #else
-/* machine specific code should provide s3c_gpiolib_getchip */
+/* machine specific code should provide samsung_gpiolib_getchip */
 
 #include <mach/gpio-track.h>
 
-static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
+static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { }
 #endif
 
 #ifdef CONFIG_PM
-extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
-extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
+extern struct samsung_gpio_pm samsung_gpio_pm_1bit;
+extern struct samsung_gpio_pm samsung_gpio_pm_2bit;
+extern struct samsung_gpio_pm samsung_gpio_pm_4bit;
 #define __gpio_pm(x) x
 #else
-#define s3c_gpio_pm_1bit NULL
-#define s3c_gpio_pm_2bit NULL
-#define s3c_gpio_pm_4bit NULL
+#define samsung_gpio_pm_1bit NULL
+#define samsung_gpio_pm_2bit NULL
+#define samsung_gpio_pm_4bit NULL
 #define __gpio_pm(x) NULL
 
 #endif /* CONFIG_PM */
 
 /* locking wrappers to deal with multiple access to the same gpio bank */
-#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
-#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
+#define samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#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 (file)
index 0000000..bab1392
--- /dev/null
@@ -0,0 +1,98 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+ *
+ * Copyright (c) 2003-2009 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - hardware
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_GPIO_FNS_H
+#define __MACH_GPIO_FNS_H __FILE__
+
+/* These functions are in the to-be-removed category and it is strongly
+ * encouraged not to use these in new code. They will be marked deprecated
+ * very soon.
+ *
+ * Most of the functionality can be either replaced by the gpiocfg calls
+ * for the s3c platform or by the generic GPIOlib API.
+ *
+ * As of 2.6.35-rc, these will be removed, with the few drivers using them
+ * either replaced or given a wrapper until the calls can be removed.
+*/
+
+#include <plat/gpio-cfg.h>
+
+static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
+{
+       /* 1:1 mapping between cfgpin and setcfg calls at the moment */
+       s3c_gpio_cfgpin(pin, cfg);
+}
+
+/* external functions for GPIO support
+ *
+ * These allow various different clients to access the same GPIO
+ * registers without conflicting. If your driver only owns the entire
+ * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
+*/
+
+extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
+
+/* s3c2410_gpio_getirq
+ *
+ * turn the given pin number into the corresponding IRQ number
+ *
+ * returns:
+ *     < 0 = no interrupt for this pin
+ *     >=0 = interrupt number for the pin
+*/
+
+extern int s3c2410_gpio_getirq(unsigned int pin);
+
+/* s3c2410_gpio_irqfilter
+ *
+ * set the irq filtering on the given pin
+ *
+ * on = 0 => disable filtering
+ *      1 => enable filtering
+ *
+ * config = S3C2410_EINTFLT_PCLK or S3C2410_EINTFLT_EXTCLK orred with
+ *          width of filter (0 through 63)
+ *
+ *
+*/
+
+extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+                                 unsigned int config);
+
+/* s3c2410_gpio_pullup
+ *
+ * This call should be replaced with s3c_gpio_setpull().
+ *
+ * As a note, there is currently no distinction between pull-up and pull-down
+ * in the s3c24xx series devices with only an on/off configuration.
+ */
+
+/* s3c2410_gpio_pullup
+ *
+ * configure the pull-up control on the given pin
+ *
+ * to = 1 => disable the pull-up
+ *      0 => enable the pull-up
+ *
+ * eg;
+ *
+ *   s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
+ *   s3c2410_gpio_pullup(S3C2410_GPE(8), 0);
+*/
+
+extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
+
+extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
+
+extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
+
+#endif /* __MACH_GPIO_FNS_H */
index 56b0059439e158edba132f10c15fdaa1fba14e1b..51d52e767a1955b52dc83e2510f1b5aec13ea1be 100644 (file)
@@ -60,6 +60,7 @@ extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
 extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
 extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
 extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *i2c);
 
 /* defined by architecture to configure gpio */
 extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/plat-samsung/include/plat/irq.h b/arch/arm/plat-samsung/include/plat/irq.h
new file mode 100644 (file)
index 0000000..e21a89b
--- /dev/null
@@ -0,0 +1,116 @@
+/* linux/arch/arm/plat-samsung/include/plat/irq.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+#define EXTINT_OFF (IRQ_EINT4 - 4)
+
+/* these are exported for arch/arm/mach-* usage */
+extern struct irq_chip s3c_irq_level_chip;
+extern struct irq_chip s3c_irq_chip;
+
+static inline void s3c_irqsub_mask(unsigned int irqno,
+                                  unsigned int parentbit,
+                                  int subcheck)
+{
+       unsigned long mask;
+       unsigned long submask;
+
+       submask = __raw_readl(S3C2410_INTSUBMSK);
+       mask = __raw_readl(S3C2410_INTMSK);
+
+       submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
+
+       /* check to see if we need to mask the parent IRQ */
+
+       if ((submask  & subcheck) == subcheck)
+               __raw_writel(mask | parentbit, S3C2410_INTMSK);
+
+       /* write back masks */
+       __raw_writel(submask, S3C2410_INTSUBMSK);
+
+}
+
+static inline void s3c_irqsub_unmask(unsigned int irqno,
+                                    unsigned int parentbit)
+{
+       unsigned long mask;
+       unsigned long submask;
+
+       submask = __raw_readl(S3C2410_INTSUBMSK);
+       mask = __raw_readl(S3C2410_INTMSK);
+
+       submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
+       mask &= ~parentbit;
+
+       /* write back masks */
+       __raw_writel(submask, S3C2410_INTSUBMSK);
+       __raw_writel(mask, S3C2410_INTMSK);
+}
+
+
+static inline void s3c_irqsub_maskack(unsigned int irqno,
+                                     unsigned int parentmask,
+                                     unsigned int group)
+{
+       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+       s3c_irqsub_mask(irqno, parentmask, group);
+
+       __raw_writel(bit, S3C2410_SUBSRCPND);
+
+       /* only ack parent if we've got all the irqs (seems we must
+        * ack, all and hope that the irq system retriggers ok when
+        * the interrupt goes off again)
+        */
+
+       if (1) {
+               __raw_writel(parentmask, S3C2410_SRCPND);
+               __raw_writel(parentmask, S3C2410_INTPND);
+       }
+}
+
+static inline void s3c_irqsub_ack(unsigned int irqno,
+                                 unsigned int parentmask,
+                                 unsigned int group)
+{
+       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+       __raw_writel(bit, S3C2410_SUBSRCPND);
+
+       /* only ack parent if we've got all the irqs (seems we must
+        * ack, all and hope that the irq system retriggers ok when
+        * the interrupt goes off again)
+        */
+
+       if (1) {
+               __raw_writel(parentmask, S3C2410_SRCPND);
+               __raw_writel(parentmask, S3C2410_INTPND);
+       }
+}
+
+/* exported for use in arch/arm/mach-s3c2410 */
+
+#ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
+#else
+#define s3c_irq_wake NULL
+#endif
+
+extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
new file mode 100644 (file)
index 0000000..08d1a7e
--- /dev/null
@@ -0,0 +1,80 @@
+/* linux/arch/arm/plat-samsung/include/plat/irqs.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P Common IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_IRQS_H
+#define __PLAT_SAMSUNG_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S5P_IRQ_OFFSET         (32)
+
+#define S5P_IRQ(x)             ((x) + S5P_IRQ_OFFSET)
+
+#define S5P_VIC0_BASE          S5P_IRQ(0)
+#define S5P_VIC1_BASE          S5P_IRQ(32)
+#define S5P_VIC2_BASE          S5P_IRQ(64)
+#define S5P_VIC3_BASE          S5P_IRQ(96)
+
+#define VIC_BASE(x)            (S5P_VIC0_BASE + ((x)*32))
+
+#define IRQ_VIC0_BASE          S5P_VIC0_BASE
+#define IRQ_VIC1_BASE          S5P_VIC1_BASE
+#define IRQ_VIC2_BASE          S5P_VIC2_BASE
+
+/* VIC based IRQs */
+
+#define S5P_IRQ_VIC0(x)                (S5P_VIC0_BASE + (x))
+#define S5P_IRQ_VIC1(x)                (S5P_VIC1_BASE + (x))
+#define S5P_IRQ_VIC2(x)                (S5P_VIC2_BASE + (x))
+#define S5P_IRQ_VIC3(x)                (S5P_VIC3_BASE + (x))
+
+#define S5P_TIMER_IRQ(x)       (11 + (x))
+
+#define IRQ_TIMER0             S5P_TIMER_IRQ(0)
+#define IRQ_TIMER1             S5P_TIMER_IRQ(1)
+#define IRQ_TIMER2             S5P_TIMER_IRQ(2)
+#define IRQ_TIMER3             S5P_TIMER_IRQ(3)
+#define IRQ_TIMER4             S5P_TIMER_IRQ(4)
+
+#define IRQ_EINT(x)            ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
+                                       : ((x) - 16 + S5P_EINT_BASE2))
+
+#define EINT_OFFSET(irq)       ((irq) < S5P_EINT_BASE2 ? \
+                                               ((irq) - S5P_EINT_BASE1) : \
+                                               ((irq) + 16 - S5P_EINT_BASE2))
+
+#define IRQ_EINT_BIT(x)                EINT_OFFSET(x)
+
+/* Typically only a few gpio chips require gpio interrupt support.
+   To avoid memory waste irq descriptors are allocated only for
+   S5P_GPIOINT_GROUP_COUNT chips, each with total number of
+   S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
+   to any gpio chip with the s5p_register_gpio_interrupt() function */
+#define S5P_GPIOINT_GROUP_COUNT 4
+#define S5P_GPIOINT_GROUP_SIZE 8
+#define S5P_GPIOINT_COUNT      (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
+
+/* IRQ types common for all s5p platforms */
+#define S5P_IRQ_TYPE_LEVEL_LOW         (0x00)
+#define S5P_IRQ_TYPE_LEVEL_HIGH                (0x01)
+#define S5P_IRQ_TYPE_EDGE_FALLING      (0x02)
+#define S5P_IRQ_TYPE_EDGE_RISING       (0x03)
+#define S5P_IRQ_TYPE_EDGE_BOTH         (0x04)
+
+#endif /* __PLAT_SAMSUNG_IRQS_H */
diff --git a/arch/arm/plat-samsung/include/plat/mci.h b/arch/arm/plat-samsung/include/plat/mci.h
new file mode 100644 (file)
index 0000000..c42d317
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _ARCH_MCI_H
+#define _ARCH_MCI_H
+
+/**
+ * struct s3c24xx_mci_pdata - sd/mmc controller platform data
+ * @no_wprotect: Set this to indicate there is no write-protect switch.
+ * @no_detect: Set this if there is no detect switch.
+ * @wprotect_invert: Invert the default sense of the write protect switch.
+ * @detect_invert: Invert the default sense of the write protect switch.
+ * @use_dma: Set to allow the use of DMA.
+ * @gpio_detect: GPIO number for the card detect line.
+ * @gpio_wprotect: GPIO number for the write protect line.
+ * @ocr_avail: The mask of the available power states, non-zero to use.
+ * @set_power: Callback to control the power mode.
+ *
+ * The @gpio_detect is used for card detection when @no_wprotect is unset,
+ * and the default sense is that 0 returned from gpio_get_value() means
+ * that a card is inserted. If @detect_invert is set, then the value from
+ * gpio_get_value() is inverted, which makes 1 mean card inserted.
+ *
+ * The driver will use @gpio_wprotect to signal whether the card is write
+ * protected if @no_wprotect is not set. A 0 returned from gpio_get_value()
+ * means the card is read/write, and 1 means read-only. The @wprotect_invert
+ * will invert the value returned from gpio_get_value().
+ *
+ * Card power is set by @ocr_availa, using MCC_VDD_ constants if it is set
+ * to a non-zero value, otherwise the default of 3.2-3.4V is used.
+ */
+struct s3c24xx_mci_pdata {
+       unsigned int    no_wprotect:1;
+       unsigned int    no_detect:1;
+       unsigned int    wprotect_invert:1;
+       unsigned int    detect_invert:1;        /* set => detect active high */
+       unsigned int    use_dma:1;
+
+       unsigned int    gpio_detect;
+       unsigned int    gpio_wprotect;
+       unsigned long   ocr_avail;
+       void            (*set_power)(unsigned char power_mode,
+                                    unsigned short vdd);
+};
+
+/**
+ * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device
+ * @pdata: The platform data
+ *
+ * Copy the platform data supplied by @pdata so that this can be marked
+ * __initdata.
+ */
+extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata);
+
+#endif /* _ARCH_NCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/mfc.h b/arch/arm/plat-samsung/include/plat/mfc.h
new file mode 100644 (file)
index 0000000..ac13227
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_SAMSUNG_MFC_H
+#define __PLAT_SAMSUNG_MFC_H __FILE__
+
+/**
+ * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
+ * @rbase:     base address for MFC 'right' memory interface
+ * @rsize:     size of the memory reserved for MFC 'right' interface
+ * @lbase:     base address for MFC 'left' memory interface
+ * @lsize:     size of the memory reserved for MFC 'left' interface
+ *
+ * This function reserves system memory for both MFC device memory
+ * interfaces and registers it to respective struct device entries as
+ * coherent memory.
+ */
+void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
+                               phys_addr_t lbase, unsigned int lsize);
+
+#endif /* __PLAT_SAMSUNG_MFC_H */
diff --git a/arch/arm/plat-samsung/include/plat/mipi_csis.h b/arch/arm/plat-samsung/include/plat/mipi_csis.h
new file mode 100644 (file)
index 0000000..c45b1e8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series MIPI CSI slave device support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_SAMSUNG_MIPI_CSIS_H_
+#define __PLAT_SAMSUNG_MIPI_CSIS_H_ __FILE__
+
+struct platform_device;
+
+/**
+ * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver
+ * @clk_rate: bus clock frequency
+ * @lanes: number of data lanes used
+ * @alignment: data alignment in bits
+ * @hs_settle: HS-RX settle time
+ * @fixed_phy_vdd: false to enable external D-PHY regulator management in the
+ *                driver or true in case this regulator has no enable function
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct s5p_platform_mipi_csis {
+       unsigned long clk_rate;
+       u8 lanes;
+       u8 alignment;
+       u8 hs_settle;
+       bool fixed_phy_vdd;
+       int (*phy_enable)(struct platform_device *pdev, bool on);
+};
+
+/**
+ * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
+ * @pdev: MIPI-CSIS platform device
+ * @on: true to enable D-PHY and deassert its reset
+ *     false to disable D-PHY
+ */
+int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
+
+#endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/pll.h b/arch/arm/plat-samsung/include/plat/pll.h
new file mode 100644 (file)
index 0000000..357af7c
--- /dev/null
@@ -0,0 +1,323 @@
+/* linux/arch/arm/plat-samsung/include/plat/pll.h
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Samsung PLL codes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <asm/div64.h>
+
+#define S3C24XX_PLL_MDIV_MASK          (0xFF)
+#define S3C24XX_PLL_PDIV_MASK          (0x1F)
+#define S3C24XX_PLL_SDIV_MASK          (0x3)
+#define S3C24XX_PLL_MDIV_SHIFT         (12)
+#define S3C24XX_PLL_PDIV_SHIFT         (4)
+#define S3C24XX_PLL_SDIV_SHIFT         (0)
+
+static inline unsigned int s3c24xx_get_pll(unsigned int pllval,
+                                          unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = (pllval >> S3C24XX_PLL_MDIV_SHIFT) & S3C24XX_PLL_MDIV_MASK;
+       pdiv = (pllval >> S3C24XX_PLL_PDIV_SHIFT) & S3C24XX_PLL_PDIV_MASK;
+       sdiv = (pllval >> S3C24XX_PLL_SDIV_SHIFT) & S3C24XX_PLL_SDIV_MASK;
+
+       fvco = (uint64_t)baseclk * (mdiv + 8);
+       do_div(fvco, (pdiv + 2) << sdiv);
+
+       return (unsigned int)fvco;
+}
+
+#define S3C2416_PLL_MDIV_MASK          (0x3FF)
+#define S3C2416_PLL_PDIV_MASK          (0x3F)
+#define S3C2416_PLL_SDIV_MASK          (0x7)
+#define S3C2416_PLL_MDIV_SHIFT         (14)
+#define S3C2416_PLL_PDIV_SHIFT         (5)
+#define S3C2416_PLL_SDIV_SHIFT         (0)
+
+static inline unsigned int s3c2416_get_pll(unsigned int pllval,
+                                          unsigned int baseclk)
+{
+       unsigned int mdiv, pdiv, sdiv;
+       uint64_t fvco;
+
+       mdiv = (pllval >> S3C2416_PLL_MDIV_SHIFT) & S3C2416_PLL_MDIV_MASK;
+       pdiv = (pllval >> S3C2416_PLL_PDIV_SHIFT) & S3C2416_PLL_PDIV_MASK;
+       sdiv = (pllval >> S3C2416_PLL_SDIV_SHIFT) & S3C2416_PLL_SDIV_MASK;
+
+       fvco = (uint64_t)baseclk * mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned int)fvco;
+}
+
+#define S3C6400_PLL_MDIV_MASK          (0x3FF)
+#define S3C6400_PLL_PDIV_MASK          (0x3F)
+#define S3C6400_PLL_SDIV_MASK          (0x7)
+#define S3C6400_PLL_MDIV_SHIFT         (16)
+#define S3C6400_PLL_PDIV_SHIFT         (8)
+#define S3C6400_PLL_SDIV_SHIFT         (0)
+
+static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
+                                           u32 pllcon)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
+       pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
+       sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
+
+#define PLL6553X_MDIV_MASK     (0x7F)
+#define PLL6553X_PDIV_MASK     (0x1F)
+#define PLL6553X_SDIV_MASK     (0x3)
+#define PLL6553X_KDIV_MASK     (0xFFFF)
+#define PLL6553X_MDIV_SHIFT    (16)
+#define PLL6553X_PDIV_SHIFT    (8)
+#define PLL6553X_SDIV_SHIFT    (0)
+
+static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
+                                            u32 pll_con0, u32 pll_con1)
+{
+       unsigned long result;
+       u32 mdiv, pdiv, sdiv, kdiv;
+       u64 tmp;
+
+       mdiv = (pll_con0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+       kdiv = pll_con1 & PLL6553X_KDIV_MASK;
+
+       /*
+        * We need to multiple baseclk by mdiv (the integer part) and kdiv
+        * which is in 2^16ths, so shift mdiv up (does not overflow) and
+        * add kdiv before multiplying. The use of tmp is to avoid any
+        * overflows before shifting bac down into result when multipling
+        * by the mdiv and kdiv pair.
+        */
+
+       tmp = baseclk;
+       tmp *= (mdiv << 16) + kdiv;
+       do_div(tmp, (pdiv << sdiv));
+       result = tmp >> 16;
+
+       return result;
+}
+
+#define PLL35XX_MDIV_MASK      (0x3FF)
+#define PLL35XX_PDIV_MASK      (0x3F)
+#define PLL35XX_SDIV_MASK      (0x7)
+#define PLL35XX_MDIV_SHIFT     (16)
+#define PLL35XX_PDIV_SHIFT     (8)
+#define PLL35XX_SDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
+
+#define PLL36XX_KDIV_MASK      (0xFFFF)
+#define PLL36XX_MDIV_MASK      (0x1FF)
+#define PLL36XX_PDIV_MASK      (0x3F)
+#define PLL36XX_SDIV_MASK      (0x7)
+#define PLL36XX_MDIV_SHIFT     (16)
+#define PLL36XX_PDIV_SHIFT     (8)
+#define PLL36XX_SDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
+                                           u32 pll_con0, u32 pll_con1)
+{
+       unsigned long result;
+       u32 mdiv, pdiv, sdiv, kdiv;
+       u64 tmp;
+
+       mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+       kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+       tmp = baseclk;
+
+       tmp *= (mdiv << 16) + kdiv;
+       do_div(tmp, (pdiv << sdiv));
+       result = tmp >> 16;
+
+       return result;
+}
+
+#define PLL45XX_MDIV_MASK      (0x3FF)
+#define PLL45XX_PDIV_MASK      (0x3F)
+#define PLL45XX_SDIV_MASK      (0x7)
+#define PLL45XX_MDIV_SHIFT     (16)
+#define PLL45XX_PDIV_SHIFT     (8)
+#define PLL45XX_SDIV_SHIFT     (0)
+
+enum pll45xx_type_t {
+       pll_4500,
+       pll_4502,
+       pll_4508
+};
+
+static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+                                           enum pll45xx_type_t pll_type)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+       if (pll_type == pll_4508)
+               sdiv = sdiv - 1;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
+
+/* CON0 bit-fields */
+#define PLL46XX_MDIV_MASK      (0x1FF)
+#define PLL46XX_PDIV_MASK      (0x3F)
+#define PLL46XX_SDIV_MASK      (0x7)
+#define PLL46XX_LOCKED_SHIFT   (29)
+#define PLL46XX_MDIV_SHIFT     (16)
+#define PLL46XX_PDIV_SHIFT     (8)
+#define PLL46XX_SDIV_SHIFT     (0)
+
+/* CON1 bit-fields */
+#define PLL46XX_MRR_MASK       (0x1F)
+#define PLL46XX_MFR_MASK       (0x3F)
+#define PLL46XX_KDIV_MASK      (0xFFFF)
+#define PLL4650C_KDIV_MASK     (0xFFF)
+#define PLL46XX_MRR_SHIFT      (24)
+#define PLL46XX_MFR_SHIFT      (16)
+#define PLL46XX_KDIV_SHIFT     (0)
+
+enum pll46xx_type_t {
+       pll_4600,
+       pll_4650,
+       pll_4650c,
+};
+
+static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
+                                           u32 pll_con0, u32 pll_con1,
+                                           enum pll46xx_type_t pll_type)
+{
+       unsigned long result;
+       u32 mdiv, pdiv, sdiv, kdiv;
+       u64 tmp;
+
+       mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+       kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
+       if (pll_type == pll_4650c)
+               kdiv = pll_con1 & PLL4650C_KDIV_MASK;
+       else
+               kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
+       tmp = baseclk;
+
+       if (pll_type == pll_4600) {
+               tmp *= (mdiv << 16) + kdiv;
+               do_div(tmp, (pdiv << sdiv));
+               result = tmp >> 16;
+       } else {
+               tmp *= (mdiv << 10) + kdiv;
+               do_div(tmp, (pdiv << sdiv));
+               result = tmp >> 10;
+       }
+
+       return result;
+}
+
+#define PLL90XX_MDIV_MASK      (0xFF)
+#define PLL90XX_PDIV_MASK      (0x3F)
+#define PLL90XX_SDIV_MASK      (0x7)
+#define PLL90XX_KDIV_MASK      (0xffff)
+#define PLL90XX_LOCKED_SHIFT   (29)
+#define PLL90XX_MDIV_SHIFT     (16)
+#define PLL90XX_PDIV_SHIFT     (8)
+#define PLL90XX_SDIV_SHIFT     (0)
+#define PLL90XX_KDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
+                                           u32 pll_con, u32 pll_conk)
+{
+       unsigned long result;
+       u32 mdiv, pdiv, sdiv, kdiv;
+       u64 tmp;
+
+       mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
+       kdiv = pll_conk & PLL90XX_KDIV_MASK;
+
+       /*
+        * We need to multiple baseclk by mdiv (the integer part) and kdiv
+        * which is in 2^16ths, so shift mdiv up (does not overflow) and
+        * add kdiv before multiplying. The use of tmp is to avoid any
+        * overflows before shifting bac down into result when multipling
+        * by the mdiv and kdiv pair.
+        */
+
+       tmp = baseclk;
+       tmp *= (mdiv << 16) + kdiv;
+       do_div(tmp, (pdiv << sdiv));
+       result = tmp >> 16;
+
+       return result;
+}
+
+#define PLL65XX_MDIV_MASK      (0x3FF)
+#define PLL65XX_PDIV_MASK      (0x3F)
+#define PLL65XX_SDIV_MASK      (0x7)
+#define PLL65XX_MDIV_SHIFT     (16)
+#define PLL65XX_PDIV_SHIFT     (8)
+#define PLL65XX_SDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
deleted file mode 100644 (file)
index b8b7e1d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/pll6553x.h
- *     partially from arch/arm/mach-s3c64xx/include/mach/pll.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *     http://armlinux.simtec.co.uk/
- *
- * Samsung PLL6553x PLL code
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
-
-#define PLL6553X_MDIV_MASK     ((1 << (23-16)) - 1)
-#define PLL6553X_PDIV_MASK     ((1 << (13-8)) - 1)
-#define PLL6553X_SDIV_MASK     ((1 << (2-0)) - 1)
-#define PLL6553X_MDIV_SHIFT    (16)
-#define PLL6553X_PDIV_SHIFT    (8)
-#define PLL6553X_SDIV_SHIFT    (0)
-#define PLL6553X_KDIV_MASK     (0xffff)
-
-static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
-                                            u32 pll0, u32 pll1)
-{
-       unsigned long result;
-       u32 mdiv, pdiv, sdiv, kdiv;
-       u64 tmp;
-
-       mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
-       pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
-       sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
-       kdiv = pll1 & PLL6553X_KDIV_MASK;
-
-       /* We need to multiple baseclk by mdiv (the integer part) and kdiv
-        * which is in 2^16ths, so shift mdiv up (does not overflow) and
-        * add kdiv before multiplying. The use of tmp is to avoid any
-        * overflows before shifting bac down into result when multipling
-        * by the mdiv and kdiv pair.
-        */
-
-       tmp = baseclk;
-       tmp *= (mdiv << 16) + kdiv;
-       do_div(tmp, (pdiv << sdiv));
-       result = tmp >> 16;
-
-       return result;
-}
index f6749916d194b8d1e2a2e0a59cc35ccfa44ded16..dcf68709f9cff7f0f73986638e6643cf35c8fad0 100644 (file)
@@ -165,20 +165,20 @@ extern void s3c_pm_check_store(void);
 extern void s3c_pm_configure_extint(void);
 
 /**
- * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ * samsung_pm_restore_gpios() - restore the state of the gpios after sleep.
  *
  * Restore the state of the GPIO pins after sleep, which may involve ensuring
  * that we do not glitch the state of the pins from that the bootloader's
  * resume code has done.
 */
-extern void s3c_pm_restore_gpios(void);
+extern void samsung_pm_restore_gpios(void);
 
 /**
- * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ * samsung_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
  *
- * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios().
  */
-extern void s3c_pm_save_gpios(void);
+extern void samsung_pm_save_gpios(void);
 
 extern void s3c_pm_save_core(void);
 extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-samsung/include/plat/pwm-clock.h b/arch/arm/plat-samsung/include/plat/pwm-clock.h
new file mode 100644 (file)
index 0000000..bf6a60e
--- /dev/null
@@ -0,0 +1,81 @@
+/* linux/arch/arm/plat-samsung/include/plat/pwm-clock.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * SAMSUNG - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_PWM_CLOCK_H
+#define __ASM_PLAT_PWM_CLOCK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+       if (soc_is_s3c24xx())
+               return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       else if (soc_is_s3c64xx() || soc_is_s5pc100())
+               return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
+       else if (soc_is_s5p6440() || soc_is_s5p6450())
+               return 0;
+       else
+               return tcfg == S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+       if (soc_is_s3c24xx())
+               return 1 << (tcfg1 + 1);
+       else
+               return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+       if (soc_is_s3c24xx())
+               return 0;
+       else
+               return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+       if (soc_is_s3c24xx())
+               return ilog2(div) - 1;
+       else
+               return ilog2(div);
+}
+#endif /* __ASM_PLAT_PWM_CLOCK_H */
index 035e8c38d69cc31cce19c06e7ca1205ecd5ba674..70612100120fb0b0694dbd872f983d9bad55d492 100644 (file)
@@ -20,6 +20,7 @@
 #define S3C2410_ADCDAT0           S3C2410_ADCREG(0x0C)
 #define S3C2410_ADCDAT1           S3C2410_ADCREG(0x10)
 #define S3C64XX_ADCUPDN                S3C2410_ADCREG(0x14)
+#define S3C2443_ADCMUX         S3C2410_ADCREG(0x18)
 #define S3C64XX_ADCCLRINT      S3C2410_ADCREG(0x18)
 #define S5P_ADCMUX             S3C2410_ADCREG(0x1C)
 #define S3C64XX_ADCCLRINTPNDNUP        S3C2410_ADCREG(0x20)
@@ -33,6 +34,7 @@
 #define S3C2410_ADCCON_PRSCVLMASK      (0xFF<<6)
 #define S3C2410_ADCCON_SELMUX(x)       (((x)&0x7)<<3)
 #define S3C2410_ADCCON_MUXMASK         (0x7<<3)
+#define S3C2416_ADCCON_RESSEL          (1 << 3)
 #define S3C2410_ADCCON_STDBM           (1<<2)
 #define S3C2410_ADCCON_READ_START      (1<<1)
 #define S3C2410_ADCCON_ENABLE_START    (1<<0)
@@ -40,6 +42,7 @@
 
 
 /* ADCTSC Register Bits */
+#define S3C2443_ADCTSC_UD_SEN          (1 << 8)
 #define S3C2410_ADCTSC_YM_SEN          (1<<7)
 #define S3C2410_ADCTSC_YP_SEN          (1<<6)
 #define S3C2410_ADCTSC_XM_SEN          (1<<5)
diff --git a/arch/arm/plat-samsung/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h
new file mode 100644 (file)
index 0000000..178bccb
--- /dev/null
@@ -0,0 +1,151 @@
+/* arch/arm/plat-samsung/include/plat/regs-dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_DMA_H
+#define __ASM_PLAT_REGS_DMA_H __FILE__
+
+#define S3C2410_DMA_DISRC              (0x00)
+#define S3C2410_DMA_DISRCC             (0x04)
+#define S3C2410_DMA_DIDST              (0x08)
+#define S3C2410_DMA_DIDSTC             (0x0C)
+#define S3C2410_DMA_DCON               (0x10)
+#define S3C2410_DMA_DSTAT              (0x14)
+#define S3C2410_DMA_DCSRC              (0x18)
+#define S3C2410_DMA_DCDST              (0x1C)
+#define S3C2410_DMA_DMASKTRIG          (0x20)
+#define S3C2412_DMA_DMAREQSEL          (0x24)
+#define S3C2443_DMA_DMAREQSEL          (0x24)
+
+#define S3C2410_DISRCC_INC             (1 << 0)
+#define S3C2410_DISRCC_APB             (1 << 1)
+
+#define S3C2410_DMASKTRIG_STOP         (1 << 2)
+#define S3C2410_DMASKTRIG_ON           (1 << 1)
+#define S3C2410_DMASKTRIG_SWTRIG       (1 << 0)
+
+#define S3C2410_DCON_DEMAND            (0 << 31)
+#define S3C2410_DCON_HANDSHAKE         (1 << 31)
+#define S3C2410_DCON_SYNC_PCLK         (0 << 30)
+#define S3C2410_DCON_SYNC_HCLK         (1 << 30)
+
+#define S3C2410_DCON_INTREQ            (1 << 29)
+
+#define S3C2410_DCON_CH0_XDREQ0                (0 << 24)
+#define S3C2410_DCON_CH0_UART0         (1 << 24)
+#define S3C2410_DCON_CH0_SDI           (2 << 24)
+#define S3C2410_DCON_CH0_TIMER         (3 << 24)
+#define S3C2410_DCON_CH0_USBEP1                (4 << 24)
+
+#define S3C2410_DCON_CH1_XDREQ1                (0 << 24)
+#define S3C2410_DCON_CH1_UART1         (1 << 24)
+#define S3C2410_DCON_CH1_I2SSDI                (2 << 24)
+#define S3C2410_DCON_CH1_SPI           (3 << 24)
+#define S3C2410_DCON_CH1_USBEP2                (4 << 24)
+
+#define S3C2410_DCON_CH2_I2SSDO                (0 << 24)
+#define S3C2410_DCON_CH2_I2SSDI                (1 << 24)
+#define S3C2410_DCON_CH2_SDI           (2 << 24)
+#define S3C2410_DCON_CH2_TIMER         (3 << 24)
+#define S3C2410_DCON_CH2_USBEP3                (4 << 24)
+
+#define S3C2410_DCON_CH3_UART2         (0 << 24)
+#define S3C2410_DCON_CH3_SDI           (1 << 24)
+#define S3C2410_DCON_CH3_SPI           (2 << 24)
+#define S3C2410_DCON_CH3_TIMER         (3 << 24)
+#define S3C2410_DCON_CH3_USBEP4                (4 << 24)
+
+#define S3C2410_DCON_SRCSHIFT          (24)
+#define S3C2410_DCON_SRCMASK           (7 << 24)
+
+#define S3C2410_DCON_BYTE              (0 << 20)
+#define S3C2410_DCON_HALFWORD          (1 << 20)
+#define S3C2410_DCON_WORD              (2 << 20)
+
+#define S3C2410_DCON_AUTORELOAD                (0 << 22)
+#define S3C2410_DCON_NORELOAD          (1 << 22)
+#define S3C2410_DCON_HWTRIG            (1 << 23)
+
+#ifdef CONFIG_CPU_S3C2440
+
+#define S3C2440_DIDSTC_CHKINT          (1 << 2)
+
+#define S3C2440_DCON_CH0_I2SSDO                (5 << 24)
+#define S3C2440_DCON_CH0_PCMIN         (6 << 24)
+
+#define S3C2440_DCON_CH1_PCMOUT                (5 << 24)
+#define S3C2440_DCON_CH1_SDI           (6 << 24)
+
+#define S3C2440_DCON_CH2_PCMIN         (5 << 24)
+#define S3C2440_DCON_CH2_MICIN         (6 << 24)
+
+#define S3C2440_DCON_CH3_MICIN         (5 << 24)
+#define S3C2440_DCON_CH3_PCMOUT                (6 << 24)
+#endif /* CONFIG_CPU_S3C2440 */
+
+#ifdef CONFIG_CPU_S3C2412
+
+#define S3C2412_DMAREQSEL_SRC(x)       ((x) << 1)
+
+#define S3C2412_DMAREQSEL_HW           (1)
+
+#define S3C2412_DMAREQSEL_SPI0TX       S3C2412_DMAREQSEL_SRC(0)
+#define S3C2412_DMAREQSEL_SPI0RX       S3C2412_DMAREQSEL_SRC(1)
+#define S3C2412_DMAREQSEL_SPI1TX       S3C2412_DMAREQSEL_SRC(2)
+#define S3C2412_DMAREQSEL_SPI1RX       S3C2412_DMAREQSEL_SRC(3)
+#define S3C2412_DMAREQSEL_I2STX                S3C2412_DMAREQSEL_SRC(4)
+#define S3C2412_DMAREQSEL_I2SRX                S3C2412_DMAREQSEL_SRC(5)
+#define S3C2412_DMAREQSEL_TIMER                S3C2412_DMAREQSEL_SRC(9)
+#define S3C2412_DMAREQSEL_SDI          S3C2412_DMAREQSEL_SRC(10)
+#define S3C2412_DMAREQSEL_USBEP1       S3C2412_DMAREQSEL_SRC(13)
+#define S3C2412_DMAREQSEL_USBEP2       S3C2412_DMAREQSEL_SRC(14)
+#define S3C2412_DMAREQSEL_USBEP3       S3C2412_DMAREQSEL_SRC(15)
+#define S3C2412_DMAREQSEL_USBEP4       S3C2412_DMAREQSEL_SRC(16)
+#define S3C2412_DMAREQSEL_XDREQ0       S3C2412_DMAREQSEL_SRC(17)
+#define S3C2412_DMAREQSEL_XDREQ1       S3C2412_DMAREQSEL_SRC(18)
+#define S3C2412_DMAREQSEL_UART0_0      S3C2412_DMAREQSEL_SRC(19)
+#define S3C2412_DMAREQSEL_UART0_1      S3C2412_DMAREQSEL_SRC(20)
+#define S3C2412_DMAREQSEL_UART1_0      S3C2412_DMAREQSEL_SRC(21)
+#define S3C2412_DMAREQSEL_UART1_1      S3C2412_DMAREQSEL_SRC(22)
+#define S3C2412_DMAREQSEL_UART2_0      S3C2412_DMAREQSEL_SRC(23)
+#define S3C2412_DMAREQSEL_UART2_1      S3C2412_DMAREQSEL_SRC(24)
+#endif /* CONFIG_CPU_S3C2412 */
+
+#ifdef CONFIG_CPU_S3C2443
+
+#define S3C2443_DMAREQSEL_SRC(x)       ((x) << 1)
+
+#define S3C2443_DMAREQSEL_HW           (1)
+
+#define S3C2443_DMAREQSEL_SPI0TX       S3C2443_DMAREQSEL_SRC(0)
+#define S3C2443_DMAREQSEL_SPI0RX       S3C2443_DMAREQSEL_SRC(1)
+#define S3C2443_DMAREQSEL_SPI1TX       S3C2443_DMAREQSEL_SRC(2)
+#define S3C2443_DMAREQSEL_SPI1RX       S3C2443_DMAREQSEL_SRC(3)
+#define S3C2443_DMAREQSEL_I2STX                S3C2443_DMAREQSEL_SRC(4)
+#define S3C2443_DMAREQSEL_I2SRX                S3C2443_DMAREQSEL_SRC(5)
+#define S3C2443_DMAREQSEL_TIMER                S3C2443_DMAREQSEL_SRC(9)
+#define S3C2443_DMAREQSEL_SDI          S3C2443_DMAREQSEL_SRC(10)
+#define S3C2443_DMAREQSEL_XDREQ0       S3C2443_DMAREQSEL_SRC(17)
+#define S3C2443_DMAREQSEL_XDREQ1       S3C2443_DMAREQSEL_SRC(18)
+#define S3C2443_DMAREQSEL_UART0_0      S3C2443_DMAREQSEL_SRC(19)
+#define S3C2443_DMAREQSEL_UART0_1      S3C2443_DMAREQSEL_SRC(20)
+#define S3C2443_DMAREQSEL_UART1_0      S3C2443_DMAREQSEL_SRC(21)
+#define S3C2443_DMAREQSEL_UART1_1      S3C2443_DMAREQSEL_SRC(22)
+#define S3C2443_DMAREQSEL_UART2_0      S3C2443_DMAREQSEL_SRC(23)
+#define S3C2443_DMAREQSEL_UART2_1      S3C2443_DMAREQSEL_SRC(24)
+#define S3C2443_DMAREQSEL_UART3_0      S3C2443_DMAREQSEL_SRC(25)
+#define S3C2443_DMAREQSEL_UART3_1      S3C2443_DMAREQSEL_SRC(26)
+#define S3C2443_DMAREQSEL_PCMOUT       S3C2443_DMAREQSEL_SRC(27)
+#define S3C2443_DMAREQSEL_PCMIN                S3C2443_DMAREQSEL_SRC(28)
+#define S3C2443_DMAREQSEL_MICIN                S3C2443_DMAREQSEL_SRC(29)
+#endif /* CONFIG_CPU_S3C2443 */
+
+#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 (file)
index 0000000..a18d35e
--- /dev/null
@@ -0,0 +1,70 @@
+/* arch/arm/plat-samsung/include/plat/regs-iis.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ *                   http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_IIS_H
+#define __ASM_ARCH_REGS_IIS_H
+
+#define S3C2410_IISCON                 (0x00)
+
+#define S3C2410_IISCON_LRINDEX         (1 << 8)
+#define S3C2410_IISCON_TXFIFORDY       (1 << 7)
+#define S3C2410_IISCON_RXFIFORDY       (1 << 6)
+#define S3C2410_IISCON_TXDMAEN         (1 << 5)
+#define S3C2410_IISCON_RXDMAEN         (1 << 4)
+#define S3C2410_IISCON_TXIDLE          (1 << 3)
+#define S3C2410_IISCON_RXIDLE          (1 << 2)
+#define S3C2410_IISCON_PSCEN           (1 << 1)
+#define S3C2410_IISCON_IISEN           (1 << 0)
+
+#define S3C2410_IISMOD                 (0x04)
+
+#define S3C2440_IISMOD_MPLL            (1 << 9)
+#define S3C2410_IISMOD_SLAVE           (1 << 8)
+#define S3C2410_IISMOD_NOXFER          (0 << 6)
+#define S3C2410_IISMOD_RXMODE          (1 << 6)
+#define S3C2410_IISMOD_TXMODE          (2 << 6)
+#define S3C2410_IISMOD_TXRXMODE                (3 << 6)
+#define S3C2410_IISMOD_LR_LLOW         (0 << 5)
+#define S3C2410_IISMOD_LR_RLOW         (1 << 5)
+#define S3C2410_IISMOD_IIS             (0 << 4)
+#define S3C2410_IISMOD_MSB             (1 << 4)
+#define S3C2410_IISMOD_8BIT            (0 << 3)
+#define S3C2410_IISMOD_16BIT           (1 << 3)
+#define S3C2410_IISMOD_BITMASK         (1 << 3)
+#define S3C2410_IISMOD_256FS           (0 << 2)
+#define S3C2410_IISMOD_384FS           (1 << 2)
+#define S3C2410_IISMOD_16FS            (0 << 0)
+#define S3C2410_IISMOD_32FS            (1 << 0)
+#define S3C2410_IISMOD_48FS            (2 << 0)
+#define S3C2410_IISMOD_FS_MASK         (3 << 0)
+
+#define S3C2410_IISPSR                 (0x08)
+
+#define S3C2410_IISPSR_INTMASK         (31 << 5)
+#define S3C2410_IISPSR_INTSHIFT                (5)
+#define S3C2410_IISPSR_EXTMASK         (31 << 0)
+#define S3C2410_IISPSR_EXTSHFIT                (0)
+
+#define S3C2410_IISFCON                        (0x0c)
+
+#define S3C2410_IISFCON_TXDMA          (1 << 15)
+#define S3C2410_IISFCON_RXDMA          (1 << 14)
+#define S3C2410_IISFCON_TXENABLE       (1 << 13)
+#define S3C2410_IISFCON_RXENABLE       (1 << 12)
+#define S3C2410_IISFCON_TXMASK         (0x3f << 6)
+#define S3C2410_IISFCON_TXSHIFT                (6)
+#define S3C2410_IISFCON_RXMASK         (0x3f)
+#define S3C2410_IISFCON_RXSHIFT                (0)
+
+#define S3C2410_IISFIFO                        (0x10)
+
+#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 (file)
index 0000000..552fe7c
--- /dev/null
@@ -0,0 +1,48 @@
+/* arch/arm/plat-samsung/include/plat/regs-spi.h
+ *
+ * Copyright (c) 2004 Fetron GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 SPI register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_SPI_H
+#define __ASM_ARCH_REGS_SPI_H
+
+#define S3C2410_SPI1           (0x20)
+#define S3C2412_SPI1           (0x100)
+
+#define S3C2410_SPCON          (0x00)
+
+#define S3C2410_SPCON_SMOD_DMA (2 << 5)        /* DMA mode */
+#define S3C2410_SPCON_SMOD_INT (1 << 5)        /* interrupt mode */
+#define S3C2410_SPCON_SMOD_POLL        (0 << 5)        /* polling mode */
+#define S3C2410_SPCON_ENSCK    (1 << 4)        /* Enable SCK */
+#define S3C2410_SPCON_MSTR     (1 << 3)        /* Master:1, Slave:0 select */
+#define S3C2410_SPCON_CPOL_HIGH        (1 << 2)        /* Clock polarity select */
+#define S3C2410_SPCON_CPOL_LOW (0 << 2)        /* Clock polarity select */
+
+#define S3C2410_SPCON_CPHA_FMTB        (1 << 1)        /* Clock Phase Select */
+#define S3C2410_SPCON_CPHA_FMTA        (0 << 1)        /* Clock Phase Select */
+
+#define S3C2410_SPSTA          (0x04)
+
+#define S3C2410_SPSTA_DCOL     (1 << 2)        /* Data Collision Error */
+#define S3C2410_SPSTA_MULD     (1 << 1)        /* Multi Master Error */
+#define S3C2410_SPSTA_READY    (1 << 0)        /* Data Tx/Rx ready */
+#define S3C2412_SPSTA_READY_ORG        (1 << 3)
+
+#define S3C2410_SPPIN          (0x08)
+
+#define S3C2410_SPPIN_ENMUL    (1 << 2)        /* Multi Master Error detect */
+#define S3C2410_SPPIN_RESERVED (1 << 1)
+#define S3C2410_SPPIN_KEEP     (1 << 0)        /* Master Out keep */
+
+#define S3C2410_SPPRE          (0x0C)
+#define S3C2410_SPTDAT         (0x10)
+#define S3C2410_SPRDAT         (0x14)
+
+#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-srom.h b/arch/arm/plat-samsung/include/plat/regs-srom.h
new file mode 100644 (file)
index 0000000..9b6729c
--- /dev/null
@@ -0,0 +1,54 @@
+/* linux/arch/arm/plat-samsung/include/plat/regs-srom.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P SROMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_REGS_SROM_H
+#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_SROMREG(x)         (S5P_VA_SROMC + (x))
+
+#define S5P_SROM_BW            S5P_SROMREG(0x0)
+#define S5P_SROM_BC0           S5P_SROMREG(0x4)
+#define S5P_SROM_BC1           S5P_SROMREG(0x8)
+#define S5P_SROM_BC2           S5P_SROMREG(0xc)
+#define S5P_SROM_BC3           S5P_SROMREG(0x10)
+#define S5P_SROM_BC4           S5P_SROMREG(0x14)
+#define S5P_SROM_BC5           S5P_SROMREG(0x18)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define S5P_SROM_BW__DATAWIDTH__SHIFT          0
+#define S5P_SROM_BW__ADDRMODE__SHIFT           1
+#define S5P_SROM_BW__WAITENABLE__SHIFT         2
+#define S5P_SROM_BW__BYTEENABLE__SHIFT         3
+
+#define S5P_SROM_BW__CS_MASK                   0xf
+
+#define S5P_SROM_BW__NCS0__SHIFT               0
+#define S5P_SROM_BW__NCS1__SHIFT               4
+#define S5P_SROM_BW__NCS2__SHIFT               8
+#define S5P_SROM_BW__NCS3__SHIFT               12
+#define S5P_SROM_BW__NCS4__SHIFT               16
+#define S5P_SROM_BW__NCS5__SHIFT               20
+
+/* applies to same to BCS0 - BCS3 */
+
+#define S5P_SROM_BCX__PMC__SHIFT               0
+#define S5P_SROM_BCX__TACP__SHIFT              4
+#define S5P_SROM_BCX__TCAH__SHIFT              8
+#define S5P_SROM_BCX__TCOH__SHIFT              12
+#define S5P_SROM_BCX__TACC__SHIFT              16
+#define S5P_SROM_BCX__TCOS__SHIFT              24
+#define S5P_SROM_BCX__TACS__SHIFT              28
+
+#endif /* __PLAT_SAMSUNG_REGS_SROM_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-udc.h b/arch/arm/plat-samsung/include/plat/regs-udc.h
new file mode 100644 (file)
index 0000000..4003d3d
--- /dev/null
@@ -0,0 +1,151 @@
+/* arch/arm/plat-samsung/include/plat/regs-udc.h
+ *
+ * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
+ *
+ * This include file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+*/
+
+#ifndef __ASM_ARCH_REGS_UDC_H
+#define __ASM_ARCH_REGS_UDC_H
+
+#define S3C2410_USBDREG(x) (x)
+
+#define S3C2410_UDC_FUNC_ADDR_REG      S3C2410_USBDREG(0x0140)
+#define S3C2410_UDC_PWR_REG            S3C2410_USBDREG(0x0144)
+#define S3C2410_UDC_EP_INT_REG         S3C2410_USBDREG(0x0148)
+
+#define S3C2410_UDC_USB_INT_REG                S3C2410_USBDREG(0x0158)
+#define S3C2410_UDC_EP_INT_EN_REG      S3C2410_USBDREG(0x015c)
+
+#define S3C2410_UDC_USB_INT_EN_REG     S3C2410_USBDREG(0x016c)
+
+#define S3C2410_UDC_FRAME_NUM1_REG     S3C2410_USBDREG(0x0170)
+#define S3C2410_UDC_FRAME_NUM2_REG     S3C2410_USBDREG(0x0174)
+
+#define S3C2410_UDC_EP0_FIFO_REG       S3C2410_USBDREG(0x01c0)
+#define S3C2410_UDC_EP1_FIFO_REG       S3C2410_USBDREG(0x01c4)
+#define S3C2410_UDC_EP2_FIFO_REG       S3C2410_USBDREG(0x01c8)
+#define S3C2410_UDC_EP3_FIFO_REG       S3C2410_USBDREG(0x01cc)
+#define S3C2410_UDC_EP4_FIFO_REG       S3C2410_USBDREG(0x01d0)
+
+#define S3C2410_UDC_EP1_DMA_CON                S3C2410_USBDREG(0x0200)
+#define S3C2410_UDC_EP1_DMA_UNIT       S3C2410_USBDREG(0x0204)
+#define S3C2410_UDC_EP1_DMA_FIFO       S3C2410_USBDREG(0x0208)
+#define S3C2410_UDC_EP1_DMA_TTC_L      S3C2410_USBDREG(0x020c)
+#define S3C2410_UDC_EP1_DMA_TTC_M      S3C2410_USBDREG(0x0210)
+#define S3C2410_UDC_EP1_DMA_TTC_H      S3C2410_USBDREG(0x0214)
+
+#define S3C2410_UDC_EP2_DMA_CON                S3C2410_USBDREG(0x0218)
+#define S3C2410_UDC_EP2_DMA_UNIT       S3C2410_USBDREG(0x021c)
+#define S3C2410_UDC_EP2_DMA_FIFO       S3C2410_USBDREG(0x0220)
+#define S3C2410_UDC_EP2_DMA_TTC_L      S3C2410_USBDREG(0x0224)
+#define S3C2410_UDC_EP2_DMA_TTC_M      S3C2410_USBDREG(0x0228)
+#define S3C2410_UDC_EP2_DMA_TTC_H      S3C2410_USBDREG(0x022c)
+
+#define S3C2410_UDC_EP3_DMA_CON                S3C2410_USBDREG(0x0240)
+#define S3C2410_UDC_EP3_DMA_UNIT       S3C2410_USBDREG(0x0244)
+#define S3C2410_UDC_EP3_DMA_FIFO       S3C2410_USBDREG(0x0248)
+#define S3C2410_UDC_EP3_DMA_TTC_L      S3C2410_USBDREG(0x024c)
+#define S3C2410_UDC_EP3_DMA_TTC_M      S3C2410_USBDREG(0x0250)
+#define S3C2410_UDC_EP3_DMA_TTC_H      S3C2410_USBDREG(0x0254)
+
+#define S3C2410_UDC_EP4_DMA_CON                S3C2410_USBDREG(0x0258)
+#define S3C2410_UDC_EP4_DMA_UNIT       S3C2410_USBDREG(0x025c)
+#define S3C2410_UDC_EP4_DMA_FIFO       S3C2410_USBDREG(0x0260)
+#define S3C2410_UDC_EP4_DMA_TTC_L      S3C2410_USBDREG(0x0264)
+#define S3C2410_UDC_EP4_DMA_TTC_M      S3C2410_USBDREG(0x0268)
+#define S3C2410_UDC_EP4_DMA_TTC_H      S3C2410_USBDREG(0x026c)
+
+#define S3C2410_UDC_INDEX_REG          S3C2410_USBDREG(0x0178)
+
+/* indexed registers */
+
+#define S3C2410_UDC_MAXP_REG           S3C2410_USBDREG(0x0180)
+
+#define S3C2410_UDC_EP0_CSR_REG                S3C2410_USBDREG(0x0184)
+
+#define S3C2410_UDC_IN_CSR1_REG                S3C2410_USBDREG(0x0184)
+#define S3C2410_UDC_IN_CSR2_REG                S3C2410_USBDREG(0x0188)
+
+#define S3C2410_UDC_OUT_CSR1_REG       S3C2410_USBDREG(0x0190)
+#define S3C2410_UDC_OUT_CSR2_REG       S3C2410_USBDREG(0x0194)
+#define S3C2410_UDC_OUT_FIFO_CNT1_REG  S3C2410_USBDREG(0x0198)
+#define S3C2410_UDC_OUT_FIFO_CNT2_REG  S3C2410_USBDREG(0x019c)
+
+#define S3C2410_UDC_FUNCADDR_UPDATE    (1 << 7)
+
+#define S3C2410_UDC_PWR_ISOUP          (1 << 7) /* R/W */
+#define S3C2410_UDC_PWR_RESET          (1 << 3) /* R   */
+#define S3C2410_UDC_PWR_RESUME         (1 << 2) /* R/W */
+#define S3C2410_UDC_PWR_SUSPEND                (1 << 1) /* R   */
+#define S3C2410_UDC_PWR_ENSUSPEND      (1 << 0) /* R/W */
+
+#define S3C2410_UDC_PWR_DEFAULT                (0x00)
+
+#define S3C2410_UDC_INT_EP4            (1 << 4) /* R/W (clear only) */
+#define S3C2410_UDC_INT_EP3            (1 << 3) /* R/W (clear only) */
+#define S3C2410_UDC_INT_EP2            (1 << 2) /* R/W (clear only) */
+#define S3C2410_UDC_INT_EP1            (1 << 1) /* R/W (clear only) */
+#define S3C2410_UDC_INT_EP0            (1 << 0) /* R/W (clear only) */
+
+#define S3C2410_UDC_USBINT_RESET       (1 << 2) /* R/W (clear only) */
+#define S3C2410_UDC_USBINT_RESUME      (1 << 1) /* R/W (clear only) */
+#define S3C2410_UDC_USBINT_SUSPEND     (1 << 0) /* R/W (clear only) */
+
+#define S3C2410_UDC_INTE_EP4           (1 << 4) /* R/W */
+#define S3C2410_UDC_INTE_EP3           (1 << 3) /* R/W */
+#define S3C2410_UDC_INTE_EP2           (1 << 2) /* R/W */
+#define S3C2410_UDC_INTE_EP1           (1 << 1) /* R/W */
+#define S3C2410_UDC_INTE_EP0           (1 << 0) /* R/W */
+
+#define S3C2410_UDC_USBINTE_RESET      (1 << 2) /* R/W */
+#define S3C2410_UDC_USBINTE_SUSPEND    (1 << 0) /* R/W */
+
+#define S3C2410_UDC_INDEX_EP0          (0x00)
+#define S3C2410_UDC_INDEX_EP1          (0x01)
+#define S3C2410_UDC_INDEX_EP2          (0x02)
+#define S3C2410_UDC_INDEX_EP3          (0x03)
+#define S3C2410_UDC_INDEX_EP4          (0x04)
+
+#define S3C2410_UDC_ICSR1_CLRDT                (1 << 6) /* R/W */
+#define S3C2410_UDC_ICSR1_SENTSTL      (1 << 5) /* R/W (clear only) */
+#define S3C2410_UDC_ICSR1_SENDSTL      (1 << 4) /* R/W */
+#define S3C2410_UDC_ICSR1_FFLUSH       (1 << 3) /* W   (set only) */
+#define S3C2410_UDC_ICSR1_UNDRUN       (1 << 2) /* R/W (clear only) */
+#define S3C2410_UDC_ICSR1_PKTRDY       (1 << 0) /* R/W (set only) */
+
+#define S3C2410_UDC_ICSR2_AUTOSET      (1 << 7) /* R/W */
+#define S3C2410_UDC_ICSR2_ISO          (1 << 6) /* R/W */
+#define S3C2410_UDC_ICSR2_MODEIN       (1 << 5) /* R/W */
+#define S3C2410_UDC_ICSR2_DMAIEN       (1 << 4) /* R/W */
+
+#define S3C2410_UDC_OCSR1_CLRDT                (1 << 7) /* R/W */
+#define S3C2410_UDC_OCSR1_SENTSTL      (1 << 6) /* R/W (clear only) */
+#define S3C2410_UDC_OCSR1_SENDSTL      (1 << 5) /* R/W */
+#define S3C2410_UDC_OCSR1_FFLUSH       (1 << 4) /* R/W */
+#define S3C2410_UDC_OCSR1_DERROR       (1 << 3) /* R   */
+#define S3C2410_UDC_OCSR1_OVRRUN       (1 << 2) /* R/W (clear only) */
+#define S3C2410_UDC_OCSR1_PKTRDY       (1 << 0) /* R/W (clear only) */
+
+#define S3C2410_UDC_OCSR2_AUTOCLR      (1 << 7) /* R/W */
+#define S3C2410_UDC_OCSR2_ISO          (1 << 6) /* R/W */
+#define S3C2410_UDC_OCSR2_DMAIEN       (1 << 5) /* R/W */
+
+#define S3C2410_UDC_EP0_CSR_OPKRDY     (1 << 0)
+#define S3C2410_UDC_EP0_CSR_IPKRDY     (1 << 1)
+#define S3C2410_UDC_EP0_CSR_SENTSTL    (1 << 2)
+#define S3C2410_UDC_EP0_CSR_DE         (1 << 3)
+#define S3C2410_UDC_EP0_CSR_SE         (1 << 4)
+#define S3C2410_UDC_EP0_CSR_SENDSTL    (1 << 5)
+#define S3C2410_UDC_EP0_CSR_SOPKTRDY   (1 << 6)
+#define S3C2410_UDC_EP0_CSR_SSE                (1 << 7)
+
+#define S3C2410_UDC_MAXP_8             (1 << 0)
+#define S3C2410_UDC_MAXP_16            (1 << 1)
+#define S3C2410_UDC_MAXP_32            (1 << 2)
+#define S3C2410_UDC_MAXP_64            (1 << 3)
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/reset.h b/arch/arm/plat-samsung/include/plat/reset.h
new file mode 100644 (file)
index 0000000..32ca517
--- /dev/null
@@ -0,0 +1,16 @@
+/* linux/arch/arm/plat-samsung/include/plat/reset.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_RESET_H
+#define __PLAT_SAMSUNG_RESET_H __FILE__
+
+extern void (*s5p_reset_hook)(void);
+
+#endif /* __PLAT_SAMSUNG_RESET_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h
new file mode 100644 (file)
index 0000000..3986497
--- /dev/null
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c2410.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 machine directory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#ifdef CONFIG_CPU_S3C2410
+
+extern  int s3c2410_init(void);
+extern  int s3c2410a_init(void);
+
+extern void s3c2410_map_io(void);
+
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2410_init_clocks(int xtal);
+
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#define s3c2410a_init NULL
+#endif
+
+extern int s3c2410_baseclk_add(void);
diff --git a/arch/arm/plat-samsung/include/plat/s3c2412.h b/arch/arm/plat-samsung/include/plat/s3c2412.h
new file mode 100644 (file)
index 0000000..5bcfd14
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c2412.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2412 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2412
+
+extern  int s3c2412_init(void);
+
+extern void s3c2412_map_io(void);
+
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2412_init_clocks(int xtal);
+
+extern  int s3c2412_baseclk_add(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
new file mode 100644 (file)
index 0000000..a764f85
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+ *
+ * Header file for s3c2416 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2416
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2416_init(void);
+
+extern void s3c2416_map_io(void);
+
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2416_init_clocks(int xtal);
+
+extern  int s3c2416_baseclk_add(void);
+
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h
new file mode 100644 (file)
index 0000000..7fae1a0
--- /dev/null
@@ -0,0 +1,52 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c2443.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2443 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C2443
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2443_init(void);
+
+extern void s3c2443_map_io(void);
+
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2443_init_clocks(int xtal);
+
+extern  int s3c2443_baseclk_add(void);
+
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
+
+/* common code used by s3c2443 and others.
+ * note, not to be used outside of arch/arm/mach-s3c* */
+
+struct clk;    /* some files don't need clk.h otherwise */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+                                      unsigned int *divs, int nr_divs,
+                                      int divmask);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
+
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-samsung/include/plat/s3c244x.h b/arch/arm/plat-samsung/include/plat/s3c244x.h
new file mode 100644 (file)
index 0000000..ea0c961
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c244x.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(void);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern  int s3c2440_init(void);
+
+extern void s3c2440_map_io(void);
+#else
+#define s3c2440_init NULL
+#define s3c2440_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern  int s3c2442_init(void);
+
+extern void s3c2442_map_io(void);
+#else
+#define s3c2442_init NULL
+#define s3c2442_map_io NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c6400.h b/arch/arm/plat-samsung/include/plat/s3c6400.h
new file mode 100644 (file)
index 0000000..37d428a
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c6400.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6400 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S3C6400 related SoCs */
+
+extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c6400_setup_clocks(void);
+
+extern void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern  int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+extern void s3c6400_init_clocks(int xtal);
+
+#define s3c6400_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6400_init_clocks NULL
+#define s3c6400_init_uarts NULL
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c6410.h b/arch/arm/plat-samsung/include/plat/s3c6410.h
new file mode 100644 (file)
index 0000000..20a6675
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c6410.h
+ *
+ * Copyright 2008 Openmoko,  Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6410 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern  int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+extern void s3c6410_init_clocks(int xtal);
+
+#define s3c6410_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6410_init_clocks NULL
+#define s3c6410_init_uarts NULL
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h
new file mode 100644 (file)
index 0000000..984bf9e
--- /dev/null
@@ -0,0 +1,55 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5p-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for s5p clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_CLOCK_H
+#define __ASM_PLAT_S5P_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_dpll clk_ext_xtal_mux
+#define clk_fin_vpll clk_ext_xtal_mux
+#define clk_fin_hpll clk_ext_xtal_mux
+
+extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_xusbxti;
+extern struct clk clk_48m;
+extern struct clk s5p_clk_27m;
+extern struct clk clk_fout_apll;
+extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_epll;
+extern struct clk clk_fout_dpll;
+extern struct clk clk_fout_vpll;
+extern struct clk clk_arm;
+extern struct clk clk_vpll;
+
+extern struct clksrc_sources clk_src_apll;
+extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_epll;
+extern struct clksrc_sources clk_src_dpll;
+
+extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
+
+/* Common EPLL operations for S5P platform */
+extern int s5p_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p_epll_get_rate(struct clk *clk);
+
+/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */
+extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long s5p_spdif_get_rate(struct clk *clk);
+
+extern struct clk_ops s5p_sclk_spdif_ops;
+#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-samsung/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h
new file mode 100644 (file)
index 0000000..3a70aeb
--- /dev/null
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5p-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Header file for s5p time support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_TIME_H
+#define __ASM_PLAT_S5P_TIME_H __FILE__
+
+/* S5P HR-Timer Clock mode */
+enum s5p_timer_mode {
+       S5P_PWM0,
+       S5P_PWM1,
+       S5P_PWM2,
+       S5P_PWM3,
+       S5P_PWM4,
+};
+
+struct s5p_timer_source {
+       unsigned int event_id;
+       unsigned int source_id;
+};
+
+/* Be able to sleep for atleast 4 seconds (usually more) */
+#define S5PTIMER_MIN_RANGE     4
+
+#define TCNT_MAX               0xffffffff
+#define NON_PERIODIC           0
+#define PERIODIC               1
+
+extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
+                                       enum s5p_timer_mode source);
+extern struct sys_timer s5p_timer;
+#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-samsung/include/plat/s5p6440.h b/arch/arm/plat-samsung/include/plat/s5p6440.h
new file mode 100644 (file)
index 0000000..bf85ebb
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5p6440.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Header file for s5p6440 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+ /* Common init code for S5P6440 related SoCs */
+
+extern void s5p6440_register_clocks(void);
+extern void s5p6440_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6440
+
+extern  int s5p64x0_init(void);
+extern void s5p6440_init_irq(void);
+extern void s5p6440_map_io(void);
+extern void s5p6440_init_clocks(int xtal);
+
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6440_init_clocks NULL
+#define s5p6440_init_uarts NULL
+#define s5p6440_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6440 timer */
+
+extern struct sys_timer s5p6440_timer;
diff --git a/arch/arm/plat-samsung/include/plat/s5p6450.h b/arch/arm/plat-samsung/include/plat/s5p6450.h
new file mode 100644 (file)
index 0000000..da25f9a
--- /dev/null
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5p6450.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Header file for s5p6450 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5P6450 related SoCs */
+
+extern void s5p6450_register_clocks(void);
+extern void s5p6450_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6450
+
+extern  int s5p64x0_init(void);
+extern void s5p6450_init_irq(void);
+extern void s5p6450_map_io(void);
+extern void s5p6450_init_clocks(int xtal);
+
+extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6450_init_clocks NULL
+#define s5p6450_init_uarts NULL
+#define s5p6450_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6450 timer */
+
+extern struct sys_timer s5p6450_timer;
diff --git a/arch/arm/plat-samsung/include/plat/s5pc100.h b/arch/arm/plat-samsung/include/plat/s5pc100.h
new file mode 100644 (file)
index 0000000..9a21aea
--- /dev/null
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5pc100.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Header file for s5pc100 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5PC100 related SoCs */
+
+extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pc100_register_clocks(void);
+extern void s5pc100_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PC100
+
+extern  int s5pc100_init(void);
+extern void s5pc100_init_irq(void);
+extern void s5pc100_map_io(void);
+extern void s5pc100_init_clocks(int xtal);
+
+#define s5pc100_init_uarts s5pc100_common_init_uarts
+
+#else
+#define s5pc100_init_clocks NULL
+#define s5pc100_init_uarts NULL
+#define s5pc100_map_io NULL
+#define s5pc100_init NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/s5pv210.h b/arch/arm/plat-samsung/include/plat/s5pv210.h
new file mode 100644 (file)
index 0000000..b4bc6be
--- /dev/null
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-samsung/include/plat/s5pv210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Header file for s5pv210 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5PV210 related SoCs */
+
+extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pv210_register_clocks(void);
+extern void s5pv210_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PV210
+
+extern  int s5pv210_init(void);
+extern void s5pv210_init_irq(void);
+extern void s5pv210_map_io(void);
+extern void s5pv210_init_clocks(int xtal);
+
+#define s5pv210_init_uarts s5pv210_common_init_uarts
+
+#else
+#define s5pv210_init_clocks NULL
+#define s5pv210_init_uarts NULL
+#define s5pv210_map_io NULL
+#define s5pv210_init NULL
+#endif
index 4a6552066c7ef1ee71b92620dab90ecdc9f65847..e7b3c752e91963e542d53c832775b08ede46ef6e 100644 (file)
@@ -55,10 +55,6 @@ enum clk_types {
  *              cd_type == S3C_SDHCI_CD_GPIO
  * @ext_cd_gpio_invert: invert values for external CD gpio line
  * @cfg_gpio: Configure the GPIO for a specific card bit-width
- * @cfg_card: Configure the interface for a specific card and speed. This
- *            is necessary the controllers and/or GPIO blocks require the
- *           changing of driver-strength and other controls dependent on
- *           the card and speed of operation.
  *
  * Initialisation data specific to either the machine or the platform
  * for the device driver to use or call-back when configuring gpio or
@@ -80,10 +76,6 @@ struct s3c_sdhci_platdata {
                                                      int state));
 
        void    (*cfg_gpio)(struct platform_device *dev, int width);
-       void    (*cfg_card)(struct platform_device *dev,
-                           void __iomem *regbase,
-                           struct mmc_ios *ios,
-                           struct mmc_card *card);
 };
 
 /* 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);
 #ifdef CONFIG_S3C2416_SETUP_SDHCI
 extern char *s3c2416_hsmmc_clksrcs[4];
 
-extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
-                                          void __iomem *r,
-                                          struct mmc_ios *ios,
-                                          struct mmc_card *card);
-
 static inline void s3c2416_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
 #endif /* CONFIG_S3C_DEV_HSMMC */
 }
 
@@ -158,7 +144,6 @@ static inline void s3c2416_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
 #endif /* CONFIG_S3C_DEV_HSMMC1 */
 }
 
@@ -172,17 +157,11 @@ static inline void s3c2416_default_sdhci1(void) { }
 #ifdef CONFIG_S3C64XX_SETUP_SDHCI
 extern char *s3c64xx_hsmmc_clksrcs[4];
 
-extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
-                                        void __iomem *r,
-                                        struct mmc_ios *ios,
-                                        struct mmc_card *card);
-
 static inline void s3c6400_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -191,7 +170,6 @@ static inline void s3c6400_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -200,21 +178,14 @@ static inline void s3c6400_default_sdhci2(void)
 #ifdef CONFIG_S3C_DEV_HSMMC2
        s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
-       s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
 #endif
 }
 
-extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
-                                        void __iomem *r,
-                                        struct mmc_ios *ios,
-                                        struct mmc_card *card);
-
 static inline void s3c6410_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -223,7 +194,6 @@ static inline void s3c6410_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -232,7 +202,6 @@ static inline void s3c6410_default_sdhci2(void)
 #ifdef CONFIG_S3C_DEV_HSMMC2
        s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
        s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
-       s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -251,17 +220,11 @@ static inline void s3c6400_default_sdhci2(void) { }
 #ifdef CONFIG_S5PC100_SETUP_SDHCI
 extern char *s5pc100_hsmmc_clksrcs[4];
 
-extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
-                                          void __iomem *r,
-                                          struct mmc_ios *ios,
-                                          struct mmc_card *card);
-
 static inline void s5pc100_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
 #endif
 }
 
@@ -270,7 +233,6 @@ static inline void s5pc100_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
 #endif
 }
 
@@ -279,7 +241,6 @@ static inline void s5pc100_default_sdhci2(void)
 #ifdef CONFIG_S3C_DEV_HSMMC2
        s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
        s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
-       s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
 #endif
 }
 
@@ -295,17 +256,11 @@ static inline void s5pc100_default_sdhci2(void) { }
 #ifdef CONFIG_S5PV210_SETUP_SDHCI
 extern char *s5pv210_hsmmc_clksrcs[4];
 
-extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
-                                          void __iomem *r,
-                                          struct mmc_ios *ios,
-                                          struct mmc_card *card);
-
 static inline void s5pv210_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -314,7 +269,6 @@ static inline void s5pv210_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -323,7 +277,6 @@ static inline void s5pv210_default_sdhci2(void)
 #ifdef CONFIG_S3C_DEV_HSMMC2
        s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
        s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
-       s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -332,7 +285,6 @@ static inline void s5pv210_default_sdhci3(void)
 #ifdef CONFIG_S3C_DEV_HSMMC3
        s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
        s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
-       s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -348,17 +300,11 @@ static inline void s5pv210_default_sdhci3(void) { }
 #ifdef CONFIG_EXYNOS4_SETUP_SDHCI
 extern char *exynos4_hsmmc_clksrcs[4];
 
-extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev,
-                                          void __iomem *r,
-                                          struct mmc_ios *ios,
-                                          struct mmc_card *card);
-
 static inline void exynos4_default_sdhci0(void)
 {
 #ifdef CONFIG_S3C_DEV_HSMMC
        s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
        s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio;
-       s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -367,7 +313,6 @@ static inline void exynos4_default_sdhci1(void)
 #ifdef CONFIG_S3C_DEV_HSMMC1
        s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
        s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio;
-       s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -376,7 +321,6 @@ static inline void exynos4_default_sdhci2(void)
 #ifdef CONFIG_S3C_DEV_HSMMC2
        s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
        s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio;
-       s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
 #endif
 }
 
@@ -385,7 +329,6 @@ static inline void exynos4_default_sdhci3(void)
 #ifdef CONFIG_S3C_DEV_HSMMC3
        s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
        s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio;
-       s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
 #endif
 }
 
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
new file mode 100644 (file)
index 0000000..5fe8ee0
--- /dev/null
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-samsung/include/plat/sysmmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung System MMU driver for S5P platform
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_SYSMMU_H
+#define __PLAT_SAMSUNG_SYSMMU_H __FILE__
+
+enum S5P_SYSMMU_INTERRUPT_TYPE {
+       SYSMMU_PAGEFAULT,
+       SYSMMU_AR_MULTIHIT,
+       SYSMMU_AW_MULTIHIT,
+       SYSMMU_BUSERROR,
+       SYSMMU_AR_SECURITY,
+       SYSMMU_AR_ACCESS,
+       SYSMMU_AW_SECURITY,
+       SYSMMU_AW_PROTECTION, /* 7 */
+       SYSMMU_FAULTS_NUM
+};
+
+#ifdef CONFIG_S5P_SYSTEM_MMU
+
+#include <mach/sysmmu.h>
+
+/**
+ * s5p_sysmmu_enable() - enable system mmu of ip
+ * @ips: The ip connected system mmu.
+ * #pgd: Base physical address of the 1st level page table
+ *
+ * This function enable system mmu to transfer address
+ * from virtual address to physical address
+ */
+void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
+
+/**
+ * s5p_sysmmu_disable() - disable sysmmu mmu of ip
+ * @ips: The ip connected system mmu.
+ *
+ * This function disable system mmu to transfer address
+ * from virtual address to physical address
+ */
+void s5p_sysmmu_disable(sysmmu_ips ips);
+
+/**
+ * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
+ * @ips: The ip connected system mmu.
+ * @pgd: The page table base address.
+ *
+ * This function set page table base address
+ * When system mmu transfer address from virtaul address to physical address,
+ * system mmu refer address information from page table
+ */
+void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
+
+/**
+ * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
+ * @ips: The ip connected system mmu.
+ *
+ * This function flush all TLB entry in system mmu
+ */
+void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
+
+/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
+ * @itype: type of fault.
+ * @pgtable_base: the physical address of page table base. This is 0 if @ips is
+ *               SYSMMU_BUSERROR.
+ * @fault_addr: the device (virtual) address that the System MMU tried to
+ *             translated. This is 0 if @ips is SYSMMU_BUSERROR.
+ * Called when interrupt occurred by the System MMUs
+ * The device drivers of peripheral devices that has a System MMU can implement
+ * a fault handler to resolve address translation fault by System MMU.
+ * The meanings of return value and parameters are described below.
+
+ * return value: non-zero if the fault is correctly resolved.
+ *         zero if the fault is not handled.
+ */
+void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
+                       int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
+                                       unsigned long pgtable_base,
+                                       unsigned long fault_addr));
+#else
+#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
+#define s5p_sysmmu_disable(ips) do { } while (0)
+#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
+#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
+#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
+#endif
+#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-samsung/include/plat/system-reset.h b/arch/arm/plat-samsung/include/plat/system-reset.h
new file mode 100644 (file)
index 0000000..a448e99
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/arch/arm/plat-samsung/include/plat/system-reset.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h
+ *
+ * S5P - System define for arch_reset()
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <plat/watchdog-reset.h>
+
+void (*s5p_reset_hook)(void);
+
+static void arch_reset(char mode, const char *cmd)
+{
+       /* SWRESET support in s5p_reset_hook() */
+
+       if (s5p_reset_hook)
+               s5p_reset_hook();
+
+       /* Perform reset using Watchdog reset
+        * if there is no s5p_reset_hook()
+        */
+
+       arch_wdt_reset();
+}
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 (file)
index 0000000..3bc34f3
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/plat-samsung/include/plat/tv.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ *     Tomasz Stanislawski <t.stanislaws@samsung.com>
+ *
+ * Samsung TV driver core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SAMSUNG_PLAT_TV_H
+#define __SAMSUNG_PLAT_TV_H __FILE__
+
+/*
+ * These functions are only for use with the core support code, such as
+ * the CPU-specific initialization code.
+ */
+
+/* Re-define device name to differentiate the subsystem in various SoCs. */
+static inline void s5p_hdmi_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+       s5p_device_hdmi.name = name;
+#endif
+}
+
+static inline void s5p_mixer_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+       s5p_device_mixer.name = name;
+#endif
+}
+
+static inline void s5p_sdo_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+       s5p_device_sdo.name = name;
+#endif
+}
+
+#endif /* __SAMSUNG_PLAT_TV_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc.h b/arch/arm/plat-samsung/include/plat/udc.h
new file mode 100644 (file)
index 0000000..8c22d58
--- /dev/null
@@ -0,0 +1,57 @@
+/* arch/arm/plat-samsung/include/plat/udc.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ *  Changelog:
+ *     14-Mar-2005     RTP     Created file
+ *     02-Aug-2005     RTP     File rename
+ *     07-Sep-2005     BJD     Minor cleanups, changed cmd to enum
+ *     18-Jan-2007     HMW     Add per-platform vbus_draw function
+*/
+
+#ifndef __ASM_ARM_ARCH_UDC_H
+#define __ASM_ARM_ARCH_UDC_H
+
+enum s3c2410_udc_cmd_e {
+       S3C2410_UDC_P_ENABLE    = 1,    /* Pull-up enable        */
+       S3C2410_UDC_P_DISABLE   = 2,    /* Pull-up disable       */
+       S3C2410_UDC_P_RESET     = 3,    /* UDC reset, in case of */
+};
+
+struct s3c2410_udc_mach_info {
+       void    (*udc_command)(enum s3c2410_udc_cmd_e);
+       void    (*vbus_draw)(unsigned int ma);
+
+       unsigned int pullup_pin;
+       unsigned int pullup_pin_inverted;
+
+       unsigned int vbus_pin;
+       unsigned char vbus_pin_inverted;
+};
+
+extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
+
+/**
+ * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
+ * @epnum: Number of endpoints to be instantiated by the controller driver.
+ * @gpio_init: Platform specific USB related GPIO initialization.
+ * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
+ *
+ * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
+ * controllers.
+ */
+struct s3c24xx_hsudc_platdata {
+       unsigned int    epnum;
+       void            (*gpio_init)(void);
+       void            (*gpio_uninit)(void);
+};
+
+extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
+
+#endif /* __ASM_ARM_ARCH_UDC_H */
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h
new file mode 100644 (file)
index 0000000..959bcdb
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_SAMSUNG_USB_PHY_H
+#define __PLAT_SAMSUNG_USB_PHY_H __FILE__
+
+enum s5p_usb_phy_type {
+       S5P_USB_PHY_DEVICE,
+       S5P_USB_PHY_HOST,
+};
+
+extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+
+#endif /* __PLAT_SAMSUNG_USB_PHY_H */
index efe1d564473e02c6195774fbc47c51a23a97fad4..312b510d86b76bf0b96feba92de8aae8163380c3 100644 (file)
@@ -11,7 +11,7 @@
 */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
index 6de1a38259276de08a0b1dbe9835801fb5affba8..ceb9fa3a80c0768a10411740547a42dd0fbcceb1 100644 (file)
@@ -10,6 +10,7 @@
 */
 
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/platform_device.h>
 
@@ -50,8 +51,6 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
                set->max_width = pd->max_width;
        if (pd->cfg_gpio)
                set->cfg_gpio = pd->cfg_gpio;
-       if (pd->cfg_card)
-               set->cfg_card = pd->cfg_card;
        if (pd->host_caps)
                set->host_caps |= pd->host_caps;
        if (pd->clk_type)
index 96528200eb79aae3ac06928930997e86102bb18c..4be016eaa6dba9c6180a399e0ebdc69794cb0930 100644 (file)
 #define OFFS_DAT       (0x04)
 #define OFFS_UP                (0x08)
 
-static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_1bit_save(struct samsung_gpio_chip *chip)
 {
        chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
        chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
 }
 
-static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_1bit_resume(struct samsung_gpio_chip *chip)
 {
        void __iomem *base = chip->base;
        u32 old_gpcon = __raw_readl(base + OFFS_CON);
@@ -60,12 +60,12 @@ static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
                  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
 }
 
-struct s3c_gpio_pm s3c_gpio_pm_1bit = {
-       .save   = s3c_gpio_pm_1bit_save,
-       .resume = s3c_gpio_pm_1bit_resume,
+struct samsung_gpio_pm samsung_gpio_pm_1bit = {
+       .save   = samsung_gpio_pm_1bit_save,
+       .resume = samsung_gpio_pm_1bit_resume,
 };
 
-static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_2bit_save(struct samsung_gpio_chip *chip)
 {
        chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
        chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
@@ -95,7 +95,7 @@ static inline int is_out(unsigned long con)
 }
 
 /**
- * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
+ * samsung_gpio_pm_2bit_resume() - restore the given GPIO bank
  * @chip: The chip information to resume.
  *
  * 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)
  * [1] this assumes that writing to a pin DAT whilst in SFN will set the
  *     state for when it is next output.
  */
-static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_2bit_resume(struct samsung_gpio_chip *chip)
 {
        void __iomem *base = chip->base;
        u32 old_gpcon = __raw_readl(base + OFFS_CON);
@@ -187,13 +187,13 @@ static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
                  chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
 }
 
-struct s3c_gpio_pm s3c_gpio_pm_2bit = {
-       .save   = s3c_gpio_pm_2bit_save,
-       .resume = s3c_gpio_pm_2bit_resume,
+struct samsung_gpio_pm samsung_gpio_pm_2bit = {
+       .save   = samsung_gpio_pm_2bit_save,
+       .resume = samsung_gpio_pm_2bit_resume,
 };
 
 #if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
-static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
 {
        chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
        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)
                chip->pm_save[0] = __raw_readl(chip->base - 4);
 }
 
-static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
+static u32 samsung_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
 {
        u32 old, new, mask;
        u32 change_mask = 0x0;
@@ -242,14 +242,14 @@ static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
        return change_mask;
 }
 
-static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
+static void samsung_gpio_pm_4bit_con(struct samsung_gpio_chip *chip, int index)
 {
        void __iomem *con = chip->base + (index * 4);
        u32 old_gpcon = __raw_readl(con);
        u32 gps_gpcon = chip->pm_save[index + 1];
        u32 gpcon, mask;
 
-       mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+       mask = samsung_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
 
        gpcon = old_gpcon & ~mask;
        gpcon |= gps_gpcon & mask;
@@ -257,7 +257,7 @@ static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
        __raw_writel(gpcon, con);
 }
 
-static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
+static void samsung_gpio_pm_4bit_resume(struct samsung_gpio_chip *chip)
 {
        void __iomem *base = chip->base;
        u32 old_gpcon[2];
@@ -269,10 +269,10 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
        old_gpcon[0] = 0;
        old_gpcon[1] = __raw_readl(base + OFFS_CON);
 
-       s3c_gpio_pm_4bit_con(chip, 0);
+       samsung_gpio_pm_4bit_con(chip, 0);
        if (chip->chip.ngpio > 8) {
                old_gpcon[0] = __raw_readl(base - 4);
-               s3c_gpio_pm_4bit_con(chip, -1);
+               samsung_gpio_pm_4bit_con(chip, -1);
        }
 
        /* Now change the configurations that require DAT,CON */
@@ -298,19 +298,19 @@ static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
                          old_gpdat, gps_gpdat);
 }
 
-struct s3c_gpio_pm s3c_gpio_pm_4bit = {
-       .save   = s3c_gpio_pm_4bit_save,
-       .resume = s3c_gpio_pm_4bit_resume,
+struct samsung_gpio_pm samsung_gpio_pm_4bit = {
+       .save   = samsung_gpio_pm_4bit_save,
+       .resume = samsung_gpio_pm_4bit_resume,
 };
 #endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
 
 /**
- * s3c_pm_save_gpio() - save gpio chip data for suspend
+ * samsung_pm_save_gpio() - save gpio chip data for suspend
  * @ourchip: The chip for suspend.
  */
-static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
+static void samsung_pm_save_gpio(struct samsung_gpio_chip *ourchip)
 {
-       struct s3c_gpio_pm *pm = ourchip->pm;
+       struct samsung_gpio_pm *pm = ourchip->pm;
 
        if (pm == NULL || pm->save == NULL)
                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)
 }
 
 /**
- * s3c_pm_save_gpios() - Save the state of the GPIO banks.
+ * samsung_pm_save_gpios() - Save the state of the GPIO banks.
  *
  * For all the GPIO banks, save the state of each one ready for going
  * into a suspend mode.
  */
-void s3c_pm_save_gpios(void)
+void samsung_pm_save_gpios(void)
 {
-       struct s3c_gpio_chip *ourchip;
+       struct samsung_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
        for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
-               ourchip = s3c_gpiolib_getchip(gpio_nr);
+               ourchip = samsung_gpiolib_getchip(gpio_nr);
                if (!ourchip) {
                        gpio_nr++;
                        continue;
                }
 
-               s3c_pm_save_gpio(ourchip);
+               samsung_pm_save_gpio(ourchip);
 
                S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
                          ourchip->chip.label,
@@ -351,12 +351,12 @@ void s3c_pm_save_gpios(void)
 }
 
 /**
- * s3c_pm_resume_gpio() - restore gpio chip data after suspend
+ * samsung_pm_resume_gpio() - restore gpio chip data after suspend
  * @ourchip: The suspended chip.
  */
-static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
+static void samsung_pm_resume_gpio(struct samsung_gpio_chip *ourchip)
 {
-       struct s3c_gpio_pm *pm = ourchip->pm;
+       struct samsung_gpio_pm *pm = ourchip->pm;
 
        if (pm == NULL || pm->resume == NULL)
                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)
                pm->resume(ourchip);
 }
 
-void s3c_pm_restore_gpios(void)
+void samsung_pm_restore_gpios(void)
 {
-       struct s3c_gpio_chip *ourchip;
+       struct samsung_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
        for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
-               ourchip = s3c_gpiolib_getchip(gpio_nr);
+               ourchip = samsung_gpiolib_getchip(gpio_nr);
                if (!ourchip) {
                        gpio_nr++;
                        continue;
                }
 
-               s3c_pm_resume_gpio(ourchip);
+               samsung_pm_resume_gpio(ourchip);
 
                gpio_nr += ourchip->chip.ngpio;
                gpio_nr += CONFIG_S3C_GPIO_SPACE;
index ae6f99834cddb01ea69b471b22fa823f7c7f0aa8..64ab65f0fdbc652cd1e0f165ec13bf5a61cc6377 100644 (file)
@@ -268,8 +268,8 @@ static int s3c_pm_enter(suspend_state_t state)
 
        /* save all necessary core registers not covered by the drivers */
 
-       s3c_pm_save_gpios();
-       s3c_pm_saved_gpios();
+       samsung_pm_save_gpios();
+       samsung_pm_saved_gpios();
        s3c_pm_save_uarts();
        s3c_pm_save_core();
 
@@ -306,7 +306,7 @@ static int s3c_pm_enter(suspend_state_t state)
 
        s3c_pm_restore_core();
        s3c_pm_restore_uarts();
-       s3c_pm_restore_gpios();
+       samsung_pm_restore_gpios();
        s3c_pm_restored_gpios();
 
        s3c_pm_debug_init();
index f1bba88ed2f571f9980a56c0af29798e6d75e244..a35ff3bcffe4840010b1a9bf92c737a611ce7c88 100644 (file)
@@ -27,7 +27,7 @@
 #include <plat/cpu.h>
 
 #include <plat/regs-timer.h>
-#include <mach/pwm-clock.h>
+#include <plat/pwm-clock.h>
 
 /* Each of the timers 0 through 5 go through the following
  * 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)
        unsigned long bits;
        unsigned long shift = S3C2410_TCFG1_SHIFT(id);
 
+       unsigned long mux_tclk;
+
+       if (soc_is_s3c24xx())
+               mux_tclk = S3C2410_TCFG1_MUX_TCLK;
+       else if (soc_is_s5p6440() || soc_is_s5p6450())
+               mux_tclk = 0;
+       else
+               mux_tclk = S3C64XX_TCFG1_MUX_TCLK;
+
        if (parent == s3c24xx_pwmclk_tclk(id))
-               bits = S3C_TCFG1_MUX_TCLK << shift;
+               bits = mux_tclk << shift;
        else if (parent == s3c24xx_pwmclk_tdiv(id))
                bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
        else
index f37457c52064f77b5e58139a2eb0008f695d905c..c559d8438c70ee2d873afc43a7d14ee1fc2002c2 100644 (file)
@@ -11,7 +11,7 @@
  * the Free Software Foundation; either version 2 of the License.
 */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -299,6 +299,9 @@ static int s3c_pwm_probe(struct platform_device *pdev)
                goto err_clk_tin;
        }
 
+       clk_enable(pwm->clk);
+       clk_enable(pwm->clk_div);
+
        local_irq_save(flags);
 
        tcon = __raw_readl(S3C2410_TCON);
@@ -326,6 +329,8 @@ static int s3c_pwm_probe(struct platform_device *pdev)
        return 0;
 
  err_clk_tdiv:
+       clk_disable(pwm->clk_div);
+       clk_disable(pwm->clk);
        clk_put(pwm->clk_div);
 
  err_clk_tin:
@@ -340,6 +345,8 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev)
 {
        struct pwm_device *pwm = platform_get_drvdata(pdev);
 
+       clk_disable(pwm->clk_div);
+       clk_disable(pwm->clk);
        clk_put(pwm->clk_div);
        clk_put(pwm->clk);
        kfree(pwm);
index 582333c70585222a7452a08e7684859ab554944c..78149491282749adf6c71051c1321c35c9404077 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/export.h>
 
 #include <mach/dma.h>
 
index 5bdeef9698470b354dc3f144caadabda08dae00d..ccbe16f47227e2ebb171032b2a5de66289014cd0 100644 (file)
@@ -1123,5 +1123,6 @@ blissc                    MACH_BLISSC             BLISSC                  3491
 thales_adc             MACH_THALES_ADC         THALES_ADC              3492
 ubisys_p9d_evp         MACH_UBISYS_P9D_EVP     UBISYS_P9D_EVP          3493
 atdgp318               MACH_ATDGP318           ATDGP318                3494
+m28evk                 MACH_M28EVK             M28EVK                  3613
 smdk4212               MACH_SMDK4212           SMDK4212                3638
 smdk4412               MACH_SMDK4412           SMDK4412                3765
index 0cbd5a0a9332a0f237559fa028f42787fcda0b7d..8f3ccddbdafd07787b2a57b02778f4c59046cae9 100644 (file)
@@ -8,7 +8,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
index fafed4c38fd25c18989661edcd1150b5dd3a5b4f..1f17bde52cd4dca07e6ec59aac6a13588ed8096b 100644 (file)
@@ -90,11 +90,6 @@ static struct mtd_partition nand_partitions[] = {
        },
 };
 
-static struct mtd_partition *nand_part_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(nand_partitions);
-       return nand_partitions;
-}
 
 static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
        .cle            = 21,
@@ -102,7 +97,8 @@ static struct atmel_nand_data atngw100mkii_nand_data __initdata = {
        .rdy_pin        = GPIO_PIN_PB(28),
        .enable_pin     = GPIO_PIN_PE(23),
        .bus_width_16   = true,
-       .partition_info = nand_part_info,
+       .parts          = nand_partitions,
+       .num_parts      = ARRAY_SIZE(nand_partitions),
 };
 #endif
 
index 6ce30fb2ec94924464a313aece641f392d6deb64..4643ff5107c9f76ea4b3fa10a2c02f217696a22e 100644 (file)
@@ -90,18 +90,13 @@ static struct mtd_partition nand_partitions[] = {
        },
 };
 
-static struct mtd_partition *nand_part_info(int size, int *num_partitions)
-{
-       *num_partitions = ARRAY_SIZE(nand_partitions);
-       return nand_partitions;
-}
-
 static struct atmel_nand_data atstk1006_nand_data __initdata = {
        .cle            = 21,
        .ale            = 22,
        .rdy_pin        = GPIO_PIN_PB(30),
        .enable_pin     = GPIO_PIN_PB(29),
-       .partition_info = nand_part_info,
+       .parts          = nand_partitions,
+       .num_parts      = ARRAY_SIZE(num_partitions),
 };
 #endif
 
index 86925fd6ea5bb3daf34eb039858ff69f2bb02ec6..23b1a97fae7ad686acc581c5888e95d5e4928a1e 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/string.h>
 #include <linux/list.h>
index 024c586e936c268956dbb59221e4ec8e2b77b129..627743326253f553e2da7fc2d7f95f5c9d809c28 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <asm/system.h>
 
 static struct clk *cpuclk;
index 679458d9a622365afd30fe371c229567dedc83cb..5d7ffca7d69f01bb5b28cec422b8afb702d27859 100644 (file)
@@ -128,7 +128,8 @@ struct atmel_nand_data {
        u8      ale;            /* address line number connected to ALE */
        u8      cle;            /* address line number connected to CLE */
        u8      bus_width_16;   /* buswidth is 16 bit */
-       struct mtd_partition *(*partition_info)(int size, int *num_partitions);
+       struct mtd_partition *parts;
+       unsigned int    num_parts;
 };
 struct platform_device *
 at32_add_device_nand(unsigned int id, struct atmel_nand_data *data);
index 258682bc12784cf08914e252c4d05279ecdb7329..aaff83cc50f06193aa15fd5327a46b9de5433259 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
+#include <linux/export.h>
 
 #include <asm/io.h>
 
index 9b39dea6682f83de9f81561ab6619299ede26c2e..903c7d81d0d521a1b8bcf523c609f83516d8e952 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/clk.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
index 3c0042247ea93661adbf504237be51e3d7730cec..50cdb5b10f0fc7b8bdfae25ffb9b32d5655463de 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/gfp.h>
+#include <linux/export.h>
 
 #include <asm/addrspace.h>
 #include <asm/cacheflush.h>
index 7fd0ec7b5b0f2c9326d0cd4deb0f788b6fadea34..ecacdf34768b593b0e43e91c2314927cde723e83 100644 (file)
@@ -32,6 +32,8 @@ struct work_struct;
 struct bfin_serial_port {
        struct uart_port port;
        unsigned int old_status;
+       int tx_irq;
+       int rx_irq;
        int status_irq;
 #ifndef BFIN_UART_BF54X_STYLE
        unsigned int lsr;
index 04ddcfeb798140a3ffb465157948395577874ebd..f0d1118f1825bf9c3ce5f280f45fabcdbd3e0391 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
+#include <linux/export.h>
 
 static spinlock_t dma_page_lock;
 static unsigned long *dma_page;
index 04300f29c0e7bc5584d5093063d21b9f7ce38706..e47d19ae3e0634bc582eff8bf984e76c4b76bab2 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/perf_event.h>
 #include <asm/bfin_pfmon.h>
index 89448ed7065dda739ba80a1029e3ca16520c2533..d998383cb956f5abc7bc0f750a8a6e5a9894fde4 100644 (file)
@@ -41,6 +41,7 @@ asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
 
 #if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
 #include <linux/fb.h>
+#include <linux/export.h>
 unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr,
        unsigned long len, unsigned long pgoff, unsigned long flags)
 {
index d78fc2cc7d168bcb610a9973a60cbcd0c7f17b00..d1c0c0cff3efdb2f68b91edb6a6ad892f10d0a33 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -371,9 +372,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -414,9 +420,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 55c12790881529952405cba9bd2be1a120445e4e..5470bf89e52e1147dcfcec19542dd18d2df7716d 100644 (file)
@@ -308,9 +308,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -351,9 +356,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index c04df43f6391c7e92a7f91fe9f5223e72cbcead0..5bc6938157ad831638ca4661cb61b68c18339e36 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -379,9 +380,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -422,9 +428,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 6400341cc2309071cec28a5000e231e51a1edbd9..cd289698b4dd73575682260b10ba615bf35bb71e 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -538,9 +539,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -581,9 +587,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 6dbb1b4037632ec332b09047ab39d07c794fa9bb..9f792eafd1ccf604c7b7177d3b5766e691b0c4e2 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -416,9 +417,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -459,9 +465,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 4e9dc9cf824126c770aa3e74a0db1032a003d51d..3ecafff5d2ef753416692b623324e800e0925437 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -709,9 +710,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -752,9 +758,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index ec4bc7429c9fbb4cfdb9f6576cda903ac57281f7..3a92c4318d2deaa392b2cef5693b4dd46f67170a 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -494,9 +495,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -538,9 +544,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 5da5787fc4efa8a091b3b67663d91ccbeffd9251..47cadd316e764484ac9e728d84ccfead6ee5b53f 100644 (file)
@@ -237,9 +237,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index b0ec825fb4eca73067c0ab12180406442bd61ab6..18817d57c7a15b5cf0e36bc806ef2752e91746fe 100644 (file)
@@ -192,9 +192,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 14f54a31e74c98977d488f69a6812c1c54a7bc2f..2c8f30ef6a7b2ab4b749c337814010cd9dc2fe10 100644 (file)
@@ -220,9 +220,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index ecd2801f050d9a9e0acde1e22fb6e6746edda3ba..144556e14499e6fc0a7141b8d368cd29650b5b15 100644 (file)
@@ -291,9 +291,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index fbee77fa9211a34179ae0cf5fe55bba4323af699..b597d4e50d58e74e7c29e4fd2b37658bbd12ec49 100644 (file)
@@ -150,9 +150,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 964a8e5f79b43e6e3b5ec397a5d2d4b8aed82b2b..2afd02e14bd1f317b053f0296b35161d4b71d4d3 100644 (file)
@@ -297,9 +297,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX + 1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 9fb20d6d8f9156fda7ba1e591ce2a33573d56b21..604a430038e153c73360987a5e763ee7a4af38dc 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
@@ -304,9 +305,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -365,9 +371,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 5ba389fc61aeb3d46b98e76f1cd4db76b4e45eef..d916b46a44fe9334bf49fb51b940aa2889c3245a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -305,9 +306,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -348,9 +354,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 8bc951de979d93c75f98826e99a7a2d052f876ca..5f307228be63b7b78108c9fcc19136b01e636bf1 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -235,9 +236,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -279,9 +285,14 @@ static struct resource bfin_uart1_resources[] = {
                .end   = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end   = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end   = IRQ_UART1_RX+1,
+               .end   = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index c62f9dccd9f797e4ea74d8253781f478a963e186..3901dd093b9044fad71e1a7da5480273677db7cf 100644 (file)
@@ -239,9 +239,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -282,9 +287,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 3b8151d99b9aeea28f71daffc8ebe76071692023..aebd31c845f008995c90424a5b053767a3058c78 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/device.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -100,6 +101,7 @@ static struct platform_device smc91x_device = {
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 #include <linux/bfin_mac.h>
+#include <linux/export.h>
 static const unsigned short bfin_mac_peripherals[] = P_RMII0;
 
 static struct bfin_phydev_platform_data bfin_phydev_data[] = {
@@ -307,9 +309,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -350,9 +357,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 6c916a67ef68dc3c7d9675254417435baaa0dedc..7fbb0bbf86762c3fd40336cb765c1f746b90cab6 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -1565,9 +1566,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -1620,9 +1626,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 2da0316d890e565345a04264f3875f34d241a96d..6917ce2fa55ef4f61568263462e05c1cd733aa18 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -305,9 +306,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -348,9 +354,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 629f3c3334158b57ff8250468613eaae26ddf894..8356eb599f1937cb37b552c36a91c70bf0c0b4b9 100644 (file)
@@ -48,9 +48,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -103,9 +108,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -146,9 +156,14 @@ static struct resource bfin_uart2_resources[] = {
                .end = UART2_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART2_TX,
+               .end = IRQ_UART2_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART2_RX,
-               .end = IRQ_UART2_RX+1,
+               .end = IRQ_UART2_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 212b9e0a08c8230f7ba0c28ad349839d89dd6bd5..0350eacec21b96785f2eda1cc933cca52bbde572 100644 (file)
@@ -134,9 +134,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -177,9 +182,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -236,9 +246,14 @@ static struct resource bfin_uart2_resources[] = {
                .end = UART2_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART2_TX,
+               .end = IRQ_UART2_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART2_RX,
-               .end = IRQ_UART2_RX+1,
+               .end = IRQ_UART2_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -279,9 +294,14 @@ static struct resource bfin_uart3_resources[] = {
                .end = UART3_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART3_TX,
+               .end = IRQ_UART3_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART3_RX,
-               .end = IRQ_UART3_RX+1,
+               .end = IRQ_UART3_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index cd9cbb68de692d1243d1c11dbb54f1d0e7bfa379..bb868ac0fe2dbdf5063034be857f5ece7a9c82a4 100644 (file)
@@ -240,9 +240,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = UART0_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART0_TX,
+               .end = IRQ_UART0_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART0_RX,
-               .end = IRQ_UART0_RX+1,
+               .end = IRQ_UART0_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -283,9 +288,14 @@ static struct resource bfin_uart1_resources[] = {
                .end = UART1_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART1_TX,
+               .end = IRQ_UART1_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART1_RX,
-               .end = IRQ_UART1_RX+1,
+               .end = IRQ_UART1_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -342,9 +352,14 @@ static struct resource bfin_uart2_resources[] = {
                .end = UART2_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART2_TX,
+               .end = IRQ_UART2_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART2_RX,
-               .end = IRQ_UART2_RX+1,
+               .end = IRQ_UART2_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
@@ -385,9 +400,14 @@ static struct resource bfin_uart3_resources[] = {
                .end = UART3_RBR+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART3_TX,
+               .end = IRQ_UART3_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART3_RX,
-               .end = IRQ_UART3_RX+1,
+               .end = IRQ_UART3_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 972e1347c6bc518865463a8313d32b725ee49241..b1b7339b6ba776a321d0614c091fe035508d63b7 100644 (file)
@@ -202,9 +202,14 @@ static struct resource bfin_uart0_resources[] = {
         .end = BFIN_UART_GCTL + 2,
         .flags = IORESOURCE_MEM,
         },
+       {
+        .start = IRQ_UART_TX,
+        .end = IRQ_UART_TX,
+        .flags = IORESOURCE_IRQ,
+        },
        {
         .start = IRQ_UART_RX,
-        .end = IRQ_UART_RX + 1,
+        .end = IRQ_UART_RX,
         .flags = IORESOURCE_IRQ,
         },
        {
index c1b72f2d635476ccc18d91f2d8455efe4d86ddb5..c017cf07ed4e2960f032f9d8b0c81a0a60e657de 100644 (file)
@@ -276,9 +276,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART_TX,
+               .end = IRQ_UART_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART_RX,
-               .end = IRQ_UART_RX+1,
+               .end = IRQ_UART_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 9490dc800ca589f6ef3f4337174bf257221f180a..27f22ed381d99767b0bda919964fed021f7d3cb5 100644 (file)
@@ -171,9 +171,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART_TX,
+               .end = IRQ_UART_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART_RX,
-               .end = IRQ_UART_RX+1,
+               .end = IRQ_UART_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index bb056e60f6edeb06b95e923e6bacd79590655662..1a57bc986aad154d2984798548b7a5878f9aaa67 100644 (file)
@@ -50,9 +50,14 @@ static struct resource bfin_uart0_resources[] = {
                .end = BFIN_UART_GCTL+2,
                .flags = IORESOURCE_MEM,
        },
+       {
+               .start = IRQ_UART_TX,
+               .end = IRQ_UART_TX,
+               .flags = IORESOURCE_IRQ,
+       },
        {
                .start = IRQ_UART_RX,
-               .end = IRQ_UART_RX+1,
+               .end = IRQ_UART_RX,
                .flags = IORESOURCE_IRQ,
        },
        {
index 85dc6d69f9c02e1c58a8f438b8bbedf75aba50f3..2e6eefd812f44cc0afff5265cf39f132b8e1d8a5 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
index f8435cd36c7c004dc8b27b8d335ee751a1ce69e1..78daae084915295a4d28f381477ec3145f75f535 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/swap.h>
 #include <linux/bootmem.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 #include <asm/bfin-global.h>
 #include <asm/pda.h>
 #include <asm/cplbinit.h>
index 32d90867a9841098177b1fd5969af784ef88ac19..5f2cdb3e428cd979601b6b15d5e04a24042c7a8e 100644 (file)
@@ -3,7 +3,7 @@ if ETRAX_ARCH_V10
 config ETRAX_ETHERNET
        bool "Ethernet support"
        depends on ETRAX_ARCH_V10
-       select NET_ETHERNET
+       select ETHERNET
        select NET_CORE
        select MII
        help
index e47e9c3401b08bbbde729c13e626b9a91823ec18..de43aadcdbc47963cdaa63e0e522cdc171e3d432 100644 (file)
@@ -3,7 +3,7 @@ if ETRAX_ARCH_V32
 config ETRAX_ETHERNET
        bool "Ethernet support"
        depends on ETRAX_ARCH_V32
-       select NET_ETHERNET
+       select ETHERNET
        select NET_CORE
        select MII
        help
index f58f2c1c529526f0521448dcbe53eda6c795085e..7fb52128ddc900ebfba2952654798ab04d8e5b97 100644 (file)
@@ -163,7 +163,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
        this->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       /* this->options = NAND_USE_FLASH_BBT; */
+       /* this->bbt_options = NAND_BBT_USE_FLASH; */
 
        /* Scan to find existence of the device */
        if (nand_scan(crisv32_mtd, 1)) {
index d5b0cc9f976bbf15637679dbedd78f4cd57d8fc2..e03238454b0ee541e0daa556493039cedf776dbc 100644 (file)
@@ -154,7 +154,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
        this->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       /* this->options = NAND_USE_FLASH_BBT; */
+       /* this->bbt_options = NAND_BBT_USE_FLASH; */
 
        /* Scan to find existence of the device */
        if (nand_scan(crisv32_mtd, 1)) {
index e4a80d82e3d8b570d2ce2950319094f5d286b9c7..1e4cae5ae0532e5560834bdde6b6e6382977d7df 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/swiotlb.h>
+#include <linux/export.h>
 #include <asm/machvec.h>
 
 extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
diff --git a/arch/ia64/include/asm/xen/grant_table.h b/arch/ia64/include/asm/xen/grant_table.h
deleted file mode 100644 (file)
index 2b1fae0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/******************************************************************************
- * arch/ia64/include/asm/xen/grant_table.h
- *
- * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
- *                    VA Linux Systems Japan K.K.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#ifndef _ASM_IA64_XEN_GRANT_TABLE_H
-#define _ASM_IA64_XEN_GRANT_TABLE_H
-
-struct vm_struct *xen_alloc_vm_area(unsigned long size);
-void xen_free_vm_area(struct vm_struct *area);
-
-#endif /* _ASM_IA64_XEN_GRANT_TABLE_H */
index e951e740bdf21514c8622f9b8ba875ada702e450..1d2427d116e363dbecbb98559dd002cc9b67f4a6 100644 (file)
@@ -76,6 +76,7 @@ DEFINE_GUEST_HANDLE(char);
 DEFINE_GUEST_HANDLE(int);
 DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
+DEFINE_GUEST_HANDLE(uint64_t);
 
 typedef unsigned long xen_pfn_t;
 DEFINE_GUEST_HANDLE(xen_pfn_t);
index f2c1600da097f00a6c6c388ded1a9e5523dd39d9..7f7916238208cf13999c8ccfee9086e823cea8ca 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 /* Set this to 1 if there is a HW IOMMU in the system */
 int iommu_detected __read_mostly;
index 0e0e0cc9e3929c8ddd91a4062351a2fb1b63c79d..9be1f11a01d97924e225997f2a45ee7f24b362a3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bootmem.h>
 #include <linux/nodemask.h>
 #include <linux/notifier.h>
+#include <linux/export.h>
 #include <asm/mmzone.h>
 #include <asm/numa.h>
 #include <asm/cpu.h>
index aa2533ae7e9e37f4d14f9b53ed1cd67e7e0f28af..2c27714d7b78302842bee1f6931c9f023e25c64a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
index 8cdcb173a13877842cbcc1833b68d70037c54cfc..b1725398b5af49683622765652104a85c3d95228 100644 (file)
@@ -14,6 +14,7 @@
 #include "xtalk/hubdev.h"
 #include <linux/acpi.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 
 /*
index 98079f29d9a9ff19bcdcd13bebfd7104ddd06a98..0a36f082eaf1d9e10ab95484c9e1118714d3c44a 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/sn/types.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
index 33def666a6642f256726af241df2695b7a933b7c..1e863b277ac967fa29ad0ddf3ae0517ecb281ff7 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
 #include <asm/sn/pcibr_provider.h>
index 3cb5cf37764429de80f7c89fdae1752db15e5ca5..5698f29d5add0ce3b7cc35471fa9dcb3f5a0b233 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
 #include <asm/sn/pcibr_provider.h>
index 9c271be9919aac37b2bbb87745fb8d6e64ba180f..642451e770ea870bfa317523a888dd14b9193430 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pci.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/io.h>
index 48cca37625ebdd04d08136037eeca93d92b71b73..c18281332f8472bb8204928655d7dfdc8f9ace86 100644 (file)
 
 #include <asm/xen/hypervisor.h>
 
-struct vm_struct *xen_alloc_vm_area(unsigned long size)
-{
-       int order;
-       unsigned long virt;
-       unsigned long nr_pages;
-       struct vm_struct *area;
-
-       order = get_order(size);
-       virt = __get_free_pages(GFP_KERNEL, order);
-       if (virt == 0)
-               goto err0;
-       nr_pages = 1 << order;
-       scrub_pages(virt, nr_pages);
-
-       area = kmalloc(sizeof(*area), GFP_KERNEL);
-       if (area == NULL)
-               goto err1;
-
-       area->flags = VM_IOREMAP;
-       area->addr = (void *)virt;
-       area->size = size;
-       area->pages = NULL;
-       area->nr_pages = nr_pages;
-       area->phys_addr = 0;    /* xenbus_map_ring_valloc uses this field!  */
-
-       return area;
-
-err1:
-       free_pages(virt, order);
-err0:
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(xen_alloc_vm_area);
-
-void xen_free_vm_area(struct vm_struct *area)
-{
-       unsigned int order = get_order(area->size);
-       unsigned long i;
-       unsigned long phys_addr = __pa(area->addr);
-
-       /* This area is used for foreign page mappping.
-        * So underlying machine page may not be assigned. */
-       for (i = 0; i < (1 << order); i++) {
-               unsigned long ret;
-               unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
-               struct xen_memory_reservation reservation = {
-                       .nr_extents   = 1,
-                       .address_bits = 0,
-                       .extent_order = 0,
-                       .domid        = DOMID_SELF
-               };
-               set_xen_guest_handle(reservation.extent_start, &gpfn);
-               ret = HYPERVISOR_memory_op(XENMEM_populate_physmap,
-                                          &reservation);
-               BUG_ON(ret != 1);
-       }
-       free_pages((unsigned long)area->addr, order);
-       kfree(area);
-}
-EXPORT_SYMBOL_GPL(xen_free_vm_area);
-
-
 /****************************************************************************
  * grant table hack
  * cmd: GNTTABOP_xxx
index cac4d97c0b5a549fac4c359daf939c74f9928b85..52172eee85913055d11bc1b0a33834d73cb45aae 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/privop.h>
 
index 6c4e9aaa70c195c57cfedc49281e941a53649e1d..ef80a6546ff2d37804f58298c185b5baf3dd6595 100644 (file)
@@ -323,13 +323,6 @@ config NODES_SHIFT
        default "1"
        depends on NEED_MULTIPLE_NODES
 
-# turning this on wastes a bunch of space.
-# Summit needs it only when NUMA is on
-config BOOT_IOREMAP
-       bool
-       depends on NUMA
-       default n
-
 endmenu
 
 
index 6c28582fb98f5559a39c3a0122104c561d4fa573..361d54019bb0bcafaed6e7e6d408d638ae4cd5c5 100644 (file)
@@ -4,8 +4,8 @@ config M68K
        select HAVE_IDE
        select HAVE_AOUT if MMU
        select GENERIC_ATOMIC64 if MMU
-       select HAVE_GENERIC_HARDIRQS if !MMU
-       select GENERIC_IRQ_SHOW if !MMU
+       select HAVE_GENERIC_HARDIRQS
+       select GENERIC_IRQ_SHOW
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
 
 config RWSEM_GENERIC_SPINLOCK
index 8294f0c1785ed92d5bec8911267d0f94683eea6b..3adb499584fb40d75d79d7ab6bc83defa082d7b8 100644 (file)
@@ -2,6 +2,15 @@ if MMU
 
 comment "Bus Support"
 
+config DIO
+       bool "DIO bus support"
+       depends on HP300
+       default y
+       help
+         Say Y here to enable support for the "DIO" expansion bus used in
+         HP300 machines. If you are using such a system you almost certainly
+         want this.
+
 config NUBUS
        bool
        depends on MAC
index d214034be6a6ab6e1fc9d832eab2d995f0d7baf0..6033f5d4e67e50a4b993cbdf9d0bb85cdd5cbba9 100644 (file)
@@ -24,6 +24,37 @@ config PROC_HARDWARE
          including the model, CPU, MMU, clock speed, BogoMIPS rating,
          and memory size.
 
+config NATFEAT
+       bool "ARAnyM emulator support"
+       depends on ATARI
+       help
+         This option enables support for ARAnyM native features, such as
+         access to a disk image as /dev/hda.
+
+config NFBLOCK
+       tristate "NatFeat block device support"
+       depends on BLOCK && NATFEAT
+       help
+         Say Y to include support for the ARAnyM NatFeat block device
+         which allows direct access to the hard drives without using
+         the hardware emulation.
+
+config NFCON
+       tristate "NatFeat console driver"
+       depends on NATFEAT
+       help
+         Say Y to include support for the ARAnyM NatFeat console driver
+         which allows the console output to be redirected to the stderr
+         output of ARAnyM.
+
+config NFETH
+       tristate "NatFeat Ethernet support"
+       depends on ETHERNET && NATFEAT
+       help
+         Say Y to include support for the ARAnyM NatFeat network device
+         which will emulate a regular ethernet device while presenting an
+         ethertap device to the host system.
+
 endmenu
 
 menu "Character devices"
index c5b5212cc3f91544f42b27f73323f9cf0a9bfc42..47b5f90002abe3c69bbc66ffee7a82f5cee4f6cb 100644 (file)
@@ -1,43 +1,15 @@
 /*
- * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code
+ * Amiga Linux interrupt handling code
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
- *
- * 11/07/96: rewritten interrupt handling, irq lists are exists now only for
- *           this sources where it makes sense (VERTB/PORTS/EXTER) and you must
- *           be careful that dev_id for this sources is unique since this the
- *           only possibility to distinguish between different handlers for
- *           free_irq. irq lists also have different irq flags:
- *           - IRQ_FLG_FAST: handler is inserted at top of list (after other
- *                           fast handlers)
- *           - IRQ_FLG_SLOW: handler is inserted at bottom of list and before
- *                           they're executed irq level is set to the previous
- *                           one, but handlers don't need to be reentrant, if
- *                           reentrance occurred, slow handlers will be just
- *                           called again.
- *           The whole interrupt handling for CIAs is moved to cia.c
- *           /Roman Zippel
- *
- * 07/08/99: rewamp of the interrupt handling - we now have two types of
- *           interrupts, normal and fast handlers, fast handlers being
- *           marked with IRQF_DISABLED and runs with all other interrupts
- *           disabled. Normal interrupts disable their own source but
- *           run with all other interrupt sources enabled.
- *           PORTS and EXTER interrupts are always shared even if the
- *           drivers do not explicitly mark this when calling
- *           request_irq which they really should do.
- *           This is similar to the way interrupts are handled on all
- *           other architectures and makes a ton of sense besides
- *           having the advantage of making it easier to share
- *           drivers.
- *           /Jes
  */
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/irq.h>
 
 #include <asm/irq.h>
 #include <asm/traps.h>
 #include <asm/amigaints.h>
 #include <asm/amipcmcia.h>
 
-static void amiga_enable_irq(unsigned int irq);
-static void amiga_disable_irq(unsigned int irq);
-static irqreturn_t ami_int1(int irq, void *dev_id);
-static irqreturn_t ami_int3(int irq, void *dev_id);
-static irqreturn_t ami_int4(int irq, void *dev_id);
-static irqreturn_t ami_int5(int irq, void *dev_id);
-
-static struct irq_controller amiga_irq_controller = {
-       .name           = "amiga",
-       .lock           = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock),
-       .enable         = amiga_enable_irq,
-       .disable        = amiga_disable_irq,
-};
-
-/*
- * void amiga_init_IRQ(void)
- *
- * Parameters: None
- *
- * Returns:    Nothing
- *
- * This function should be called during kernel startup to initialize
- * the amiga IRQ handling routines.
- */
-
-void __init amiga_init_IRQ(void)
-{
-       if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL))
-               pr_err("Couldn't register int%d\n", 1);
-       if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL))
-               pr_err("Couldn't register int%d\n", 3);
-       if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL))
-               pr_err("Couldn't register int%d\n", 4);
-       if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL))
-               pr_err("Couldn't register int%d\n", 5);
-
-       m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS);
-
-       /* turn off PCMCIA interrupts */
-       if (AMIGAHW_PRESENT(PCMCIA))
-               gayle.inten = GAYLE_IRQ_IDE;
-
-       /* turn off all interrupts and enable the master interrupt bit */
-       amiga_custom.intena = 0x7fff;
-       amiga_custom.intreq = 0x7fff;
-       amiga_custom.intena = IF_SETCLR | IF_INTEN;
-
-       cia_init_IRQ(&ciaa_base);
-       cia_init_IRQ(&ciab_base);
-}
 
 /*
  * Enable/disable a particular machine specific interrupt source.
@@ -103,112 +25,150 @@ void __init amiga_init_IRQ(void)
  * internal data, that may not be changed by the interrupt at the same time.
  */
 
-static void amiga_enable_irq(unsigned int irq)
+static void amiga_irq_enable(struct irq_data *data)
 {
-       amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER));
+       amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER));
 }
 
-static void amiga_disable_irq(unsigned int irq)
+static void amiga_irq_disable(struct irq_data *data)
 {
-       amiga_custom.intena = 1 << (irq - IRQ_USER);
+       amiga_custom.intena = 1 << (data->irq - IRQ_USER);
 }
 
+static struct irq_chip amiga_irq_chip = {
+       .name           = "amiga",
+       .irq_enable     = amiga_irq_enable,
+       .irq_disable    = amiga_irq_disable,
+};
+
+
 /*
  * The builtin Amiga hardware interrupt handlers.
  */
 
-static irqreturn_t ami_int1(int irq, void *dev_id)
+static void ami_int1(unsigned int irq, struct irq_desc *desc)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if serial transmit buffer empty, interrupt */
        if (ints & IF_TBE) {
                amiga_custom.intreq = IF_TBE;
-               m68k_handle_int(IRQ_AMIGA_TBE);
+               generic_handle_irq(IRQ_AMIGA_TBE);
        }
 
        /* if floppy disk transfer complete, interrupt */
        if (ints & IF_DSKBLK) {
                amiga_custom.intreq = IF_DSKBLK;
-               m68k_handle_int(IRQ_AMIGA_DSKBLK);
+               generic_handle_irq(IRQ_AMIGA_DSKBLK);
        }
 
        /* if software interrupt set, interrupt */
        if (ints & IF_SOFT) {
                amiga_custom.intreq = IF_SOFT;
-               m68k_handle_int(IRQ_AMIGA_SOFT);
+               generic_handle_irq(IRQ_AMIGA_SOFT);
        }
-       return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int3(int irq, void *dev_id)
+static void ami_int3(unsigned int irq, struct irq_desc *desc)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if a blitter interrupt */
        if (ints & IF_BLIT) {
                amiga_custom.intreq = IF_BLIT;
-               m68k_handle_int(IRQ_AMIGA_BLIT);
+               generic_handle_irq(IRQ_AMIGA_BLIT);
        }
 
        /* if a copper interrupt */
        if (ints & IF_COPER) {
                amiga_custom.intreq = IF_COPER;
-               m68k_handle_int(IRQ_AMIGA_COPPER);
+               generic_handle_irq(IRQ_AMIGA_COPPER);
        }
 
        /* if a vertical blank interrupt */
        if (ints & IF_VERTB) {
                amiga_custom.intreq = IF_VERTB;
-               m68k_handle_int(IRQ_AMIGA_VERTB);
+               generic_handle_irq(IRQ_AMIGA_VERTB);
        }
-       return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int4(int irq, void *dev_id)
+static void ami_int4(unsigned int irq, struct irq_desc *desc)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if audio 0 interrupt */
        if (ints & IF_AUD0) {
                amiga_custom.intreq = IF_AUD0;
-               m68k_handle_int(IRQ_AMIGA_AUD0);
+               generic_handle_irq(IRQ_AMIGA_AUD0);
        }
 
        /* if audio 1 interrupt */
        if (ints & IF_AUD1) {
                amiga_custom.intreq = IF_AUD1;
-               m68k_handle_int(IRQ_AMIGA_AUD1);
+               generic_handle_irq(IRQ_AMIGA_AUD1);
        }
 
        /* if audio 2 interrupt */
        if (ints & IF_AUD2) {
                amiga_custom.intreq = IF_AUD2;
-               m68k_handle_int(IRQ_AMIGA_AUD2);
+               generic_handle_irq(IRQ_AMIGA_AUD2);
        }
 
        /* if audio 3 interrupt */
        if (ints & IF_AUD3) {
                amiga_custom.intreq = IF_AUD3;
-               m68k_handle_int(IRQ_AMIGA_AUD3);
+               generic_handle_irq(IRQ_AMIGA_AUD3);
        }
-       return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int5(int irq, void *dev_id)
+static void ami_int5(unsigned int irq, struct irq_desc *desc)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if serial receive buffer full interrupt */
        if (ints & IF_RBF) {
                /* acknowledge of IF_RBF must be done by the serial interrupt */
-               m68k_handle_int(IRQ_AMIGA_RBF);
+               generic_handle_irq(IRQ_AMIGA_RBF);
        }
 
        /* if a disk sync interrupt */
        if (ints & IF_DSKSYN) {
                amiga_custom.intreq = IF_DSKSYN;
-               m68k_handle_int(IRQ_AMIGA_DSKSYN);
+               generic_handle_irq(IRQ_AMIGA_DSKSYN);
        }
-       return IRQ_HANDLED;
+}
+
+
+/*
+ * void amiga_init_IRQ(void)
+ *
+ * Parameters: None
+ *
+ * Returns:    Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the amiga IRQ handling routines.
+ */
+
+void __init amiga_init_IRQ(void)
+{
+       m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER,
+                                 AMI_STD_IRQS);
+
+       irq_set_chained_handler(IRQ_AUTO_1, ami_int1);
+       irq_set_chained_handler(IRQ_AUTO_3, ami_int3);
+       irq_set_chained_handler(IRQ_AUTO_4, ami_int4);
+       irq_set_chained_handler(IRQ_AUTO_5, ami_int5);
+
+       /* turn off PCMCIA interrupts */
+       if (AMIGAHW_PRESENT(PCMCIA))
+               gayle.inten = GAYLE_IRQ_IDE;
+
+       /* turn off all interrupts and enable the master interrupt bit */
+       amiga_custom.intena = 0x7fff;
+       amiga_custom.intreq = 0x7fff;
+       amiga_custom.intena = IF_SETCLR | IF_INTEN;
+
+       cia_init_IRQ(&ciaa_base);
+       cia_init_IRQ(&ciab_base);
 }
index ecd0f7ca6f0e34caca534e4dcc3a445805649741..18c0e29976e37475cf822b5b11d9bf32437791eb 100644 (file)
@@ -93,13 +93,14 @@ static irqreturn_t cia_handler(int irq, void *dev_id)
        amiga_custom.intreq = base->int_mask;
        for (; ints; mach_irq++, ints >>= 1) {
                if (ints & 1)
-                       m68k_handle_int(mach_irq);
+                       generic_handle_irq(mach_irq);
        }
        return IRQ_HANDLED;
 }
 
-static void cia_enable_irq(unsigned int irq)
+static void cia_irq_enable(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
        unsigned char mask;
 
        if (irq >= IRQ_AMIGA_CIAB) {
@@ -113,19 +114,20 @@ static void cia_enable_irq(unsigned int irq)
        }
 }
 
-static void cia_disable_irq(unsigned int irq)
+static void cia_irq_disable(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        if (irq >= IRQ_AMIGA_CIAB)
                cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
        else
                cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
 }
 
-static struct irq_controller cia_irq_controller = {
+static struct irq_chip cia_irq_chip = {
        .name           = "cia",
-       .lock           = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock),
-       .enable         = cia_enable_irq,
-       .disable        = cia_disable_irq,
+       .irq_enable     = cia_irq_enable,
+       .irq_disable    = cia_irq_disable,
 };
 
 /*
@@ -134,9 +136,9 @@ static struct irq_controller cia_irq_controller = {
  * into this chain.
  */
 
-static void auto_enable_irq(unsigned int irq)
+static void auto_irq_enable(struct irq_data *data)
 {
-       switch (irq) {
+       switch (data->irq) {
        case IRQ_AUTO_2:
                amiga_custom.intena = IF_SETCLR | IF_PORTS;
                break;
@@ -146,9 +148,9 @@ static void auto_enable_irq(unsigned int irq)
        }
 }
 
-static void auto_disable_irq(unsigned int irq)
+static void auto_irq_disable(struct irq_data *data)
 {
-       switch (irq) {
+       switch (data->irq) {
        case IRQ_AUTO_2:
                amiga_custom.intena = IF_PORTS;
                break;
@@ -158,24 +160,25 @@ static void auto_disable_irq(unsigned int irq)
        }
 }
 
-static struct irq_controller auto_irq_controller = {
+static struct irq_chip auto_irq_chip = {
        .name           = "auto",
-       .lock           = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
-       .enable         = auto_enable_irq,
-       .disable        = auto_disable_irq,
+       .irq_enable     = auto_irq_enable,
+       .irq_disable    = auto_irq_disable,
 };
 
 void __init cia_init_IRQ(struct ciabase *base)
 {
-       m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS);
+       m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq,
+                                 base->cia_irq, CIA_IRQS);
 
        /* clear any pending interrupt and turn off all interrupts */
        cia_set_irq(base, CIA_ICR_ALL);
        cia_able_irq(base, CIA_ICR_ALL);
 
        /* override auto int and install CIA handler */
-       m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1);
-       m68k_irq_startup(base->handler_irq);
+       m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq,
+                                 base->handler_irq, 1);
+       m68k_irq_startup_irq(base->handler_irq);
        if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED,
                        base->name, base))
                pr_err("Couldn't register %s interrupt\n", base->name);
index 5d47f3aa3810fb0d5af3abab09a01156fa6b2a7f..17be1e7e2df296dae497bebb81cd45d25184bd6d 100644 (file)
@@ -1,19 +1,13 @@
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
-#include <asm/irq.h>
 #include <asm/traps.h>
 #include <asm/apollohw.h>
 
-void dn_process_int(unsigned int irq, struct pt_regs *fp)
+unsigned int apollo_irq_startup(struct irq_data *data)
 {
-       __m68k_handle_int(irq, fp);
+       unsigned int irq = data->irq;
 
-       *(volatile unsigned char *)(pica)=0x20;
-       *(volatile unsigned char *)(picb)=0x20;
-}
-
-int apollo_irq_startup(unsigned int irq)
-{
        if (irq < 8)
                *(volatile unsigned char *)(pica+1) &= ~(1 << irq);
        else
@@ -21,24 +15,33 @@ int apollo_irq_startup(unsigned int irq)
        return 0;
 }
 
-void apollo_irq_shutdown(unsigned int irq)
+void apollo_irq_shutdown(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        if (irq < 8)
                *(volatile unsigned char *)(pica+1) |= (1 << irq);
        else
                *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8));
 }
 
-static struct irq_controller apollo_irq_controller = {
+void apollo_irq_eoi(struct irq_data *data)
+{
+       *(volatile unsigned char *)(pica) = 0x20;
+       *(volatile unsigned char *)(picb) = 0x20;
+}
+
+static struct irq_chip apollo_irq_chip = {
        .name           = "apollo",
-       .lock           = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock),
-       .startup        = apollo_irq_startup,
-       .shutdown       = apollo_irq_shutdown,
+       .irq_startup    = apollo_irq_startup,
+       .irq_shutdown   = apollo_irq_shutdown,
+       .irq_eoi        = apollo_irq_eoi,
 };
 
 
 void __init dn_init_IRQ(void)
 {
-       m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int);
-       m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16);
+       m68k_setup_user_interrupt(VEC_USER + 96, 16);
+       m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq,
+                                 IRQ_APOLLO, 16);
 }
index 26a804e67bced56a5d447ae66d23ce40c3e3fd97..6d196dadfdbc3dae5edca91a509527709ea8092c 100644 (file)
  * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
  * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
  * be allocated by atari_register_vme_int().
- *
- * Each interrupt can be of three types:
- *
- *  - SLOW: The handler runs with all interrupts enabled, except the one it
- *    was called by (to avoid reentering). This should be the usual method.
- *    But it is currently possible only for MFP ints, since only the MFP
- *    offers an easy way to mask interrupts.
- *
- *  - FAST: The handler runs with all interrupts disabled. This should be used
- *    only for really fast handlers, that just do actions immediately
- *    necessary, and let the rest do a bottom half or task queue.
- *
- *  - PRIORITIZED: The handler can be interrupted by higher-level ints
- *    (greater IPL, no MFP priorities!). This is the method of choice for ints
- *    which should be slow, but are not from a MFP.
- *
- * The feature of more than one handler for one int source is still there, but
- * only applicable if all handers are of the same type. To not slow down
- * processing of ints with only one handler by the chaining feature, the list
- * calling function atari_call_irq_list() is only plugged in at the time the
- * second handler is registered.
- *
- * Implementation notes: For fast-as-possible int handling, there are separate
- * entry points for each type (slow/fast/prio). The assembler handler calls
- * the irq directly in the usual case, no C wrapper is involved. In case of
- * multiple handlers, atari_call_irq_list() is registered as handler and calls
- * in turn the real irq's. To ease access from assembler level to the irq
- * function pointer and accompanying data, these two are stored in a separate
- * array, irq_handler[]. The rest of data (type, name) are put into a second
- * array, irq_param, that is accessed from C only. For each slow interrupt (32
- * in all) there are separate handler functions, which makes it possible to
- * hard-code the MFP register address and value, are necessary to mask the
- * int. If there'd be only one generic function, lots of calculations would be
- * needed to determine MFP register and int mask from the vector number :-(
- *
- * Furthermore, slow ints may not lower the IPL below its previous value
- * (before the int happened). This is needed so that an int of class PRIO, on
- * that this int may be stacked, cannot be reentered. This feature is
- * implemented as follows: If the stack frame format is 1 (throwaway), the int
- * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level
- * 2, which still blocks the HSYNC, but no interrupts of interest. If the
- * frame format is 0, the int is nested, and the old IPL value can be found in
- * the sr copy in the frame.
- */
-
-#if 0
-
-#define        NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
-
-typedef void (*asm_irq_handler)(void);
-
-struct irqhandler {
-       irqreturn_t (*handler)(int, void *, struct pt_regs *);
-       void    *dev_id;
-};
-
-struct irqparam {
-       unsigned long   flags;
-       const char      *devname;
-};
-
-/*
- * Array with irq's and their parameter data. This array is accessed from low
- * level assembler code, so an element size of 8 allows usage of index scaling
- * addressing mode.
  */
-static struct irqhandler irq_handler[NUM_INT_SOURCES];
-
-/*
- * This array hold the rest of parameters of int handlers: type
- * (slow,fast,prio) and the name of the handler. These values are only
- * accessed from C
- */
-static struct irqparam irq_param[NUM_INT_SOURCES];
-
-/* check for valid int number (complex, sigh...) */
-#define        IS_VALID_INTNO(n)                                                                                       \
-       ((n) > 0 &&                                                                                                             \
-        /* autovec and ST-MFP ok anyway */                                                             \
-        (((n) < TTMFP_SOURCE_BASE) ||                                                                  \
-         /* TT-MFP ok if present */                                                                    \
-         ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE &&                 \
-          ATARIHW_PRESENT(TT_MFP)) ||                                                                  \
-         /* SCC ok if present and number even */                                               \
-         ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE &&                   \
-          !((n) & 1) && ATARIHW_PRESENT(SCC)) ||                                               \
-         /* greater numbers ok if they are registered VME vectors */           \
-         ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \
-                 free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE)))))
-
-
-/*
- * Here start the assembler entry points for interrupts
- */
-
-#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void)
-
-#define        BUILD_SLOW_IRQ(n)                                                  \
-asmlinkage void IRQ_NAME(n);                                              \
-/* Dummy function to allow asm with operands.  */                         \
-void atari_slow_irq_##n##_dummy (void) {                                  \
-__asm__ (__ALIGN_STR "\n"                                                 \
-"atari_slow_irq_" #n "_handler:\t"                                        \
-"      addl    %6,%5\n"        /* preempt_count() += HARDIRQ_OFFSET */    \
-       SAVE_ALL_INT "\n"                                                  \
-       GET_CURRENT(%%d0) "\n"                                             \
-"      andb    #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */          \
-       /* get old IPL from stack frame */                                 \
-"      bfextu  %%sp@(%c2){#5,#3},%%d0\n"                                  \
-"      movew   %%sr,%%d1\n"                                               \
-"      bfins   %%d0,%%d1{#21,#3}\n"                                       \
-"      movew   %%d1,%%sr\n"            /* set IPL = previous value */     \
-"      addql   #1,%a0\n"                                                  \
-"      lea     %a1,%%a0\n"                                                \
-"      pea     %%sp@\n"                /* push addr of frame */           \
-"      movel   %%a0@(4),%%sp@-\n"      /* push handler data */            \
-"      pea     (%c3+8)\n"              /* push int number */              \
-"      movel   %%a0@,%%a0\n"                                              \
-"      jbsr    %%a0@\n"                /* call the handler */             \
-"      addql   #8,%%sp\n"                                                 \
-"      addql   #4,%%sp\n"                                                 \
-"      orw     #0x0600,%%sr\n"                                            \
-"      andw    #0xfeff,%%sr\n"         /* set IPL = 6 again */            \
-"      orb     #(1<<(%c3&7)),%a4:w\n"  /* now unmask the int again */     \
-"      jbra    ret_from_interrupt\n"                                      \
-        : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]),       \
-            "n" (PT_OFF_SR), "n" (n),                                     \
-            "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a)   \
-                       : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \
-            "m" (preempt_count()), "di" (HARDIRQ_OFFSET)                  \
-);                                                                        \
-       for (;;);                       /* fake noreturn */                \
-}
-
-BUILD_SLOW_IRQ(0);
-BUILD_SLOW_IRQ(1);
-BUILD_SLOW_IRQ(2);
-BUILD_SLOW_IRQ(3);
-BUILD_SLOW_IRQ(4);
-BUILD_SLOW_IRQ(5);
-BUILD_SLOW_IRQ(6);
-BUILD_SLOW_IRQ(7);
-BUILD_SLOW_IRQ(8);
-BUILD_SLOW_IRQ(9);
-BUILD_SLOW_IRQ(10);
-BUILD_SLOW_IRQ(11);
-BUILD_SLOW_IRQ(12);
-BUILD_SLOW_IRQ(13);
-BUILD_SLOW_IRQ(14);
-BUILD_SLOW_IRQ(15);
-BUILD_SLOW_IRQ(16);
-BUILD_SLOW_IRQ(17);
-BUILD_SLOW_IRQ(18);
-BUILD_SLOW_IRQ(19);
-BUILD_SLOW_IRQ(20);
-BUILD_SLOW_IRQ(21);
-BUILD_SLOW_IRQ(22);
-BUILD_SLOW_IRQ(23);
-BUILD_SLOW_IRQ(24);
-BUILD_SLOW_IRQ(25);
-BUILD_SLOW_IRQ(26);
-BUILD_SLOW_IRQ(27);
-BUILD_SLOW_IRQ(28);
-BUILD_SLOW_IRQ(29);
-BUILD_SLOW_IRQ(30);
-BUILD_SLOW_IRQ(31);
-
-asm_irq_handler slow_handlers[32] = {
-       [0]     = atari_slow_irq_0_handler,
-       [1]     = atari_slow_irq_1_handler,
-       [2]     = atari_slow_irq_2_handler,
-       [3]     = atari_slow_irq_3_handler,
-       [4]     = atari_slow_irq_4_handler,
-       [5]     = atari_slow_irq_5_handler,
-       [6]     = atari_slow_irq_6_handler,
-       [7]     = atari_slow_irq_7_handler,
-       [8]     = atari_slow_irq_8_handler,
-       [9]     = atari_slow_irq_9_handler,
-       [10]    = atari_slow_irq_10_handler,
-       [11]    = atari_slow_irq_11_handler,
-       [12]    = atari_slow_irq_12_handler,
-       [13]    = atari_slow_irq_13_handler,
-       [14]    = atari_slow_irq_14_handler,
-       [15]    = atari_slow_irq_15_handler,
-       [16]    = atari_slow_irq_16_handler,
-       [17]    = atari_slow_irq_17_handler,
-       [18]    = atari_slow_irq_18_handler,
-       [19]    = atari_slow_irq_19_handler,
-       [20]    = atari_slow_irq_20_handler,
-       [21]    = atari_slow_irq_21_handler,
-       [22]    = atari_slow_irq_22_handler,
-       [23]    = atari_slow_irq_23_handler,
-       [24]    = atari_slow_irq_24_handler,
-       [25]    = atari_slow_irq_25_handler,
-       [26]    = atari_slow_irq_26_handler,
-       [27]    = atari_slow_irq_27_handler,
-       [28]    = atari_slow_irq_28_handler,
-       [29]    = atari_slow_irq_29_handler,
-       [30]    = atari_slow_irq_30_handler,
-       [31]    = atari_slow_irq_31_handler
-};
-
-asmlinkage void atari_fast_irq_handler( void );
-asmlinkage void atari_prio_irq_handler( void );
-
-/* Dummy function to allow asm with operands.  */
-void atari_fast_prio_irq_dummy (void) {
-__asm__ (__ALIGN_STR "\n"
-"atari_fast_irq_handler:\n\t"
-       "orw    #0x700,%%sr\n"          /* disable all interrupts */
-"atari_prio_irq_handler:\n\t"
-       "addl   %3,%2\n\t"              /* preempt_count() += HARDIRQ_OFFSET */
-       SAVE_ALL_INT "\n\t"
-       GET_CURRENT(%%d0) "\n\t"
-       /* get vector number from stack frame and convert to source */
-       "bfextu %%sp@(%c1){#4,#10},%%d0\n\t"
-       "subw   #(0x40-8),%%d0\n\t"
-       "jpl    1f\n\t"
-       "addw   #(0x40-8-0x18),%%d0\n"
-    "1:\tlea   %a0,%%a0\n\t"
-       "addql  #1,%%a0@(%%d0:l:4)\n\t"
-       "lea    irq_handler,%%a0\n\t"
-       "lea    %%a0@(%%d0:l:8),%%a0\n\t"
-       "pea    %%sp@\n\t"              /* push frame address */
-       "movel  %%a0@(4),%%sp@-\n\t"    /* push handler data */
-       "movel  %%d0,%%sp@-\n\t"        /* push int number */
-       "movel  %%a0@,%%a0\n\t"
-       "jsr    %%a0@\n\t"              /* and call the handler */
-       "addql  #8,%%sp\n\t"
-       "addql  #4,%%sp\n\t"
-       "jbra   ret_from_interrupt"
-        : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
-            "m" (preempt_count()), "di" (HARDIRQ_OFFSET)
-);
-       for (;;);
-}
-#endif
 
 /*
  * Bitmap for free interrupt vector numbers
@@ -320,31 +84,44 @@ extern void atari_microwire_cmd(int cmd);
 
 extern int atari_SCC_reset_done;
 
-static int atari_startup_irq(unsigned int irq)
+static unsigned int atari_irq_startup(struct irq_data *data)
 {
-       m68k_irq_startup(irq);
+       unsigned int irq = data->irq;
+
+       m68k_irq_startup(data);
        atari_turnon_irq(irq);
        atari_enable_irq(irq);
        return 0;
 }
 
-static void atari_shutdown_irq(unsigned int irq)
+static void atari_irq_shutdown(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        atari_disable_irq(irq);
        atari_turnoff_irq(irq);
-       m68k_irq_shutdown(irq);
+       m68k_irq_shutdown(data);
 
        if (irq == IRQ_AUTO_4)
            vectors[VEC_INT4] = falcon_hblhandler;
 }
 
-static struct irq_controller atari_irq_controller = {
+static void atari_irq_enable(struct irq_data *data)
+{
+       atari_enable_irq(data->irq);
+}
+
+static void atari_irq_disable(struct irq_data *data)
+{
+       atari_disable_irq(data->irq);
+}
+
+static struct irq_chip atari_irq_chip = {
        .name           = "atari",
-       .lock           = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
-       .startup        = atari_startup_irq,
-       .shutdown       = atari_shutdown_irq,
-       .enable         = atari_enable_irq,
-       .disable        = atari_disable_irq,
+       .irq_startup    = atari_irq_startup,
+       .irq_shutdown   = atari_irq_shutdown,
+       .irq_enable     = atari_irq_enable,
+       .irq_disable    = atari_irq_disable,
 };
 
 /*
@@ -360,8 +137,9 @@ static struct irq_controller atari_irq_controller = {
 
 void __init atari_init_IRQ(void)
 {
-       m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
-       m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
+       m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER);
+       m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1,
+                                 NUM_ATARI_SOURCES - 1);
 
        /* Initialize the MFP(s) */
 
index a0531f34c617ca90df986902735e0b6ae5d26574..c0cc68a2c82984d619eb7ac4c91b8eb704837e0d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include <asm/atariints.h>
 
index 1edd95095cb4f6c9b1bc59a6fd219693f19454e6..81286476f7403c1a273350d686ea32d65f0b7533 100644 (file)
@@ -86,7 +86,7 @@ static void bvme6000_get_model(char *model)
  */
 static void __init bvme6000_init_IRQ(void)
 {
-       m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+       m68k_setup_user_interrupt(VEC_USER, 192);
 }
 
 void __init config_bvme6000(void)
index f6312c7d87276a1c2e4b23005874a0b247689c8a..c87fe69b0728bdccab9d2081c2ed6be95be16dca 100644 (file)
@@ -70,7 +70,7 @@ void __init hp300_sched_init(irq_handler_t vector)
 
   asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
 
-  if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector))
+  if (request_irq(IRQ_AUTO_6, hp300_tick, 0, "timer tick", vector))
     pr_err("Couldn't register timer interrupt\n");
 
   out_8(CLOCKBASE + CLKCR2, 0x1);              /* select CR1 */
index 870e5347155b373a386fd1a8a13c47c43395cd51..db30ed276878dcbf793e667d6edb279c5234a60a 100644 (file)
 
 #ifdef CONFIG_MMU
 
+static inline void ack_bad_irq(unsigned int irq)
+{
+       pr_crit("unexpected IRQ trap at vector %02x\n", irq);
+}
+
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
        unsigned int __softirq_pending;
index 69ed0d74d5327a8af398b061daf5184649fd3862..6198df5ff245346971e3b947944591c50955a8ab 100644 (file)
 
 #ifdef CONFIG_MMU
 
-#include <linux/linkage.h>
-#include <linux/hardirq.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock_types.h>
-
 /*
  * Interrupt source definitions
  * General interrupt sources are the level 1-7.
 
 #define IRQ_USER       8
 
-extern unsigned int irq_canonicalize(unsigned int irq);
-
-struct pt_regs;
-
 /*
  * various flags for request_irq() - the Amiga now uses the standard
  * mechanism like all other architectures - IRQF_DISABLED and
@@ -71,57 +62,27 @@ struct pt_regs;
 #define IRQ_FLG_STD    (0x8000)        /* internally used              */
 #endif
 
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
-       irqreturn_t     (*handler)(int, void *);
-       void            *dev_id;
-       struct irq_node *next;
-       unsigned long   flags;
-       const char      *devname;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-struct irq_handler {
-       int             (*handler)(int, void *);
-       unsigned long   flags;
-       void            *dev_id;
-       const char      *devname;
-};
-
-struct irq_controller {
-       const char *name;
-       spinlock_t lock;
-       int (*startup)(unsigned int irq);
-       void (*shutdown)(unsigned int irq);
-       void (*enable)(unsigned int irq);
-       void (*disable)(unsigned int irq);
-};
-
-extern int m68k_irq_startup(unsigned int);
-extern void m68k_irq_shutdown(unsigned int);
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
+struct irq_data;
+struct irq_chip;
+struct irq_desc;
+extern unsigned int m68k_irq_startup(struct irq_data *data);
+extern unsigned int m68k_irq_startup_irq(unsigned int irq);
+extern void m68k_irq_shutdown(struct irq_data *data);
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int,
+                                                     struct pt_regs *));
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt);
+extern void m68k_setup_irq_controller(struct irq_chip *,
+                                     void (*handle)(unsigned int irq,
+                                                    struct irq_desc *desc),
+                                     unsigned int irq, unsigned int cnt);
 
-extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
-                                     void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
-
-asmlinkage void m68k_handle_int(unsigned int);
-asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
+extern unsigned int irq_canonicalize(unsigned int irq);
 
 #else
 #define irq_canonicalize(irq)  (irq)
 #endif /* CONFIG_MMU */
 
 asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+extern atomic_t irq_err_count;
 
 #endif /* _M68K_IRQ_H_ */
index c2a1c5eac1a636367b0b59437fe478ae2d4a0aca..12ebe43b008b511839eb5825e08ee16d3fb7adaf 100644 (file)
@@ -12,6 +12,8 @@ extern void mac_reset(void);
 extern void mac_poweroff(void);
 extern void mac_init_IRQ(void);
 extern int mac_irq_pending(unsigned int);
+extern void mac_irq_enable(struct irq_data *data);
+extern void mac_irq_disable(struct irq_data *data);
 
 /*
  *     Floppy driver magic hook - probably shouldn't be here
index 3d970afb708fc5bd19937cef0afefea56e8279db..22f12c9eb910d62f4d693e9a26f9f01696670034 100644 (file)
@@ -24,6 +24,3 @@
 #define Q40_IRQ10_MASK       (1<<5)
 #define Q40_IRQ14_MASK       (1<<6)
 #define Q40_IRQ15_MASK       (1<<7)
-
-extern unsigned long q40_probe_irq_on (void);
-extern int q40_probe_irq_off (unsigned long irqs);
index 43f984e93970b8acbabbfd6554920a4b4fb265f4..303192fc9260d50f44cdf6e7ef0371a2fc41d9da 100644 (file)
 #define __NR_clock_adjtime     342
 #define __NR_syncfs            343
 #define __NR_setns             344
+#define __NR_process_vm_readv  345
+#define __NR_process_vm_writev 346
 
 #ifdef __KERNEL__
 
-#define NR_syscalls            345
+#define NR_syscalls            347
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index e7f0f2e5ad4478a767732c70f229b78aca753383..c5696193281a16a405be19906d649091c273de42 100644 (file)
@@ -6,16 +6,15 @@ extra-$(CONFIG_MMU)   := head.o
 extra-$(CONFIG_SUN3)   := sun3-head.o
 extra-y                        += vmlinux.lds
 
-obj-y  := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
-          sys_m68k.o syscalltable.o time.o traps.o
+obj-y  := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \
+          signal.o sys_m68k.o syscalltable.o time.o traps.o
 
-obj-$(CONFIG_MMU)      += ints.o devres.o vectors.o
-devres-$(CONFIG_MMU)   = ../../../kernel/irq/devres.o
+obj-$(CONFIG_MMU)      += ints.o vectors.o
 
 ifndef CONFIG_MMU_SUN3
 obj-y                  += dma.o
 endif
 ifndef CONFIG_MMU
-obj-y                  += init_task.o irq.o
+obj-y                  += init_task.o
 endif
 
index 4bbb3c2a888057e93c264c76e029909dc7bd8884..a3c471b523f249fa18457cca5b82fc07261c025e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include <asm/pgalloc.h>
 
index fc61541aeb715f6f872ce55275fdf3eb1965275f..f1dc3fc71bc270df5d799ad5129811c3085b6f35 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <asm/cacheflush.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
index bd0ec05263b2f3bc047c8008a5453e7cd98ceb31..c713f514843dbbea4ef6b42dcbec445e53847def 100644 (file)
@@ -48,7 +48,7 @@
 .globl sys_fork, sys_clone, sys_vfork
 .globl ret_from_interrupt, bad_interrupt
 .globl auto_irqhandler_fixup
-.globl user_irqvec_fixup, user_irqhandler_fixup
+.globl user_irqvec_fixup
 
 .text
 ENTRY(buserr)
@@ -207,7 +207,7 @@ ENTRY(auto_inthandler)
        movel   %sp,%sp@-
        movel   %d0,%sp@-               |  put vector # on stack
 auto_irqhandler_fixup = . + 2
-       jsr     __m68k_handle_int       |  process the IRQ
+       jsr     do_IRQ                  |  process the IRQ
        addql   #8,%sp                  |  pop parameters off stack
 
 ret_from_interrupt:
@@ -240,8 +240,7 @@ user_irqvec_fixup = . + 2
 
        movel   %sp,%sp@-
        movel   %d0,%sp@-               |  put vector # on stack
-user_irqhandler_fixup = . + 2
-       jsr     __m68k_handle_int       |  process the IRQ
+       jsr     do_IRQ                  |  process the IRQ
        addql   #8,%sp                  |  pop parameters off stack
 
        subqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
index 761ee0440c996a29d4fe784f56571e2cab3358ee..74fefac00899893add2d342726fe2d2050f88cac 100644 (file)
@@ -4,25 +4,6 @@
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
- *
- * 07/03/96: Timer initialization, and thus mach_sched_init(),
- *           removed from request_irq() and moved to init_time().
- *           We should therefore consider renaming our add_isr() and
- *           remove_isr() to request_irq() and free_irq()
- *           respectively, so they are compliant with the other
- *           architectures.                                     /Jes
- * 11/07/96: Changed all add_/remove_isr() to request_/free_irq() calls.
- *           Removed irq list support, if any machine needs an irq server
- *           it must implement this itself (as it's already done), instead
- *           only default handler are used with mach_default_handler.
- *           request_irq got some flags different from other architectures:
- *           - IRQ_FLG_REPLACE : Replace an existing handler (the default one
- *                               can be replaced without this flag)
- *           - IRQ_FLG_LOCK : handler can't be replaced
- *           There are other machine depending flags, see there
- *           If you want to replace a default handler you should know what
- *           you're doing, since it might handle different other irq sources
- *           which must be served                               /Roman Zippel
  */
 
 #include <linux/module.h>
 #endif
 
 extern u32 auto_irqhandler_fixup[];
-extern u32 user_irqhandler_fixup[];
 extern u16 user_irqvec_fixup[];
 
-/* table for system interrupt handlers */
-static struct irq_node *irq_list[NR_IRQS];
-static struct irq_controller *irq_controller[NR_IRQS];
-static int irq_depth[NR_IRQS];
-
 static int m68k_first_user_vec;
 
-static struct irq_controller auto_irq_controller = {
+static struct irq_chip auto_irq_chip = {
        .name           = "auto",
-       .lock           = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
-       .startup        = m68k_irq_startup,
-       .shutdown       = m68k_irq_shutdown,
+       .irq_startup    = m68k_irq_startup,
+       .irq_shutdown   = m68k_irq_shutdown,
 };
 
-static struct irq_controller user_irq_controller = {
+static struct irq_chip user_irq_chip = {
        .name           = "user",
-       .lock           = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock),
-       .startup        = m68k_irq_startup,
-       .shutdown       = m68k_irq_shutdown,
+       .irq_startup    = m68k_irq_startup,
+       .irq_shutdown   = m68k_irq_shutdown,
 };
 
-#define NUM_IRQ_NODES 100
-static irq_node_t nodes[NUM_IRQ_NODES];
-
 /*
  * void init_IRQ(void)
  *
@@ -96,7 +66,7 @@ void __init init_IRQ(void)
        }
 
        for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
-               irq_controller[i] = &auto_irq_controller;
+               irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
 
        mach_init_IRQ();
 }
@@ -106,7 +76,7 @@ void __init init_IRQ(void)
  * @handler: called from auto vector interrupts
  *
  * setup the handler to be called from auto vector interrupts instead of the
- * standard __m68k_handle_int(), it will be called with irq numbers in the range
+ * standard do_IRQ(), it will be called with irq numbers in the range
  * from IRQ_AUTO_1 - IRQ_AUTO_7.
  */
 void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *))
@@ -120,217 +90,49 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re
  * m68k_setup_user_interrupt
  * @vec: first user vector interrupt to handle
  * @cnt: number of active user vector interrupts
- * @handler: called from user vector interrupts
  *
  * setup user vector interrupts, this includes activating the specified range
  * of interrupts, only then these interrupts can be requested (note: this is
- * different from auto vector interrupts). An optional handler can be installed
- * to be called instead of the default __m68k_handle_int(), it will be called
- * with irq numbers starting from IRQ_USER.
+ * different from auto vector interrupts).
  */
-void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
-                                     void (*handler)(unsigned int, struct pt_regs *))
+void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt)
 {
        int i;
 
        BUG_ON(IRQ_USER + cnt > NR_IRQS);
        m68k_first_user_vec = vec;
        for (i = 0; i < cnt; i++)
-               irq_controller[IRQ_USER + i] = &user_irq_controller;
+               irq_set_chip(IRQ_USER + i, &user_irq_chip);
        *user_irqvec_fixup = vec - IRQ_USER;
-       if (handler)
-               *user_irqhandler_fixup = (u32)handler;
        flush_icache();
 }
 
 /**
  * m68k_setup_irq_controller
- * @contr: irq controller which controls specified irq
+ * @chip: irq chip which controls specified irq
+ * @handle: flow handler which handles specified irq
  * @irq: first irq to be managed by the controller
+ * @cnt: number of irqs to be managed by the controller
  *
  * Change the controller for the specified range of irq, which will be used to
  * manage these irq. auto/user irq already have a default controller, which can
  * be changed as well, but the controller probably should use m68k_irq_startup/
  * m68k_irq_shutdown.
  */
-void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq,
+void m68k_setup_irq_controller(struct irq_chip *chip,
+                              irq_flow_handler_t handle, unsigned int irq,
                               unsigned int cnt)
 {
        int i;
 
-       for (i = 0; i < cnt; i++)
-               irq_controller[irq + i] = contr;
-}
-
-irq_node_t *new_irq_node(void)
-{
-       irq_node_t *node;
-       short i;
-
-       for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) {
-               if (!node->handler) {
-                       memset(node, 0, sizeof(*node));
-                       return node;
-               }
+       for (i = 0; i < cnt; i++) {
+               irq_set_chip(irq + i, chip);
+               if (handle)
+                       irq_set_handler(irq + i, handle);
        }
-
-       printk ("new_irq_node: out of nodes\n");
-       return NULL;
 }
 
-int setup_irq(unsigned int irq, struct irq_node *node)
-{
-       struct irq_controller *contr;
-       struct irq_node **prev;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
-               printk("%s: Incorrect IRQ %d from %s\n",
-                      __func__, irq, node->devname);
-               return -ENXIO;
-       }
-
-       spin_lock_irqsave(&contr->lock, flags);
-
-       prev = irq_list + irq;
-       if (*prev) {
-               /* Can't share interrupts unless both agree to */
-               if (!((*prev)->flags & node->flags & IRQF_SHARED)) {
-                       spin_unlock_irqrestore(&contr->lock, flags);
-                       return -EBUSY;
-               }
-               while (*prev)
-                       prev = &(*prev)->next;
-       }
-
-       if (!irq_list[irq]) {
-               if (contr->startup)
-                       contr->startup(irq);
-               else
-                       contr->enable(irq);
-       }
-       node->next = NULL;
-       *prev = node;
-
-       spin_unlock_irqrestore(&contr->lock, flags);
-
-       return 0;
-}
-
-int request_irq(unsigned int irq,
-               irq_handler_t handler,
-               unsigned long flags, const char *devname, void *dev_id)
-{
-       struct irq_node *node;
-       int res;
-
-       node = new_irq_node();
-       if (!node)
-               return -ENOMEM;
-
-       node->handler = handler;
-       node->flags   = flags;
-       node->dev_id  = dev_id;
-       node->devname = devname;
-
-       res = setup_irq(irq, node);
-       if (res)
-               node->handler = NULL;
-
-       return res;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-       struct irq_controller *contr;
-       struct irq_node **p, *node;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
-               printk("%s: Incorrect IRQ %d\n", __func__, irq);
-               return;
-       }
-
-       spin_lock_irqsave(&contr->lock, flags);
-
-       p = irq_list + irq;
-       while ((node = *p)) {
-               if (node->dev_id == dev_id)
-                       break;
-               p = &node->next;
-       }
-
-       if (node) {
-               *p = node->next;
-               node->handler = NULL;
-       } else
-               printk("%s: Removing probably wrong IRQ %d\n",
-                      __func__, irq);
-
-       if (!irq_list[irq]) {
-               if (contr->shutdown)
-                       contr->shutdown(irq);
-               else
-                       contr->disable(irq);
-       }
-
-       spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(free_irq);
-
-void enable_irq(unsigned int irq)
-{
-       struct irq_controller *contr;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
-               printk("%s: Incorrect IRQ %d\n",
-                      __func__, irq);
-               return;
-       }
-
-       spin_lock_irqsave(&contr->lock, flags);
-       if (irq_depth[irq]) {
-               if (!--irq_depth[irq]) {
-                       if (contr->enable)
-                               contr->enable(irq);
-               }
-       } else
-               WARN_ON(1);
-       spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(enable_irq);
-
-void disable_irq(unsigned int irq)
-{
-       struct irq_controller *contr;
-       unsigned long flags;
-
-       if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
-               printk("%s: Incorrect IRQ %d\n",
-                      __func__, irq);
-               return;
-       }
-
-       spin_lock_irqsave(&contr->lock, flags);
-       if (!irq_depth[irq]++) {
-               if (contr->disable)
-                       contr->disable(irq);
-       }
-       spin_unlock_irqrestore(&contr->lock, flags);
-}
-
-EXPORT_SYMBOL(disable_irq);
-
-void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
-
-EXPORT_SYMBOL(disable_irq_nosync);
-
-int m68k_irq_startup(unsigned int irq)
+unsigned int m68k_irq_startup_irq(unsigned int irq)
 {
        if (irq <= IRQ_AUTO_7)
                vectors[VEC_SPUR + irq] = auto_inthandler;
@@ -339,41 +141,21 @@ int m68k_irq_startup(unsigned int irq)
        return 0;
 }
 
-void m68k_irq_shutdown(unsigned int irq)
+unsigned int m68k_irq_startup(struct irq_data *data)
 {
-       if (irq <= IRQ_AUTO_7)
-               vectors[VEC_SPUR + irq] = bad_inthandler;
-       else
-               vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
+       return m68k_irq_startup_irq(data->irq);
 }
 
-
-/*
- * Do we need these probe functions on the m68k?
- *
- *  ... may be useful with ISA devices
- */
-unsigned long probe_irq_on (void)
+void m68k_irq_shutdown(struct irq_data *data)
 {
-#ifdef CONFIG_Q40
-       if (MACH_IS_Q40)
-               return q40_probe_irq_on();
-#endif
-       return 0;
-}
+       unsigned int irq = data->irq;
 
-EXPORT_SYMBOL(probe_irq_on);
-
-int probe_irq_off (unsigned long irqs)
-{
-#ifdef CONFIG_Q40
-       if (MACH_IS_Q40)
-               return q40_probe_irq_off(irqs);
-#endif
-       return 0;
+       if (irq <= IRQ_AUTO_7)
+               vectors[VEC_SPUR + irq] = bad_inthandler;
+       else
+               vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
 }
 
-EXPORT_SYMBOL(probe_irq_off);
 
 unsigned int irq_canonicalize(unsigned int irq)
 {
@@ -386,52 +168,9 @@ unsigned int irq_canonicalize(unsigned int irq)
 
 EXPORT_SYMBOL(irq_canonicalize);
 
-asmlinkage void m68k_handle_int(unsigned int irq)
-{
-       struct irq_node *node;
-       kstat_cpu(0).irqs[irq]++;
-       node = irq_list[irq];
-       do {
-               node->handler(irq, node->dev_id);
-               node = node->next;
-       } while (node);
-}
-
-asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs)
-{
-       struct pt_regs *old_regs;
-       old_regs = set_irq_regs(regs);
-       m68k_handle_int(irq);
-       set_irq_regs(old_regs);
-}
 
 asmlinkage void handle_badint(struct pt_regs *regs)
 {
-       kstat_cpu(0).irqs[0]++;
-       printk("unexpected interrupt from %u\n", regs->vector);
-}
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-       struct irq_controller *contr;
-       struct irq_node *node;
-       int i = *(loff_t *) v;
-
-       /* autovector interrupts */
-       if (irq_list[i]) {
-               contr = irq_controller[i];
-               node = irq_list[i];
-               seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname);
-               while ((node = node->next))
-                       seq_printf(p, ", %s", node->devname);
-               seq_puts(p, "\n");
-       }
-       return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-void init_irq_proc(void)
-{
-       /* Insert /proc/irq driver here */
+       atomic_inc(&irq_err_count);
+       pr_warn("unexpected interrupt from %u\n", regs->vector);
 }
-#endif
index c468f2edaa85ec0cd2356e392a0f0e7efddb8218..ce827b376110a6a815b4ccece0a066e5ad66cc59 100644 (file)
@@ -365,4 +365,6 @@ ENTRY(sys_call_table)
        .long sys_clock_adjtime
        .long sys_syncfs
        .long sys_setns
+       .long sys_process_vm_readv      /* 345 */
+       .long sys_process_vm_writev
 
index 2a96bebd8969eb6ef304a00c8f833e010465881c..b403924a1cad16f8ddeaf35da8003a3803041eca 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 
 #include <asm/traps.h>
 #include <asm/bootinfo.h>
@@ -20,9 +21,6 @@
 
 /* #define DEBUG_IRQS */
 
-extern void mac_enable_irq(unsigned int);
-extern void mac_disable_irq(unsigned int);
-
 int baboon_present;
 static volatile struct baboon *baboon;
 static unsigned char baboon_disabled;
@@ -53,7 +51,7 @@ void __init baboon_init(void)
  * Baboon interrupt handler. This works a lot like a VIA.
  */
 
-static irqreturn_t baboon_irq(int irq, void *dev_id)
+static void baboon_irq(unsigned int irq, struct irq_desc *desc)
 {
        int irq_bit, irq_num;
        unsigned char events;
@@ -64,15 +62,16 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
                (uint) baboon->mb_status);
 #endif
 
-       if (!(events = baboon->mb_ifr & 0x07))
-               return IRQ_NONE;
+       events = baboon->mb_ifr & 0x07;
+       if (!events)
+               return;
 
        irq_num = IRQ_BABOON_0;
        irq_bit = 1;
        do {
                if (events & irq_bit) {
                        baboon->mb_ifr &= ~irq_bit;
-                       m68k_handle_int(irq_num);
+                       generic_handle_irq(irq_num);
                }
                irq_bit <<= 1;
                irq_num++;
@@ -82,7 +81,6 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
        /* for now we need to smash all interrupts */
        baboon->mb_ifr &= ~events;
 #endif
-       return IRQ_HANDLED;
 }
 
 /*
@@ -92,8 +90,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
 void __init baboon_register_interrupts(void)
 {
        baboon_disabled = 0;
-       if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
-               pr_err("Couldn't register baboon interrupt\n");
+       irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq);
 }
 
 /*
@@ -111,7 +108,7 @@ void baboon_irq_enable(int irq)
 
        baboon_disabled &= ~(1 << irq_idx);
        if (!baboon_disabled)
-               mac_enable_irq(IRQ_NUBUS_C);
+               mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
 }
 
 void baboon_irq_disable(int irq)
@@ -124,7 +121,7 @@ void baboon_irq_disable(int irq)
 
        baboon_disabled |= 1 << irq_idx;
        if (baboon_disabled)
-               mac_disable_irq(IRQ_NUBUS_C);
+               mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
 }
 
 void baboon_irq_clear(int irq)
index 1ad4e9d80eba7f5be93f530c262636136a01b5b8..a5462cc0bfd65b70da36089b4ba6c45ef9b8c5cf 100644 (file)
@@ -305,15 +305,13 @@ void __init iop_register_interrupts(void)
 {
        if (iop_ism_present) {
                if (oss_present) {
-                       if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
-                                       IRQ_FLG_LOCK, "ISM IOP",
-                                       (void *) IOP_NUM_ISM))
+                       if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0,
+                                       "ISM IOP", (void *)IOP_NUM_ISM))
                                pr_err("Couldn't register ISM IOP interrupt\n");
                        oss_irq_enable(IRQ_MAC_ADB);
                } else {
-                       if (request_irq(IRQ_VIA2_0, iop_ism_irq,
-                                       IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP",
-                                       (void *) IOP_NUM_ISM))
+                       if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP",
+                                       (void *)IOP_NUM_ISM))
                                pr_err("Couldn't register ISM IOP interrupt\n");
                }
                if (!iop_alive(iop_base[IOP_NUM_ISM])) {
index f92190c159b47f48ee0648d64c0a353f87488477..ba220b70ab8cc5ea150c54707f366de876afa934 100644 (file)
@@ -190,14 +190,10 @@ irqreturn_t mac_debug_handler(int, void *);
 
 /* #define DEBUG_MACINTS */
 
-void mac_enable_irq(unsigned int irq);
-void mac_disable_irq(unsigned int irq);
-
-static struct irq_controller mac_irq_controller = {
+static struct irq_chip mac_irq_chip = {
        .name           = "mac",
-       .lock           = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock),
-       .enable         = mac_enable_irq,
-       .disable        = mac_disable_irq,
+       .irq_enable     = mac_irq_enable,
+       .irq_disable    = mac_irq_disable,
 };
 
 void __init mac_init_IRQ(void)
@@ -205,7 +201,7 @@ void __init mac_init_IRQ(void)
 #ifdef DEBUG_MACINTS
        printk("mac_init_IRQ(): Setting things up...\n");
 #endif
-       m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER,
+       m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER,
                                  NUM_MAC_SOURCES - IRQ_USER);
        /* Make sure the SONIC interrupt is cleared or things get ugly */
 #ifdef SHUTUP_SONIC
@@ -241,16 +237,17 @@ void __init mac_init_IRQ(void)
 }
 
 /*
- *  mac_enable_irq - enable an interrupt source
- * mac_disable_irq - disable an interrupt source
+ *  mac_irq_enable - enable an interrupt source
+ * mac_irq_disable - disable an interrupt source
  *   mac_clear_irq - clears a pending interrupt
- * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending)
+ * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
  *
  * These routines are just dispatchers to the VIA/OSS/PSC routines.
  */
 
-void mac_enable_irq(unsigned int irq)
+void mac_irq_enable(struct irq_data *data)
 {
+       int irq = data->irq;
        int irq_src = IRQ_SRC(irq);
 
        switch(irq_src) {
@@ -283,8 +280,9 @@ void mac_enable_irq(unsigned int irq)
        }
 }
 
-void mac_disable_irq(unsigned int irq)
+void mac_irq_disable(struct irq_data *data)
 {
+       int irq = data->irq;
        int irq_src = IRQ_SRC(irq);
 
        switch(irq_src) {
index a9c0f5ab4cc0251213dd8e1e034f7007d9d8a6d9..a4c82dab9ff1acd3d9d5f90aafa8fb2c55a913f9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 
 #include <asm/bootinfo.h>
 #include <asm/macintosh.h>
 int oss_present;
 volatile struct mac_oss *oss;
 
-static irqreturn_t oss_irq(int, void *);
-static irqreturn_t oss_nubus_irq(int, void *);
-
-extern irqreturn_t via1_irq(int, void *);
+extern void via1_irq(unsigned int irq, struct irq_desc *desc);
 
 /*
  * Initialize the OSS
@@ -59,26 +57,6 @@ void __init oss_init(void)
        oss->irq_level[OSS_VIA1] = OSS_IRQLEV_VIA1;
 }
 
-/*
- * Register the OSS and NuBus interrupt dispatchers.
- */
-
-void __init oss_register_interrupts(void)
-{
-       if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
-                       "scsi", (void *) oss))
-               pr_err("Couldn't register %s interrupt\n", "scsi");
-       if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
-                       "nubus", (void *) oss))
-               pr_err("Couldn't register %s interrupt\n", "nubus");
-       if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
-                       "sound", (void *) oss))
-               pr_err("Couldn't register %s interrupt\n", "sound");
-       if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
-                       "via1", (void *) via1))
-               pr_err("Couldn't register %s interrupt\n", "via1");
-}
-
 /*
  * Initialize OSS for Nubus access
  */
@@ -92,17 +70,17 @@ void __init oss_nubus_init(void)
  * and SCSI; everything else is routed to its own autovector IRQ.
  */
 
-static irqreturn_t oss_irq(int irq, void *dev_id)
+static void oss_irq(unsigned int irq, struct irq_desc *desc)
 {
        int events;
 
        events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI);
        if (!events)
-               return IRQ_NONE;
+               return;
 
 #ifdef DEBUG_IRQS
        if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) {
-               printk("oss_irq: irq %d events = 0x%04X\n", irq,
+               printk("oss_irq: irq %u events = 0x%04X\n", irq,
                        (int) oss->irq_pending);
        }
 #endif
@@ -113,11 +91,10 @@ static irqreturn_t oss_irq(int irq, void *dev_id)
                /* FIXME: call sound handler */
        } else if (events & OSS_IP_SCSI) {
                oss->irq_pending &= ~OSS_IP_SCSI;
-               m68k_handle_int(IRQ_MAC_SCSI);
+               generic_handle_irq(IRQ_MAC_SCSI);
        } else {
                /* FIXME: error check here? */
        }
-       return IRQ_HANDLED;
 }
 
 /*
@@ -126,13 +103,13 @@ static irqreturn_t oss_irq(int irq, void *dev_id)
  * Unlike the VIA/RBV this is on its own autovector interrupt level.
  */
 
-static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
+static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc)
 {
        int events, irq_bit, i;
 
        events = oss->irq_pending & OSS_IP_NUBUS;
        if (!events)
-               return IRQ_NONE;
+               return;
 
 #ifdef DEBUG_NUBUS_INT
        if (console_loglevel > 7) {
@@ -148,10 +125,21 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
                irq_bit >>= 1;
                if (events & irq_bit) {
                        oss->irq_pending &= ~irq_bit;
-                       m68k_handle_int(NUBUS_SOURCE_BASE + i);
+                       generic_handle_irq(NUBUS_SOURCE_BASE + i);
                }
        } while(events & (irq_bit - 1));
-       return IRQ_HANDLED;
+}
+
+/*
+ * Register the OSS and NuBus interrupt dispatchers.
+ */
+
+void __init oss_register_interrupts(void)
+{
+       irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq);
+       irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq);
+       irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq);
+       irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq);
 }
 
 /*
index a4c3eb60706ebc8266fe4eeb377c36b30f0b8ba9..e6c2d20f328d0599192994721fe72b3f1adaf90a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 
 #include <asm/traps.h>
 #include <asm/bootinfo.h>
@@ -30,8 +31,6 @@
 int psc_present;
 volatile __u8 *psc;
 
-irqreturn_t psc_irq(int, void *);
-
 /*
  * Debugging dump, used in various places to see what's going on.
  */
@@ -111,53 +110,53 @@ void __init psc_init(void)
        }
 }
 
-/*
- * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
- */
-
-void __init psc_register_interrupts(void)
-{
-       if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30))
-               pr_err("Couldn't register psc%d interrupt\n", 3);
-       if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40))
-               pr_err("Couldn't register psc%d interrupt\n", 4);
-       if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50))
-               pr_err("Couldn't register psc%d interrupt\n", 5);
-       if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60))
-               pr_err("Couldn't register psc%d interrupt\n", 6);
-}
-
 /*
  * PSC interrupt handler. It's a lot like the VIA interrupt handler.
  */
 
-irqreturn_t psc_irq(int irq, void *dev_id)
+static void psc_irq(unsigned int irq, struct irq_desc *desc)
 {
-       int pIFR        = pIFRbase + ((int) dev_id);
-       int pIER        = pIERbase + ((int) dev_id);
+       unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc);
+       int pIFR        = pIFRbase + offset;
+       int pIER        = pIERbase + offset;
        int irq_num;
        unsigned char irq_bit, events;
 
 #ifdef DEBUG_IRQS
-       printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n",
+       printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n",
                irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER));
 #endif
 
        events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF;
        if (!events)
-               return IRQ_NONE;
+               return;
 
        irq_num = irq << 3;
        irq_bit = 1;
        do {
                if (events & irq_bit) {
                        psc_write_byte(pIFR, irq_bit);
-                       m68k_handle_int(irq_num);
+                       generic_handle_irq(irq_num);
                }
                irq_num++;
                irq_bit <<= 1;
        } while (events >= irq_bit);
-       return IRQ_HANDLED;
+}
+
+/*
+ * Register the PSC interrupt dispatchers for autovector interrupts 3-6.
+ */
+
+void __init psc_register_interrupts(void)
+{
+       irq_set_chained_handler(IRQ_AUTO_3, psc_irq);
+       irq_set_handler_data(IRQ_AUTO_3, (void *)0x30);
+       irq_set_chained_handler(IRQ_AUTO_4, psc_irq);
+       irq_set_handler_data(IRQ_AUTO_4, (void *)0x40);
+       irq_set_chained_handler(IRQ_AUTO_5, psc_irq);
+       irq_set_handler_data(IRQ_AUTO_5, (void *)0x50);
+       irq_set_chained_handler(IRQ_AUTO_6, psc_irq);
+       irq_set_handler_data(IRQ_AUTO_6, (void *)0x60);
 }
 
 void psc_irq_enable(int irq) {
index e71166daec6adf5507f3aef1ef8d53ab996bdf7c..f1600ad2662113979a16631613e6b8135c1a09e2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/irq.h>
 
 #include <asm/bootinfo.h>
 #include <asm/macintosh.h>
@@ -77,9 +78,6 @@ static int gIER,gIFR,gBufA,gBufB;
 static u8 nubus_disabled;
 
 void via_debug_dump(void);
-irqreturn_t via1_irq(int, void *);
-irqreturn_t via2_irq(int, void *);
-irqreturn_t via_nubus_irq(int, void *);
 void via_irq_enable(int irq);
 void via_irq_disable(int irq);
 void via_irq_clear(int irq);
@@ -281,39 +279,10 @@ void __init via_init_clock(irq_handler_t func)
        via1[vT1CL] = MAC_CLOCK_LOW;
        via1[vT1CH] = MAC_CLOCK_HIGH;
 
-       if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func))
+       if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func))
                pr_err("Couldn't register %s interrupt\n", "timer");
 }
 
-/*
- * Register the interrupt dispatchers for VIA or RBV machines only.
- */
-
-void __init via_register_interrupts(void)
-{
-       if (via_alt_mapping) {
-               if (request_irq(IRQ_AUTO_1, via1_irq,
-                               IRQ_FLG_LOCK|IRQ_FLG_FAST, "software",
-                               (void *) via1))
-                       pr_err("Couldn't register %s interrupt\n", "software");
-               if (request_irq(IRQ_AUTO_6, via1_irq,
-                               IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
-                               (void *) via1))
-                       pr_err("Couldn't register %s interrupt\n", "via1");
-       } else {
-               if (request_irq(IRQ_AUTO_1, via1_irq,
-                               IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
-                               (void *) via1))
-                       pr_err("Couldn't register %s interrupt\n", "via1");
-       }
-       if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
-                       "via2", (void *) via2))
-               pr_err("Couldn't register %s interrupt\n", "via2");
-       if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq,
-                       IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2))
-               pr_err("Couldn't register %s interrupt\n", "nubus");
-}
-
 /*
  * Debugging dump, used in various places to see what's going on.
  */
@@ -446,48 +415,46 @@ void __init via_nubus_init(void)
  * via6522.c :-), disable/pending masks added.
  */
 
-irqreturn_t via1_irq(int irq, void *dev_id)
+void via1_irq(unsigned int irq, struct irq_desc *desc)
 {
        int irq_num;
        unsigned char irq_bit, events;
 
        events = via1[vIFR] & via1[vIER] & 0x7F;
        if (!events)
-               return IRQ_NONE;
+               return;
 
        irq_num = VIA1_SOURCE_BASE;
        irq_bit = 1;
        do {
                if (events & irq_bit) {
                        via1[vIFR] = irq_bit;
-                       m68k_handle_int(irq_num);
+                       generic_handle_irq(irq_num);
                }
                ++irq_num;
                irq_bit <<= 1;
        } while (events >= irq_bit);
-       return IRQ_HANDLED;
 }
 
-irqreturn_t via2_irq(int irq, void *dev_id)
+static void via2_irq(unsigned int irq, struct irq_desc *desc)
 {
        int irq_num;
        unsigned char irq_bit, events;
 
        events = via2[gIFR] & via2[gIER] & 0x7F;
        if (!events)
-               return IRQ_NONE;
+               return;
 
        irq_num = VIA2_SOURCE_BASE;
        irq_bit = 1;
        do {
                if (events & irq_bit) {
                        via2[gIFR] = irq_bit | rbv_clear;
-                       m68k_handle_int(irq_num);
+                       generic_handle_irq(irq_num);
                }
                ++irq_num;
                irq_bit <<= 1;
        } while (events >= irq_bit);
-       return IRQ_HANDLED;
 }
 
 /*
@@ -495,7 +462,7 @@ irqreturn_t via2_irq(int irq, void *dev_id)
  * VIA2 dispatcher as a fast interrupt handler.
  */
 
-irqreturn_t via_nubus_irq(int irq, void *dev_id)
+void via_nubus_irq(unsigned int irq, struct irq_desc *desc)
 {
        int slot_irq;
        unsigned char slot_bit, events;
@@ -506,7 +473,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
        else
                events &= ~via2[vDirA];
        if (!events)
-               return IRQ_NONE;
+               return;
 
        do {
                slot_irq = IRQ_NUBUS_F;
@@ -514,7 +481,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
                do {
                        if (events & slot_bit) {
                                events &= ~slot_bit;
-                               m68k_handle_int(slot_irq);
+                               generic_handle_irq(slot_irq);
                        }
                        --slot_irq;
                        slot_bit >>= 1;
@@ -528,7 +495,24 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id)
                else
                        events &= ~via2[vDirA];
        } while (events);
-       return IRQ_HANDLED;
+}
+
+/*
+ * Register the interrupt dispatchers for VIA or RBV machines only.
+ */
+
+void __init via_register_interrupts(void)
+{
+       if (via_alt_mapping) {
+               /* software interrupt */
+               irq_set_chained_handler(IRQ_AUTO_1, via1_irq);
+               /* via1 interrupt */
+               irq_set_chained_handler(IRQ_AUTO_6, via1_irq);
+       } else {
+               irq_set_chained_handler(IRQ_AUTO_1, via1_irq);
+       }
+       irq_set_chained_handler(IRQ_AUTO_2, via2_irq);
+       irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq);
 }
 
 void via_irq_enable(int irq) {
index 6cb9c3a9b6c955c013ee0185c23138ac3346f745..5de924ef42ed128b78631e5096e0f85ebdac31a9 100644 (file)
@@ -81,7 +81,7 @@ static void mvme147_get_model(char *model)
 
 void __init mvme147_init_IRQ(void)
 {
-       m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+       m68k_setup_user_interrupt(VEC_USER, 192);
 }
 
 void __init config_mvme147(void)
@@ -114,8 +114,7 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
 void mvme147_sched_init (irq_handler_t timer_routine)
 {
        tick_handler = timer_routine;
-       if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE,
-                       "timer 1", NULL))
+       if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL))
                pr_err("Couldn't register timer interrupt\n");
 
        /* Init the clock with a value */
index 0b28e26216535c2212b4bd03610d503a1b82b275..31a66d99cbca3a7fb4bb66960f849c7f0c7d7f0a 100644 (file)
@@ -117,7 +117,7 @@ static void mvme16x_get_hardware_list(struct seq_file *m)
 
 static void __init mvme16x_init_IRQ (void)
 {
-       m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+       m68k_setup_user_interrupt(VEC_USER, 192);
 }
 
 #define pcc2chip       ((volatile u_char *)0xfff42000)
index 9f0e3d59bf923e240bbe648a1d2e304659f38a23..2b888491f29a121b9c2a605285937a453e188d69 100644 (file)
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
-#include <asm/irq.h>
 #include <asm/traps.h>
 
 #include <asm/q40_master.h>
 */
 
 static void q40_irq_handler(unsigned int, struct pt_regs *fp);
-static void q40_enable_irq(unsigned int);
-static void q40_disable_irq(unsigned int);
+static void q40_irq_enable(struct irq_data *data);
+static void q40_irq_disable(struct irq_data *data);
 
 unsigned short q40_ablecount[35];
 unsigned short q40_state[35];
 
-static int q40_irq_startup(unsigned int irq)
+static unsigned int q40_irq_startup(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        /* test for ISA ints not implemented by HW */
        switch (irq) {
        case 1: case 2: case 8: case 9:
        case 11: case 12: case 13:
                printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq);
-               return -ENXIO;
+               /* FIXME return -ENXIO; */
        }
        return 0;
 }
 
-static void q40_irq_shutdown(unsigned int irq)
+static void q40_irq_shutdown(struct irq_data *data)
 {
 }
 
-static struct irq_controller q40_irq_controller = {
+static struct irq_chip q40_irq_chip = {
        .name           = "q40",
-       .lock           = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock),
-       .startup        = q40_irq_startup,
-       .shutdown       = q40_irq_shutdown,
-       .enable         = q40_enable_irq,
-       .disable        = q40_disable_irq,
+       .irq_startup    = q40_irq_startup,
+       .irq_shutdown   = q40_irq_shutdown,
+       .irq_enable     = q40_irq_enable,
+       .irq_disable    = q40_irq_disable,
 };
 
 /*
@@ -81,13 +82,14 @@ static int disabled;
 
 void __init q40_init_IRQ(void)
 {
-       m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX);
+       m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1,
+                                 Q40_IRQ_MAX);
 
        /* setup handler for ISA ints */
        m68k_setup_auto_interrupt(q40_irq_handler);
 
-       m68k_irq_startup(IRQ_AUTO_2);
-       m68k_irq_startup(IRQ_AUTO_4);
+       m68k_irq_startup_irq(IRQ_AUTO_2);
+       m68k_irq_startup_irq(IRQ_AUTO_4);
 
        /* now enable some ints.. */
        master_outb(1, EXT_ENABLE_REG);  /* ISA IRQ 5-15 */
@@ -218,11 +220,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
        switch (irq) {
        case 4:
        case 6:
-               __m68k_handle_int(Q40_IRQ_SAMPLE, fp);
+               do_IRQ(Q40_IRQ_SAMPLE, fp);
                return;
        }
        if (mir & Q40_IRQ_FRAME_MASK) {
-               __m68k_handle_int(Q40_IRQ_FRAME, fp);
+               do_IRQ(Q40_IRQ_FRAME, fp);
                master_outb(-1, FRAME_CLEAR_REG);
        }
        if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) {
@@ -257,7 +259,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
                                        goto iirq;
                                }
                                q40_state[irq] |= IRQ_INPROGRESS;
-                               __m68k_handle_int(irq, fp);
+                               do_IRQ(irq, fp);
                                q40_state[irq] &= ~IRQ_INPROGRESS;
 
                                /* naively enable everything, if that fails than    */
@@ -288,25 +290,29 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
        mir = master_inb(IIRQ_REG);
        /* should test whether keyboard irq is really enabled, doing it in defhand */
        if (mir & Q40_IRQ_KEYB_MASK)
-               __m68k_handle_int(Q40_IRQ_KEYBOARD, fp);
+               do_IRQ(Q40_IRQ_KEYBOARD, fp);
 
        return;
 }
 
-void q40_enable_irq(unsigned int irq)
+void q40_irq_enable(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        if (irq >= 5 && irq <= 15) {
                mext_disabled--;
                if (mext_disabled > 0)
-                       printk("q40_enable_irq : nested disable/enable\n");
+                       printk("q40_irq_enable : nested disable/enable\n");
                if (mext_disabled == 0)
                        master_outb(1, EXT_ENABLE_REG);
        }
 }
 
 
-void q40_disable_irq(unsigned int irq)
+void q40_irq_disable(struct irq_data *data)
 {
+       unsigned int irq = data->irq;
+
        /* disable ISA iqs : only do something if the driver has been
         * verified to be Q40 "compatible" - right now IDE, NE2K
         * Any driver should not attempt to sleep across disable_irq !!
@@ -319,13 +325,3 @@ void q40_disable_irq(unsigned int irq)
                        printk("disable_irq nesting count %d\n",mext_disabled);
        }
 }
-
-unsigned long q40_probe_irq_on(void)
-{
-       printk("irq probing not working - reconfigure the driver to avoid this\n");
-       return -1;
-}
-int q40_probe_irq_off(unsigned long irqs)
-{
-       return -1;
-}
index 6464ad3ae3e6fe303732a8ab83a6eacf96473c20..78b60f53e90af7f668dd64ab3cf9071a66d59276 100644 (file)
@@ -51,25 +51,29 @@ void sun3_disable_irq(unsigned int irq)
 
 static irqreturn_t sun3_int7(int irq, void *dev_id)
 {
-       *sun3_intreg |=  (1 << irq);
-       if (!(kstat_cpu(0).irqs[irq] % 2000))
-               sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]);
+       unsigned int cnt;
+
+       cnt = kstat_irqs_cpu(irq, 0);
+       if (!(cnt % 2000))
+               sun3_leds(led_pattern[cnt % 16000 / 2000]);
        return IRQ_HANDLED;
 }
 
 static irqreturn_t sun3_int5(int irq, void *dev_id)
 {
+       unsigned int cnt;
+
 #ifdef CONFIG_SUN3
        intersil_clear();
 #endif
-        *sun3_intreg |=  (1 << irq);
 #ifdef CONFIG_SUN3
        intersil_clear();
 #endif
        xtime_update(1);
        update_process_times(user_mode(get_irq_regs()));
-        if (!(kstat_cpu(0).irqs[irq] % 20))
-                sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]);
+       cnt = kstat_irqs_cpu(irq, 0);
+       if (!(cnt % 20))
+               sun3_leds(led_pattern[cnt % 160 / 20]);
        return IRQ_HANDLED;
 }
 
@@ -79,29 +83,33 @@ static irqreturn_t sun3_vec255(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
+static void sun3_irq_enable(struct irq_data *data)
 {
-        *sun3_intreg &= ~(1 << irq);
+    sun3_enable_irq(data->irq);
+};
 
-       __m68k_handle_int(irq, fp);
-}
+static void sun3_irq_disable(struct irq_data *data)
+{
+    sun3_disable_irq(data->irq);
+};
 
-static struct irq_controller sun3_irq_controller = {
+static struct irq_chip sun3_irq_chip = {
        .name           = "sun3",
-       .lock           = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock),
-       .startup        = m68k_irq_startup,
-       .shutdown       = m68k_irq_shutdown,
-       .enable         = sun3_enable_irq,
-       .disable        = sun3_disable_irq,
+       .irq_startup    = m68k_irq_startup,
+       .irq_shutdown   = m68k_irq_shutdown,
+       .irq_enable     = sun3_irq_enable,
+       .irq_disable    = sun3_irq_disable,
+       .irq_mask       = sun3_irq_disable,
+       .irq_unmask     = sun3_irq_enable,
 };
 
 void __init sun3_init_IRQ(void)
 {
        *sun3_intreg = 1;
 
-       m68k_setup_auto_interrupt(sun3_inthandle);
-       m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7);
-       m68k_setup_user_interrupt(VEC_USER, 128, NULL);
+       m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1,
+                                 7);
+       m68k_setup_user_interrupt(VEC_USER, 128);
 
        if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL))
                pr_err("Couldn't register %s interrupt\n", "int5");
diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h
deleted file mode 100644 (file)
index 61d60b8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_NAMEI_H
-#define _ASM_MICROBLAZE_NAMEI_H
-
-#ifdef __KERNEL__
-
-/* This dummy routine maybe changed to something useful
- * for /usr/gnemul/ emulation stuff.
- * Look at asm-sparc/namei.h for details.
- */
-#define __emul_prefix() NULL
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_MICROBLAZE_NAMEI_H */
index dc6416d265d616e1ac65382b5174c81c1b22d723..65a4af4cbbbe864bb10eb75ff7fd1426c8021950 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/gfp.h>
 #include <linux/dma-debug.h>
+#include <linux/export.h>
 #include <asm/bug.h>
 
 /*
index ce7ac8435d5c947adf9920c7a28f78efe0cfa3e3..e5d63a89b9b20085e9e81042326c0e68bee362a6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
 #include <linux/of_irq.h>
+#include <linux/export.h>
 
 #include <asm/prom.h>
 
index 36a133e5ee35edede8e0f15c02febb92afd68f86..565d193c7ebfd8b307ac3efc8913bda4968dcbcd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pfn.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
+#include <linux/export.h>
 
 #include <asm/page.h>
 #include <asm/mmu_context.h>
index 3fbf16f4e16c4093cf7b524a45ce8d2543ba5bd0..57acda852f5a4723c7a294520b8fb6d51494cb54 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/mm.h>
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
 
index 4cfae20f1067a81af7b4a2d58ea0d84ebbe3769c..db841c7b9d5bad1dcbf4c55cb54301ceb76dd460 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index 62b9677c39a10bf17857f0f6b5621977771302f7..d46f1da18a3c4ca587d16db23265b2aa557ceb1b 100644 (file)
@@ -820,10 +820,6 @@ config ARCH_HAS_ILOG2_U64
        bool
        default n
 
-config ARCH_SUPPORTS_OPROFILE
-       bool
-       default y if !MIPS_MT_SMTC
-
 config GENERIC_HWEIGHT
        bool
        default y
@@ -2255,16 +2251,6 @@ config HZ
 
 source "kernel/Kconfig.preempt"
 
-config MIPS_INSANE_LARGE
-       bool "Support for large 64-bit configurations"
-       depends on CPU_R10000 && 64BIT
-       help
-         MIPS R10000 does support a 44 bit / 16TB address space as opposed to
-         previous 64-bit processors which only supported 40 bit / 1TB. If you
-         need processes of more than 1TB virtual address space, say Y here.
-         This will result in additional memory usage, so it is not
-         recommended for normal users.
-
 config KEXEC
        bool "Kexec system call (EXPERIMENTAL)"
        depends on EXPERIMENTAL
index 9b4cb00407d7c468f607213f88dd729731a588be..0be318609fc62832c44fa6a47b1c9670c1e9b2b7 100644 (file)
@@ -286,11 +286,11 @@ CLEAN_FILES += vmlinux.32 vmlinux.64
 archprepare:
 ifdef CONFIG_MIPS32_N32
        @echo '  Checking missing-syscalls for N32'
-       $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32"
+       $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=n32"
 endif
 ifdef CONFIG_MIPS32_O32
        @echo '  Checking missing-syscalls for O32'
-       $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32"
+       $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=32"
 endif
 
 install:
index 57b425fd4d412b2e685804065255fef55af7affc..5ebdf62e96bb6bf130d45a6e8db7f7c77ff00e2e 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
  */
 
+#include <linux/export.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_driver_chipcommon.h>
 #include <linux/ssb/ssb_driver_extif.h>
index 17c3d14d7c4900d5e06c5a0549a27de5db86f06e..1cfdda03546a8dc5819d682107e3c52289231e24 100644 (file)
@@ -26,6 +26,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
index 29d56afbb02d889e68b959eafe27626d7cfe9498..ce6483a9302a8989a3f26a0bf52e352d08de8f98 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (C) 2009, 2010 Cavium Networks, Inc.
  */
 #include <linux/clocksource.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/smp.h>
 
index 1abb66caaa1d84459e5564fe788b0d39e61f4aeb..ea4febaa4bb1caf50f2ef92cc6c711e94c4285e2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/swiotlb.h>
 #include <linux/types.h>
 #include <linux/init.h>
index 0ee02f5e51cce7e6bb1bfb10304539059f211169..0a430e06f5e5e11f3989265a1f49336d1b10abee 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 2007, 2008 Cavium Networks
  */
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
@@ -16,8 +17,6 @@
 
 static struct map_info flash_map;
 static struct mtd_info *mymtd;
-static int nr_parts;
-static struct mtd_partition *parts;
 static const char *part_probe_types[] = {
        "cmdlinepart",
 #ifdef CONFIG_MTD_REDBOOT_PARTS
@@ -60,11 +59,8 @@ static int __init flash_init(void)
                mymtd = do_map_probe("cfi_probe", &flash_map);
                if (mymtd) {
                        mymtd->owner = THIS_MODULE;
-
-                       nr_parts = parse_mtd_partitions(mymtd,
-                                                       part_probe_types,
-                                                       &parts, 0);
-                       mtd_device_register(mymtd, parts, nr_parts);
+                       mtd_device_parse_register(mymtd, part_probe_types,
+                                                 0, NULL, 0);
                } else {
                        pr_err("Failed to register MTD device for flash\n");
                }
index 8b606423bbd7f84dcacd4b043297844fc59200d4..efcfff4d4627c55f4238bfd3361fe937be25465e 100644 (file)
@@ -207,8 +207,9 @@ void octeon_prepare_cpus(unsigned int max_cpus)
         * the other bits alone.
         */
        cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
-       if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
-                       "SMP-IPI", mailbox_interrupt)) {
+       if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt,
+                       IRQF_PERCPU | IRQF_NO_THREAD, "SMP-IPI",
+                       mailbox_interrupt)) {
                panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
        }
 }
index 708f08761406fe3bfdbd308822f163a2ae7c9822..cae42259d6da9cc49efd4ceb8bccdbad941fe3d0 100644 (file)
@@ -50,7 +50,7 @@ void __init prom_init(void)
 
        /* arg[0] is "g", the rest is boot parameters */
        for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+               if (strlen(arcs_cmdline) + strlen(arg[i]) + 1
                    >= sizeof(arcs_cmdline))
                        break;
                strcat(arcs_cmdline, arg[i]);
index 76961cabeedfe1cdac4caaef7e9989ca04a345be..2ef17e8df40346f07aea6e01431186686214a1f7 100644 (file)
@@ -36,6 +36,8 @@ static inline int gpio_get_value(unsigned gpio)
        return -EINVAL;
 }
 
+#define gpio_get_value_cansleep        gpio_get_value
+
 static inline void gpio_set_value(unsigned gpio, int value)
 {
        switch (bcm47xx_bus_type) {
@@ -54,6 +56,19 @@ static inline void gpio_set_value(unsigned gpio, int value)
        }
 }
 
+#define gpio_set_value_cansleep gpio_set_value
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+       return 0;
+}
+
+static inline int gpio_is_valid(unsigned gpio)
+{
+       return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
+}
+
+
 static inline int gpio_direction_input(unsigned gpio)
 {
        switch (bcm47xx_bus_type) {
@@ -137,7 +152,4 @@ static inline int gpio_polarity(unsigned gpio, int value)
 }
 
 
-/* cansleep wrappers */
-#include <asm-generic/gpio.h>
-
 #endif /* __BCM47XX_GPIO_H */
index ecea7871dec28f6e4e44e1652a2d10b87e8a87b1..d8dad5340ea30d22eac825883012a14341fbf157 100644 (file)
 #define __NR_syncfs                    (__NR_Linux + 342)
 #define __NR_sendmmsg                  (__NR_Linux + 343)
 #define __NR_setns                     (__NR_Linux + 344)
+#define __NR_process_vm_readv          (__NR_Linux + 345)
+#define __NR_process_vm_writev         (__NR_Linux + 346)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            344
+#define __NR_Linux_syscalls            346
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                344
+#define __NR_O32_Linux_syscalls                346
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_syncfs                    (__NR_Linux + 301)
 #define __NR_sendmmsg                  (__NR_Linux + 302)
 #define __NR_setns                     (__NR_Linux + 303)
+#define __NR_process_vm_readv          (__NR_Linux + 304)
+#define __NR_process_vm_writev         (__NR_Linux + 305)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            303
+#define __NR_Linux_syscalls            305
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         303
+#define __NR_64_Linux_syscalls         305
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_syncfs                    (__NR_Linux + 306)
 #define __NR_sendmmsg                  (__NR_Linux + 307)
 #define __NR_setns                     (__NR_Linux + 308)
+#define __NR_process_vm_readv          (__NR_Linux + 309)
+#define __NR_process_vm_writev         (__NR_Linux + 310)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            308
+#define __NR_Linux_syscalls            310
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                308
+#define __NR_N32_Linux_syscalls                310
 
 #ifdef __KERNEL__
 
index cbf3fe20ad17eb0f76690e92995b96558914000b..5c6b2ab1f56efe40860d802cf886ad98119801d0 100644 (file)
@@ -5,7 +5,6 @@
  *
  * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  */
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/serial_8250.h>
 
index 98c5a9737c14d2c200a161640122f9a8af053e88..e2d8e199be323345a6feaf3eb03a738e515dd5f5 100644 (file)
@@ -103,19 +103,10 @@ static int c0_compare_int_pending(void)
 
 /*
  * Compare interrupt can be routed and latched outside the core,
- * so a single execution hazard barrier may not be enough to give
- * it time to clear as seen in the Cause register.  4 time the
- * pipeline depth seems reasonably conservative, and empirically
- * works better in configurations with high CPU/bus clock ratios.
+ * so wait up to worst case number of cycle counter ticks for timer interrupt
+ * changes to propagate to the cause register.
  */
-
-#define compare_change_hazard() \
-       do { \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-               irq_disable_hazard(); \
-       } while (0)
+#define COMPARE_INT_SEEN_TICKS 50
 
 int c0_compare_int_usable(void)
 {
@@ -126,8 +117,12 @@ int c0_compare_int_usable(void)
         * IP7 already pending?  Try to clear it by acking the timer.
         */
        if (c0_compare_int_pending()) {
-               write_c0_compare(read_c0_count());
-               compare_change_hazard();
+               cnt = read_c0_count();
+               write_c0_compare(cnt);
+               back_to_back_c0_hazard();
+               while (read_c0_count() < (cnt  + COMPARE_INT_SEEN_TICKS))
+                       if (!c0_compare_int_pending())
+                               break;
                if (c0_compare_int_pending())
                        return 0;
        }
@@ -136,7 +131,7 @@ int c0_compare_int_usable(void)
                cnt = read_c0_count();
                cnt += delta;
                write_c0_compare(cnt);
-               compare_change_hazard();
+               back_to_back_c0_hazard();
                if ((int)(read_c0_count() - cnt) < 0)
                    break;
                /* increase delta if the timer was already expired */
@@ -145,12 +140,17 @@ int c0_compare_int_usable(void)
        while ((int)(read_c0_count() - cnt) <= 0)
                ;       /* Wait for expiry  */
 
-       compare_change_hazard();
+       while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+               if (c0_compare_int_pending())
+                       break;
        if (!c0_compare_int_pending())
                return 0;
-
-       write_c0_compare(read_c0_count());
-       compare_change_hazard();
+       cnt = read_c0_count();
+       write_c0_compare(cnt);
+       back_to_back_c0_hazard();
+       while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+               if (!c0_compare_int_pending())
+                       break;
        if (c0_compare_int_pending())
                return 0;
 
index aa327a755982e86134fd88b014d42781ff6d6b7b..c7d3cf1ce46e275b11df8c210f1553c5eb0bd74c 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/bugs.h>
 #include <asm/cpu.h>
@@ -24,6 +24,7 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 #include <asm/watch.h>
+#include <asm/elf.h>
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
index cefc6e259bafd3acd986588af2c87a6e3ce0f32d..5426779d9fdb77700d05b897e7af3acff8d753e1 100644 (file)
@@ -7,6 +7,7 @@
  * for more details.
  */
 
+#include <linux/module.h>
 #include <linux/cpufreq.h>
 #include <linux/platform_device.h>
 
index be4ee7d63e04cadc441a5684b48924dda36a9496..7047bff35ea52829a85a9fc94e8f33ad05ead786 100644 (file)
@@ -4,7 +4,7 @@
  */
 #include <linux/clockchips.h>
 #include <linux/i8253.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/smp.h>
 #include <linux/irq.h>
 
index 6d6ca53058951307ad992cac83c0325c389ff556..5f9a76263c9a9e669abf6d5b02cdf120e1f149d8 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/init_task.h>
 #include <linux/fs.h>
index 0c6afeed89d2b71d382f7ec826bb5a64d762c90e..14ac52c5ae86c15a380b9ded947309ed61af80bc 100644 (file)
@@ -9,7 +9,6 @@
  *
  * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
  */
-#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index b53970d809916efafff50fde04b371c279efb8ac..7f50318061b5689d295bbafe3b7eaa71da82dea1 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
-#include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/random.h>
index 594ca69cb867aa67b91098fe1b262e90fc832b57..c23d11f6851de3116125f21cb88a73ceb9e4f5a1 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/security.h>
 
index 1d04807874db4b48af8f80e518e729f531e37fc2..57ba13edb03af10da20a9ce936645902d9f562c1 100644 (file)
@@ -9,7 +9,7 @@
  * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
  */
 #include <linux/interrupt.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
index 4b930ac4aff250b84aeed1d4ee895da5af79469a..a5066b1c3de37185896fe529839c5133a158ccb0 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/jump_label.h>
 
index 4f2971bcf8e5464577885b5ecc64db11c388d295..315fc0b250f8fe3373684f12f5c0437fd3d0b7b1 100644 (file)
@@ -623,7 +623,7 @@ static int mipspmu_event_init(struct perf_event *event)
        if (!atomic_inc_not_zero(&active_events)) {
                if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
                        atomic_dec(&active_events);
-                       return -ENOSPC;
+                       return -EINVAL;
                }
 
                mutex_lock(&pmu_reserve_mutex);
@@ -732,15 +732,15 @@ static int validate_group(struct perf_event *event)
        memset(&fake_cpuc, 0, sizeof(fake_cpuc));
 
        if (!validate_event(&fake_cpuc, leader))
-               return -ENOSPC;
+               return -EINVAL;
 
        list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
                if (!validate_event(&fake_cpuc, sibling))
-                       return -ENOSPC;
+                       return -EINVAL;
        }
 
        if (!validate_event(&fake_cpuc, event))
-               return -ENOSPC;
+               return -EINVAL;
 
        return 0;
 }
index b30cb2573aaf8cc8a3edae6d8b0a70a1a564a867..c47f96e453c0fd4c2d3118b194ebed14134e6390 100644 (file)
@@ -9,13 +9,13 @@
  * Copyright (C) 2004 Thiemo Seufer
  */
 #include <linux/errno.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/tick.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/personality.h>
index 5b7eade41fa3866e5adc4d029688db5b0beb8570..6b8b4208481e6855104508711fc98e60aa3ac844 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/bootmem.h>
index 060563a712b6064d837d85a529723bc770caeeee..07fc5244aed4917392542399e8547ed276aa3518 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pm.h>
 #include <linux/types.h>
 #include <linux/reboot.h>
index 7a80b7cda7cc0219e1de607aebed7c316cf6b0ee..933166f44a6d8647c4f75deaf13b11a02e04adaf 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index 47920657968d2e65368edd0c2cbd39c6a5052ef2..a632bc144efa1b9ca977a582864530e33ee039cb 100644 (file)
@@ -591,6 +591,8 @@ einval:     li      v0, -ENOSYS
        sys     sys_syncfs              1
        sys     sys_sendmmsg            4
        sys     sys_setns               2
+       sys     sys_process_vm_readv    6       /* 4345 */
+       sys     sys_process_vm_writev   6
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index fb7334bea7316aedd8071ff41d63178539504cc8..3b5a5e9ae49c132640c95a87037e48ac95e5b932 100644 (file)
@@ -430,4 +430,6 @@ sys_call_table:
        PTR     sys_syncfs
        PTR     sys_sendmmsg
        PTR     sys_setns
+       PTR     sys_process_vm_readv
+       PTR     sys_process_vm_writev           /* 5305 */
        .size   sys_call_table,.-sys_call_table
index 6de1f598346e3bfd527f1d3cad321160aedb3c02..6be6f7020923f1224260a0bf4df420a2d951db7a 100644 (file)
@@ -430,4 +430,6 @@ EXPORT(sysn32_call_table)
        PTR     sys_syncfs
        PTR     compat_sys_sendmmsg
        PTR     sys_setns
+       PTR     compat_sys_process_vm_readv
+       PTR     compat_sys_process_vm_writev    /* 6310 */
        .size   sysn32_call_table,.-sysn32_call_table
index 1d813169e453ea3709b0410521b8526638d96a98..54228553691d60903559706c00bc8a0d16a05b86 100644 (file)
@@ -548,4 +548,6 @@ sys_call_table:
        PTR     sys_syncfs
        PTR     compat_sys_sendmmsg
        PTR     sys_setns
+       PTR     compat_sys_process_vm_readv     /* 4345 */
+       PTR     compat_sys_process_vm_writev
        .size   sys_call_table,.-sys_call_table
index 8ad1d5679f1440ebe2393e1d25f1a3ab38c7a017..84af26ab221236d3a4077e76fea2497ae769a640 100644 (file)
@@ -12,7 +12,7 @@
  */
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/screen_info.h>
 #include <linux/bootmem.h>
 #include <linux/initrd.h>
index da61134dfc539917bef64d5fbb2caf6ae9b2570a..39f7ab7b04269b6a22b3573fc3f2bc377605d088 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/hrtimer.h>
 #include <linux/fs.h>
 #include <linux/debugfs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 
 
index d52ff77baf3f8b22f169f8e4aba269fbff2c6941..1ba775d24d38f890d4e29a2168b533870d7cfb8b 100644 (file)
@@ -5,7 +5,7 @@
  */
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/stacktrace.h>
 
 /*
index 1083ad4e1017be924f5a6922807971dc75853825..99d73b72b00b763e537425d6d63d8bdd7c8ccdbb 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/timex.h>
 #include <linux/smp.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/cpu-features.h>
 #include <asm/div64.h>
index cbea618af0b4071feacd04e8abb922f9c0556c09..5c8a49d55054dffce696066bad88d1863c5e7f35 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/spinlock.h>
@@ -1597,7 +1596,8 @@ void __cpuinit per_cpu_trap_init(void)
        }
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-       cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+       if (!cpu_data[cpu].asid_cache)
+               cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
 
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
index eb319b58035377f5305286a587926f1f356ced41..aedb8941caa536c9ed76d07292ab63d905f9f7d2 100644 (file)
@@ -73,7 +73,6 @@
  *       Undo the partial store in this case.
  */
 #include <linux/mm.h>
-#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/sched.h>
index 3efcb065f78a4fcc9a55a842f7574ceb89d43f7a..bfa12a4f97b96e46d5339aa0bfbb96bfeed4459e 100644 (file)
@@ -29,7 +29,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/device.h>
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
index 7e9c0ffc11a51c42bd58b1f465d54481aab6023c..77ed70fc2fe5953cd9bf31aa2514820b41e2bbd6 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
index 44a36771c819bebcb03732744566764c6d60b574..de1cb2bcd79a167e36b9602d14d6fa889e9a2b1d 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
index 56ba007bf1e59ee37d5a7a2627d603d635df447d..e34fcfd0d5ca5763983c2b0a248352275b40f49b 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index 9b8af77ed0f9868baf4d1873121213cc6a8c556c..1ff6c9d6cb93eb6e21109f9a8c0a3f3941cba4a5 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <asm/bootinfo.h>
index 22d823acd536a3bcfee7708c90a593f57835d143..652258309c9c14220ebdbcaa5a43ac1faa01b7cc 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 
index ddd39593c581453237b26e831716f853cd349a9d..696b1a3e06421d605097535384427ba7632e3396 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/clk.h>
 
index d0e32ab2ea074b9fa75ebd56e2c77ff1a15c994a..d614aa7ff07f48f89789694236aadf90b5f30004 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mtd/physmap.h>
index 4278a459d6c483afd2f371fb856bff8eb1851714..cbb6ae5747b97f81c67c8d77916bd10bad34e125 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <lantiq_soc.h>
 #include <xway_dma.h>
index a321451a54554bc0cba17a0458e61436ce62801e..d2fa98f3c78d8185d6bfec384b88e23720829b88 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/ioport.h>
index a479355abdb92755759366fa1b50325474d93810..b91c7f17f10f043ae906c322e12669438e7f562a 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
index 67d59d69034063ab37dcffa6e4f135c7a531396b..ff9991cddeaa8c3fd6e44048730b09b6d24efb1f 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
index abe49f4db57f1ad670b6c6c6a6709bea6dcfe1e6..ae4959ae865c464cddd5da9393664f148fc448ca 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index 1686692ac24d52eee2338feaebd3cdf943bb22e3..2228133ca3566a0e6a192a9191625f7f2078db28 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
index a1be36d0e490481b9fcdfdf6579e576ee115c111..3d41f0bb5bf73f0d84108129a979642770e632f7 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/reboot.h>
 
 #include <lantiq_soc.h>
index ed007a2e0e1f0641e0406c63e3b0b7c48c5d9feb..502b059de42274d21ae94b3606cdb8a5cc39b5e9 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/smp.h>
 #include <linux/platform_device.h>
 
 static struct platform_device loongson2_cpufreq_device = {
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
deleted file mode 100644 (file)
index 98e86dd..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *
- * Author: source@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <pci.h>
-#include <glb.h>
-#include <nand.h>
-
-static struct resource pci_io_resource = {
-       .start  = PNX8550_PCIIO + 0x1000,       /* reserve regacy I/O space */
-       .end    = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
-       .name   = "pci IO space",
-       .flags  = IORESOURCE_IO
-};
-
-static struct resource pci_mem_resource = {
-       .start  = PNX8550_PCIMEM,
-       .end    = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
-       .name   = "pci memory space",
-       .flags  = IORESOURCE_MEM
-};
-
-extern struct pci_ops pnx8550_pci_ops;
-
-static struct pci_controller pnx8550_controller = {
-       .pci_ops        = &pnx8550_pci_ops,
-       .io_map_base    = PNX8550_PORT_BASE,
-       .io_resource    = &pci_io_resource,
-       .mem_resource   = &pci_mem_resource,
-};
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-static inline unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-static int __init pnx8550_pci_setup(void)
-{
-       int pci_mem_code;
-       int mem_size = get_system_mem_size() >> 20;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* Calc the PCI mem size code */
-       if (mem_size >= 128)
-               pci_mem_code = SIZE_128M;
-       else if (mem_size >= 64)
-               pci_mem_code = SIZE_64M;
-       else if (mem_size >= 32)
-               pci_mem_code = SIZE_32M;
-       else
-               pci_mem_code = SIZE_16M;
-
-       /* Set PCI_XIO registers */
-       outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
-       outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
-       outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
-       outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
-
-       /* Send memory transaction via PCI_BASE2 */
-       outl(0x00000001, PCI_BASE | PCI_IO);
-
-       /* Unlock the setup register */
-       outl(0xca, PCI_BASE | PCI_UNLOCKREG);
-
-       /*
-        * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
-        * to work, and in order for bus_to_baddr to work without any
-        * hacks.
-        */
-       outl(0x00000000, PCI_BASE | PCI_BASE10);
-
-       /*
-        *These two bars are set by default or the boot code.
-        * However, it's safer to set them here so we're not boot
-        * code dependent.
-        */
-       outl(0x1be00000, PCI_BASE | PCI_BASE14);  /* PNX MMIO */
-       outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18);  /* XIO      */
-
-       outl(PCI_EN_TA |
-            PCI_EN_PCI2MMI |
-            PCI_EN_XIO |
-            PCI_SETUP_BASE18_SIZE(SIZE_32M) |
-            PCI_SETUP_BASE18_EN |
-            PCI_SETUP_BASE14_EN |
-            PCI_SETUP_BASE10_PREF |
-            PCI_SETUP_BASE10_SIZE(pci_mem_code) |
-            PCI_SETUP_CFGMANAGE_EN |
-            PCI_SETUP_PCIARB_EN,
-            PCI_BASE |
-            PCI_SETUP);        /* PCI_SETUP */
-       outl(0x00000000, PCI_BASE | PCI_CTRL);  /* PCI_CONTROL */
-
-       register_pci_controller(&pnx8550_controller);
-
-       return 0;
-}
-
-arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
deleted file mode 100644 (file)
index 71adac3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *
- * 2.6 port, Embedded Alley Solutions, Inc
- *
- *  Based on Per Hallsmark, per.hallsmark@mvista.com
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/serial_pnx8xxx.h>
-#include <linux/pm.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/reboot.h>
-#include <asm/pgtable.h>
-#include <asm/time.h>
-
-#include <glb.h>
-#include <int.h>
-#include <pci.h>
-#include <uart.h>
-#include <nand.h>
-
-extern void __init board_setup(void);
-extern void pnx8550_machine_restart(char *);
-extern void pnx8550_machine_halt(void);
-extern void pnx8550_machine_power_off(void);
-extern struct resource ioport_resource;
-extern struct resource iomem_resource;
-extern char *prom_getcmdline(void);
-
-struct resource standard_io_resources[] = {
-       {
-               .start  = 0x00,
-               .end    = 0x1f,
-               .name   = "dma1",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x40,
-               .end    = 0x5f,
-               .name   = "timer",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0x80,
-               .end    = 0x8f,
-               .name   = "dma page reg",
-               .flags  = IORESOURCE_BUSY
-       }, {
-               .start  = 0xc0,
-               .end    = 0xdf,
-               .name   = "dma2",
-               .flags  = IORESOURCE_BUSY
-       },
-};
-
-#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
-
-extern struct resource pci_io_resource;
-extern struct resource pci_mem_resource;
-
-/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
-unsigned long get_system_mem_size(void)
-{
-       /* Read IP2031_RANK0_ADDR_LO */
-       unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
-       /* Read IP2031_RANK1_ADDR_HI */
-       unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
-
-       return dram_r1_hi - dram_r0_lo + 1;
-}
-
-int pnx8550_console_port = -1;
-
-void __init plat_mem_setup(void)
-{
-       int i;
-       char* argptr;
-
-       board_setup();  /* board specific setup */
-
-        _machine_restart = pnx8550_machine_restart;
-        _machine_halt = pnx8550_machine_halt;
-        pm_power_off = pnx8550_machine_power_off;
-
-       /* Clear the Global 2 Register, PCI Inta Output Enable Registers
-          Bit 1:Enable DAC Powerdown
-         -> 0:DACs are enabled and are working normally
-            1:DACs are powerdown
-          Bit 0:Enable of PCI inta output
-         -> 0 = Disable PCI inta output
-            1 = Enable PCI inta output
-       */
-       PNX8550_GLB2_ENAB_INTA_O = 0;
-
-       /* IO/MEM resources. */
-       set_io_port_base(PNX8550_PORT_BASE);
-       ioport_resource.start = 0;
-       ioport_resource.end = ~0;
-       iomem_resource.start = 0;
-       iomem_resource.end = ~0;
-
-       /* Request I/O space for devices on this board */
-       for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-               request_resource(&ioport_resource, standard_io_resources + i);
-
-       /* Place the Mode Control bit for GPIO pin 16 in primary function */
-       /* Pin 16 is used by UART1, UA1_TX                                */
-       outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
-                       (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
-                       PNX8550_GPIO_MC1);
-
-       argptr = prom_getcmdline();
-       if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
-               argptr += strlen("console=ttyS");
-               pnx8550_console_port = *argptr == '0' ? 0 : 1;
-
-               /* We must initialize the UART (console) before early printk */
-               /* Set LCR to 8-bit and BAUD to 38400 (no 5)                */
-               ip3106_lcr(UART_BASE, pnx8550_console_port) =
-                       PNX8XXX_UART_LCR_8BIT;
-               ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
-       }
-}
index 4ee57104e47bb78ef4b8957480e04de5ee8198b9..b5ce041cdafb54667b7c11738892ab7e9020000a 100644 (file)
@@ -7,6 +7,7 @@
  * Support for all devices (greater than 16) added by David Gathright.
  */
 
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
index a0e726eb039aeb0cd8c842d72873d4fcfd8ed3a7..193e9494f98e060bfa66e2bcd0105685fd90f4ff 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <asm/sn/arch.h>
index 8656388b34bd4fac95d7dadf6584d9fe6cdbceb6..be1e1afe12c3ce3aa527b4142d8f8b7aee17143e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 
 #include <asm/pci.h>
index 33bba7bff25840dd8e034083239dc4c49839f1c5..41af7fa2887b7c6266800a1c000bff0d8da06099 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
index cf4c868715acaaba37e9aec317d0224ca5b6d060..dcc926e06fcec573a4478b2359b2218d5ca942cf 100644 (file)
@@ -102,7 +102,7 @@ void __init prom_init(void)
 
        /* Get the boot parameters */
        for (i = 1; i < argc; i++) {
-               if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >=
+               if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >=
                    sizeof(arcs_cmdline))
                        break;
 
index ff0e7e3e6954c21bed60c7be86c2b52fe5e1660b..1a1b03ea639800afce418ea6e2d2e8ec1287aaee 100644 (file)
@@ -1,5 +1,3 @@
-source "arch/mips/powertv/asic/Kconfig"
-
 config BOOTLOADER_DRIVER
        bool "PowerTV Bootloader Driver Support"
        default n
diff --git a/arch/mips/powertv/asic/Kconfig b/arch/mips/powertv/asic/Kconfig
deleted file mode 100644 (file)
index 2016bfe..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-config MIN_RUNTIME_RESOURCES
-       bool "Support for minimum runtime resources"
-       default n
-       depends on POWERTV
-       help
-         Enables support for minimizing the number of (SA asic) runtime
-         resources that are preallocated by the kernel.
-
-config MIN_RUNTIME_DOCSIS
-       bool "Support for minimum DOCSIS resource"
-       default y
-       depends on MIN_RUNTIME_RESOURCES
-       help
-         Enables support for the preallocated DOCSIS resource.
-
-config MIN_RUNTIME_PMEM
-       bool "Support for minimum PMEM resource"
-       default y
-       depends on MIN_RUNTIME_RESOURCES
-       help
-         Enables support for the preallocated Memory resource.
-
-config MIN_RUNTIME_TFTP
-       bool "Support for minimum TFTP resource"
-       default y
-       depends on MIN_RUNTIME_RESOURCES
-       help
-         Enables support for the preallocated TFTP resource.
index 726bc2e824b374ed6766a23e1201af0d89bb8bb9..d7ecbae64a6eff7f9a1ee7c24609e838418c342a 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <asm/mach-powertv/interrupts.h>
 #include "powertv-pci.h"
index 6ac85cf7aa2069ab640dd172685d8749570db048..b0e2afa89395383cc73cde140fbf52c04432575e 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <asm/mach-powertv/asic.h>
index 6c47dfeb7be326bf2dc4c5a7a1cbb1984b87efec..6ec41df3cb99f22e96683c2c3b563af8ee7eee51 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
index 50f530f5b602a1cbeb5808c5428df3c637992dd1..d0c64e71d53269287a2b7f2eac369aac0ec0f04f 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
index 103abc13d6234764469f33545f6c1710ae74b55e..3dbad99d5611e2428666a4475cd5504f441d0c40 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
index 7dc0fafbec80b896c615ef5bacf3a41c63c26ac3..2ad8973ba13d732d8a5770473de98197cf33fe1f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/interrupt.h>
index 22cc6f2100a1acba6d15f983804c3ee46660bdaa..b32b3bc604410b39ce602575c9acfbddfce13afe 100644 (file)
@@ -19,6 +19,7 @@
  */
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
index ebc5dcf0ed8e29dad672a529e6cf6abf45c66f6c..76e3e8af7c96e7c5975e7d328be1297f101f881a 100644 (file)
@@ -19,6 +19,7 @@
  */
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
index 9460e1c266dd8a5b2d9c4c100666a138c4555a55..e518a5a4cf4c19abf6f3fa537c478957602a86ad 100644 (file)
@@ -19,9 +19,6 @@ config OPENRISC
 config MMU
        def_bool y
 
-config WISHBONE_BUS_BIG_ENDIAN
-       def_bool y
-
 config SYMBOL_PREFIX
         string
         default ""
@@ -160,15 +157,6 @@ config JUMP_UPON_UNHANDLED_EXCEPTION
 
          Say Y if you are unsure.
 
-config OPENRISC_EXCEPTION_DEBUG
-       bool "Print processor state at each exception"
-       default n
-       help
-         This option will make your kernel unusable for all but kernel
-         debugging.
-
-         Say N if you are unsure.
-
 config OPENRISC_ESR_EXCEPTION_BUG_CHECK
        bool "Check for possible ESR exception bug"
        default n
index 994bcd980909d62d2d1d3c474e22cf2c0b744ce4..5709c5e59be82c14c544bd06ad693c071a31c434 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
index d047edea25044f59ade85453d2d0dff28a2880d6..d87d1c476d851c233b02580beaffbb25cc22eb1a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
+#include <linux/export.h>
 
 #include <asm/cacheflush.h>
 #include <asm/dma.h>    /* for DMA_CHUNK_SIZE */
index cb71f3dac99525a525027fa2f532a20e4c3caa93..a3328c2616b0a6cf3f99eaff2fa2968cc58e1105 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/pci.h>
 #undef PCI_DEBUG
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/pdc.h>
index 5069e8b2ca712a85a437b495b1195aefda364a9c..8f470c93b16d10a94706f3f5375f2152db22e582 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/io.h>
 
 /*
index 47682b67fd361b412b884a2b900b603818325ccb..951e18f5335b268965d3880881d900bed63e7356 100644 (file)
@@ -323,7 +323,7 @@ config SWIOTLB
 
 config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
-       depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
+       depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV)
        ---help---
          Say Y here to be able to disable and re-enable individual
          CPUs at runtime on SMP machines.
@@ -345,7 +345,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on (PPC_BOOK3S || FSL_BOOKE) && EXPERIMENTAL
+       depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP && !PPC_47x)) && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
@@ -379,10 +379,6 @@ config PHYP_DUMP
 
          If unsure, say "N"
 
-config PPCBUG_NVRAM
-       bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
-       default y if PPC_PREP
-
 config IRQ_ALL_CPUS
        bool "Distribute interrupts on all CPUs by default"
        depends on SMP && !MV64360
@@ -429,8 +425,7 @@ config ARCH_POPULATES_NODE_MAP
        def_bool y
 
 config SYS_SUPPORTS_HUGETLBFS
-       def_bool y
-       depends on PPC_BOOK3S_64
+       bool
 
 source "mm/Kconfig"
 
@@ -746,24 +741,6 @@ config 8260_PCI9
        depends on PCI_8260 && !8272
        default y
 
-choice
-       prompt "IDMA channel for PCI 9 workaround"
-       depends on 8260_PCI9
-
-config 8260_PCI9_IDMA1
-       bool "IDMA1"
-
-config 8260_PCI9_IDMA2
-       bool "IDMA2"
-
-config 8260_PCI9_IDMA3
-       bool "IDMA3"
-
-config 8260_PCI9_IDMA4
-       bool "IDMA4"
-
-endchoice
-
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
index 067cb8480747104082d9d79aea10a1d71a33eb18..1b8a9c905cf7f429e13be1ab97f809cd5a92aa80 100644 (file)
@@ -141,9 +141,6 @@ config BOOTX_TEXT
 
 config PPC_EARLY_DEBUG
        bool "Early debugging (dangerous)"
-       # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water
-       # mark, which doesn't work with current 440 KVM.
-       depends on !KVM
        help
          Say Y to enable some early debugging facilities that may be available
          for your processor/board combination. Those facilities are hacks
@@ -222,7 +219,9 @@ config PPC_EARLY_DEBUG_BEAT
 
 config PPC_EARLY_DEBUG_44x
        bool "Early serial debugging for IBM/AMCC 44x CPUs"
-       depends on 44x
+       # PPC_EARLY_DEBUG on 440 leaves AS=1 mappings above the TLB high water
+       # mark, which doesn't work with current 440 KVM.
+       depends on 44x && !KVM
        help
          Select this to enable early debugging for IBM 44x chips via the
          inbuilt serial port.  If you enable this, ensure you set
@@ -258,8 +257,35 @@ config PPC_EARLY_DEBUG_WSP
        depends on PPC_WSP
        select PPC_UDBG_16550
 
+config PPC_EARLY_DEBUG_PS3GELIC
+       bool "Early debugging through the PS3 Ethernet port"
+       depends on PPC_PS3
+       select PS3GELIC_UDBG
+       help
+         Select this to enable early debugging for the PlayStation3 via
+         UDP broadcasts sent out through the Ethernet port.
+
+config PPC_EARLY_DEBUG_OPAL_RAW
+       bool "OPAL raw console"
+       depends on HVC_OPAL
+       help
+         Select this to enable early debugging for the PowerNV platform
+         using a "raw" console
+
+config PPC_EARLY_DEBUG_OPAL_HVSI
+       bool "OPAL hvsi console"
+       depends on HVC_OPAL
+       help
+         Select this to enable early debugging for the PowerNV platform
+         using an "hvsi" console
+
 endchoice
 
+config PPC_EARLY_DEBUG_OPAL
+       def_bool y
+       depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
+
+
 config PPC_EARLY_DEBUG_HVSI_VTERMNO
        hex "vterm number to use with early debug HVSI"
        depends on PPC_EARLY_DEBUG_LPAR_HVSI
@@ -268,6 +294,18 @@ config PPC_EARLY_DEBUG_HVSI_VTERMNO
          You probably want 0x30000000 for your first serial port and
          0x30000001 for your second one
 
+config PPC_EARLY_DEBUG_OPAL_VTERMNO
+       hex "vterm number to use with OPAL early debug"
+       depends on PPC_EARLY_DEBUG_OPAL
+       default "0"
+       help
+         This correspond to which /dev/hvcN you want to use for early
+         debug.
+
+         On OPAL v1 (takeover) this should always be 0
+         On OPAL v2, this will be 0 for network console and 1 or 2 for
+         the machine built-in serial ports.
+
 config PPC_EARLY_DEBUG_44x_PHYSLOW
        hex "Low 32 bits of early debug UART physical address"
        depends on PPC_EARLY_DEBUG_44x
index 57af16edc19231ad0b4511f30174607a57711494..70ba0c0a1223d475cd2d2c2cdfddbf5b901a7527 100644 (file)
@@ -255,12 +255,6 @@ checkbin:
                echo 'disable kernel modules' ; \
                false ; \
        fi
-       @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
-               echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
-               echo 'correctly with old versions of binutils.' ; \
-               echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
-               false ; \
-       fi
 
 CLEAN_FILES += $(TOUT)
 
index c26200b40a47f37e242c7a2e27a0775395d35bb8..72ee8c1fba4838e9596a848865d7d7e198ec6330 100644 (file)
@@ -58,7 +58,7 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \
 libfdt       := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
 libfdtheader := fdt.h libfdt.h libfdt_internal.h
 
-$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o): \
+$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \
        $(addprefix $(obj)/,$(libfdtheader))
 
 src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \
@@ -171,6 +171,7 @@ quiet_cmd_wrap      = WRAP    $@
                $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
 
 image-$(CONFIG_PPC_PSERIES)            += zImage.pseries
+image-$(CONFIG_PPC_POWERNV)            += zImage.pseries
 image-$(CONFIG_PPC_MAPLE)              += zImage.maple
 image-$(CONFIG_PPC_IBM_CELL_BLADE)     += zImage.pseries
 image-$(CONFIG_PPC_PS3)                        += dtbImage.ps3
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
new file mode 100644 (file)
index 0000000..0e00e50
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * charon board Device Tree Source
+ *
+ * Copyright (C) 2007 Semihalf
+ * Marian Balakowicz <m8@semihalf.com>
+ *
+ * Copyright (C) 2010 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "anon,charon";
+       compatible = "anon,charon";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&mpc5200_pic>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,5200@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;
+                       i-cache-line-size = <32>;
+                       d-cache-size = <0x4000>;        // L1, 16K
+                       i-cache-size = <0x4000>;        // L1, 16K
+                       timebase-frequency = <0>;       // from bootloader
+                       bus-frequency = <0>;            // from bootloader
+                       clock-frequency = <0>;          // from bootloader
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x08000000>;  // 128MB
+       };
+
+       soc5200@f0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc5200-immr";
+               ranges = <0 0xf0000000 0x0000c000>;
+               reg = <0xf0000000 0x00000100>;
+               bus-frequency = <0>;            // from bootloader
+               system-frequency = <0>;         // from bootloader
+
+               cdm@200 {
+                       compatible = "fsl,mpc5200-cdm";
+                       reg = <0x200 0x38>;
+               };
+
+               mpc5200_pic: interrupt-controller@500 {
+                       // 5200 interrupts are encoded into two levels;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       compatible = "fsl,mpc5200-pic";
+                       reg = <0x500 0x80>;
+               };
+
+               timer@600 {     // General Purpose Timer
+                       compatible = "fsl,mpc5200-gpt";
+                       reg = <0x600 0x10>;
+                       interrupts = <1 9 0>;
+                       fsl,has-wdt;
+               };
+
+               can@900 {
+                       compatible = "fsl,mpc5200-mscan";
+                       interrupts = <2 17 0>;
+                       reg = <0x900 0x80>;
+               };
+
+               can@980 {
+                       compatible = "fsl,mpc5200-mscan";
+                       interrupts = <2 18 0>;
+                       reg = <0x980 0x80>;
+               };
+
+               gpio_simple: gpio@b00 {
+                       compatible = "fsl,mpc5200-gpio";
+                       reg = <0xb00 0x40>;
+                       interrupts = <1 7 0>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               usb@1000 {
+                       compatible = "fsl,mpc5200-ohci","ohci-be";
+                       reg = <0x1000 0xff>;
+                       interrupts = <2 6 0>;
+               };
+
+               dma-controller@1200 {
+                       device_type = "dma-controller";
+                       compatible = "fsl,mpc5200-bestcomm";
+                       reg = <0x1200 0x80>;
+                       interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
+                                     3 4 0  3 5 0  3 6 0  3 7 0
+                                     3 8 0  3 9 0  3 10 0  3 11 0
+                                     3 12 0  3 13 0  3 14 0  3 15 0>;
+               };
+
+               xlb@1f00 {
+                       compatible = "fsl,mpc5200-xlb";
+                       reg = <0x1f00 0x100>;
+               };
+
+               serial@2000 {           // PSC1
+                       compatible = "fsl,mpc5200-psc-uart";
+                       reg = <0x2000 0x100>;
+                       interrupts = <2 1 0>;
+               };
+
+               serial@2400 {           // PSC3
+                       compatible = "fsl,mpc5200-psc-uart";
+                       reg = <0x2400 0x100>;
+                       interrupts = <2 3 0>;
+               };
+
+               ethernet@3000 {
+                       compatible = "fsl,mpc5200-fec";
+                       reg = <0x3000 0x400>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <2 5 0>;
+                       fixed-link = <1 1 100 0 0>;
+               };
+
+               mdio@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-mdio";
+                       reg = <0x3000 0x400>;       // fec range, since we need to setup fec interrupts
+                       interrupts = <2 5 0>;   // these are for "mii command finished", not link changes & co.
+               };
+
+               ata@3a00 {
+                       compatible = "fsl,mpc5200-ata";
+                       reg = <0x3a00 0x100>;
+                       interrupts = <2 7 0>;
+               };
+
+               i2c@3d00 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d00 0x40>;
+                       interrupts = <2 15 0>;
+               };
+
+
+               i2c@3d40 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc5200-i2c","fsl-i2c";
+                       reg = <0x3d40 0x40>;
+                       interrupts = <2 16 0>;
+
+                       dtt@28 {
+                               compatible = "national,lm80";
+                               reg = <0x28>;
+                       };
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                       };
+               };
+
+               sram@8000 {
+                       compatible = "fsl,mpc5200-sram";
+                       reg = <0x8000 0x4000>;
+               };
+       };
+
+       localbus {
+               compatible = "fsl,mpc5200-lpb","simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <      0 0 0xfc000000 0x02000000
+                               1 0 0xe0000000 0x04000000 // CS1 range, SM501
+                               3 0 0xe8000000 0x00080000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x02000000>;
+                       bank-width = <4>;
+                       device-width = <2>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+               };
+
+               display@1,0 {
+                       compatible = "smi,sm501";
+                       reg = <1 0x00000000 0x00800000
+                              1 0x03e00000 0x00200000>;
+                       mode = "640x480-32@60";
+                       interrupts = <1 1 3>;
+                       little-endian;
+               };
+
+               mram0@3,0 {
+                       compatible = "mtd-ram";
+                       reg = <3 0x00000 0x80000>;
+                       bank-width = <1>;
+               };
+       };
+
+       pci@f0000d00 {
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               device_type = "pci";
+               compatible = "fsl,mpc5200-pci";
+               reg = <0xf0000d00 0x100>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
+                                0xc000 0 0 2 &mpc5200_pic 0 0 3
+                                0xc000 0 0 3 &mpc5200_pic 0 0 3
+                                0xc000 0 0 4 &mpc5200_pic 0 0 3>;
+               clock-frequency = <0>; // From boot loader
+               interrupts = <2 8 0 2 9 0 2 10 0>;
+               bus-range = <0 0>;
+               ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
+                         0x02000000 0 0x90000000 0x90000000 0 0x10000000
+                         0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+       };
+};
index 27bd267d631cb58a42ebd7f149d8709e1e607755..a7511f2d844d9155a1c193effc52f34cd081f46f 100644 (file)
 
        soc5200@f0000000 {
                timer@600 {     // General Purpose Timer
+                       #gpio-cells = <2>;
                        fsl,has-wdt;
+                       gpio-controller;
                };
 
-               rtc@800 {
-                       status = "disabled";
+               timer@610 {
+                       #gpio-cells = <2>;
+                       gpio-controller;
                };
 
-               can@900 {
+               rtc@800 {
                        status = "disabled";
                };
 
-               can@980 {
-                       status = "disabled";
+               spi@f00 {
+                       msp430@0 {
+                               compatible = "spidev";
+                               spi-max-frequency = <32000>;
+                               reg = <0>;
+                       };
                };
 
                psc@2000 {              // PSC1
                };
 
                i2c@3d00 {
-                       rtc@50 {
+                       eeprom@50 {
                                compatible = "at,24c08";
                                reg = <0x50>;
                        };
 
+                       rtc@56 {
+                               compatible = "mc,rv3029c2";
+                               reg = <0x56>;
+                       };
+
                        rtc@68 {
                                compatible = "dallas,ds1339";
                                reg = <0x68>;
        };
 
        pci@f0000d00 {
-               status = "disabled";
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
+                                0xc000 0 0 2 &mpc5200_pic 0 0 3
+                                0xc000 0 0 3 &mpc5200_pic 0 0 3
+                                0xc000 0 0 4 &mpc5200_pic 0 0 3>;
+               clock-frequency = <0>; // From boot loader
+               interrupts = <2 8 0 2 9 0 2 10 0>;
+               bus-range = <0 0>;
+               ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
+                         0x02000000 0 0x90000000 0x90000000 0 0x10000000
+                         0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
        };
 
        localbus {
-               ranges = <0 0 0xff000000 0x1000000>;
+               ranges = <0 0 0xff000000 0x1000000
+                         4 0 0x60000000 0x0001000>;
 
                // 16-bit flash device at LocalPlus Bus CS0
                flash@0,0 {
                                reg = <0x00f00000 0x100000>;
                        };
                };
+
+               can@4,0 {
+                       compatible = "nxp,sja1000";
+                       reg = <4 0x000 0x80>;
+                       nxp,external-clock-frequency = <24000000>;
+                       interrupts = <1 2 3>; // Level-low
+               };
+
+               can@4,100 {
+                       compatible = "nxp,sja1000";
+                       reg = <4 0x100 0x80>;
+                       nxp,external-clock-frequency = <24000000>;
+                       interrupts = <1 2 3>;  // Level-low
+               };
+
+               serial@4,200 {
+                       compatible = "nxp,sc28l92";
+                       reg = <4 0x200 0x10>;
+                       interrupts = <1 3 3>;
+               };
        };
 };
index 83f4b79dff8597a4b492d168748510ed7de91b5d..2266bbb303d02d8df56c7f8595ba9e2e0e39890f 100644 (file)
                enet0: ethernet@24000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       cell-index = <0>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x24000 0x1000>;
                        ranges = <0x0 0x24000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+                       interrupts = <29 2 30  2 34 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
                        phy-handle = <&phy0>;
                        phy-connection-type = "gmii";
 
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x9 0x4>;
                                        reg = <1>;
+                                       device_type = "ethernet-phy";
                                };
                                phy2: ethernet-phy@2 {
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x8 0x4>;
                                        reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
                                };
                        };
                };
 
                enet1: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+                       interrupts = <31 2 32 2 33 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
                        phy-handle = <&phy2>;
                        phy-connection-type = "gmii";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
                };
 
                serial0: serial@4500 {
index fc3a331dd3923ed0758541b687cab6286ddff654..429e87d9acef12128fd947773f85b142d63ece97 100644 (file)
                enet0: ethernet@24000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       cell-index = <0>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x24000 0x1000>;
                        ranges = <0x0 0x24000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+                       interrupts = <29 2 30  2 34 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
                        phy-handle = <&phy0>;
                        phy-connection-type = "gmii";
 
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x9 0x4>;
                                        reg = <1>;
+                                       device_type = "ethernet-phy";
                                };
                                phy2: ethernet-phy@2 {
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x8 0x4>;
                                        reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
                                };
                        };
                };
 
                enet1: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+                       interrupts = <31 2 32 2 33 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
                        phy-handle = <&phy2>;
                        phy-connection-type = "gmii";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
                };
 
                serial0: serial@4500 {
index c0671cc9812522bc04ced27ee81dcbf70ded647a..d81201ac2cadb1900fedd8efb3c2d427086f492a 100644 (file)
                enet0: ethernet@24000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       cell-index = <0>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x24000 0x1000>;
                        ranges = <0x0 0x24000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+                       interrupts = <29 2 30  2 34 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
                        phy-handle = <&phy0>;
                        phy-connection-type = "gmii";
 
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x9 0x4>;
                                        reg = <1>;
+                                       device_type = "ethernet-phy";
                                };
                                phy2: ethernet-phy@2 {
                                        interrupt-parent = <&gef_pic>;
                                        interrupts = <0x8 0x4>;
                                        reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
                                };
                        };
                };
 
                enet1: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
                        device_type = "network";
-                       model = "eTSEC";
+                       model = "TSEC";
                        compatible = "gianfar";
                        reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
-                       interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+                       interrupts = <31 2 32 2 33 2>;
                        interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
                        phy-handle = <&phy2>;
                        phy-connection-type = "gmii";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
                };
 
                serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts
deleted file mode 100644 (file)
index 7988598..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-* Device Tree Source for Netstal Maschinen HCU4
-* based on the IBM Walnut
-*
-* Copyright 2008
-* Niklaus Giger <niklaus.giger@member.fsf.org>
-*
-* Copyright 2007 IBM Corp.
-* Josh Boyer <jwboyer@linux.vnet.ibm.com>
-*
-* This file is licensed under the terms of the GNU General Public
-* License version 2.  This program is licensed "as is" without
-* any warranty of any kind, whether express or implied.
-*/
-
-/dts-v1/;
-
-/ {
-       #address-cells = <0x1>;
-       #size-cells = <0x1>;
-       model = "netstal,hcu4";
-       compatible = "netstal,hcu4";
-       dcr-parent = <0x1>;
-
-       aliases {
-               ethernet0 = "/plb/opb/ethernet@ef600800";
-               serial0 = "/plb/opb/serial@ef600300";
-       };
-
-       cpus {
-               #address-cells = <0x1>;
-               #size-cells = <0x0>;
-
-               cpu@0 {
-                       device_type = "cpu";
-                       model = "PowerPC,405GPr";
-                       reg = <0x0>;
-                       clock-frequency = <0>;          /* Filled in by U-Boot */
-                       timebase-frequency = <0x0>;     /* Filled in by U-Boot */
-                       i-cache-line-size = <0x20>;
-                       d-cache-line-size = <0x20>;
-                       i-cache-size = <0x4000>;
-                       d-cache-size = <0x4000>;
-                       dcr-controller;
-                       dcr-access-method = "native";
-                       linux,phandle = <0x1>;
-               };
-       };
-
-       memory {
-               device_type = "memory";
-               reg = <0x0 0x0>;        /* Filled in by U-Boot */
-       };
-
-       UIC0: interrupt-controller {
-               compatible = "ibm,uic";
-               interrupt-controller;
-               cell-index = <0x0>;
-               dcr-reg = <0xc0 0x9>;
-               #address-cells = <0x0>;
-               #size-cells = <0x0>;
-               #interrupt-cells = <0x2>;
-               linux,phandle = <0x2>;
-       };
-
-       plb {
-               compatible = "ibm,plb3";
-               #address-cells = <0x1>;
-               #size-cells = <0x1>;
-               ranges;
-               clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-               SDRAM0: memory-controller {
-                       compatible = "ibm,sdram-405gp";
-                       dcr-reg = <0x10 0x2>;
-               };
-
-               MAL: mcmal {
-                       compatible = "ibm,mcmal-405gp", "ibm,mcmal";
-                       dcr-reg = <0x180 0x62>;
-                       num-tx-chans = <0x1>;
-                       num-rx-chans = <0x1>;
-                       interrupt-parent = <0x2>;
-                       interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>;
-                       linux,phandle = <0x3>;
-               };
-
-               POB0: opb {
-                       compatible = "ibm,opb-405gp", "ibm,opb";
-                       #address-cells = <0x1>;
-                       #size-cells = <0x1>;
-                       ranges = <0xef600000 0xef600000 0xa00000>;
-                       dcr-reg = <0xa0 0x5>;
-                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-                       UART0: serial@ef600300 {
-                               device_type = "serial";
-                               compatible = "ns16550";
-                               reg = <0xef600300 0x8>;
-                               virtual-reg = <0xef600300>;
-                               clock-frequency = <0x0>;/* Filled in by U-Boot */
-                               current-speed = <0>;    /* Filled in by U-Boot */
-                               interrupt-parent = <0x2>;
-                               interrupts = <0x0 0x4>;
-                       };
-
-                       IIC: i2c@ef600500 {
-                               compatible = "ibm,iic-405gp", "ibm,iic";
-                               reg = <0xef600500 0x11>;
-                               interrupt-parent = <0x2>;
-                               interrupts = <0x2 0x4>;
-                       };
-
-                       GPIO: gpio@ef600700 {
-                               compatible = "ibm,gpio-405gp";
-                               reg = <0xef600700 0x20>;
-                       };
-
-                       EMAC: ethernet@ef600800 {
-                               device_type = "network";
-                               compatible = "ibm,emac-405gp", "ibm,emac";
-                               interrupt-parent = <0x2>;
-                               interrupts = <0xf 0x4 0x9 0x4>;
-                               local-mac-address = [00 00 00 00 00 00];
-                               reg = <0xef600800 0x70>;
-                               mal-device = <0x3>;
-                               mal-tx-channel = <0x0>;
-                               mal-rx-channel = <0x0>;
-                               cell-index = <0x0>;
-                               max-frame-size = <0x5dc>;
-                               rx-fifo-size = <0x1000>;
-                               tx-fifo-size = <0x800>;
-                               phy-mode = "rmii";
-                               phy-map = <0x1>;
-                       };
-               };
-
-               EBC0: ebc {
-                       compatible = "ibm,ebc-405gp", "ibm,ebc";
-                       dcr-reg = <0x12 0x2>;
-                       #address-cells = <0x2>;
-                       #size-cells = <0x1>;
-                       clock-frequency = <0x0>;        /* Filled in by U-Boot */
-
-                       sram@0,0 {
-                               reg = <0x0 0x0 0x80000>;
-                       };
-
-                       flash@0,80000 {
-                               compatible = "jedec-flash";
-                               bank-width = <0x1>;
-                               reg = <0x0 0x80000 0x80000>;
-                               #address-cells = <0x1>;
-                               #size-cells = <0x1>;
-
-                               partition@0 {
-                                       label = "OpenBIOS";
-                                       reg = <0x0 0x80000>;
-                                       read-only;
-                               };
-                       };
-               };
-       };
-
-       chosen {
-               linux,stdout-path = "/plb/opb/serial@ef600300";
-       };
-};
index bdb7fc0fa3327c53e0ccfc8bf054a12684766a20..296c572ea605e991d79de406088cfab943603aa4 100644 (file)
        localbus@fdf05000 {
                #address-cells = <2>;
                #size-cells = <1>;
-               compatible = "fsl,mpc8560-localbus";
+               compatible = "fsl,mpc8560-localbus", "simple-bus";
                reg = <0xfdf05000 0x68>;
 
                ranges = <0x0 0x0 0xe0000000 0x00800000
index 1360d2f69024ea976389ccaa129079a4376217f2..ededaf5ac015e78b2fc269b4151b919ce5552497 100644 (file)
                                linux,network-index = <2>;
                                fsl,cpm-command = <0x16200300>;
                        };
+
+                       usb@11b60 {
+                               compatible = "fsl,mpc8272-cpm-usb";
+                               mode = "peripheral";
+                               reg = <0x11b60 0x40 0x8b00 0x100>;
+                               interrupts = <11 8>;
+                               interrupt-parent = <&PIC>;
+                               usb-clock = <5>;
+                       };
                };
 
                cpm2_pio_c: gpio-controller@10d40 {
index bc27548e895d2ee48dd9cc5dd50fc9c09d74aab4..7ab286ab5300accb706fb72a2e343153cae85d18 100644 (file)
                };
 
                spi@f00 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                        compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
                        reg = <0xf00 0x20>;
                        interrupts = <2 13 0 2 14 0>;
index b53d1df11e2d85ed791710695819aaec11eae61c..505dc842d80849936a5d349f4f0edfccffb96228 100644 (file)
                #address-cells = <2>;
                #size-cells = <1>;
                compatible = "fsl,mpc8349e-localbus",
-                            "fsl,pq2pro-localbus";
+                            "fsl,pq2pro-localbus",
+                            "simple-bus";
                reg = <0xe0005000 0xd8>;
                ranges = <0x0 0x0 0xfe000000 0x1000000  /* flash */
                          0x1 0x0 0xf8000000 0x20000    /* VSC 7385 */
index 1be9743ab5e085e93e346c22aa7b7a0369e9099c..b9b8719a6204d9a6a9f374b455493b94c2f7554c 100644 (file)
                };
 
                board-control@3,0 {
-                       compatible = "fsl,p1022ds-pixis";
+                       compatible = "fsl,p1022ds-fpga", "fsl,fpga-ngpixis";
                        reg = <3 0 0x30>;
                        interrupt-parent = <&mpic>;
                        /*
index d9b776740a6739707d26a9ad836a39533bc8718c..d3b478242ea9586b793f9def431a6d9a4ea00c80 100644 (file)
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /* IRQ[0:3] are pulled up on board, set to active-low */
                        interrupt-map = <
                                /* IDSEL 0x0 */
                                0000 0 0 1 &mpic 0 1
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /*
+                        * IRQ[4:6] only for PCIe, set to active-high,
+                        * IRQ[7] is pulled up on board, set to active-low
+                        */
                        interrupt-map = <
                                /* IDSEL 0x0 */
-                               0000 0 0 1 &mpic 4 1
-                               0000 0 0 2 &mpic 5 1
-                               0000 0 0 3 &mpic 6 1
+                               0000 0 0 1 &mpic 4 2
+                               0000 0 0 2 &mpic 5 2
+                               0000 0 0 3 &mpic 6 2
                                0000 0 0 4 &mpic 7 1
                                >;
                        ranges = <0x2000000 0x0 0xa0000000
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                        interrupt-map-mask = <0xf800 0 0 7>;
+                       /*
+                        * IRQ[8:10] are pulled up on board, set to active-low
+                        * IRQ[11] only for PCIe, set to active-high,
+                        */
                        interrupt-map = <
                                /* IDSEL 0x0 */
                                0000 0 0 1 &mpic 8 1
                                0000 0 0 2 &mpic 9 1
                                0000 0 0 3 &mpic 10 1
-                               0000 0 0 4 &mpic 11 1
+                               0000 0 0 4 &mpic 11 2
                                >;
                        ranges = <0x2000000 0x0 0x80000000
                                  0x2000000 0x0 0x80000000
index dae403100f2f8f798c2e81f02e4355d494efe57c..66f03d6477b2804cb1774f33ac833e0359d73619 100644 (file)
                        };
                };
 
+               board-control@3,0 {
+                       compatible = "fsl,p2020ds-fpga", "fsl,fpga-ngpixis";
+                       reg = <0x3 0x0 0x30>;
+               };
+
                nand@4,0 {
                        compatible = "fsl,elbc-fcm-nand";
                        reg = <0x4 0x0 0x40000>;
diff --git a/arch/powerpc/boot/dts/p2040rdb.dts b/arch/powerpc/boot/dts/p2040rdb.dts
deleted file mode 100644 (file)
index 7d84e39..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * P2040RDB Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Freescale Semiconductor nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/include/ "p2040si.dtsi"
-
-/ {
-       model = "fsl,P2040RDB";
-       compatible = "fsl,P2040RDB";
-       #address-cells = <2>;
-       #size-cells = <2>;
-       interrupt-parent = <&mpic>;
-
-       memory {
-               device_type = "memory";
-       };
-
-       soc: soc@ffe000000 {
-               spi@110000 {
-                       flash@0 {
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               compatible = "spansion,s25sl12801";
-                               reg = <0>;
-                               spi-max-frequency = <40000000>; /* input clock */
-                               partition@u-boot {
-                                       label = "u-boot";
-                                       reg = <0x00000000 0x00100000>;
-                                       read-only;
-                               };
-                               partition@kernel {
-                                       label = "kernel";
-                                       reg = <0x00100000 0x00500000>;
-                                       read-only;
-                               };
-                               partition@dtb {
-                                       label = "dtb";
-                                       reg = <0x00600000 0x00100000>;
-                                       read-only;
-                               };
-                               partition@fs {
-                                       label = "file system";
-                                       reg = <0x00700000 0x00900000>;
-                               };
-                       };
-               };
-
-               i2c@118000 {
-                       lm75b@48 {
-                               compatible = "nxp,lm75a";
-                               reg = <0x48>;
-                       };
-                       eeprom@50 {
-                               compatible = "at24,24c256";
-                               reg = <0x50>;
-                       };
-                       rtc@68 {
-                               compatible = "pericom,pt7c4338";
-                               reg = <0x68>;
-                       };
-               };
-
-               i2c@118100 {
-                       eeprom@50 {
-                               compatible = "at24,24c256";
-                               reg = <0x50>;
-                       };
-               };
-
-               usb0: usb@210000 {
-                       phy_type = "utmi";
-               };
-
-               usb1: usb@211000 {
-                       dr_mode = "host";
-                       phy_type = "utmi";
-               };
-       };
-
-       localbus@ffe124000 {
-               reg = <0xf 0xfe124000 0 0x1000>;
-               ranges = <0 0 0xf 0xe8000000 0x08000000>;
-
-               flash@0,0 {
-                       compatible = "cfi-flash";
-                       reg = <0 0 0x08000000>;
-                       bank-width = <2>;
-                       device-width = <2>;
-               };
-       };
-
-       pci0: pcie@ffe200000 {
-               reg = <0xf 0xfe200000 0 0x1000>;
-               ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
-                         0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
-               pcie@0 {
-                       ranges = <0x02000000 0 0xe0000000
-                                 0x02000000 0 0xe0000000
-                                 0 0x20000000
-
-                                 0x01000000 0 0x00000000
-                                 0x01000000 0 0x00000000
-                                 0 0x00010000>;
-               };
-       };
-
-       pci1: pcie@ffe201000 {
-               reg = <0xf 0xfe201000 0 0x1000>;
-               ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
-                         0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
-               pcie@0 {
-                       ranges = <0x02000000 0 0xe0000000
-                                 0x02000000 0 0xe0000000
-                                 0 0x20000000
-
-                                 0x01000000 0 0x00000000
-                                 0x01000000 0 0x00000000
-                                 0 0x00010000>;
-               };
-       };
-
-       pci2: pcie@ffe202000 {
-               reg = <0xf 0xfe202000 0 0x1000>;
-               ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
-                         0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
-               pcie@0 {
-                       ranges = <0x02000000 0 0xe0000000
-                                 0x02000000 0 0xe0000000
-                                 0 0x20000000
-
-                                 0x01000000 0 0x00000000
-                                 0x01000000 0 0x00000000
-                                 0 0x00010000>;
-               };
-       };
-};
diff --git a/arch/powerpc/boot/dts/p2040si.dtsi b/arch/powerpc/boot/dts/p2040si.dtsi
deleted file mode 100644 (file)
index 5fdbb24..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * P2040 Silicon Device Tree Source
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of Freescale Semiconductor nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") as published by the Free Software
- * Foundation, either version 2 of that License or (at your option) any
- * later version.
- *
- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/dts-v1/;
-
-/ {
-       compatible = "fsl,P2040";
-       #address-cells = <2>;
-       #size-cells = <2>;
-       interrupt-parent = <&mpic>;
-
-       aliases {
-               ccsr = &soc;
-
-               serial0 = &serial0;
-               serial1 = &serial1;
-               serial2 = &serial2;
-               serial3 = &serial3;
-               pci0 = &pci0;
-               pci1 = &pci1;
-               pci2 = &pci2;
-               usb0 = &usb0;
-               usb1 = &usb1;
-               dma0 = &dma0;
-               dma1 = &dma1;
-               sdhc = &sdhc;
-               msi0 = &msi0;
-               msi1 = &msi1;
-               msi2 = &msi2;
-
-               crypto = &crypto;
-               sec_jr0 = &sec_jr0;
-               sec_jr1 = &sec_jr1;
-               sec_jr2 = &sec_jr2;
-               sec_jr3 = &sec_jr3;
-               rtic_a = &rtic_a;
-               rtic_b = &rtic_b;
-               rtic_c = &rtic_c;
-               rtic_d = &rtic_d;
-               sec_mon = &sec_mon;
-       };
-
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               cpu0: PowerPC,e500mc@0 {
-                       device_type = "cpu";
-                       reg = <0>;
-                       next-level-cache = <&L2_0>;
-                       L2_0: l2-cache {
-                               next-level-cache = <&cpc>;
-                       };
-               };
-               cpu1: PowerPC,e500mc@1 {
-                       device_type = "cpu";
-                       reg = <1>;
-                       next-level-cache = <&L2_1>;
-                       L2_1: l2-cache {
-                               next-level-cache = <&cpc>;
-                       };
-               };
-               cpu2: PowerPC,e500mc@2 {
-                       device_type = "cpu";
-                       reg = <2>;
-                       next-level-cache = <&L2_2>;
-                       L2_2: l2-cache {
-                               next-level-cache = <&cpc>;
-                       };
-               };
-               cpu3: PowerPC,e500mc@3 {
-                       device_type = "cpu";
-                       reg = <3>;
-                       next-level-cache = <&L2_3>;
-                       L2_3: l2-cache {
-                               next-level-cache = <&cpc>;
-                       };
-               };
-       };
-
-       soc: soc@ffe000000 {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               device_type = "soc";
-               compatible = "simple-bus";
-               ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
-               reg = <0xf 0xfe000000 0 0x00001000>;
-
-               soc-sram-error {
-                       compatible = "fsl,soc-sram-error";
-                       interrupts = <16 2 1 29>;
-               };
-
-               corenet-law@0 {
-                       compatible = "fsl,corenet-law";
-                       reg = <0x0 0x1000>;
-                       fsl,num-laws = <32>;
-               };
-
-               memory-controller@8000 {
-                       compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
-                       reg = <0x8000 0x1000>;
-                       interrupts = <16 2 1 23>;
-               };
-
-               cpc: l3-cache-controller@10000 {
-                       compatible = "fsl,p2040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
-                       reg = <0x10000 0x1000>;
-                       interrupts = <16 2 1 27>;
-               };
-
-               corenet-cf@18000 {
-                       compatible = "fsl,corenet-cf";
-                       reg = <0x18000 0x1000>;
-                       interrupts = <16 2 1 31>;
-                       fsl,ccf-num-csdids = <32>;
-                       fsl,ccf-num-snoopids = <32>;
-               };
-
-               iommu@20000 {
-                       compatible = "fsl,pamu-v1.0", "fsl,pamu";
-                       reg = <0x20000 0x4000>;
-                       interrupts = <
-                               24 2 0 0
-                               16 2 1 30>;
-               };
-
-               mpic: pic@40000 {
-                       clock-frequency = <0>;
-                       interrupt-controller;
-                       #address-cells = <0>;
-                       #interrupt-cells = <4>;
-                       reg = <0x40000 0x40000>;
-                       compatible = "fsl,mpic", "chrp,open-pic";
-                       device_type = "open-pic";
-               };
-
-               msi0: msi@41600 {
-                       compatible = "fsl,mpic-msi";
-                       reg = <0x41600 0x200>;
-                       msi-available-ranges = <0 0x100>;
-                       interrupts = <
-                               0xe0 0 0 0
-                               0xe1 0 0 0
-                               0xe2 0 0 0
-                               0xe3 0 0 0
-                               0xe4 0 0 0
-                               0xe5 0 0 0
-                               0xe6 0 0 0
-                               0xe7 0 0 0>;
-               };
-
-               msi1: msi@41800 {
-                       compatible = "fsl,mpic-msi";
-                       reg = <0x41800 0x200>;
-                       msi-available-ranges = <0 0x100>;
-                       interrupts = <
-                               0xe8 0 0 0
-                               0xe9 0 0 0
-                               0xea 0 0 0
-                               0xeb 0 0 0
-                               0xec 0 0 0
-                               0xed 0 0 0
-                               0xee 0 0 0
-                               0xef 0 0 0>;
-               };
-
-               msi2: msi@41a00 {
-                       compatible = "fsl,mpic-msi";
-                       reg = <0x41a00 0x200>;
-                       msi-available-ranges = <0 0x100>;
-                       interrupts = <
-                               0xf0 0 0 0
-                               0xf1 0 0 0
-                               0xf2 0 0 0
-                               0xf3 0 0 0
-                               0xf4 0 0 0
-                               0xf5 0 0 0
-                               0xf6 0 0 0
-                               0xf7 0 0 0>;
-               };
-
-               guts: global-utilities@e0000 {
-                       compatible = "fsl,qoriq-device-config-1.0";
-                       reg = <0xe0000 0xe00>;
-                       fsl,has-rstcr;
-                       #sleep-cells = <1>;
-                       fsl,liodn-bits = <12>;
-               };
-
-               pins: global-utilities@e0e00 {
-                       compatible = "fsl,qoriq-pin-control-1.0";
-                       reg = <0xe0e00 0x200>;
-                       #sleep-cells = <2>;
-               };
-
-               clockgen: global-utilities@e1000 {
-                       compatible = "fsl,p2040-clockgen", "fsl,qoriq-clockgen-1.0";
-                       reg = <0xe1000 0x1000>;
-                       clock-frequency = <0>;
-               };
-
-               rcpm: global-utilities@e2000 {
-                       compatible = "fsl,qoriq-rcpm-1.0";
-                       reg = <0xe2000 0x1000>;
-                       #sleep-cells = <1>;
-               };
-
-               sfp: sfp@e8000 {
-                       compatible = "fsl,p2040-sfp", "fsl,qoriq-sfp-1.0";
-                       reg        = <0xe8000 0x1000>;
-               };
-
-               serdes: serdes@ea000 {
-                       compatible = "fsl,p2040-serdes";
-                       reg        = <0xea000 0x1000>;
-               };
-
-               dma0: dma@100300 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       compatible = "fsl,p2040-dma", "fsl,eloplus-dma";
-                       reg = <0x100300 0x4>;
-                       ranges = <0x0 0x100100 0x200>;
-                       cell-index = <0>;
-                       dma-channel@0 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x0 0x80>;
-                               cell-index = <0>;
-                               interrupts = <28 2 0 0>;
-                       };
-                       dma-channel@80 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x80 0x80>;
-                               cell-index = <1>;
-                               interrupts = <29 2 0 0>;
-                       };
-                       dma-channel@100 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x100 0x80>;
-                               cell-index = <2>;
-                               interrupts = <30 2 0 0>;
-                       };
-                       dma-channel@180 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x180 0x80>;
-                               cell-index = <3>;
-                               interrupts = <31 2 0 0>;
-                       };
-               };
-
-               dma1: dma@101300 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       compatible = "fsl,p2040-dma", "fsl,eloplus-dma";
-                       reg = <0x101300 0x4>;
-                       ranges = <0x0 0x101100 0x200>;
-                       cell-index = <1>;
-                       dma-channel@0 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x0 0x80>;
-                               cell-index = <0>;
-                               interrupts = <32 2 0 0>;
-                       };
-                       dma-channel@80 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x80 0x80>;
-                               cell-index = <1>;
-                               interrupts = <33 2 0 0>;
-                       };
-                       dma-channel@100 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x100 0x80>;
-                               cell-index = <2>;
-                               interrupts = <34 2 0 0>;
-                       };
-                       dma-channel@180 {
-                               compatible = "fsl,p2040-dma-channel",
-                                               "fsl,eloplus-dma-channel";
-                               reg = <0x180 0x80>;
-                               cell-index = <3>;
-                               interrupts = <35 2 0 0>;
-                       };
-               };
-
-               spi@110000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "fsl,p2040-espi", "fsl,mpc8536-espi";
-                       reg = <0x110000 0x1000>;
-                       interrupts = <53 0x2 0 0>;
-                       fsl,espi-num-chipselects = <4>;
-
-               };
-
-               sdhc: sdhc@114000 {
-                       compatible = "fsl,p2040-esdhc", "fsl,esdhc";
-                       reg = <0x114000 0x1000>;
-                       interrupts = <48 2 0 0>;
-                       sdhci,auto-cmd12;
-                       clock-frequency = <0>;
-               };
-
-
-               i2c@118000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <0>;
-                       compatible = "fsl-i2c";
-                       reg = <0x118000 0x100>;
-                       interrupts = <38 2 0 0>;
-                       dfsrr;
-               };
-
-               i2c@118100 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <1>;
-                       compatible = "fsl-i2c";
-                       reg = <0x118100 0x100>;
-                       interrupts = <38 2 0 0>;
-                       dfsrr;
-               };
-
-               i2c@119000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <2>;
-                       compatible = "fsl-i2c";
-                       reg = <0x119000 0x100>;
-                       interrupts = <39 2 0 0>;
-                       dfsrr;
-               };
-
-               i2c@119100 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <3>;
-                       compatible = "fsl-i2c";
-                       reg = <0x119100 0x100>;
-                       interrupts = <39 2 0 0>;
-                       dfsrr;
-               };
-
-               serial0: serial@11c500 {
-                       cell-index = <0>;
-                       device_type = "serial";
-                       compatible = "ns16550";
-                       reg = <0x11c500 0x100>;
-                       clock-frequency = <0>;
-                       interrupts = <36 2 0 0>;
-               };
-
-               serial1: serial@11c600 {
-                       cell-index = <1>;
-                       device_type = "serial";
-                       compatible = "ns16550";
-                       reg = <0x11c600 0x100>;
-                       clock-frequency = <0>;
-                       interrupts = <36 2 0 0>;
-               };
-
-               serial2: serial@11d500 {
-                       cell-index = <2>;
-                       device_type = "serial";
-                       compatible = "ns16550";
-                       reg = <0x11d500 0x100>;
-                       clock-frequency = <0>;
-                       interrupts = <37 2 0 0>;
-               };
-
-               serial3: serial@11d600 {
-                       cell-index = <3>;
-                       device_type = "serial";
-                       compatible = "ns16550";
-                       reg = <0x11d600 0x100>;
-                       clock-frequency = <0>;
-                       interrupts = <37 2 0 0>;
-               };
-
-               gpio0: gpio@130000 {
-                       compatible = "fsl,p2040-gpio", "fsl,qoriq-gpio";
-                       reg = <0x130000 0x1000>;
-                       interrupts = <55 2 0 0>;
-                       #gpio-cells = <2>;
-                       gpio-controller;
-               };
-
-               usb0: usb@210000 {
-                       compatible = "fsl,p2040-usb2-mph",
-                                       "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
-                       reg = <0x210000 0x1000>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <44 0x2 0 0>;
-                       port0;
-               };
-
-               usb1: usb@211000 {
-                       compatible = "fsl,p2040-usb2-dr",
-                                       "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
-                       reg = <0x211000 0x1000>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <45 0x2 0 0>;
-               };
-
-               sata@220000 {
-                       compatible = "fsl,p2040-sata", "fsl,pq-sata-v2";
-                       reg = <0x220000 0x1000>;
-                       interrupts = <68 0x2 0 0>;
-               };
-
-               sata@221000 {
-                       compatible = "fsl,p2040-sata", "fsl,pq-sata-v2";
-                       reg = <0x221000 0x1000>;
-                       interrupts = <69 0x2 0 0>;
-               };
-
-               crypto: crypto@300000 {
-                       compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       reg = <0x300000 0x10000>;
-                       ranges = <0 0x300000 0x10000>;
-                       interrupts = <92 2 0 0>;
-
-                       sec_jr0: jr@1000 {
-                               compatible = "fsl,sec-v4.2-job-ring",
-                                            "fsl,sec-v4.0-job-ring";
-                               reg = <0x1000 0x1000>;
-                               interrupts = <88 2 0 0>;
-                       };
-
-                       sec_jr1: jr@2000 {
-                               compatible = "fsl,sec-v4.2-job-ring",
-                                            "fsl,sec-v4.0-job-ring";
-                               reg = <0x2000 0x1000>;
-                               interrupts = <89 2 0 0>;
-                       };
-
-                       sec_jr2: jr@3000 {
-                               compatible = "fsl,sec-v4.2-job-ring",
-                                            "fsl,sec-v4.0-job-ring";
-                               reg = <0x3000 0x1000>;
-                               interrupts = <90 2 0 0>;
-                       };
-
-                       sec_jr3: jr@4000 {
-                               compatible = "fsl,sec-v4.2-job-ring",
-                                            "fsl,sec-v4.0-job-ring";
-                               reg = <0x4000 0x1000>;
-                               interrupts = <91 2 0 0>;
-                       };
-
-                       rtic@6000 {
-                               compatible = "fsl,sec-v4.2-rtic",
-                                            "fsl,sec-v4.0-rtic";
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               reg = <0x6000 0x100>;
-                               ranges = <0x0 0x6100 0xe00>;
-
-                               rtic_a: rtic-a@0 {
-                                       compatible = "fsl,sec-v4.2-rtic-memory",
-                                                    "fsl,sec-v4.0-rtic-memory";
-                                       reg = <0x00 0x20 0x100 0x80>;
-                               };
-
-                               rtic_b: rtic-b@20 {
-                                       compatible = "fsl,sec-v4.2-rtic-memory",
-                                                    "fsl,sec-v4.0-rtic-memory";
-                                       reg = <0x20 0x20 0x200 0x80>;
-                               };
-
-                               rtic_c: rtic-c@40 {
-                                       compatible = "fsl,sec-v4.2-rtic-memory",
-                                                    "fsl,sec-v4.0-rtic-memory";
-                                       reg = <0x40 0x20 0x300 0x80>;
-                               };
-
-                               rtic_d: rtic-d@60 {
-                                       compatible = "fsl,sec-v4.2-rtic-memory",
-                                                    "fsl,sec-v4.0-rtic-memory";
-                                       reg = <0x60 0x20 0x500 0x80>;
-                               };
-                       };
-               };
-
-               sec_mon: sec_mon@314000 {
-                       compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
-                       reg = <0x314000 0x1000>;
-                       interrupts = <93 2 0 0>;
-               };
-
-       };
-
-       localbus@ffe124000 {
-               compatible = "fsl,p2040-elbc", "fsl,elbc", "simple-bus";
-               interrupts = <25 2 0 0>;
-               #address-cells = <2>;
-               #size-cells = <1>;
-       };
-
-       pci0: pcie@ffe200000 {
-               compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2";
-               device_type = "pci";
-               #size-cells = <2>;
-               #address-cells = <3>;
-               bus-range = <0x0 0xff>;
-               clock-frequency = <0x1fca055>;
-               fsl,msi = <&msi0>;
-               interrupts = <16 2 1 15>;
-               pcie@0 {
-                       reg = <0 0 0 0 0>;
-                       #interrupt-cells = <1>;
-                       #size-cells = <2>;
-                       #address-cells = <3>;
-                       device_type = "pci";
-                       interrupts = <16 2 1 15>;
-                       interrupt-map-mask = <0xf800 0 0 7>;
-                       interrupt-map = <
-                               /* IDSEL 0x0 */
-                               0000 0 0 1 &mpic 40 1 0 0
-                               0000 0 0 2 &mpic 1 1 0 0
-                               0000 0 0 3 &mpic 2 1 0 0
-                               0000 0 0 4 &mpic 3 1 0 0
-                               >;
-               };
-       };
-
-       pci1: pcie@ffe201000 {
-               compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2";
-               device_type = "pci";
-               #size-cells = <2>;
-               #address-cells = <3>;
-               bus-range = <0 0xff>;
-               clock-frequency = <0x1fca055>;
-               fsl,msi = <&msi1>;
-               interrupts = <16 2 1 14>;
-               pcie@0 {
-                       reg = <0 0 0 0 0>;
-                       #interrupt-cells = <1>;
-                       #size-cells = <2>;
-                       #address-cells = <3>;
-                       device_type = "pci";
-                       interrupts = <16 2 1 14>;
-                       interrupt-map-mask = <0xf800 0 0 7>;
-                       interrupt-map = <
-                               /* IDSEL 0x0 */
-                               0000 0 0 1 &mpic 41 1 0 0
-                               0000 0 0 2 &mpic 5 1 0 0
-                               0000 0 0 3 &mpic 6 1 0 0
-                               0000 0 0 4 &mpic 7 1 0 0
-                               >;
-               };
-       };
-
-       pci2: pcie@ffe202000 {
-               compatible = "fsl,p2040-pcie", "fsl,qoriq-pcie-v2.2";
-               device_type = "pci";
-               #size-cells = <2>;
-               #address-cells = <3>;
-               bus-range = <0x0 0xff>;
-               clock-frequency = <0x1fca055>;
-               fsl,msi = <&msi2>;
-               interrupts = <16 2 1 13>;
-               pcie@0 {
-                       reg = <0 0 0 0 0>;
-                       #interrupt-cells = <1>;
-                       #size-cells = <2>;
-                       #address-cells = <3>;
-                       device_type = "pci";
-                       interrupts = <16 2 1 13>;
-                       interrupt-map-mask = <0xf800 0 0 7>;
-                       interrupt-map = <
-                               /* IDSEL 0x0 */
-                               0000 0 0 1 &mpic 42 1 0 0
-                               0000 0 0 2 &mpic 9 1 0 0
-                               0000 0 0 3 &mpic 10 1 0 0
-                               0000 0 0 4 &mpic 11 1 0 0
-                               >;
-               };
-       };
-};
diff --git a/arch/powerpc/boot/dts/p2041rdb.dts b/arch/powerpc/boot/dts/p2041rdb.dts
new file mode 100644 (file)
index 0000000..79b6895
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * P2041RDB Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "p2041si.dtsi"
+
+/ {
+       model = "fsl,P2041RDB";
+       compatible = "fsl,P2041RDB";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       memory {
+               device_type = "memory";
+       };
+
+       dcsr: dcsr@f00000000 {
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
+       soc: soc@ffe000000 {
+               spi@110000 {
+                       flash@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "spansion,s25sl12801";
+                               reg = <0>;
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@u-boot {
+                                       label = "u-boot";
+                                       reg = <0x00000000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@kernel {
+                                       label = "kernel";
+                                       reg = <0x00100000 0x00500000>;
+                                       read-only;
+                               };
+                               partition@dtb {
+                                       label = "dtb";
+                                       reg = <0x00600000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@fs {
+                                       label = "file system";
+                                       reg = <0x00700000 0x00900000>;
+                               };
+                       };
+               };
+
+               i2c@118000 {
+                       lm75b@48 {
+                               compatible = "nxp,lm75a";
+                               reg = <0x48>;
+                       };
+                       eeprom@50 {
+                               compatible = "at24,24c256";
+                               reg = <0x50>;
+                       };
+                       rtc@68 {
+                               compatible = "pericom,pt7c4338";
+                               reg = <0x68>;
+                       };
+               };
+
+               i2c@118100 {
+                       eeprom@50 {
+                               compatible = "at24,24c256";
+                               reg = <0x50>;
+                       };
+               };
+
+               usb1: usb@211000 {
+                       dr_mode = "host";
+               };
+       };
+
+       localbus@ffe124000 {
+               reg = <0xf 0xfe124000 0 0x1000>;
+               ranges = <0 0 0xf 0xe8000000 0x08000000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x08000000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+               };
+       };
+
+       pci0: pcie@ffe200000 {
+               reg = <0xf 0xfe200000 0 0x1000>;
+               ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+                         0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+               pcie@0 {
+                       ranges = <0x02000000 0 0xe0000000
+                                 0x02000000 0 0xe0000000
+                                 0 0x20000000
+
+                                 0x01000000 0 0x00000000
+                                 0x01000000 0 0x00000000
+                                 0 0x00010000>;
+               };
+       };
+
+       pci1: pcie@ffe201000 {
+               reg = <0xf 0xfe201000 0 0x1000>;
+               ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+               pcie@0 {
+                       ranges = <0x02000000 0 0xe0000000
+                                 0x02000000 0 0xe0000000
+                                 0 0x20000000
+
+                                 0x01000000 0 0x00000000
+                                 0x01000000 0 0x00000000
+                                 0 0x00010000>;
+               };
+       };
+
+       pci2: pcie@ffe202000 {
+               reg = <0xf 0xfe202000 0 0x1000>;
+               ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000
+                         0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+               pcie@0 {
+                       ranges = <0x02000000 0 0xe0000000
+                                 0x02000000 0 0xe0000000
+                                 0 0x20000000
+
+                                 0x01000000 0 0x00000000
+                                 0x01000000 0 0x00000000
+                                 0 0x00010000>;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/p2041si.dtsi b/arch/powerpc/boot/dts/p2041si.dtsi
new file mode 100644 (file)
index 0000000..f7492ed
--- /dev/null
@@ -0,0 +1,692 @@
+/*
+ * P2041 Silicon Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/ {
+       compatible = "fsl,P2041";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       aliases {
+               ccsr = &soc;
+               dcsr = &dcsr;
+
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
+               pci0 = &pci0;
+               pci1 = &pci1;
+               pci2 = &pci2;
+               usb0 = &usb0;
+               usb1 = &usb1;
+               dma0 = &dma0;
+               dma1 = &dma1;
+               sdhc = &sdhc;
+               msi0 = &msi0;
+               msi1 = &msi1;
+               msi2 = &msi2;
+
+               crypto = &crypto;
+               sec_jr0 = &sec_jr0;
+               sec_jr1 = &sec_jr1;
+               sec_jr2 = &sec_jr2;
+               sec_jr3 = &sec_jr3;
+               rtic_a = &rtic_a;
+               rtic_b = &rtic_b;
+               rtic_c = &rtic_c;
+               rtic_d = &rtic_d;
+               sec_mon = &sec_mon;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: PowerPC,e500mc@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2_0>;
+                       L2_0: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu1: PowerPC,e500mc@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       next-level-cache = <&L2_1>;
+                       L2_1: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu2: PowerPC,e500mc@2 {
+                       device_type = "cpu";
+                       reg = <2>;
+                       next-level-cache = <&L2_2>;
+                       L2_2: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu3: PowerPC,e500mc@3 {
+                       device_type = "cpu";
+                       reg = <3>;
+                       next-level-cache = <&L2_3>;
+                       L2_3: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+       };
+
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+
+               dcsr-epu@0 {
+                       compatible = "fsl,dcsr-epu";
+                       interrupts = <52 2 0 0
+                                     84 2 0 0
+                                     85 2 0 0>;
+                       interrupt-parent = <&mpic>;
+                       reg = <0x0 0x1000>;
+               };
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p2041-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p2041-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr>;
+                       reg = <0x12000 0x1000>;
+               };
+               dcsr-nal@18000 {
+                       compatible = "fsl,p2041-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p2041-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@42000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu2>;
+                       reg = <0x42000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@43000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu3>;
+                       reg = <0x43000 0x1000>;
+               };
+       };
+
+       soc: soc@ffe000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "simple-bus";
+               ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+               reg = <0xf 0xfe000000 0 0x00001000>;
+
+               soc-sram-error {
+                       compatible = "fsl,soc-sram-error";
+                       interrupts = <16 2 1 29>;
+               };
+
+               corenet-law@0 {
+                       compatible = "fsl,corenet-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <32>;
+               };
+
+               ddr: memory-controller@8000 {
+                       compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+                       reg = <0x8000 0x1000>;
+                       interrupts = <16 2 1 23>;
+               };
+
+               cpc: l3-cache-controller@10000 {
+                       compatible = "fsl,p2041-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache";
+                       reg = <0x10000 0x1000>;
+                       interrupts = <16 2 1 27>;
+               };
+
+               corenet-cf@18000 {
+                       compatible = "fsl,corenet-cf";
+                       reg = <0x18000 0x1000>;
+                       interrupts = <16 2 1 31>;
+                       fsl,ccf-num-csdids = <32>;
+                       fsl,ccf-num-snoopids = <32>;
+               };
+
+               iommu@20000 {
+                       compatible = "fsl,pamu-v1.0", "fsl,pamu";
+                       reg = <0x20000 0x4000>;
+                       interrupts = <
+                               24 2 0 0
+                               16 2 1 30>;
+               };
+
+               mpic: pic@40000 {
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <4>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "fsl,mpic", "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi0: msi@41600 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41600 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0 0 0
+                               0xe1 0 0 0
+                               0xe2 0 0 0
+                               0xe3 0 0 0
+                               0xe4 0 0 0
+                               0xe5 0 0 0
+                               0xe6 0 0 0
+                               0xe7 0 0 0>;
+               };
+
+               msi1: msi@41800 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41800 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe8 0 0 0
+                               0xe9 0 0 0
+                               0xea 0 0 0
+                               0xeb 0 0 0
+                               0xec 0 0 0
+                               0xed 0 0 0
+                               0xee 0 0 0
+                               0xef 0 0 0>;
+               };
+
+               msi2: msi@41a00 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41a00 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xf0 0 0 0
+                               0xf1 0 0 0
+                               0xf2 0 0 0
+                               0xf3 0 0 0
+                               0xf4 0 0 0
+                               0xf5 0 0 0
+                               0xf6 0 0 0
+                               0xf7 0 0 0>;
+               };
+
+               guts: global-utilities@e0000 {
+                       compatible = "fsl,qoriq-device-config-1.0";
+                       reg = <0xe0000 0xe00>;
+                       fsl,has-rstcr;
+                       #sleep-cells = <1>;
+                       fsl,liodn-bits = <12>;
+               };
+
+               pins: global-utilities@e0e00 {
+                       compatible = "fsl,qoriq-pin-control-1.0";
+                       reg = <0xe0e00 0x200>;
+                       #sleep-cells = <2>;
+               };
+
+               clockgen: global-utilities@e1000 {
+                       compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
+                       reg = <0xe1000 0x1000>;
+                       clock-frequency = <0>;
+               };
+
+               rcpm: global-utilities@e2000 {
+                       compatible = "fsl,qoriq-rcpm-1.0";
+                       reg = <0xe2000 0x1000>;
+                       #sleep-cells = <1>;
+               };
+
+               sfp: sfp@e8000 {
+                       compatible = "fsl,p2041-sfp", "fsl,qoriq-sfp-1.0";
+                       reg        = <0xe8000 0x1000>;
+               };
+
+               serdes: serdes@ea000 {
+                       compatible = "fsl,p2041-serdes";
+                       reg        = <0xea000 0x1000>;
+               };
+
+               dma0: dma@100300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+                       reg = <0x100300 0x4>;
+                       ranges = <0x0 0x100100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupts = <28 2 0 0>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupts = <29 2 0 0>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupts = <30 2 0 0>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupts = <31 2 0 0>;
+                       };
+               };
+
+               dma1: dma@101300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p2041-dma", "fsl,eloplus-dma";
+                       reg = <0x101300 0x4>;
+                       ranges = <0x0 0x101100 0x200>;
+                       cell-index = <1>;
+                       dma-channel@0 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupts = <32 2 0 0>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupts = <33 2 0 0>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupts = <34 2 0 0>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,p2041-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupts = <35 2 0 0>;
+                       };
+               };
+
+               spi@110000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,p2041-espi", "fsl,mpc8536-espi";
+                       reg = <0x110000 0x1000>;
+                       interrupts = <53 0x2 0 0>;
+                       fsl,espi-num-chipselects = <4>;
+               };
+
+               sdhc: sdhc@114000 {
+                       compatible = "fsl,p2041-esdhc", "fsl,esdhc";
+                       reg = <0x114000 0x1000>;
+                       interrupts = <48 2 0 0>;
+                       sdhci,auto-cmd12;
+                       clock-frequency = <0>;
+               };
+
+               i2c@118000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x118000 0x100>;
+                       interrupts = <38 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@118100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x118100 0x100>;
+                       interrupts = <38 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@119000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <2>;
+                       compatible = "fsl-i2c";
+                       reg = <0x119000 0x100>;
+                       interrupts = <39 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@119100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <3>;
+                       compatible = "fsl-i2c";
+                       reg = <0x119100 0x100>;
+                       interrupts = <39 2 0 0>;
+                       dfsrr;
+               };
+
+               serial0: serial@11c500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11c500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <36 2 0 0>;
+               };
+
+               serial1: serial@11c600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11c600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <36 2 0 0>;
+               };
+
+               serial2: serial@11d500 {
+                       cell-index = <2>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11d500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <37 2 0 0>;
+               };
+
+               serial3: serial@11d600 {
+                       cell-index = <3>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11d600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <37 2 0 0>;
+               };
+
+               gpio0: gpio@130000 {
+                       compatible = "fsl,p2041-gpio", "fsl,qoriq-gpio";
+                       reg = <0x130000 0x1000>;
+                       interrupts = <55 2 0 0>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+               };
+
+               usb0: usb@210000 {
+                       compatible = "fsl,p2041-usb2-mph",
+                                       "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+                       reg = <0x210000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <44 0x2 0 0>;
+                       phy_type = "utmi";
+                       port0;
+               };
+
+               usb1: usb@211000 {
+                       compatible = "fsl,p2041-usb2-dr",
+                                       "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+                       reg = <0x211000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <45 0x2 0 0>;
+                       phy_type = "utmi";
+               };
+
+               sata@220000 {
+                       compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+                       reg = <0x220000 0x1000>;
+                       interrupts = <68 0x2 0 0>;
+               };
+
+               sata@221000 {
+                       compatible = "fsl,p2041-sata", "fsl,pq-sata-v2";
+                       reg = <0x221000 0x1000>;
+                       interrupts = <69 0x2 0 0>;
+               };
+
+               crypto: crypto@300000 {
+                       compatible = "fsl,sec-v4.2", "fsl,sec-v4.0";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x300000 0x10000>;
+                       ranges = <0 0x300000 0x10000>;
+                       interrupts = <92 2 0 0>;
+
+                       sec_jr0: jr@1000 {
+                               compatible = "fsl,sec-v4.2-job-ring",
+                                            "fsl,sec-v4.0-job-ring";
+                               reg = <0x1000 0x1000>;
+                               interrupts = <88 2 0 0>;
+                       };
+
+                       sec_jr1: jr@2000 {
+                               compatible = "fsl,sec-v4.2-job-ring",
+                                            "fsl,sec-v4.0-job-ring";
+                               reg = <0x2000 0x1000>;
+                               interrupts = <89 2 0 0>;
+                       };
+
+                       sec_jr2: jr@3000 {
+                               compatible = "fsl,sec-v4.2-job-ring",
+                                            "fsl,sec-v4.0-job-ring";
+                               reg = <0x3000 0x1000>;
+                               interrupts = <90 2 0 0>;
+                       };
+
+                       sec_jr3: jr@4000 {
+                               compatible = "fsl,sec-v4.2-job-ring",
+                                            "fsl,sec-v4.0-job-ring";
+                               reg = <0x4000 0x1000>;
+                               interrupts = <91 2 0 0>;
+                       };
+
+                       rtic@6000 {
+                               compatible = "fsl,sec-v4.2-rtic",
+                                            "fsl,sec-v4.0-rtic";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x6000 0x100>;
+                               ranges = <0x0 0x6100 0xe00>;
+
+                               rtic_a: rtic-a@0 {
+                                       compatible = "fsl,sec-v4.2-rtic-memory",
+                                                    "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x00 0x20 0x100 0x80>;
+                               };
+
+                               rtic_b: rtic-b@20 {
+                                       compatible = "fsl,sec-v4.2-rtic-memory",
+                                                    "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x20 0x20 0x200 0x80>;
+                               };
+
+                               rtic_c: rtic-c@40 {
+                                       compatible = "fsl,sec-v4.2-rtic-memory",
+                                                    "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x40 0x20 0x300 0x80>;
+                               };
+
+                               rtic_d: rtic-d@60 {
+                                       compatible = "fsl,sec-v4.2-rtic-memory",
+                                                    "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x60 0x20 0x500 0x80>;
+                               };
+                       };
+               };
+
+               sec_mon: sec_mon@314000 {
+                       compatible = "fsl,sec-v4.2-mon", "fsl,sec-v4.0-mon";
+                       reg = <0x314000 0x1000>;
+                       interrupts = <93 2 0 0>;
+               };
+
+       };
+
+       localbus@ffe124000 {
+               compatible = "fsl,p2041-elbc", "fsl,elbc", "simple-bus";
+               interrupts = <25 2 0 0>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+       };
+
+       pci0: pcie@ffe200000 {
+               compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+               device_type = "pci";
+               #size-cells = <2>;
+               #address-cells = <3>;
+               bus-range = <0x0 0xff>;
+               clock-frequency = <33333333>;
+               fsl,msi = <&msi0>;
+               interrupts = <16 2 1 15>;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       interrupts = <16 2 1 15>;
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map = <
+                               /* IDSEL 0x0 */
+                               0000 0 0 1 &mpic 40 1 0 0
+                               0000 0 0 2 &mpic 1 1 0 0
+                               0000 0 0 3 &mpic 2 1 0 0
+                               0000 0 0 4 &mpic 3 1 0 0
+                               >;
+               };
+       };
+
+       pci1: pcie@ffe201000 {
+               compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+               device_type = "pci";
+               #size-cells = <2>;
+               #address-cells = <3>;
+               bus-range = <0 0xff>;
+               clock-frequency = <33333333>;
+               fsl,msi = <&msi1>;
+               interrupts = <16 2 1 14>;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       interrupts = <16 2 1 14>;
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map = <
+                               /* IDSEL 0x0 */
+                               0000 0 0 1 &mpic 41 1 0 0
+                               0000 0 0 2 &mpic 5 1 0 0
+                               0000 0 0 3 &mpic 6 1 0 0
+                               0000 0 0 4 &mpic 7 1 0 0
+                               >;
+               };
+       };
+
+       pci2: pcie@ffe202000 {
+               compatible = "fsl,p2041-pcie", "fsl,qoriq-pcie-v2.2";
+               device_type = "pci";
+               #size-cells = <2>;
+               #address-cells = <3>;
+               bus-range = <0x0 0xff>;
+               clock-frequency = <33333333>;
+               fsl,msi = <&msi2>;
+               interrupts = <16 2 1 13>;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       interrupts = <16 2 1 13>;
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map = <
+                               /* IDSEL 0x0 */
+                               0000 0 0 1 &mpic 42 1 0 0
+                               0000 0 0 2 &mpic 9 1 0 0
+                               0000 0 0 3 &mpic 10 1 0 0
+                               0000 0 0 4 &mpic 11 1 0 0
+                               >;
+               };
+       };
+};
index 69cae674f39663bf2361aed0f7c2eed1386d83b9..bbd113b49a8f215625fd6f993b09fab0bf5009b6 100644 (file)
                device_type = "memory";
        };
 
+       dcsr: dcsr@f00000000 {
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
        soc: soc@ffe000000 {
                spi@110000 {
                        flash@0 {
                };
 
                board-control@3,0 {
-                       compatible = "fsl,p3041ds-pixis";
-                       reg = <3 0 0x20>;
+                       compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis";
+                       reg = <3 0 0x30>;
                };
        };
 
index 8b695801f505bc8a47ab0d29514bf21a2f01ff6d..87130b732bc78d6a1480f37f983ac8869bfae929 100644 (file)
@@ -42,6 +42,7 @@
 
        aliases {
                ccsr = &soc;
+               dcsr = &dcsr;
 
                serial0 = &serial0;
                serial1 = &serial1;
                };
        };
 
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+
+               dcsr-epu@0 {
+                       compatible = "fsl,dcsr-epu";
+                       interrupts = <52 2 0 0
+                                     84 2 0 0
+                                     85 2 0 0>;
+                       interrupt-parent = <&mpic>;
+                       reg = <0x0 0x1000>;
+               };
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p43041-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p43041-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr>;
+                       reg = <0x12000 0x1000>;
+               };
+               dcsr-nal@18000 {
+                       compatible = "fsl,p43041-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p43041-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@42000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu2>;
+                       reg = <0x42000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@43000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu3>;
+                       reg = <0x43000 0x1000>;
+               };
+       };
+
        soc: soc@ffe000000 {
                #address-cells = <1>;
                #size-cells = <1>;
                        fsl,num-laws = <32>;
                };
 
-               memory-controller@8000 {
+               ddr: memory-controller@8000 {
                        compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
                        reg = <0x8000 0x1000>;
                        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 (file)
index 0000000..08b9193
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * P3060QDS Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "p3060si.dtsi"
+
+/ {
+       model = "fsl,P3060QDS";
+       compatible = "fsl,P3060QDS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       memory {
+               device_type = "memory";
+       };
+
+       dcsr: dcsr@f00000000 {
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
+       soc: soc@ffe000000 {
+               spi@110000 {
+                       flash@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "spansion,s25sl12801";
+                               reg = <0>;
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@u-boot {
+                                       label = "u-boot";
+                                       reg = <0x00000000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@kernel {
+                                       label = "kernel";
+                                       reg = <0x00100000 0x00500000>;
+                                       read-only;
+                               };
+                               partition@dtb {
+                                       label = "dtb";
+                                       reg = <0x00600000 0x00100000>;
+                                       read-only;
+                               };
+                               partition@fs {
+                                       label = "file system";
+                                       reg = <0x00700000 0x00900000>;
+                               };
+                       };
+                       flash@1 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "spansion,en25q32b";
+                               reg = <1>;
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@spi1 {
+                                       label = "spi1";
+                                       reg = <0x00000000 0x00400000>;
+                               };
+                       };
+                       flash@2 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "atmel,at45db081d";
+                               reg = <2>;
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@spi1 {
+                                       label = "spi2";
+                                       reg = <0x00000000 0x00100000>;
+                               };
+                       };
+                       flash@3 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "spansion,sst25wf040";
+                               reg = <3>;
+                               spi-max-frequency = <40000000>; /* input clock */
+                               partition@spi3 {
+                                       label = "spi3";
+                                       reg = <0x00000000 0x00080000>;
+                               };
+                       };
+               };
+
+               i2c@118000 {
+                       eeprom@51 {
+                               compatible = "at24,24c256";
+                               reg = <0x51>;
+                       };
+                       eeprom@53 {
+                               compatible = "at24,24c256";
+                               reg = <0x53>;
+                       };
+                       rtc@68 {
+                               compatible = "dallas,ds3232";
+                               reg = <0x68>;
+                               interrupts = <0x1 0x1 0 0>;
+                       };
+               };
+
+               usb0: usb@210000 {
+                       phy_type = "ulpi";
+               };
+
+               usb1: usb@211000 {
+                       dr_mode = "host";
+                       phy_type = "ulpi";
+               };
+       };
+
+       rapidio@ffe0c0000 {
+               reg = <0xf 0xfe0c0000 0 0x11000>;
+
+               port1 {
+                       ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+               };
+               port2 {
+                       ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+               };
+       };
+
+       localbus@ffe124000 {
+               reg = <0xf 0xfe124000 0 0x1000>;
+               ranges = <0 0 0xf 0xe8000000 0x08000000
+                         2 0 0xf 0xffa00000 0x00040000
+                         3 0 0xf 0xffdf0000 0x00008000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x08000000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+               };
+
+               nand@2,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x2 0x0 0x40000>;
+
+                       partition@0 {
+                               label = "NAND U-Boot Image";
+                               reg = <0x0 0x02000000>;
+                               read-only;
+                       };
+
+                       partition@2000000 {
+                               label = "NAND Root File System";
+                               reg = <0x02000000 0x10000000>;
+                       };
+
+                       partition@12000000 {
+                               label = "NAND Compressed RFS Image";
+                               reg = <0x12000000 0x08000000>;
+                       };
+
+                       partition@1a000000 {
+                               label = "NAND Linux Kernel Image";
+                               reg = <0x1a000000 0x04000000>;
+                       };
+
+                       partition@1e000000 {
+                               label = "NAND DTB Image";
+                               reg = <0x1e000000 0x01000000>;
+                       };
+
+                       partition@1f000000 {
+                               label = "NAND Writable User area";
+                               reg = <0x1f000000 0x21000000>;
+                       };
+               };
+
+               board-control@3,0 {
+                       compatible = "fsl,p3060qds-fpga", "fsl,fpga-qixis";
+                       reg = <3 0 0x100>;
+               };
+       };
+
+       pci0: pcie@ffe200000 {
+               reg = <0xf 0xfe200000 0 0x1000>;
+               ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+                         0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+               pcie@0 {
+                       ranges = <0x02000000 0 0xe0000000
+                                 0x02000000 0 0xe0000000
+                                 0 0x20000000
+
+                                 0x01000000 0 0x00000000
+                                 0x01000000 0 0x00000000
+                                 0 0x00010000>;
+               };
+       };
+
+       pci1: pcie@ffe201000 {
+               reg = <0xf 0xfe201000 0 0x1000>;
+               ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+               pcie@0 {
+                       ranges = <0x02000000 0 0xe0000000
+                                 0x02000000 0 0xe0000000
+                                 0 0x20000000
+
+                                 0x01000000 0 0x00000000
+                                 0x01000000 0 0x00000000
+                                 0 0x00010000>;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/p3060si.dtsi b/arch/powerpc/boot/dts/p3060si.dtsi
new file mode 100644 (file)
index 0000000..68947e1
--- /dev/null
@@ -0,0 +1,719 @@
+/*
+ * P3060 Silicon Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/ {
+       compatible = "fsl,P3060";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       aliases {
+               ccsr = &soc;
+               dcsr = &dcsr;
+
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
+               pci0 = &pci0;
+               pci1 = &pci1;
+               usb0 = &usb0;
+               usb1 = &usb1;
+               dma0 = &dma0;
+               dma1 = &dma1;
+               msi0 = &msi0;
+               msi1 = &msi1;
+               msi2 = &msi2;
+
+               crypto = &crypto;
+               sec_jr0 = &sec_jr0;
+               sec_jr1 = &sec_jr1;
+               sec_jr2 = &sec_jr2;
+               sec_jr3 = &sec_jr3;
+               rtic_a = &rtic_a;
+               rtic_b = &rtic_b;
+               rtic_c = &rtic_c;
+               rtic_d = &rtic_d;
+               sec_mon = &sec_mon;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: PowerPC,e500mc@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2_0>;
+                       L2_0: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu1: PowerPC,e500mc@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       next-level-cache = <&L2_1>;
+                       L2_1: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu4: PowerPC,e500mc@4 {
+                       device_type = "cpu";
+                       reg = <4>;
+                       next-level-cache = <&L2_4>;
+                       L2_4: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu5: PowerPC,e500mc@5 {
+                       device_type = "cpu";
+                       reg = <5>;
+                       next-level-cache = <&L2_5>;
+                       L2_5: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu6: PowerPC,e500mc@6 {
+                       device_type = "cpu";
+                       reg = <6>;
+                       next-level-cache = <&L2_6>;
+                       L2_6: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+               cpu7: PowerPC,e500mc@7 {
+                       device_type = "cpu";
+                       reg = <7>;
+                       next-level-cache = <&L2_7>;
+                       L2_7: l2-cache {
+                               next-level-cache = <&cpc>;
+                       };
+               };
+       };
+
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+
+               dcsr-epu@0 {
+                       compatible = "fsl,dcsr-epu";
+                       interrupts = <52 2 0 0
+                                     84 2 0 0
+                                     85 2 0 0>;
+                       interrupt-parent = <&mpic>;
+                       reg = <0x0 0x1000>;
+               };
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p3060-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p3060-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr>;
+                       reg = <0x12000 0x1000>;
+               };
+               dcsr-nal@18000 {
+                       compatible = "fsl,p3060-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p3060-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@44000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu4>;
+                       reg = <0x44000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@45000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu5>;
+                       reg = <0x45000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@46000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu6>;
+                       reg = <0x46000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@47000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu7>;
+                       reg = <0x47000 0x1000>;
+               };
+       };
+
+       soc: soc@ffe000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "simple-bus";
+               ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+               reg = <0xf 0xfe000000 0 0x00001000>;
+
+               soc-sram-error {
+                       compatible = "fsl,soc-sram-error";
+                       interrupts = <16 2 1 29>;
+               };
+
+               corenet-law@0 {
+                       compatible = "fsl,corenet-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <32>;
+               };
+
+               ddr: memory-controller@8000 {
+                       compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller";
+                       reg = <0x8000 0x1000>;
+                       interrupts = <16 2 1 23>;
+               };
+
+               cpc: l3-cache-controller@10000 {
+                       compatible = "fsl,p3060-l3-cache-controller", "cache";
+                       reg = <0x10000 0x1000
+                              0x11000 0x1000>;
+                       interrupts = <16 2 1 27>;
+               };
+
+               corenet-cf@18000 {
+                       compatible = "fsl,corenet-cf";
+                       reg = <0x18000 0x1000>;
+                       interrupts = <16 2 1 31>;
+                       fsl,ccf-num-csdids = <32>;
+                       fsl,ccf-num-snoopids = <32>;
+               };
+
+               iommu@20000 {
+                       compatible = "fsl,pamu-v1.0", "fsl,pamu";
+                       reg = <0x20000 0x5000>;
+                       interrupts = <
+                               24 2 0 0
+                               16 2 1 30>;
+               };
+
+               mpic: pic@40000 {
+                       clock-frequency = <0>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <4>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "fsl,mpic", "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi0: msi@41600 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41600 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0 0 0
+                               0xe1 0 0 0
+                               0xe2 0 0 0
+                               0xe3 0 0 0
+                               0xe4 0 0 0
+                               0xe5 0 0 0
+                               0xe6 0 0 0
+                               0xe7 0 0 0>;
+               };
+
+               msi1: msi@41800 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41800 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe8 0 0 0
+                               0xe9 0 0 0
+                               0xea 0 0 0
+                               0xeb 0 0 0
+                               0xec 0 0 0
+                               0xed 0 0 0
+                               0xee 0 0 0
+                               0xef 0 0 0>;
+               };
+
+               msi2: msi@41a00 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41a00 0x200>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xf0 0 0 0
+                               0xf1 0 0 0
+                               0xf2 0 0 0
+                               0xf3 0 0 0
+                               0xf4 0 0 0
+                               0xf5 0 0 0
+                               0xf6 0 0 0
+                               0xf7 0 0 0>;
+               };
+
+               rmu: rmu@d3000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,srio-rmu";
+                       reg = <0xd3000 0x500>;
+                       ranges = <0x0 0xd3000 0x500>;
+
+                       message-unit@0 {
+                               compatible = "fsl,srio-msg-unit";
+                               reg = <0x0 0x100>;
+                               interrupts = <
+                                       60 2 0 0  /* msg1_tx_irq */
+                                       61 2 0 0>;/* msg1_rx_irq */
+                       };
+                       message-unit@100 {
+                               compatible = "fsl,srio-msg-unit";
+                               reg = <0x100 0x100>;
+                               interrupts = <
+                                       62 2 0 0  /* msg2_tx_irq */
+                                       63 2 0 0>;/* msg2_rx_irq */
+                       };
+                       doorbell-unit@400 {
+                               compatible = "fsl,srio-dbell-unit";
+                               reg = <0x400 0x80>;
+                               interrupts = <
+                                       56 2 0 0  /* bell_outb_irq */
+                                       57 2 0 0>;/* bell_inb_irq */
+                       };
+                       port-write-unit@4e0 {
+                               compatible = "fsl,srio-port-write-unit";
+                               reg = <0x4e0 0x20>;
+                               interrupts = <16 2 1 11>;
+                       };
+               };
+
+               guts: global-utilities@e0000 {
+                       compatible = "fsl,qoriq-device-config-1.0";
+                       reg = <0xe0000 0xe00>;
+                       fsl,has-rstcr;
+                       #sleep-cells = <1>;
+                       fsl,liodn-bits = <12>;
+               };
+
+               pins: global-utilities@e0e00 {
+                       compatible = "fsl,qoriq-pin-control-1.0";
+                       reg = <0xe0e00 0x200>;
+                       #sleep-cells = <2>;
+               };
+
+               clockgen: global-utilities@e1000 {
+                       compatible = "fsl,p3060-clockgen", "fsl,qoriq-clockgen-1.0";
+                       reg = <0xe1000 0x1000>;
+                       clock-frequency = <0>;
+               };
+
+               rcpm: global-utilities@e2000 {
+                       compatible = "fsl,qoriq-rcpm-1.0";
+                       reg = <0xe2000 0x1000>;
+                       #sleep-cells = <1>;
+               };
+
+               sfp: sfp@e8000 {
+                       compatible = "fsl,p3060-sfp", "fsl,qoriq-sfp-1.0";
+                       reg        = <0xe8000 0x1000>;
+               };
+
+               serdes: serdes@ea000 {
+                       compatible = "fsl,p3060-serdes";
+                       reg        = <0xea000 0x1000>;
+               };
+
+               dma0: dma@100300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p3060-dma", "fsl,eloplus-dma";
+                       reg = <0x100300 0x4>;
+                       ranges = <0x0 0x100100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupts = <28 2 0 0>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupts = <29 2 0 0>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupts = <30 2 0 0>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupts = <31 2 0 0>;
+                       };
+               };
+
+               dma1: dma@101300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,p3060-dma", "fsl,eloplus-dma";
+                       reg = <0x101300 0x4>;
+                       ranges = <0x0 0x101100 0x200>;
+                       cell-index = <1>;
+                       dma-channel@0 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupts = <32 2 0 0>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupts = <33 2 0 0>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupts = <34 2 0 0>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,p3060-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupts = <35 2 0 0>;
+                       };
+               };
+
+               spi@110000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,p3060-espi", "fsl,mpc8536-espi";
+                       reg = <0x110000 0x1000>;
+                       interrupts = <53 0x2 0 0>;
+                       fsl,espi-num-chipselects = <4>;
+               };
+
+               i2c@118000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x118000 0x100>;
+                       interrupts = <38 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@118100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x118100 0x100>;
+                       interrupts = <38 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@119000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <2>;
+                       compatible = "fsl-i2c";
+                       reg = <0x119000 0x100>;
+                       interrupts = <39 2 0 0>;
+                       dfsrr;
+               };
+
+               i2c@119100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <3>;
+                       compatible = "fsl-i2c";
+                       reg = <0x119100 0x100>;
+                       interrupts = <39 2 0 0>;
+                       dfsrr;
+               };
+
+               serial0: serial@11c500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11c500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <36 2 0 0>;
+               };
+
+               serial1: serial@11c600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11c600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <36 2 0 0>;
+               };
+
+               serial2: serial@11d500 {
+                       cell-index = <2>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11d500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <37 2 0 0>;
+               };
+
+               serial3: serial@11d600 {
+                       cell-index = <3>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x11d600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <37 2 0 0>;
+               };
+
+               gpio0: gpio@130000 {
+                       compatible = "fsl,p3060-gpio", "fsl,qoriq-gpio";
+                       reg = <0x130000 0x1000>;
+                       interrupts = <55 2 0 0>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+               };
+
+               usb0: usb@210000 {
+                       compatible = "fsl,p3060-usb2-mph",
+                                       "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph";
+                       reg = <0x210000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <44 0x2 0 0>;
+               };
+
+               usb1: usb@211000 {
+                       compatible = "fsl,p3060-usb2-dr",
+                                       "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr";
+                       reg = <0x211000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <45 0x2 0 0>;
+               };
+
+               crypto: crypto@300000 {
+                       compatible = "fsl,sec-v4.1", "fsl,sec-v4.0";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x300000 0x10000>;
+                       ranges = <0 0x300000 0x10000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <92 2 0 0>;
+
+                       sec_jr0: jr@1000 {
+                               compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
+                               reg = <0x1000 0x1000>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <88 2 0 0>;
+                       };
+
+                       sec_jr1: jr@2000 {
+                               compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
+                               reg = <0x2000 0x1000>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <89 2 0 0>;
+                       };
+
+                       sec_jr2: jr@3000 {
+                               compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
+                               reg = <0x3000 0x1000>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <90 2 0 0>;
+                       };
+
+                       sec_jr3: jr@4000 {
+                               compatible = "fsl,sec-v4.1-job-ring", "fsl,sec-v4.0-job-ring";
+                               reg = <0x4000 0x1000>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <91 2 0 0>;
+                       };
+
+                       rtic@6000 {
+                               compatible = "fsl,sec-v4.1-rtic", "fsl,sec-v4.0-rtic";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x6000 0x100>;
+                               ranges = <0x0 0x6100 0xe00>;
+
+                               rtic_a: rtic-a@0 {
+                                       compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x00 0x20 0x100 0x80>;
+                               };
+
+                               rtic_b: rtic-b@20 {
+                                       compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x20 0x20 0x200 0x80>;
+                               };
+
+                               rtic_c: rtic-c@40 {
+                                       compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x40 0x20 0x300 0x80>;
+                               };
+
+                               rtic_d: rtic-d@60 {
+                                       compatible = "fsl,sec-v4.1-rtic-memory", "fsl,sec-v4.0-rtic-memory";
+                                       reg = <0x60 0x20 0x500 0x80>;
+                               };
+                       };
+               };
+
+               sec_mon: sec_mon@314000 {
+                       compatible = "fsl,sec-v4.1-mon", "fsl,sec-v4.0-mon";
+                       reg = <0x314000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <93 2 0 0>;
+               };
+       };
+
+       rapidio@ffe0c0000 {
+               compatible = "fsl,srio";
+               interrupts = <16 2 1 11>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               fsl,srio-rmu-handle = <&rmu>;
+               ranges;
+
+               port1 {
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       cell-index = <1>;
+               };
+
+               port2 {
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       cell-index = <2>;
+               };
+       };
+
+       localbus@ffe124000 {
+               compatible = "fsl,p3060-elbc", "fsl,elbc", "simple-bus";
+               interrupts = <25 2 0 0>;
+               #address-cells = <2>;
+               #size-cells = <1>;
+       };
+
+       pci0: pcie@ffe200000 {
+               compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2";
+               device_type = "pci";
+               #size-cells = <2>;
+               #address-cells = <3>;
+               bus-range = <0x0 0xff>;
+               clock-frequency = <33333333>;
+               fsl,msi = <&msi0>;
+               interrupts = <16 2 1 15>;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       interrupts = <16 2 1 15>;
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map = <
+                               /* IDSEL 0x0 */
+                               0000 0 0 1 &mpic 40 1 0 0
+                               0000 0 0 2 &mpic 1 1 0 0
+                               0000 0 0 3 &mpic 2 1 0 0
+                               0000 0 0 4 &mpic 3 1 0 0
+                               >;
+               };
+       };
+
+       pci1: pcie@ffe201000 {
+               compatible = "fsl,p3060-pcie", "fsl,qoriq-pcie-v2.2";
+               device_type = "pci";
+               #size-cells = <2>;
+               #address-cells = <3>;
+               bus-range = <0 0xff>;
+               clock-frequency = <33333333>;
+               fsl,msi = <&msi1>;
+               interrupts = <16 2 1 14>;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       interrupts = <16 2 1 14>;
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map = <
+                               /* IDSEL 0x0 */
+                               0000 0 0 1 &mpic 41 1 0 0
+                               0000 0 0 2 &mpic 5 1 0 0
+                               0000 0 0 3 &mpic 6 1 0 0
+                               0000 0 0 4 &mpic 7 1 0 0
+                               >;
+               };
+       };
+};
index eb11098bb687c421d33fdc238bec31a59b018c13..c7916dc2801449c6c2a862d271114f7dcb94115e 100644 (file)
                device_type = "memory";
        };
 
+       dcsr: dcsr@f00000000 {
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
        soc: soc@ffe000000 {
                spi@110000 {
                        flash@0 {
 
        localbus@ffe124000 {
                reg = <0xf 0xfe124000 0 0x1000>;
-               ranges = <0 0 0xf 0xe8000000 0x08000000>;
+               ranges = <0 0 0xf 0xe8000000 0x08000000
+                         3 0 0xf 0xffdf0000 0x00008000>;
 
                flash@0,0 {
                        compatible = "cfi-flash";
                        bank-width = <2>;
                        device-width = <2>;
                };
+
+               board-control@3,0 {
+                       compatible = "fsl,p4080ds-fpga", "fsl,fpga-ngpixis";
+                       reg = <3 0 0x30>;
+               };
        };
 
        pci0: pcie@ffe200000 {
index b71051f506c1763fbb911a0df62b58577eda2ce0..f20c01ab2473a279209c38e7a221bee48fe09b54 100644 (file)
@@ -42,6 +42,7 @@
 
        aliases {
                ccsr = &soc;
+               dcsr = &dcsr;
 
                serial0 = &serial0;
                serial1 = &serial1;
@@ -77,7 +78,7 @@
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu0: PowerPC,4080@0 {
+               cpu0: PowerPC,e500mc@0 {
                        device_type = "cpu";
                        reg = <0>;
                        next-level-cache = <&L2_0>;
@@ -85,7 +86,7 @@
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu1: PowerPC,4080@1 {
+               cpu1: PowerPC,e500mc@1 {
                        device_type = "cpu";
                        reg = <1>;
                        next-level-cache = <&L2_1>;
@@ -93,7 +94,7 @@
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu2: PowerPC,4080@2 {
+               cpu2: PowerPC,e500mc@2 {
                        device_type = "cpu";
                        reg = <2>;
                        next-level-cache = <&L2_2>;
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu3: PowerPC,4080@3 {
+               cpu3: PowerPC,e500mc@3 {
                        device_type = "cpu";
                        reg = <3>;
                        next-level-cache = <&L2_3>;
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu4: PowerPC,4080@4 {
+               cpu4: PowerPC,e500mc@4 {
                        device_type = "cpu";
                        reg = <4>;
                        next-level-cache = <&L2_4>;
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu5: PowerPC,4080@5 {
+               cpu5: PowerPC,e500mc@5 {
                        device_type = "cpu";
                        reg = <5>;
                        next-level-cache = <&L2_5>;
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu6: PowerPC,4080@6 {
+               cpu6: PowerPC,e500mc@6 {
                        device_type = "cpu";
                        reg = <6>;
                        next-level-cache = <&L2_6>;
                                next-level-cache = <&cpc>;
                        };
                };
-               cpu7: PowerPC,4080@7 {
+               cpu7: PowerPC,e500mc@7 {
                        device_type = "cpu";
                        reg = <7>;
                        next-level-cache = <&L2_7>;
                };
        };
 
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+
+               dcsr-epu@0 {
+                       compatible = "fsl,dcsr-epu";
+                       interrupts = <52 2 0 0
+                                     84 2 0 0
+                                     85 2 0 0>;
+                       interrupt-parent = <&mpic>;
+                       reg = <0x0 0x1000>;
+               };
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p4080-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p4080-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr1>;
+                       reg = <0x12000 0x1000>;
+               };
+               dcsr-ddr@13000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr2>;
+                       reg = <0x13000 0x1000>;
+               };
+               dcsr-nal@18000 {
+                       compatible = "fsl,p4080-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p4080-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@42000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu2>;
+                       reg = <0x42000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@43000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu3>;
+                       reg = <0x43000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@44000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu4>;
+                       reg = <0x44000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@45000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu5>;
+                       reg = <0x45000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@46000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu6>;
+                       reg = <0x46000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@47000 {
+                       compatible = "fsl,dcsr-e500mc-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu7>;
+                       reg = <0x47000 0x1000>;
+               };
+       };
+
        soc: soc@ffe000000 {
                #address-cells = <1>;
                #size-cells = <1>;
                        fsl,num-laws = <32>;
                };
 
-               memory-controller@8000 {
+               ddr1: memory-controller@8000 {
                        compatible = "fsl,qoriq-memory-controller-v4.4", "fsl,qoriq-memory-controller";
                        reg = <0x8000 0x1000>;
                        interrupts = <16 2 1 23>;
                };
 
-               memory-controller@9000 {
+               ddr2: memory-controller@9000 {
                        compatible = "fsl,qoriq-memory-controller-v4.4","fsl,qoriq-memory-controller";
                        reg = <0x9000 0x1000>;
                        interrupts = <16 2 1 22>;
index 8366e2fd2fbafc6c946bbb94d8c91122f1210469..e6d40999ccd713efc2952040b220f54892cd3cf3 100644 (file)
                device_type = "memory";
        };
 
+       dcsr: dcsr@f00000000 {
+               ranges = <0x00000000 0xf 0x00000000 0x01008000>;
+       };
+
        soc: soc@ffe000000 {
                spi@110000 {
                        flash@0 {
                };
 
                board-control@3,0 {
-                       compatible = "fsl,p5020ds-pixis";
-                       reg = <3 0 0x20>;
+                       compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis";
+                       reg = <3 0 0x30>;
                };
        };
 
index 5e6048ec55bb3ce31011669b0e4ddb43f89bb58a..e7948ad71fa39385d3001c16f3bfe0ac3e85ee1e 100644 (file)
@@ -42,6 +42,7 @@
 
        aliases {
                ccsr = &soc;
+               dcsr = &dcsr;
 
                serial0 = &serial0;
                serial1 = &serial1;
                };
        };
 
+       dcsr: dcsr@f00000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "fsl,dcsr", "simple-bus";
+
+               dcsr-epu@0 {
+                       compatible = "fsl,dcsr-epu";
+                       interrupts = <52 2 0 0
+                                     84 2 0 0
+                                     85 2 0 0>;
+                       interrupt-parent = <&mpic>;
+                       reg = <0x0 0x1000>;
+               };
+               dcsr-npc {
+                       compatible = "fsl,dcsr-npc";
+                       reg = <0x1000 0x1000 0x1000000 0x8000>;
+               };
+               dcsr-nxc@2000 {
+                       compatible = "fsl,dcsr-nxc";
+                       reg = <0x2000 0x1000>;
+               };
+               dcsr-corenet {
+                       compatible = "fsl,dcsr-corenet";
+                       reg = <0x8000 0x1000 0xB0000 0x1000>;
+               };
+               dcsr-dpaa@9000 {
+                       compatible = "fsl,p5020-dcsr-dpaa", "fsl,dcsr-dpaa";
+                       reg = <0x9000 0x1000>;
+               };
+               dcsr-ocn@11000 {
+                       compatible = "fsl,p5020-dcsr-ocn", "fsl,dcsr-ocn";
+                       reg = <0x11000 0x1000>;
+               };
+               dcsr-ddr@12000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr1>;
+                       reg = <0x12000 0x1000>;
+               };
+               dcsr-ddr@13000 {
+                       compatible = "fsl,dcsr-ddr";
+                       dev-handle = <&ddr2>;
+                       reg = <0x13000 0x1000>;
+               };
+               dcsr-nal@18000 {
+                       compatible = "fsl,p5020-dcsr-nal", "fsl,dcsr-nal";
+                       reg = <0x18000 0x1000>;
+               };
+               dcsr-rcpm@22000 {
+                       compatible = "fsl,p5020-dcsr-rcpm", "fsl,dcsr-rcpm";
+                       reg = <0x22000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@40000 {
+                       compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu0>;
+                       reg = <0x40000 0x1000>;
+               };
+               dcsr-cpu-sb-proxy@41000 {
+                       compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+                       cpu-handle = <&cpu1>;
+                       reg = <0x41000 0x1000>;
+               };
+       };
+
        soc: soc@ffe000000 {
                #address-cells = <1>;
                #size-cells = <1>;
                        fsl,num-laws = <32>;
                };
 
-               memory-controller@8000 {
+               ddr1: memory-controller@8000 {
                        compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
                        reg = <0x8000 0x1000>;
                        interrupts = <16 2 1 23>;
                };
 
-               memory-controller@9000 {
+               ddr2: memory-controller@9000 {
                        compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
                        reg = <0x9000 0x1000>;
                        interrupts = <16 2 1 22>;
index 9e13ed8a1193ff25fa0a60df7c9f61beead574ae..72078eb1561637a1f59152c23ee563d2da0635fb 100644 (file)
        };
 
        localbus@ff705000 {
-               compatible = "fsl,mpc8560-localbus";
+               compatible = "fsl,mpc8560-localbus", "simple-bus";
                #address-cells = <2>;
                #size-cells = <1>;
                reg = <0xff705000 0x100>;       // BRx, ORx, etc.
index 64923245f0e5adb8d481a62a49f95f709b8ed048..30bb4753577a92652d3524ac7632894e207a5c5a 100644 (file)
                                clock-frequency = <0>; /* Filled in by zImage */
                                interrupts = <0x5 0x1>;
                                interrupt-parent = <&UIC1>;
+
+                               nor_flash@0,0 {
+                                       compatible = "amd,s29gl256n", "cfi-flash";
+                                       bank-width = <2>;
+                                       reg = <0x00000000 0x00000000 0x04000000>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       partition@0 {
+                                               label = "kernel";
+                                               reg = <0x00000000 0x001e0000>;
+                                       };
+                                       partition@1e0000 {
+                                               label = "dtb";
+                                               reg = <0x001e0000 0x00020000>;
+                                       };
+                                       partition@200000 {
+                                               label = "ramdisk";
+                                               reg = <0x00200000 0x01400000>;
+                                       };
+                                       partition@1600000 {
+                                               label = "jffs2";
+                                               reg = <0x01600000 0x00400000>;
+                                       };
+                                       partition@1a00000 {
+                                               label = "user";
+                                               reg = <0x01a00000 0x02540000>;
+                                       };
+                                       partition@3f40000 {
+                                               label = "env";
+                                               reg = <0x03f40000 0x00040000>;
+                                       };
+                                       partition@3f80000 {
+                                               label = "u-boot";
+                                               reg = <0x03f80000 0x00080000>;
+                                       };
+                               };
                        };
 
                        UART0: serial@ef600300 {
diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig
deleted file mode 100644 (file)
index dba263c..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-CONFIG_40x=y
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_HCU4=y
-# CONFIG_WALNUT is not set
-CONFIG_SPARSE_IRQ=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_PROC_DEVICETREE=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=35000
-CONFIG_NETDEVICES=y
-CONFIG_ETHERNET=y
-CONFIG_NET_VENDOR_IBM=y
-CONFIG_IBM_EMAC=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
index 959cd2cfc2756488fcbe4080a29b396653d5e8d5..716a37be16e33b5d071416592ca8eb39fc7cca2f 100644 (file)
@@ -1,9 +1,10 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
+CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_EPOLL is not set
@@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_BESTCOMM=y
-CONFIG_SPARSE_IRQ=y
 CONFIG_PM=y
 # CONFIG_PCI is not set
 CONFIG_NET=y
@@ -38,17 +38,18 @@ CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_MISC_DEVICES is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
@@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=y
 CONFIG_PATA_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_LXT_PHY=y
+CONFIG_FIXED_PHY=y
 CONFIG_NET_ETHERNET=y
 CONFIG_FEC_MPC52xx=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
 CONFIG_SERIAL_MPC52xx=y
 CONFIG_SERIAL_MPC52xx_CONSOLE=y
 CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
@@ -70,7 +69,13 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MPC=y
+CONFIG_SENSORS_LM80=y
 CONFIG_WATCHDOG=y
+CONFIG_MFD_SM501=y
+CONFIG_FB=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_SM501=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
@@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_STORAGE=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_PROC_KCORE=y
@@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
index 3ff5a81c709f2f9febae80a5e1edd3a3a1ee9ca1..c091aaf7685f60efce4d72d989e2503ab3a11310 100644 (file)
@@ -24,7 +24,7 @@ CONFIG_P1023_RDS=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_CPM2=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
 CONFIG_HIGHMEM=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
index 5ea3124518fddd030460299c5a4e9319aead3652..1cd6fcb368e95f5d26a6eae5db157796c94f21de 100644 (file)
@@ -20,7 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_XES_MPC85xx=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
 CONFIG_HIGHMEM=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SPARSE_IRQ=y
index 4311d02a3bfdaf1c250cf2c437809d768a611861..f087de6ec03f5fc7025e4b9948e714063f061a94 100644 (file)
@@ -12,9 +12,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
@@ -23,8 +21,9 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
-CONFIG_P2040_RDB=y
+CONFIG_P2041_RDB=y
 CONFIG_P3041_DS=y
+CONFIG_P3060_QDS=y
 CONFIG_P4080_DS=y
 CONFIG_P5020_DS=y
 CONFIG_HIGHMEM=y
@@ -69,7 +68,6 @@ CONFIG_IPV6=y
 CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -107,7 +105,6 @@ CONFIG_FSL_PQ_MDIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_LEGACY_PTYS is not set
-CONFIG_PPC_EPAPR_HV_BYTECHAN=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -136,8 +133,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_MPC85XX=y
@@ -146,7 +141,6 @@ CONFIG_RTC_DRV_DS3232=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_UIO=y
 CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
 CONFIG_VIRT_DRIVERS=y
 CONFIG_FSL_HV_MANAGER=y
 CONFIG_EXT2_FS=y
@@ -173,7 +167,6 @@ CONFIG_MAC_PARTITION=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=m
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
index c92c204a204b22f6403552a961286135c61b603c..782822c32d155245c3d6678087094352524ee94f 100644 (file)
@@ -11,10 +11,8 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -25,7 +23,6 @@ CONFIG_P5020_DS=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BINFMT_MISC=m
-# CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -93,10 +90,8 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_VIRQ_DEBUG=y
 CONFIG_CRYPTO_PCBC=m
index 6cb588a7d425cb8e1a66a67545ac413514bcff6e..0d36b0e1e2681134f86d50934c1413f46b27f71b 100644 (file)
@@ -1,15 +1,22 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
 CONFIG_SPARSE_IRQ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
+# CONFIG_RD_GZIP is not set
 CONFIG_KALLSYMS_ALL=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 # CONFIG_IOSCHED_CFQ is not set
+# CONFIG_PPC_PMAC is not set
 CONFIG_PPC_82xx=y
 CONFIG_MGCOGE=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BINFMT_MISC=y
 # CONFIG_SECCOMP is not set
 CONFIG_NET=y
@@ -24,11 +31,10 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_LRO is not set
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
+CONFIG_TIPC=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
@@ -42,7 +48,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
-# CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
 CONFIG_FIXED_PHY=y
 CONFIG_NET_ETHERNET=y
@@ -50,6 +55,7 @@ CONFIG_FS_ENET=y
 CONFIG_FS_ENET_MDIO_FCC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
@@ -57,24 +63,24 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_POWERMAC is not set
 CONFIG_I2C_CPM=y
 # CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_FSL_USB2=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=y
 CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_EXT3_FS_XATTR is not set
 CONFIG_AUTOFS4_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_MAC_PARTITION is not set
 CONFIG_NLS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
@@ -82,7 +88,6 @@ CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_DEBUG_INFO=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index c02bbb2fddf8ddef4529846c84c9bf812937f95d..211fcc9ed7002f9f9f8743d209558b7717bc4ac3 100644 (file)
@@ -1,9 +1,9 @@
 CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
@@ -13,10 +13,11 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_PPC_CHRP is not set
 CONFIG_PPC_MPC512x=y
 CONFIG_MPC5121_ADS=y
+CONFIG_MPC5121_GENERIC=y
+CONFIG_PDM360NG=y
 # CONFIG_PPC_PMAC is not set
 CONFIG_NO_HZ=y
 CONFIG_HZ_1000=y
-CONFIG_SPARSE_IRQ=y
 # CONFIG_MIGRATION is not set
 # CONFIG_SECCOMP is not set
 # CONFIG_PCI is not set
@@ -35,18 +36,16 @@ CONFIG_CAN=y
 CONFIG_CAN_RAW=y
 CONFIG_CAN_BCM=y
 CONFIG_CAN_VCAN=y
-CONFIG_CAN_DEV=y
 CONFIG_CAN_MSCAN=y
 CONFIG_CAN_DEBUG_DEVICES=y
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
@@ -63,6 +62,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_XIP=y
 CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
@@ -99,10 +99,14 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MPC=y
+CONFIG_SPI=y
+CONFIG_SPI_MPC512x_PSC=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MPC8XXX=y
 # CONFIG_HWMON is not set
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
-# CONFIG_VIDEO_ALLOW_V4L1 is not set
 CONFIG_VIDEO_ADV_DEBUG=y
 # CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
 CONFIG_VIDEO_SAA711X=y
@@ -132,6 +136,5 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
index e63f537b854a3eb7af79d55763117d0b417ecbf3..2a1320fb27232457bf8afe7ccede0186774575bf 100644 (file)
@@ -88,6 +88,18 @@ CONFIG_FB_RADEON=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_PPC is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MPC5200_I2S=y
+CONFIG_SND_MPC52xx_SOC_PCM030=y
+CONFIG_SND_MPC52xx_SOC_EFIKA=y
 CONFIG_HID_DRAGONRISE=y
 CONFIG_HID_GYRATION=y
 CONFIG_HID_TWINHAN=y
index a3467bfb767100aaf71a4c6e2b666a7448060020..a1e5a178a4ac4f8b4e814900ff22b7858e47baf0 100644 (file)
@@ -10,10 +10,8 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -41,7 +39,6 @@ CONFIG_TQM8560=y
 CONFIG_SBC8548=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
-CONFIG_MPC8xxx_GPIO=y
 CONFIG_HIGHMEM=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -123,6 +120,7 @@ CONFIG_NVRAM=y
 CONFIG_I2C=y
 CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
+CONFIG_GPIO_MPC8XXX=y
 # CONFIG_HWMON is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
@@ -206,7 +204,6 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 9693f6ed3da066ad0fe7839fa399826987274c0f..dd1e41386c4ce676957982a7ee0c2e1686569813 100644 (file)
@@ -12,10 +12,8 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -42,7 +40,6 @@ CONFIG_TQM8560=y
 CONFIG_SBC8548=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
-CONFIG_MPC8xxx_GPIO=y
 CONFIG_HIGHMEM=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -124,6 +121,7 @@ CONFIG_NVRAM=y
 CONFIG_I2C=y
 CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
+CONFIG_GPIO_MPC8XXX=y
 # CONFIG_HWMON is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
@@ -207,10 +205,8 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_VIRQ_DEBUG=y
 CONFIG_CRYPTO_PCBC=m
index 7cb703b948b1053451a353a6f141484370d9caef..1eb19ac45d09ac35172c7a57f1d046c71bc30401 100644 (file)
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_PPC4xx_GPIO=y
 CONFIG_ACADIA=y
 CONFIG_EP405=y
-CONFIG_HCU4=y
 CONFIG_HOTFOOT=y
 CONFIG_KILAUEA=y
 CONFIG_MAKALU=y
index 6cdf1c0d2c8a10acc43796c20af80d52f7b78d64..3b98d735434142bb9240a6a2d4906d0b882a3ab2 100644 (file)
@@ -52,6 +52,8 @@ CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_NDFC=m
 CONFIG_MTD_UBI=m
 CONFIG_MTD_UBI_GLUEBI=m
 CONFIG_PROC_DEVICETREE=y
index 84a685a505fe115a39ebfbe99ce3baa399bf85d3..535711fcb13c54ad3f35adedfe7a0752f7991497 100644 (file)
@@ -485,3 +485,7 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_VHOST_NET=m
index 04360f9b010939686b142791b7a24607d79e91c4..c47f2becfbc303c63a5e76b208ad4263a34b7563 100644 (file)
@@ -70,7 +70,7 @@ CONFIG_TAU_AVERAGE=y
 CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_PPC_BESTCOMM=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
 CONFIG_MCU_MPC8349EMITX=m
 CONFIG_HIGHMEM=y
 CONFIG_NO_HZ=y
index 96a58b709705ccae5e071aa474f19b7f1a506ce0..a72f2415a64709193a20f6aa16b117da4f1ea075 100644 (file)
@@ -362,3 +362,7 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_VHOST_NET=m
index e2a4c26ad37793874dce3902d561dd749c78681d..02e41b53488d8d8574f42c6a4e0ce1f99df9aaa8 100644 (file)
@@ -49,13 +49,13 @@ static __inline__ int atomic_add_return(int a, atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%2         # atomic_add_return\n\
        add     %0,%1,%0\n"
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -85,13 +85,13 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%2         # atomic_sub_return\n\
        subf    %0,%1,%0\n"
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -119,13 +119,13 @@ static __inline__ int atomic_inc_return(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_inc_return\n\
        addic   %0,%0,1\n"
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -163,13 +163,13 @@ static __inline__ int atomic_dec_return(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_dec_return\n\
        addic   %0,%0,-1\n"
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -194,7 +194,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
        int t;
 
        __asm__ __volatile__ (
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # __atomic_add_unless\n\
        cmpw    0,%0,%3 \n\
        beq-    2f \n\
@@ -202,7 +202,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
        PPC405_ERR77(0,%2)
 "      stwcx.  %0,0,%1 \n\
        bne-    1b \n"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
 "      subf    %0,%2,%0 \n\
 2:"
        : "=&r" (t)
@@ -226,7 +226,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
        int t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    lwarx   %0,0,%1         # atomic_dec_if_positive\n\
        cmpwi   %0,1\n\
        addi    %0,%0,-1\n\
@@ -234,7 +234,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v)
        PPC405_ERR77(0,%1)
 "      stwcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        "\n\
 2:"    : "=&b" (t)
        : "r" (&v->counter)
@@ -285,12 +285,12 @@ static __inline__ long atomic64_add_return(long a, atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%2         # atomic64_add_return\n\
        add     %0,%1,%0\n\
        stdcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -319,12 +319,12 @@ static __inline__ long atomic64_sub_return(long a, atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%2         # atomic64_sub_return\n\
        subf    %0,%1,%0\n\
        stdcx.  %0,0,%2 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (a), "r" (&v->counter)
        : "cc", "memory");
@@ -351,12 +351,12 @@ static __inline__ long atomic64_inc_return(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_inc_return\n\
        addic   %0,%0,1\n\
        stdcx.  %0,0,%1 \n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -393,12 +393,12 @@ static __inline__ long atomic64_dec_return(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_dec_return\n\
        addic   %0,%0,-1\n\
        stdcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        : "=&r" (t)
        : "r" (&v->counter)
        : "cc", "xer", "memory");
@@ -418,13 +418,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
        long t;
 
        __asm__ __volatile__(
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # atomic64_dec_if_positive\n\
        addic.  %0,%0,-1\n\
        blt-    2f\n\
        stdcx.  %0,0,%1\n\
        bne-    1b"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
        "\n\
 2:"    : "=&r" (t)
        : "r" (&v->counter)
@@ -450,14 +450,14 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
        long t;
 
        __asm__ __volatile__ (
-       PPC_RELEASE_BARRIER
+       PPC_ATOMIC_ENTRY_BARRIER
 "1:    ldarx   %0,0,%1         # __atomic_add_unless\n\
        cmpd    0,%0,%3 \n\
        beq-    2f \n\
        add     %0,%2,%0 \n"
 "      stdcx.  %0,0,%1 \n\
        bne-    1b \n"
-       PPC_ACQUIRE_BARRIER
+       PPC_ATOMIC_EXIT_BARRIER
 "      subf    %0,%2,%0 \n\
 2:"
        : "=&r" (t)
index e137afcc10fae89cb0987bbe982af5653916e9e1..efdc92618b38ddfa7da075a53fb3ba93e9c71dae 100644 (file)
@@ -124,14 +124,14 @@ static __inline__ unsigned long fn(                       \
        return (old & mask);                            \
 }
 
-DEFINE_TESTOP(test_and_set_bits, or, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_set_bits, or, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
 DEFINE_TESTOP(test_and_set_bits_lock, or, "",
              PPC_ACQUIRE_BARRIER, 1)
-DEFINE_TESTOP(test_and_clear_bits, andc, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
-DEFINE_TESTOP(test_and_change_bits, xor, PPC_RELEASE_BARRIER,
-             PPC_ACQUIRE_BARRIER, 0)
+DEFINE_TESTOP(test_and_clear_bits, andc, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
+DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
+             PPC_ATOMIC_EXIT_BARRIER, 0)
 
 static __inline__ int test_and_set_bit(unsigned long nr,
                                       volatile unsigned long *addr)
index 16d25c0974be9d7a4afa7c60f9b11942735caa16..d57c08acedfc2e5f1167a1f3a861094662c486fb 100644 (file)
@@ -37,4 +37,6 @@ struct pdev_archdata {
        u64 dma_mask;
 };
 
+#define ARCH_HAS_DMA_GET_REQUIRED_MASK
+
 #endif /* _ASM_POWERPC_DEVICE_H */
index 3a6c586c4e40f3ec479271dabbc2c4ccc85cd0da..14db29b18d0ed9664629550c48cc76106b35fcc6 100644 (file)
@@ -48,6 +48,8 @@
 #define FW_FEATURE_CMO         ASM_CONST(0x0000000002000000)
 #define FW_FEATURE_VPHN                ASM_CONST(0x0000000004000000)
 #define FW_FEATURE_XCMO                ASM_CONST(0x0000000008000000)
+#define FW_FEATURE_OPAL                ASM_CONST(0x0000000010000000)
+#define FW_FEATURE_OPALv2      ASM_CONST(0x0000000020000000)
 
 #ifndef __ASSEMBLY__
 
@@ -65,6 +67,8 @@ enum {
        FW_FEATURE_PSERIES_ALWAYS = 0,
        FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
        FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
+       FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
+       FW_FEATURE_POWERNV_ALWAYS = 0,
        FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
        FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
        FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT,
@@ -78,6 +82,9 @@ enum {
 #ifdef CONFIG_PPC_ISERIES
                FW_FEATURE_ISERIES_POSSIBLE |
 #endif
+#ifdef CONFIG_PPC_POWERNV
+               FW_FEATURE_POWERNV_POSSIBLE |
+#endif
 #ifdef CONFIG_PPC_PS3
                FW_FEATURE_PS3_POSSIBLE |
 #endif
@@ -95,6 +102,9 @@ enum {
 #ifdef CONFIG_PPC_ISERIES
                FW_FEATURE_ISERIES_ALWAYS &
 #endif
+#ifdef CONFIG_PPC_POWERNV
+               FW_FEATURE_POWERNV_ALWAYS &
+#endif
 #ifdef CONFIG_PPC_PS3
                FW_FEATURE_PS3_ALWAYS &
 #endif
index 24bd34c57e9d020bac9f24dc3be933db06e6e019..936a904ae78c6c0712127de3b15d23ab5a5c0b18 100644 (file)
@@ -108,10 +108,10 @@ static int fd_request_irq(void)
 {
        if (can_use_virtual_dma)
                return request_irq(FLOPPY_IRQ, floppy_hardint,
-                                  IRQF_DISABLED, "floppy", NULL);
+                                  0, "floppy", NULL);
        else
                return request_irq(FLOPPY_IRQ, floppy_interrupt,
-                                  IRQF_DISABLED, "floppy", NULL);
+                                  0, "floppy", NULL);
 }
 
 static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
index c94e4a3fe2ef3de09decfd1aa47bda3b77342f53..2a9cf845473bb51a4aea7d5317dde0a4b5ab37ed 100644 (file)
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
-       PPC_RELEASE_BARRIER \
+       PPC_ATOMIC_ENTRY_BARRIER \
 "1:    lwarx   %0,0,%2\n" \
        insn \
        PPC405_ERR77(0, %2) \
 "2:    stwcx.  %1,0,%2\n" \
        "bne-   1b\n" \
+       PPC_ATOMIC_EXIT_BARRIER \
        "li     %1,0\n" \
 "3:    .section .fixup,\"ax\"\n" \
 "4:    li      %1,%3\n" \
@@ -92,14 +93,14 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
                return -EFAULT;
 
         __asm__ __volatile__ (
-        PPC_RELEASE_BARRIER
+        PPC_ATOMIC_ENTRY_BARRIER
 "1:     lwarx   %1,0,%3         # futex_atomic_cmpxchg_inatomic\n\
         cmpw    0,%1,%4\n\
         bne-    3f\n"
         PPC405_ERR77(0,%3)
 "2:     stwcx.  %5,0,%3\n\
         bne-    1b\n"
-        PPC_ACQUIRE_BARRIER
+        PPC_ATOMIC_EXIT_BARRIER
 "3:    .section .fixup,\"ax\"\n\
 4:     li      %0,%6\n\
        b       3b\n\
index 5856a66ab4047e02c1ce8ed09a69b7c6a2b209be..86004930a78e4b79cc5e5dc7a070dc5939a72665 100644 (file)
@@ -1,15 +1,60 @@
 #ifndef _ASM_POWERPC_HUGETLB_H
 #define _ASM_POWERPC_HUGETLB_H
 
+#ifdef CONFIG_HUGETLB_PAGE
 #include <asm/page.h>
 
+extern struct kmem_cache *hugepte_cache;
+extern void __init reserve_hugetlb_gpages(void);
+
+static inline pte_t *hugepd_page(hugepd_t hpd)
+{
+       BUG_ON(!hugepd_ok(hpd));
+       return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
+}
+
+static inline unsigned int hugepd_shift(hugepd_t hpd)
+{
+       return hpd.pd & HUGEPD_SHIFT_MASK;
+}
+
+static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
+                                   unsigned pdshift)
+{
+       /*
+        * On 32-bit, we have multiple higher-level table entries that point to
+        * the same hugepte.  Just use the first one since they're all
+        * identical.  So for that case, idx=0.
+        */
+       unsigned long idx = 0;
+
+       pte_t *dir = hugepd_page(*hpdp);
+#ifdef CONFIG_PPC64
+       idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp);
+#endif
+
+       return dir + idx;
+}
+
 pte_t *huge_pte_offset_and_shift(struct mm_struct *mm,
                                 unsigned long addr, unsigned *shift);
 
 void flush_dcache_icache_hugepage(struct page *page);
 
+#if defined(CONFIG_PPC_MM_SLICES) || defined(CONFIG_PPC_SUBPAGE_PROT)
 int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
                           unsigned long len);
+#else
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+                                        unsigned long addr,
+                                        unsigned long len)
+{
+       return 0;
+}
+#endif
+
+void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte);
+void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
 
 void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
                            unsigned long end, unsigned long floor,
@@ -50,8 +95,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
                                            unsigned long addr, pte_t *ptep)
 {
-       unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1);
-       return __pte(old);
+#ifdef CONFIG_PPC64
+       return __pte(pte_update(mm, addr, ptep, ~0UL, 1));
+#else
+       return __pte(pte_update(ptep, ~0UL, 0));
+#endif
 }
 
 static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -93,4 +141,15 @@ static inline void arch_release_hugepage(struct page *page)
 {
 }
 
+#else /* ! CONFIG_HUGETLB_PAGE */
+static inline void reserve_hugetlb_gpages(void)
+{
+       pr_err("Cannot reserve gpages without hugetlb enabled\n");
+}
+static inline void flush_hugetlb_page(struct vm_area_struct *vma,
+                                     unsigned long vmaddr)
+{
+}
+#endif
+
 #endif /* _ASM_POWERPC_HUGETLB_H */
index 8a33698c61bd7ab98c0b7e08ee21e6a17aeeb409..f921eb121d39730265d54c6f1a97eb1881c897fe 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_POWERPC_KEXEC_H
 #ifdef __KERNEL__
 
-#ifdef CONFIG_FSL_BOOKE
+#if defined(CONFIG_FSL_BOOKE) || defined(CONFIG_44x)
 
 /*
  * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
index 08fe69edcd103f7882a3e172b7c5a55764009550..0ad432bc81d66259d82e4e94f691c46e4c765555 100644 (file)
@@ -148,12 +148,6 @@ struct kvm_regs {
 #define KVM_SREGS_E_UPDATE_DEC         (1 << 2)
 #define KVM_SREGS_E_UPDATE_DBSR                (1 << 3)
 
-/*
- * Book3S special bits to indicate contents in the struct by maintaining
- * backwards compatibility with older structs. If adding a new field,
- * please make sure to add a flag for that new field */
-#define KVM_SREGS_S_HIOR               (1 << 0)
-
 /*
  * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
  * previous KVM_GET_REGS.
@@ -179,8 +173,6 @@ struct kvm_sregs {
                                __u64 ibat[8]; 
                                __u64 dbat[8]; 
                        } ppc32;
-                       __u64 flags; /* KVM_SREGS_S_ */
-                       __u64 hior;
                } s;
                struct {
                        union {
index a384ffdf33de0af850ca03f18aab3e6c36515540..d4df013ad77964353fdf5a59c8ed6afde4ed1ce2 100644 (file)
@@ -90,8 +90,6 @@ struct kvmppc_vcpu_book3s {
 #endif
        int context_id[SID_CONTEXTS];
 
-       bool hior_sregs;                /* HIOR is set by SREGS, not PVR */
-
        struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
        struct hlist_head hpte_hash_pte_long[HPTEG_HASH_NUM_PTE_LONG];
        struct hlist_head hpte_hash_vpte[HPTEG_HASH_NUM_VPTE];
index 81713acf752997787b2ab58b7316debf10aec178..f77c708c67a05c2b576daec3476f74993a8d9ed6 100644 (file)
@@ -25,6 +25,7 @@
 #if !defined(__ASSEMBLY__)
 
 #include <linux/types.h>
+#include <linux/export.h>
 
 /* lv1 call declaration macros */
 
@@ -315,7 +316,7 @@ LV1_CALL(gpu_context_free,                              1, 0, 218 )
 LV1_CALL(gpu_context_iomap,                             5, 0, 221 )
 LV1_CALL(gpu_context_attribute,                         6, 0, 225 )
 LV1_CALL(gpu_context_intr,                              1, 1, 227 )
-LV1_CALL(gpu_attribute,                                 5, 0, 228 )
+LV1_CALL(gpu_attribute,                                 3, 0, 228 )
 LV1_CALL(get_rtc,                                       0, 2, 232 )
 LV1_CALL(set_ppe_periodic_tracer_frequency,             1, 0, 240 )
 LV1_CALL(start_ppe_periodic_tracer,                     5, 0, 241 )
index 47cacddb14cf26732a4550bbd213333f06df15be..b540d6fcedd6a1105350b087f100c2aaa6fbbf58 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <asm/setup.h>
 
@@ -85,8 +86,9 @@ struct machdep_calls {
        void            (*pci_dma_dev_setup)(struct pci_dev *dev);
        void            (*pci_dma_bus_setup)(struct pci_bus *bus);
 
-       /* Platform set_dma_mask override */
+       /* Platform set_dma_mask and dma_get_required_mask overrides */
        int             (*dma_set_mask)(struct device *dev, u64 dma_mask);
+       u64             (*dma_get_required_mask)(struct device *dev);
 
        int             (*probe)(void);
        void            (*setup_arch)(void); /* Optional, may be NULL */
index 3ea0f9a259d85b24304632537e0a571b93455716..0260ea5ec3c22f18137dd9c30156a82e26a093a6 100644 (file)
@@ -66,6 +66,7 @@
 #define MAS2_M                 0x00000004
 #define MAS2_G                 0x00000002
 #define MAS2_E                 0x00000001
+#define MAS2_WIMGE_MASK                0x0000001f
 #define MAS2_EPN_MASK(size)            (~0 << (size + 10))
 #define MAS2_VAL(addr, size, flags)    ((addr) & MAS2_EPN_MASK(size) | (flags))
 
@@ -80,6 +81,7 @@
 #define MAS3_SW                        0x00000004
 #define MAS3_UR                        0x00000002
 #define MAS3_SR                        0x00000001
+#define MAS3_BAP_MASK          0x0000003f
 #define MAS3_SPSIZE            0x0000003e
 #define MAS3_SPSIZE_SHIFT      1
 
@@ -212,6 +214,11 @@ typedef struct {
        unsigned int    id;
        unsigned int    active;
        unsigned long   vdso_base;
+#ifdef CONFIG_PPC_MM_SLICES
+       u64 low_slices_psize;   /* SLB page size encodings */
+       u64 high_slices_psize;  /* 4 bits per slice for now */
+       u16 user_psize;         /* page size index */
+#endif
 } mm_context_t;
 
 /* Page size definitions, common between 32 and 64-bit
index b445e0af4c2b152e751020c4bd58a060708b5ff2..db645ec842bddfe6e0de323629ee2f47e4a19acc 100644 (file)
@@ -262,8 +262,7 @@ extern void hash_failure_debug(unsigned long ea, unsigned long access,
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                             unsigned long pstart, unsigned long prot,
                             int psize, int ssize);
-extern void add_gpage(unsigned long addr, unsigned long page_size,
-                         unsigned long number_of_pages);
+extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages);
 extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
 
 extern void hpte_init_native(void);
index 698b3063868104118c39ed7ae9506f12e18a5de1..f0145522cfbae427805cad72ac900d3d3432ea06 100644 (file)
@@ -175,14 +175,16 @@ extern u64 ppc64_rma_size;
 #define MMU_PAGE_64K_AP        3       /* "Admixed pages" (hash64 only) */
 #define MMU_PAGE_256K  4
 #define MMU_PAGE_1M    5
-#define MMU_PAGE_8M    6
-#define MMU_PAGE_16M   7
-#define MMU_PAGE_256M  8
-#define MMU_PAGE_1G    9
-#define MMU_PAGE_16G   10
-#define MMU_PAGE_64G   11
-#define MMU_PAGE_COUNT 12
-
+#define MMU_PAGE_4M    6
+#define MMU_PAGE_8M    7
+#define MMU_PAGE_16M   8
+#define MMU_PAGE_64M   9
+#define MMU_PAGE_256M  10
+#define MMU_PAGE_1G    11
+#define MMU_PAGE_16G   12
+#define MMU_PAGE_64G   13
+
+#define MMU_PAGE_COUNT 14
 
 #if defined(CONFIG_PPC_STD_MMU_64)
 /* 64-bit classic hash table MMU */
index df18989e78d4dc5edcb4f086d211036a48dac073..e6fae49e0b745ff75e7433bc5d2b1c7832ca820f 100644 (file)
@@ -273,8 +273,6 @@ struct mpic
        unsigned int            irq_count;
        /* Number of sources */
        unsigned int            num_sources;
-       /* Number of CPUs */
-       unsigned int            num_cpus;
        /* default senses array */
        unsigned char           *senses;
        unsigned int            senses_count;
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
new file mode 100644 (file)
index 0000000..2893e8f
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * PowerNV OPAL definitions.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __OPAL_H
+#define __OPAL_H
+
+/****** Takeover interface ********/
+
+/* PAPR H-Call used to querty the HAL existence and/or instanciate
+ * it from within pHyp (tech preview only).
+ *
+ * This is exclusively used in prom_init.c
+ */
+
+#ifndef __ASSEMBLY__
+
+struct opal_takeover_args {
+       u64     k_image;                /* r4 */
+       u64     k_size;                 /* r5 */
+       u64     k_entry;                /* r6 */
+       u64     k_entry2;               /* r7 */
+       u64     hal_addr;               /* r8 */
+       u64     rd_image;               /* r9 */
+       u64     rd_size;                /* r10 */
+       u64     rd_loc;                 /* r11 */
+};
+
+extern long opal_query_takeover(u64 *hal_size, u64 *hal_align);
+
+extern long opal_do_takeover(struct opal_takeover_args *args);
+
+struct rtas_args;
+extern int opal_enter_rtas(struct rtas_args *args,
+                          unsigned long data,
+                          unsigned long entry);
+
+#endif /* __ASSEMBLY__ */
+
+/****** OPAL APIs ******/
+
+/* Return codes */
+#define OPAL_SUCCESS           0
+#define OPAL_PARAMETER         -1
+#define OPAL_BUSY              -2
+#define OPAL_PARTIAL           -3
+#define OPAL_CONSTRAINED       -4
+#define OPAL_CLOSED            -5
+#define OPAL_HARDWARE          -6
+#define OPAL_UNSUPPORTED       -7
+#define OPAL_PERMISSION                -8
+#define OPAL_NO_MEM            -9
+#define OPAL_RESOURCE          -10
+#define OPAL_INTERNAL_ERROR    -11
+#define OPAL_BUSY_EVENT                -12
+#define OPAL_HARDWARE_FROZEN   -13
+
+/* API Tokens (in r0) */
+#define OPAL_CONSOLE_WRITE                     1
+#define OPAL_CONSOLE_READ                      2
+#define OPAL_RTC_READ                          3
+#define OPAL_RTC_WRITE                         4
+#define OPAL_CEC_POWER_DOWN                    5
+#define OPAL_CEC_REBOOT                                6
+#define OPAL_READ_NVRAM                                7
+#define OPAL_WRITE_NVRAM                       8
+#define OPAL_HANDLE_INTERRUPT                  9
+#define OPAL_POLL_EVENTS                       10
+#define OPAL_PCI_SET_HUB_TCE_MEMORY            11
+#define OPAL_PCI_SET_PHB_TCE_MEMORY            12
+#define OPAL_PCI_CONFIG_READ_BYTE              13
+#define OPAL_PCI_CONFIG_READ_HALF_WORD         14
+#define OPAL_PCI_CONFIG_READ_WORD              15
+#define OPAL_PCI_CONFIG_WRITE_BYTE             16
+#define OPAL_PCI_CONFIG_WRITE_HALF_WORD                17
+#define OPAL_PCI_CONFIG_WRITE_WORD             18
+#define OPAL_SET_XIVE                          19
+#define OPAL_GET_XIVE                          20
+#define OPAL_GET_COMPLETION_TOKEN_STATUS       21 /* obsolete */
+#define OPAL_REGISTER_OPAL_EXCEPTION_HANDLER   22
+#define OPAL_PCI_EEH_FREEZE_STATUS             23
+#define OPAL_PCI_SHPC                          24
+#define OPAL_CONSOLE_WRITE_BUFFER_SPACE                25
+#define OPAL_PCI_EEH_FREEZE_CLEAR              26
+#define OPAL_PCI_PHB_MMIO_ENABLE               27
+#define OPAL_PCI_SET_PHB_MEM_WINDOW            28
+#define OPAL_PCI_MAP_PE_MMIO_WINDOW            29
+#define OPAL_PCI_SET_PHB_TABLE_MEMORY          30
+#define OPAL_PCI_SET_PE                                31
+#define OPAL_PCI_SET_PELTV                     32
+#define OPAL_PCI_SET_MVE                       33
+#define OPAL_PCI_SET_MVE_ENABLE                        34
+#define OPAL_PCI_GET_XIVE_REISSUE              35
+#define OPAL_PCI_SET_XIVE_REISSUE              36
+#define OPAL_PCI_SET_XIVE_PE                   37
+#define OPAL_GET_XIVE_SOURCE                   38
+#define OPAL_GET_MSI_32                                39
+#define OPAL_GET_MSI_64                                40
+#define OPAL_START_CPU                         41
+#define OPAL_QUERY_CPU_STATUS                  42
+#define OPAL_WRITE_OPPANEL                     43
+#define OPAL_PCI_MAP_PE_DMA_WINDOW             44
+#define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL                45
+#define OPAL_PCI_RESET                         49
+
+#ifndef __ASSEMBLY__
+
+/* Other enums */
+enum OpalVendorApiTokens {
+       OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
+};
+enum OpalFreezeState {
+       OPAL_EEH_STOPPED_NOT_FROZEN = 0,
+       OPAL_EEH_STOPPED_MMIO_FREEZE = 1,
+       OPAL_EEH_STOPPED_DMA_FREEZE = 2,
+       OPAL_EEH_STOPPED_MMIO_DMA_FREEZE = 3,
+       OPAL_EEH_STOPPED_RESET = 4,
+       OPAL_EEH_STOPPED_TEMP_UNAVAIL = 5,
+       OPAL_EEH_STOPPED_PERM_UNAVAIL = 6
+};
+enum OpalEehFreezeActionToken {
+       OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1,
+       OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2,
+       OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3
+};
+enum OpalPciStatusToken {
+       OPAL_EEH_PHB_NO_ERROR = 0,
+       OPAL_EEH_PHB_FATAL = 1,
+       OPAL_EEH_PHB_RECOVERABLE = 2,
+       OPAL_EEH_PHB_BUS_ERROR = 3,
+       OPAL_EEH_PCI_NO_DEVSEL = 4,
+       OPAL_EEH_PCI_TA = 5,
+       OPAL_EEH_PCIEX_UR = 6,
+       OPAL_EEH_PCIEX_CA = 7,
+       OPAL_EEH_PCI_MMIO_ERROR = 8,
+       OPAL_EEH_PCI_DMA_ERROR = 9
+};
+enum OpalShpcAction {
+       OPAL_SHPC_GET_LINK_STATE = 0,
+       OPAL_SHPC_GET_SLOT_STATE = 1
+};
+enum OpalShpcLinkState {
+       OPAL_SHPC_LINK_DOWN = 0,
+       OPAL_SHPC_LINK_UP = 1
+};
+enum OpalMmioWindowType {
+       OPAL_M32_WINDOW_TYPE = 1,
+       OPAL_M64_WINDOW_TYPE = 2,
+       OPAL_IO_WINDOW_TYPE = 3
+};
+enum OpalShpcSlotState {
+       OPAL_SHPC_DEV_NOT_PRESENT = 0,
+       OPAL_SHPC_DEV_PRESENT = 1
+};
+enum OpalExceptionHandler {
+       OPAL_MACHINE_CHECK_HANDLER = 1,
+       OPAL_HYPERVISOR_MAINTENANCE_HANDLER = 2,
+       OPAL_SOFTPATCH_HANDLER = 3
+};
+enum OpalPendingState {
+       OPAL_EVENT_OPAL_INTERNAL = 0x1,
+       OPAL_EVENT_NVRAM = 0x2,
+       OPAL_EVENT_RTC = 0x4,
+       OPAL_EVENT_CONSOLE_OUTPUT = 0x8,
+       OPAL_EVENT_CONSOLE_INPUT = 0x10
+};
+
+/* Machine check related definitions */
+enum OpalMCE_Version {
+       OpalMCE_V1 = 1,
+};
+
+enum OpalMCE_Severity {
+       OpalMCE_SEV_NO_ERROR = 0,
+       OpalMCE_SEV_WARNING = 1,
+       OpalMCE_SEV_ERROR_SYNC = 2,
+       OpalMCE_SEV_FATAL = 3,
+};
+
+enum OpalMCE_Disposition {
+       OpalMCE_DISPOSITION_RECOVERED = 0,
+       OpalMCE_DISPOSITION_NOT_RECOVERED = 1,
+};
+
+enum OpalMCE_Initiator {
+       OpalMCE_INITIATOR_UNKNOWN = 0,
+       OpalMCE_INITIATOR_CPU = 1,
+};
+
+enum OpalMCE_ErrorType {
+       OpalMCE_ERROR_TYPE_UNKNOWN = 0,
+       OpalMCE_ERROR_TYPE_UE = 1,
+       OpalMCE_ERROR_TYPE_SLB = 2,
+       OpalMCE_ERROR_TYPE_ERAT = 3,
+       OpalMCE_ERROR_TYPE_TLB = 4,
+};
+
+enum OpalMCE_UeErrorType {
+       OpalMCE_UE_ERROR_INDETERMINATE = 0,
+       OpalMCE_UE_ERROR_IFETCH = 1,
+       OpalMCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2,
+       OpalMCE_UE_ERROR_LOAD_STORE = 3,
+       OpalMCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4,
+};
+
+enum OpalMCE_SlbErrorType {
+       OpalMCE_SLB_ERROR_INDETERMINATE = 0,
+       OpalMCE_SLB_ERROR_PARITY = 1,
+       OpalMCE_SLB_ERROR_MULTIHIT = 2,
+};
+
+enum OpalMCE_EratErrorType {
+       OpalMCE_ERAT_ERROR_INDETERMINATE = 0,
+       OpalMCE_ERAT_ERROR_PARITY = 1,
+       OpalMCE_ERAT_ERROR_MULTIHIT = 2,
+};
+
+enum OpalMCE_TlbErrorType {
+       OpalMCE_TLB_ERROR_INDETERMINATE = 0,
+       OpalMCE_TLB_ERROR_PARITY = 1,
+       OpalMCE_TLB_ERROR_MULTIHIT = 2,
+};
+
+enum OpalThreadStatus {
+       OPAL_THREAD_INACTIVE = 0x0,
+       OPAL_THREAD_STARTED = 0x1
+};
+
+enum OpalPciBusCompare {
+       OpalPciBusAny   = 0,    /* Any bus number match */
+       OpalPciBus3Bits = 2,    /* Match top 3 bits of bus number */
+       OpalPciBus4Bits = 3,    /* Match top 4 bits of bus number */
+       OpalPciBus5Bits = 4,    /* Match top 5 bits of bus number */
+       OpalPciBus6Bits = 5,    /* Match top 6 bits of bus number */
+       OpalPciBus7Bits = 6,    /* Match top 7 bits of bus number */
+       OpalPciBusAll   = 7,    /* Match bus number exactly */
+};
+
+enum OpalDeviceCompare {
+       OPAL_IGNORE_RID_DEVICE_NUMBER = 0,
+       OPAL_COMPARE_RID_DEVICE_NUMBER = 1
+};
+
+enum OpalFuncCompare {
+       OPAL_IGNORE_RID_FUNCTION_NUMBER = 0,
+       OPAL_COMPARE_RID_FUNCTION_NUMBER = 1
+};
+
+enum OpalPeAction {
+       OPAL_UNMAP_PE = 0,
+       OPAL_MAP_PE = 1
+};
+
+enum OpalPciResetAndReinitScope {
+       OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3,
+       OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5,
+       OPAL_PCI_IODA_RESET = 6,
+};
+
+enum OpalPciResetState { OPAL_DEASSERT_RESET = 0, OPAL_ASSERT_RESET = 1 };
+
+struct opal_machine_check_event {
+       enum OpalMCE_Version    version:8;      /* 0x00 */
+       uint8_t                 in_use;         /* 0x01 */
+       enum OpalMCE_Severity   severity:8;     /* 0x02 */
+       enum OpalMCE_Initiator  initiator:8;    /* 0x03 */
+       enum OpalMCE_ErrorType  error_type:8;   /* 0x04 */
+       enum OpalMCE_Disposition disposition:8; /* 0x05 */
+       uint8_t                 reserved_1[2];  /* 0x06 */
+       uint64_t                gpr3;           /* 0x08 */
+       uint64_t                srr0;           /* 0x10 */
+       uint64_t                srr1;           /* 0x18 */
+       union {                                 /* 0x20 */
+               struct {
+                       enum OpalMCE_UeErrorType ue_error_type:8;
+                       uint8_t         effective_address_provided;
+                       uint8_t         physical_address_provided;
+                       uint8_t         reserved_1[5];
+                       uint64_t        effective_address;
+                       uint64_t        physical_address;
+                       uint8_t         reserved_2[8];
+               } ue_error;
+
+               struct {
+                       enum OpalMCE_SlbErrorType slb_error_type:8;
+                       uint8_t         effective_address_provided;
+                       uint8_t         reserved_1[6];
+                       uint64_t        effective_address;
+                       uint8_t         reserved_2[16];
+               } slb_error;
+
+               struct {
+                       enum OpalMCE_EratErrorType erat_error_type:8;
+                       uint8_t         effective_address_provided;
+                       uint8_t         reserved_1[6];
+                       uint64_t        effective_address;
+                       uint8_t         reserved_2[16];
+               } erat_error;
+
+               struct {
+                       enum OpalMCE_TlbErrorType tlb_error_type:8;
+                       uint8_t         effective_address_provided;
+                       uint8_t         reserved_1[6];
+                       uint64_t        effective_address;
+                       uint8_t         reserved_2[16];
+               } tlb_error;
+       } u;
+};
+
+typedef struct oppanel_line {
+       /* XXX */
+} oppanel_line_t;
+
+/* API functions */
+int64_t opal_console_write(int64_t term_number, int64_t *length,
+                          const uint8_t *buffer);
+int64_t opal_console_read(int64_t term_number, int64_t *length,
+                         uint8_t *buffer);
+int64_t opal_console_write_buffer_space(int64_t term_number,
+                                       int64_t *length);
+int64_t opal_rtc_read(uint32_t *year_month_day,
+                     uint64_t *hour_minute_second_millisecond);
+int64_t opal_rtc_write(uint32_t year_month_day,
+                      uint64_t hour_minute_second_millisecond);
+int64_t opal_cec_power_down(uint64_t request);
+int64_t opal_cec_reboot(void);
+int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
+int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
+int64_t opal_handle_interrupt(uint64_t isn, uint64_t *outstanding_event_mask);
+int64_t opal_poll_events(uint64_t *outstanding_event_mask);
+int64_t opal_pci_set_hub_tce_memory(uint64_t hub_id, uint64_t tce_mem_addr,
+                                   uint64_t tce_mem_size);
+int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr,
+                                   uint64_t tce_mem_size);
+int64_t opal_pci_config_read_byte(uint64_t phb_id, uint64_t bus_dev_func,
+                                 uint64_t offset, uint8_t *data);
+int64_t opal_pci_config_read_half_word(uint64_t phb_id, uint64_t bus_dev_func,
+                                      uint64_t offset, uint16_t *data);
+int64_t opal_pci_config_read_word(uint64_t phb_id, uint64_t bus_dev_func,
+                                 uint64_t offset, uint32_t *data);
+int64_t opal_pci_config_write_byte(uint64_t phb_id, uint64_t bus_dev_func,
+                                  uint64_t offset, uint8_t data);
+int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func,
+                                       uint64_t offset, uint16_t data);
+int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func,
+                                  uint64_t offset, uint32_t data);
+int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority);
+int64_t opal_get_xive(uint32_t isn, uint16_t *server, uint8_t *priority);
+int64_t opal_register_exception_handler(uint64_t opal_exception,
+                                       uint64_t handler_address,
+                                       uint64_t glue_cache_line);
+int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number,
+                                  uint8_t *freeze_state,
+                                  uint16_t *pci_error_type,
+                                  uint64_t *phb_status);
+int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number,
+                                 uint64_t eeh_action_token);
+int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state);
+
+
+
+int64_t opal_pci_phb_mmio_enable(uint64_t phb_id, uint16_t window_type,
+                                uint16_t window_num, uint16_t enable);
+int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type,
+                                   uint16_t window_num,
+                                   uint64_t starting_real_address,
+                                   uint64_t starting_pci_address,
+                                   uint16_t segment_size);
+int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number,
+                                   uint16_t window_type, uint16_t window_num,
+                                   uint16_t segment_num);
+int64_t opal_pci_set_phb_table_memory(uint64_t phb_id, uint64_t rtt_addr,
+                                     uint64_t ivt_addr, uint64_t ivt_len,
+                                     uint64_t reject_array_addr,
+                                     uint64_t peltv_addr);
+int64_t opal_pci_set_pe(uint64_t phb_id, uint64_t pe_number, uint64_t bus_dev_func,
+                       uint8_t bus_compare, uint8_t dev_compare, uint8_t func_compare,
+                       uint8_t pe_action);
+int64_t opal_pci_set_peltv(uint64_t phb_id, uint32_t parent_pe, uint32_t child_pe,
+                          uint8_t state);
+int64_t opal_pci_set_mve(uint64_t phb_id, uint32_t mve_number, uint32_t pe_number);
+int64_t opal_pci_set_mve_enable(uint64_t phb_id, uint32_t mve_number,
+                               uint32_t state);
+int64_t opal_pci_get_xive_reissue(uint64_t phb_id, uint32_t xive_number,
+                                 uint8_t *p_bit, uint8_t *q_bit);
+int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number,
+                                 uint8_t p_bit, uint8_t q_bit);
+int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number,
+                            uint32_t xive_num);
+int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num,
+                            int32_t *interrupt_source_number);
+int64_t opal_get_msi_32(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num,
+                       uint8_t msi_range, uint32_t *msi_address,
+                       uint32_t *message_data);
+int64_t opal_get_msi_64(uint64_t phb_id, uint32_t mve_number,
+                       uint32_t xive_num, uint8_t msi_range,
+                       uint64_t *msi_address, uint32_t *message_data);
+int64_t opal_start_cpu(uint64_t thread_number, uint64_t start_address);
+int64_t opal_query_cpu_status(uint64_t thread_number, uint8_t *thread_status);
+int64_t opal_write_oppanel(oppanel_line_t *lines, uint64_t num_lines);
+int64_t opal_pci_map_pe_dma_window(uint64_t phb_id, uint16_t pe_number, uint16_t window_id,
+                                  uint16_t tce_levels, uint64_t tce_table_addr,
+                                  uint64_t tce_table_size, uint64_t tce_page_size);
+int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id, uint16_t pe_number,
+                                       uint16_t dma_window_number, uint64_t pci_start_addr,
+                                       uint64_t pci_mem_size);
+int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope, uint8_t assert_state);
+
+/* Internal functions */
+extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
+
+extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
+extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
+
+extern void hvc_opal_init_early(void);
+
+/* Internal functions */
+extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
+                                  int depth, void *data);
+
+extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
+extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
+
+extern void hvc_opal_init_early(void);
+
+struct rtc_time;
+extern int opal_set_rtc_time(struct rtc_time *tm);
+extern void opal_get_rtc_time(struct rtc_time *tm);
+extern unsigned long opal_get_boot_time(void);
+extern void opal_nvram_init(void);
+
+extern int opal_machine_check(struct pt_regs *regs);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __OPAL_H */
index 516bfb3f47d9fef3916b1760c11c27888eaed4c3..17722c73ba2e91e24b31c0d5c4435d9d57b0f1c2 100644 (file)
@@ -43,6 +43,7 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
 #define get_slb_shadow()       (get_paca()->slb_shadow_ptr)
 
 struct task_struct;
+struct opal_machine_check_event;
 
 /*
  * Defines the layout of the paca.
@@ -135,6 +136,13 @@ struct paca_struct {
        u8 io_sync;                     /* writel() needs spin_unlock sync */
        u8 irq_work_pending;            /* IRQ_WORK interrupt while soft-disable */
 
+#ifdef CONFIG_PPC_POWERNV
+       /* Pointer to OPAL machine check event structure set by the
+        * early exception handler for use by high level C handler
+        */
+       struct opal_machine_check_event *opal_mc_evt;
+#endif
+
        /* Stuff for accurate time accounting */
        u64 user_time;                  /* accumulated usermode TB ticks */
        u64 system_time;                /* accumulated system TB ticks */
index 2cd664ef0a5e66abd924002e56839379657efd41..dd9c4fd038e00b336d14c68e4d00a63cf20073b8 100644 (file)
 
 #define PAGE_SIZE              (ASM_CONST(1) << PAGE_SHIFT)
 
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_HUGETLB_PAGE
+extern unsigned int HPAGE_SHIFT;
+#else
+#define HPAGE_SHIFT PAGE_SHIFT
+#endif
+#define HPAGE_SIZE             ((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK             (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
+#define HUGE_MAX_HSTATE                (MMU_PAGE_COUNT-1)
+#endif
+
 /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
 #define __HAVE_ARCH_GATE_AREA          1
 
@@ -158,6 +170,24 @@ extern phys_addr_t kernstart_addr;
 #define is_kernel_addr(x)      ((x) >= PAGE_OFFSET)
 #endif
 
+/*
+ * Use the top bit of the higher-level page table entries to indicate whether
+ * the entries we point to contain hugepages.  This works because we know that
+ * the page tables live in kernel space.  If we ever decide to support having
+ * page tables at arbitrary addresses, this breaks and will have to change.
+ */
+#ifdef CONFIG_PPC64
+#define PD_HUGE 0x8000000000000000
+#else
+#define PD_HUGE 0x80000000
+#endif
+
+/*
+ * Some number of bits at the level of the page table that points to
+ * a hugepte are used to encode the size.  This masks those bits.
+ */
+#define HUGEPD_SHIFT_MASK     0x3f
+
 #ifndef __ASSEMBLY__
 
 #undef STRICT_MM_TYPECHECKS
@@ -243,7 +273,6 @@ typedef unsigned long pgprot_t;
 #endif
 
 typedef struct { signed long pd; } hugepd_t;
-#define HUGEPD_SHIFT_MASK     0x3f
 
 #ifdef CONFIG_HUGETLB_PAGE
 static inline int hugepd_ok(hugepd_t hpd)
index 9356262fd3ccdbbf3eab35f217101056684055eb..fb40ede6bc0dc414de55258680366b98115fda8a 100644 (file)
@@ -64,17 +64,6 @@ extern void copy_page(void *to, void *from);
 /* Log 2 of page table size */
 extern u64 ppc64_pft_size;
 
-/* Large pages size */
-#ifdef CONFIG_HUGETLB_PAGE
-extern unsigned int HPAGE_SHIFT;
-#else
-#define HPAGE_SHIFT PAGE_SHIFT
-#endif
-#define HPAGE_SIZE             ((1UL) << HPAGE_SHIFT)
-#define HPAGE_MASK             (~(HPAGE_SIZE - 1))
-#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
-#define HUGE_MAX_HSTATE                (MMU_PAGE_COUNT-1)
-
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PPC_MM_SLICES
index 082d515930a258b0da70b9c9b2d190b2ac74098a..0156702ba24e2bb4f8c9131627dac0e9f6406c7e 100644 (file)
@@ -72,6 +72,9 @@
 #define        PTE_RPN_SHIFT   (24)
 #endif
 
+#define PTE_WIMGE_SHIFT (19)
+#define PTE_BAP_SHIFT  (2)
+
 /* On 32-bit, we never clear the top part of the PTE */
 #ifdef CONFIG_PPC32
 #define _PTE_NONE_MASK 0xffffffff00000000ULL
index 9ec0b39f9ddc3cf98a65c67b452e021519783d1e..03c48e819c8e3ff3bc600242dc85ef9111aca478 100644 (file)
@@ -31,7 +31,7 @@
 
 #define MSR_           MSR_ME | MSR_CE
 #define MSR_KERNEL     MSR_ | MSR_64BIT
-#define MSR_USER32     MSR_ | MSR_PR | MSR_EE | MSR_DE
+#define MSR_USER32     MSR_ | MSR_PR | MSR_EE
 #define MSR_USER64     MSR_USER32 | MSR_64BIT
 #elif defined (CONFIG_40x)
 #define MSR_KERNEL     (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
 #define L1CSR1_ICFI    0x00000002      /* Instr Cache Flash Invalidate */
 #define L1CSR1_ICE     0x00000001      /* Instr Cache Enable */
 
+/* Bit definitions for L1CSR2. */
+#define L1CSR2_DCWS    0x40000000      /* Data Cache write shadow */
+
 /* Bit definitions for L2CSR0. */
 #define L2CSR0_L2E     0x80000000      /* L2 Cache Enable */
 #define L2CSR0_L2PE    0x40000000      /* L2 Cache Parity/ECC Enable */
index 58625d1e78023e2037a2442513f3103e84658b9b..41f69ae79d4ec3946fd934eb80300d81b6f76542 100644 (file)
@@ -249,10 +249,12 @@ extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
 #define ERR_FLAG_ALREADY_LOGGED        0x0
 #define ERR_FLAG_BOOT          0x1     /* log was pulled from NVRAM on boot */
 #define ERR_TYPE_RTAS_LOG      0x2     /* from rtas event-scan */
-#define ERR_TYPE_KERNEL_PANIC  0x4     /* from panic() */
+#define ERR_TYPE_KERNEL_PANIC  0x4     /* from die()/panic() */
+#define ERR_TYPE_KERNEL_PANIC_GZ 0x8   /* ditto, compressed */
 
 /* All the types and not flags */
-#define ERR_TYPE_MASK  (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC)
+#define ERR_TYPE_MASK \
+       (ERR_TYPE_RTAS_LOG | ERR_TYPE_KERNEL_PANIC | ERR_TYPE_KERNEL_PANIC_GZ)
 
 #define RTAS_DEBUG KERN_DEBUG "RTAS: "
  
index 6fbce725c710f97453079205e190c02c7365cd0b..a0f358d4a00cd57ba3b22fbbf1024c7daba65fa4 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifdef __powerpc64__
 
-extern char _end[];
+extern char __end_interrupts[];
 
 static inline int in_kernel_text(unsigned long addr)
 {
index 15a70b7f638bc48f3b81d27fc4dc5b19b659fa99..adba970ce918595047e40ba2925849076acbffa9 100644 (file)
@@ -65,6 +65,7 @@ int generic_cpu_disable(void);
 void generic_cpu_die(unsigned int cpu);
 void generic_mach_cpu_die(void);
 void generic_set_cpu_dead(unsigned int cpu);
+int generic_check_cpu_restart(unsigned int cpu);
 #endif
 
 #ifdef CONFIG_PPC64
index 54a47ea2c3aa23385dcd5855614f962529bdda5f..0c5fa3145615c28074208ca64e79fdac12b06170 100644 (file)
@@ -16,7 +16,7 @@
 #endif /* CONFIG_SPARSEMEM */
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-extern void create_section_mapping(unsigned long start, unsigned long end);
+extern int create_section_mapping(unsigned long start, unsigned long end);
 extern int remove_section_mapping(unsigned long start, unsigned long end);
 #ifdef CONFIG_NUMA
 extern int hot_add_scn_to_nid(unsigned long scn_addr);
index 0c8b35d75232363f0fe66c7a9c6df2c6c53dcb0b..4e360bd4a35af803f3eebf9e49646b0033124ee1 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/workqueue.h>
 #include <linux/sysdev.h>
+#include <linux/mutex.h>
 
 #define LS_SIZE (256 * 1024)
 #define LS_ADDR_MASK (LS_SIZE - 1)
index d7cab44643c51d90f1f79509939e3c734b735eba..e682a7143edb767826705243df3613cc85e305ab 100644 (file)
@@ -13,6 +13,7 @@
 extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup;
 extern void do_lwsync_fixups(unsigned long value, void *fixup_start,
                             void *fixup_end);
+extern void do_final_fixups(void);
 
 static inline void eieio(void)
 {
@@ -41,11 +42,15 @@ static inline void isync(void)
        START_LWSYNC_SECTION(97);                       \
        isync;                                          \
        MAKE_LWSYNC_SECTION_ENTRY(97, __lwsync_fixup);
-#define PPC_ACQUIRE_BARRIER    "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
-#define PPC_RELEASE_BARRIER    stringify_in_c(LWSYNC) "\n"
+#define PPC_ACQUIRE_BARRIER     "\n" stringify_in_c(__PPC_ACQUIRE_BARRIER)
+#define PPC_RELEASE_BARRIER     stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_ENTRY_BARRIER "\n" stringify_in_c(LWSYNC) "\n"
+#define PPC_ATOMIC_EXIT_BARRIER         "\n" stringify_in_c(sync) "\n"
 #else
 #define PPC_ACQUIRE_BARRIER
 #define PPC_RELEASE_BARRIER
+#define PPC_ATOMIC_ENTRY_BARRIER
+#define PPC_ATOMIC_EXIT_BARRIER
 #endif
 
 #endif /* __KERNEL__ */
index 7ef0d90defc8ec752cb1f1a4850efb4781343a21..1e104af08483d6c1c648e151b15f226f816a741b 100644 (file)
@@ -19,14 +19,10 @@ struct device_node;
 #define RECLAIM_DISTANCE 10
 
 /*
- * Before going off node we want the VM to try and reclaim from the local
- * node. It does this if the remote distance is larger than RECLAIM_DISTANCE.
- * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of
- * 20, we never reclaim and go off node straight away.
- *
- * To fix this we choose a smaller value of RECLAIM_DISTANCE.
+ * Avoid creating an extra level of balancing (SD_ALLNODES) on the largest
+ * POWER7 boxes which have a maximum of 32 nodes.
  */
-#define RECLAIM_DISTANCE 10
+#define SD_NODES_PER_DOMAIN 32
 
 #include <asm/mmzone.h>
 
@@ -69,11 +65,11 @@ static inline int pcibus_to_node(struct pci_bus *bus)
        .forkexec_idx           = 0,                                    \
                                                                        \
        .flags                  = 1*SD_LOAD_BALANCE                     \
-                               | 1*SD_BALANCE_NEWIDLE                  \
+                               | 0*SD_BALANCE_NEWIDLE                  \
                                | 1*SD_BALANCE_EXEC                     \
                                | 1*SD_BALANCE_FORK                     \
                                | 0*SD_BALANCE_WAKE                     \
-                               | 0*SD_WAKE_AFFINE                      \
+                               | 1*SD_WAKE_AFFINE                      \
                                | 0*SD_PREFER_LOCAL                     \
                                | 0*SD_SHARE_CPUPOWER                   \
                                | 0*SD_POWERSAVINGS_BALANCE             \
index 5354ae91bdde8f2d168c68552a50f5f97f5520e9..8338aef5a4d3ee7fe556b188e56057cb3ea076bf 100644 (file)
@@ -55,6 +55,9 @@ extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
 extern void __init udbg_init_ehv_bc(void);
+extern void __init udbg_init_ps3gelic(void);
+extern void __init udbg_init_debug_opal_raw(void);
+extern void __init udbg_init_debug_opal_hvsi(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
index b183a4062011a337dbd6281d56e93c34bf7d6857..c48de98ba94eef1c4ee98db7b79a33f270d47d04 100644 (file)
@@ -15,8 +15,8 @@
 #define        DEFAULT_PRIORITY        5
 
 /*
- * Mark IPIs as higher priority so we can take them inside interrupts that
- * arent marked IRQF_DISABLED
+ * Mark IPIs as higher priority so we can take them inside interrupts
+ * FIXME: still true now?
  */
 #define IPI_PRIORITY           4
 
 #define MAX_NUM_PRIORITIES     3
 
 /* Native ICP */
+#ifdef CONFIG_PPC_ICP_NATIVE
 extern int icp_native_init(void);
+#else
+static inline int icp_native_init(void) { return -ENODEV; }
+#endif
 
 /* PAPR ICP */
+#ifdef CONFIG_PPC_ICP_HV
 extern int icp_hv_init(void);
+#else
+static inline int icp_hv_init(void) { return -ENODEV; }
+#endif
 
 /* ICP ops */
 struct icp_ops {
@@ -51,7 +59,18 @@ extern const struct icp_ops *icp_ops;
 extern int ics_native_init(void);
 
 /* RTAS ICS */
+#ifdef CONFIG_PPC_ICS_RTAS
 extern int ics_rtas_init(void);
+#else
+static inline int ics_rtas_init(void) { return -ENODEV; }
+#endif
+
+/* HAL ICS */
+#ifdef CONFIG_PPC_POWERNV
+extern int ics_opal_init(void);
+#else
+static inline int ics_opal_init(void) { return -ENODEV; }
+#endif
 
 /* ICS instance, hooked up to chip_data of an irq */
 struct ics {
index 69f7ffe7f6749479d5280d5317b3697e150259f4..7c5324f1ec9c35671fcda0fd0dffc791b25ceaa7 100644 (file)
@@ -49,6 +49,9 @@
 #ifdef CONFIG_PPC_ISERIES
 #include <asm/iseries/alpaca.h>
 #endif
+#ifdef CONFIG_PPC_POWERNV
+#include <asm/opal.h>
+#endif
 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_GUEST)
 #include <linux/kvm_host.h>
 #endif
@@ -610,5 +613,12 @@ int main(void)
                                        arch.timing_last_enter.tv32.tbl));
 #endif
 
+#ifdef CONFIG_PPC_POWERNV
+       DEFINE(OPAL_MC_GPR3, offsetof(struct opal_machine_check_event, gpr3));
+       DEFINE(OPAL_MC_SRR0, offsetof(struct opal_machine_check_event, srr0));
+       DEFINE(OPAL_MC_SRR1, offsetof(struct opal_machine_check_event, srr1));
+       DEFINE(PACA_OPAL_MC_EVT, offsetof(struct paca_struct, opal_mc_evt));
+#endif
+
        return 0;
 }
index 60b3e377b1e4e8c71ed0976b4a03e2269fae8305..ac8f52732fde2948675be0983a5a47dd8163584c 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/memblock.h>
 
 #include <asm/sections.h>
index ce668f545758cf7bf92231b5d888a48132d7b80b..a764b47791e858af282d14d595c0aa96c2f63847 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/clk_interface.h>
 
 struct clk_interface clk_functions;
index fa44ff538861fa4b44c81b60ebff7b2a4ac0be64..edae5bb06f1f3906847b0207955f9d560bc57aae 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/sched.h>
 #include <linux/threads.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/oprofile_impl.h>
 #include <asm/cputable.h>
index cc6a9d5d69ab08da9a87635c342f83d0083db8f3..d879809d5c454a6d37a8b179c368c3bb9f78cd9c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/reboot.h>
 #include <linux/kexec.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/crash_dump.h>
 #include <linux/delay.h>
 #include <linux/elf.h>
index e7554154a6de8a3567d14bd4a6d06da4c1347688..3f6464b4d970e48cce597657ca6d77e84967666d 100644 (file)
@@ -5,6 +5,7 @@
  * busses using the iommu infrastructure
  */
 
+#include <linux/export.h>
 #include <asm/iommu.h>
 
 /*
@@ -90,13 +91,27 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
                return 1;
 }
 
+static u64 dma_iommu_get_required_mask(struct device *dev)
+{
+       struct iommu_table *tbl = get_iommu_table_base(dev);
+       u64 mask;
+       if (!tbl)
+               return 0;
+
+       mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1);
+       mask += mask - 1;
+
+       return mask;
+}
+
 struct dma_map_ops dma_iommu_ops = {
-       .alloc_coherent = dma_iommu_alloc_coherent,
-       .free_coherent  = dma_iommu_free_coherent,
-       .map_sg         = dma_iommu_map_sg,
-       .unmap_sg       = dma_iommu_unmap_sg,
-       .dma_supported  = dma_iommu_dma_supported,
-       .map_page       = dma_iommu_map_page,
-       .unmap_page     = dma_iommu_unmap_page,
+       .alloc_coherent         = dma_iommu_alloc_coherent,
+       .free_coherent          = dma_iommu_free_coherent,
+       .map_sg                 = dma_iommu_map_sg,
+       .unmap_sg               = dma_iommu_unmap_sg,
+       .dma_supported          = dma_iommu_dma_supported,
+       .map_page               = dma_iommu_map_page,
+       .unmap_page             = dma_iommu_unmap_page,
+       .get_required_mask      = dma_iommu_get_required_mask,
 };
 EXPORT_SYMBOL(dma_iommu_ops);
index 4295e0b94b2db31238f008c49756955fd4922702..1ebc9189aada9ff21d9268b71e486589010a20a8 100644 (file)
 
 unsigned int ppc_swiotlb_enable;
 
+static u64 swiotlb_powerpc_get_required(struct device *dev)
+{
+       u64 end, mask, max_direct_dma_addr = dev->archdata.max_direct_dma_addr;
+
+       end = memblock_end_of_DRAM();
+       if (max_direct_dma_addr && end > max_direct_dma_addr)
+               end = max_direct_dma_addr;
+       end += get_dma_offset(dev);
+
+       mask = 1ULL << (fls64(end) - 1);
+       mask += mask - 1;
+
+       return mask;
+}
+
 /*
  * At the moment, all platforms that use this code only require
  * swiotlb to be used if we're operating on HIGHMEM.  Since
@@ -44,6 +59,7 @@ struct dma_map_ops swiotlb_dma_ops = {
        .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
        .sync_sg_for_device = swiotlb_sync_sg_for_device,
        .mapping_error = swiotlb_dma_mapping_error,
+       .get_required_mask = swiotlb_powerpc_get_required,
 };
 
 void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
index 4f0959fbfbee02d4538427b7be1ab2a988adeb9d..7d0233c12ee3febac282f37083648ce703cbd349 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/dma-debug.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
+#include <linux/export.h>
 #include <asm/bug.h>
 #include <asm/abs_addr.h>
 #include <asm/machdep.h>
@@ -96,6 +97,18 @@ static int dma_direct_dma_supported(struct device *dev, u64 mask)
 #endif
 }
 
+static u64 dma_direct_get_required_mask(struct device *dev)
+{
+       u64 end, mask;
+
+       end = memblock_end_of_DRAM() + get_dma_offset(dev);
+
+       mask = 1ULL << (fls64(end) - 1);
+       mask += mask - 1;
+
+       return mask;
+}
+
 static inline dma_addr_t dma_direct_map_page(struct device *dev,
                                             struct page *page,
                                             unsigned long offset,
@@ -137,13 +150,14 @@ static inline void dma_direct_sync_single(struct device *dev,
 #endif
 
 struct dma_map_ops dma_direct_ops = {
-       .alloc_coherent = dma_direct_alloc_coherent,
-       .free_coherent  = dma_direct_free_coherent,
-       .map_sg         = dma_direct_map_sg,
-       .unmap_sg       = dma_direct_unmap_sg,
-       .dma_supported  = dma_direct_dma_supported,
-       .map_page       = dma_direct_map_page,
-       .unmap_page     = dma_direct_unmap_page,
+       .alloc_coherent                 = dma_direct_alloc_coherent,
+       .free_coherent                  = dma_direct_free_coherent,
+       .map_sg                         = dma_direct_map_sg,
+       .unmap_sg                       = dma_direct_unmap_sg,
+       .dma_supported                  = dma_direct_dma_supported,
+       .map_page                       = dma_direct_map_page,
+       .unmap_page                     = dma_direct_unmap_page,
+       .get_required_mask              = dma_direct_get_required_mask,
 #ifdef CONFIG_NOT_COHERENT_CACHE
        .sync_single_for_cpu            = dma_direct_sync_single,
        .sync_single_for_device         = dma_direct_sync_single,
@@ -170,6 +184,23 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
 }
 EXPORT_SYMBOL(dma_set_mask);
 
+u64 dma_get_required_mask(struct device *dev)
+{
+       struct dma_map_ops *dma_ops = get_dma_ops(dev);
+
+       if (ppc_md.dma_get_required_mask)
+               return ppc_md.dma_get_required_mask(dev);
+
+       if (unlikely(dma_ops == NULL))
+               return 0;
+
+       if (dma_ops->get_required_mask)
+               return dma_ops->get_required_mask(dev);
+
+       return DMA_BIT_MASK(8 * sizeof(dma_addr_t));
+}
+EXPORT_SYMBOL_GPL(dma_get_required_mask);
+
 static int __init dma_init(void)
 {
        dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
index 56212bc0ab087c4b40bb21df3496c89849a01f06..4f80cf1ce77b84c30e905bcb8cb8d660c005c22b 100644 (file)
@@ -215,7 +215,22 @@ reenable_mmu:                              /* re-enable mmu so we can */
        stw     r9,8(r1)
        stw     r11,12(r1)
        stw     r3,ORIG_GPR3(r1)
+       /*
+        * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1.
+        * If from user mode there is only one stack frame on the stack, and
+        * accessing CALLER_ADDR1 will cause oops. So we need create a dummy
+        * stack frame to make trace_hardirqs_off happy.
+        */
+       andi.   r12,r12,MSR_PR
+       beq     11f
+       stwu    r1,-16(r1)
+       bl      trace_hardirqs_off
+       addi    r1,r1,16
+       b       12f
+
+11:
        bl      trace_hardirqs_off
+12:
        lwz     r0,GPR0(r1)
        lwz     r3,ORIG_GPR3(r1)
        lwz     r4,GPR4(r1)
index 29ddd8b1c274eb2f32931da320a1c690c2fd1215..cf9c69b9189cb831261a8d8ca0c27d96aacfb89f 100644 (file)
@@ -267,7 +267,7 @@ vsx_unavailable_pSeries_1:
 
 #ifdef CONFIG_CBE_RAS
        STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
-       KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
+       KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
 #endif /* CONFIG_CBE_RAS */
 
        STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
@@ -275,7 +275,7 @@ vsx_unavailable_pSeries_1:
 
 #ifdef CONFIG_CBE_RAS
        STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
-       KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
+       KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
 #endif /* CONFIG_CBE_RAS */
 
        STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
@@ -283,7 +283,7 @@ vsx_unavailable_pSeries_1:
 
 #ifdef CONFIG_CBE_RAS
        STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
-       KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
+       KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
 #endif /* CONFIG_CBE_RAS */
 
        . = 0x3000
@@ -1133,7 +1133,7 @@ _GLOBAL(do_stab_bolted)
        rfid
        b       .       /* prevent speculative execution */
 
-#ifdef CONFIG_PPC_PSERIES
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
  * Data area reserved for FWNMI option.
  * This address (0x7000) is fixed by the RPA.
@@ -1141,7 +1141,7 @@ _GLOBAL(do_stab_bolted)
        .= 0x7000
        .globl fwnmi_data_area
 fwnmi_data_area:
-#endif /* CONFIG_PPC_PSERIES */
+#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 
        /* iSeries does not use the FWNMI stuff, so it is safe to put
         * this here, even if we later allow kernels that will boot on
@@ -1166,9 +1166,12 @@ xLparMap:
 
 #endif /* CONFIG_PPC_ISERIES */
 
-#ifdef CONFIG_PPC_PSERIES
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
+       /* pseries and powernv need to keep the whole page from
+        * 0x7000 to 0x8000 free for use by the firmware
+        */
         . = 0x8000
-#endif /* CONFIG_PPC_PSERIES */
+#endif /* defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) */
 
 /*
  * Space for CPU0's segment table.
@@ -1183,3 +1186,19 @@ xLparMap:
        .globl initial_stab
 initial_stab:
        .space  4096
+#ifdef CONFIG_PPC_POWERNV
+_GLOBAL(opal_mc_secondary_handler)
+       HMT_MEDIUM
+       SET_SCRATCH0(r13)
+       GET_PACA(r13)
+       clrldi  r3,r3,2
+       tovirt(r3,r3)
+       std     r3,PACA_OPAL_MC_EVT(r13)
+       ld      r13,OPAL_MC_SRR0(r3)
+       mtspr   SPRN_SRR0,r13
+       ld      r13,OPAL_MC_SRR1(r3)
+       mtspr   SPRN_SRR1,r13
+       ld      r3,OPAL_MC_GPR3(r3)
+       GET_SCRATCH0(r13)
+       b       machine_check_pSeries
+#endif /* CONFIG_PPC_POWERNV */
index 6b1f4271eb5366a4ce8855b2a1b55ebfd46a4631..2eae4478f7a1d23b0c4808605c1b0bbaeb460e06 100644 (file)
@@ -13,7 +13,8 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/cache.h>
 
 #include <asm/firmware.h>
 
index ba250d505e07d210f21cb26c3ac92ddff0bca6d5..0654dba2c1f18a3582c7dc82854765d776c7dcf0 100644 (file)
@@ -139,8 +139,7 @@ __start:
        trap
 #endif /* CONFIG_PPC_PMAC */
 
-1:     mr      r31,r3                  /* save parameters */
-       mr      r30,r4
+1:     mr      r31,r3                  /* save device tree ptr */
        li      r24,0                   /* cpu # */
 
 /*
@@ -964,8 +963,8 @@ start_here:
  * Do early platform-specific initialization,
  * and set up the MMU.
  */
-       mr      r3,r31
-       mr      r4,r30
+       li      r3,0
+       mr      r4,r31
        bl      machine_init
        bl      __save_cpu_setup
        bl      MMU_init
index a91626d87fc96261a54e3637eab986e80119377c..872a6af83bad56c95cde844fc2044817e8fc8275 100644 (file)
 _ENTRY(_stext);
 _ENTRY(_start);
 
-       /* Save parameters we are passed.
-       */
-       mr      r31,r3
-       mr      r30,r4
-       mr      r29,r5
-       mr      r28,r6
-       mr      r27,r7
+       mr      r31,r3                  /* save device tree ptr */
 
        /* We have to turn on the MMU right away so we get cache modes
         * set correctly.
@@ -849,11 +843,8 @@ start_here:
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
-       mr      r3,r31
-       mr      r4,r30
-       mr      r5,r29
-       mr      r6,r28
-       mr      r7,r27
+       li      r3,0
+       mr      r4,r31
        bl      machine_init
        bl      MMU_init
 
index f8e971ba94f5b66231da5194f125efd35020b5d6..b725dab0f88a01eae1e085e094310e21d898e605 100644 (file)
@@ -61,14 +61,7 @@ _ENTRY(_start);
         * of abatron_pteptrs
         */
        nop
-/*
- * Save parameters we are passed
- */
-       mr      r31,r3
-       mr      r30,r4
-       mr      r29,r5
-       mr      r28,r6
-       mr      r27,r7
+       mr      r31,r3          /* save device tree ptr */
        li      r24,0           /* CPU number */
 
        bl      init_cpu_state
@@ -120,11 +113,8 @@ _ENTRY(_start);
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
-       mr      r3,r31
-       mr      r4,r30
-       mr      r5,r29
-       mr      r6,r28
-       mr      r7,r27
+       li      r3,0
+       mr      r4,r31
        bl      machine_init
        bl      MMU_init
 
index 3564c49c683e1b870da4b7aa455e7155058526d5..06c7251c1bf7df7a617627e45f285ee9562a8f47 100644 (file)
  *  For pSeries or server processors:
  *   1. The MMU is off & open firmware is running in real mode.
  *   2. The kernel is entered at __start
+ * -or- For OPAL entry:
+ *   1. The MMU is off, processor in HV mode, primary CPU enters at 0
+ *      with device-tree in gpr3. We also get OPAL base in r8 and
+ *     entry in r9 for debugging purposes
+ *   2. Secondary processors enter at 0x60 with PIR in gpr3
  *
  *  For iSeries:
  *   1. The MMU is on (as it always is for iSeries)
@@ -331,6 +336,11 @@ _GLOBAL(__start_initialization_multiplatform)
        /* Save parameters */
        mr      r31,r3
        mr      r30,r4
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
+       /* Save OPAL entry */
+       mr      r28,r8
+       mr      r29,r9
+#endif
 
 #ifdef CONFIG_PPC_BOOK3E
        bl      .start_initialization_book3e
@@ -674,9 +684,9 @@ _GLOBAL(enable_64b_mode)
 _GLOBAL(relative_toc)
        mflr    r0
        bcl     20,31,$+4
-0:     mflr    r9
-       ld      r2,(p_toc - 0b)(r9)
-       add     r2,r2,r9
+0:     mflr    r11
+       ld      r2,(p_toc - 0b)(r11)
+       add     r2,r2,r11
        mtlr    r0
        blr
 
@@ -707,6 +717,12 @@ _INIT_STATIC(start_here_multiplatform)
        bdnz    3b
 4:
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
+       /* Setup OPAL entry */
+       std     r28,0(r11);
+       std     r29,8(r11);
+#endif
+
 #ifndef CONFIG_PPC_BOOK3E
        mfmsr   r6
        ori     r6,r6,MSR_RI
index 1cbf64e6b416c1139b1f57582597477aef4cd61d..b68cb173ba2c6a500c37f369b9daadcf8c519d0c 100644 (file)
@@ -76,11 +76,7 @@ _ENTRY(_start);
  */
        .globl  __start
 __start:
-       mr      r31,r3                  /* save parameters */
-       mr      r30,r4
-       mr      r29,r5
-       mr      r28,r6
-       mr      r27,r7
+       mr      r31,r3                  /* save device tree ptr */
 
        /* We have to turn on the MMU right away so we get cache modes
         * set correctly.
@@ -723,11 +719,8 @@ start_here:
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
-       mr      r3,r31
-       mr      r4,r30
-       mr      r5,r29
-       mr      r6,r28
-       mr      r7,r27
+       li      r3,0
+       mr      r4,r31
        bl      machine_init
        bl      MMU_init
 
index 50845924b7d9472ad88b1b5031468ab2493d560a..9f5d210ddf3fd02b94570eec31081d7f246fe0f7 100644 (file)
@@ -63,17 +63,30 @@ _ENTRY(_start);
         * of abatron_pteptrs
         */
        nop
-/*
- * Save parameters we are passed
- */
-       mr      r31,r3
-       mr      r30,r4
-       mr      r29,r5
-       mr      r28,r6
-       mr      r27,r7
-       li      r25,0           /* phys kernel start (low) */
-       li      r24,0           /* CPU number */
-       li      r23,0           /* phys kernel start (high) */
+
+       /* Translate device tree address to physical, save in r30/r31 */
+       mfmsr   r16
+       mfspr   r17,SPRN_PID
+       rlwinm  r17,r17,16,0x3fff0000   /* turn PID into MAS6[SPID] */
+       rlwimi  r17,r16,28,0x00000001   /* turn MSR[DS] into MAS6[SAS] */
+       mtspr   SPRN_MAS6,r17
+
+       tlbsx   0,r3                    /* must succeed */
+
+       mfspr   r16,SPRN_MAS1
+       mfspr   r20,SPRN_MAS3
+       rlwinm  r17,r16,25,0x1f         /* r17 = log2(page size) */
+       li      r18,1024
+       slw     r18,r18,r17             /* r18 = page size */
+       addi    r18,r18,-1
+       and     r19,r3,r18              /* r19 = page offset */
+       andc    r31,r20,r18             /* r31 = page base */
+       or      r31,r31,r19             /* r31 = devtree phys addr */
+       mfspr   r30,SPRN_MAS7
+
+       li      r25,0                   /* phys kernel start (low) */
+       li      r24,0                   /* CPU number */
+       li      r23,0                   /* phys kernel start (high) */
 
 /* We try to not make any assumptions about how the boot loader
  * setup or used the TLBs.  We invalidate all mappings from the
@@ -198,11 +211,8 @@ _ENTRY(__early_start)
 /*
  * Decide what sort of machine this is and initialize the MMU.
  */
-       mr      r3,r31
-       mr      r4,r30
-       mr      r5,r29
-       mr      r6,r28
-       mr      r7,r27
+       mr      r3,r30
+       mr      r4,r31
        bl      machine_init
        bl      MMU_init
 
@@ -236,8 +246,24 @@ _ENTRY(__early_start)
  * if we find the pte (fall through):
  *   r11 is low pte word
  *   r12 is pointer to the pte
+ *   r10 is the pshift from the PGD, if we're a hugepage
  */
 #ifdef CONFIG_PTE_64BIT
+#ifdef CONFIG_HUGETLB_PAGE
+#define FIND_PTE       \
+       rlwinm  r12, r10, 13, 19, 29;   /* Compute pgdir/pmd offset */  \
+       lwzx    r11, r12, r11;          /* Get pgd/pmd entry */         \
+       rlwinm. r12, r11, 0, 0, 20;     /* Extract pt base address */   \
+       blt     1000f;                  /* Normal non-huge page */      \
+       beq     2f;                     /* Bail if no table */          \
+       oris    r11, r11, PD_HUGE@h;    /* Put back address bit */      \
+       andi.   r10, r11, HUGEPD_SHIFT_MASK@l; /* extract size field */ \
+       xor     r12, r10, r11;          /* drop size bits from pointer */ \
+       b       1001f;                                                  \
+1000:  rlwimi  r12, r10, 23, 20, 28;   /* Compute pte address */       \
+       li      r10, 0;                 /* clear r10 */                 \
+1001:  lwz     r11, 4(r12);            /* Get pte entry */
+#else
 #define FIND_PTE       \
        rlwinm  r12, r10, 13, 19, 29;   /* Compute pgdir/pmd offset */  \
        lwzx    r11, r12, r11;          /* Get pgd/pmd entry */         \
@@ -245,7 +271,8 @@ _ENTRY(__early_start)
        beq     2f;                     /* Bail if no table */          \
        rlwimi  r12, r10, 23, 20, 28;   /* Compute pte address */       \
        lwz     r11, 4(r12);            /* Get pte entry */
-#else
+#endif /* HUGEPAGE */
+#else /* !PTE_64BIT */
 #define FIND_PTE       \
        rlwimi  r11, r10, 12, 20, 29;   /* Create L1 (pgdir/pmd) address */     \
        lwz     r11, 0(r11);            /* Get L1 entry */                      \
@@ -402,8 +429,8 @@ interrupt_base:
 
 #ifdef CONFIG_PTE_64BIT
 #ifdef CONFIG_SMP
-       subf    r10,r11,r12             /* create false data dep */
-       lwzx    r13,r11,r10             /* Get upper pte bits */
+       subf    r13,r11,r12             /* create false data dep */
+       lwzx    r13,r11,r13             /* Get upper pte bits */
 #else
        lwz     r13,0(r12)              /* Get upper pte bits */
 #endif
@@ -483,8 +510,8 @@ interrupt_base:
 
 #ifdef CONFIG_PTE_64BIT
 #ifdef CONFIG_SMP
-       subf    r10,r11,r12             /* create false data dep */
-       lwzx    r13,r11,r10             /* Get upper pte bits */
+       subf    r13,r11,r12             /* create false data dep */
+       lwzx    r13,r11,r13             /* Get upper pte bits */
 #else
        lwz     r13,0(r12)              /* Get upper pte bits */
 #endif
@@ -548,7 +575,7 @@ interrupt_base:
 /*
  * Both the instruction and data TLB miss get to this
  * point to load the TLB.
- *     r10 - available to use
+ *     r10 - tsize encoding (if HUGETLB_PAGE) or available to use
  *     r11 - TLB (info from Linux PTE)
  *     r12 - available to use
  *     r13 - upper bits of PTE (if PTE_64BIT) or available to use
@@ -558,21 +585,73 @@ interrupt_base:
  *     Upon exit, we reload everything and RFI.
  */
 finish_tlb_load:
+#ifdef CONFIG_HUGETLB_PAGE
+       cmpwi   6, r10, 0                       /* check for huge page */
+       beq     6, finish_tlb_load_cont         /* !huge */
+
+       /* Alas, we need more scratch registers for hugepages */
+       mfspr   r12, SPRN_SPRG_THREAD
+       stw     r14, THREAD_NORMSAVE(4)(r12)
+       stw     r15, THREAD_NORMSAVE(5)(r12)
+       stw     r16, THREAD_NORMSAVE(6)(r12)
+       stw     r17, THREAD_NORMSAVE(7)(r12)
+
+       /* Get the next_tlbcam_idx percpu var */
+#ifdef CONFIG_SMP
+       lwz     r12, THREAD_INFO-THREAD(r12)
+       lwz     r15, TI_CPU(r12)
+       lis     r14, __per_cpu_offset@h
+       ori     r14, r14, __per_cpu_offset@l
+       rlwinm  r15, r15, 2, 0, 29
+       lwzx    r16, r14, r15
+#else
+       li      r16, 0
+#endif
+       lis     r17, next_tlbcam_idx@h
+       ori     r17, r17, next_tlbcam_idx@l
+       add     r17, r17, r16                   /* r17 = *next_tlbcam_idx */
+       lwz     r15, 0(r17)                     /* r15 = next_tlbcam_idx */
+
+       lis     r14, MAS0_TLBSEL(1)@h           /* select TLB1 (TLBCAM) */
+       rlwimi  r14, r15, 16, 4, 15             /* next_tlbcam_idx entry */
+       mtspr   SPRN_MAS0, r14
+
+       /* Extract TLB1CFG(NENTRY) */
+       mfspr   r16, SPRN_TLB1CFG
+       andi.   r16, r16, 0xfff
+
+       /* Update next_tlbcam_idx, wrapping when necessary */
+       addi    r15, r15, 1
+       cmpw    r15, r16
+       blt     100f
+       lis     r14, tlbcam_index@h
+       ori     r14, r14, tlbcam_index@l
+       lwz     r15, 0(r14)
+100:   stw     r15, 0(r17)
+
+       /*
+        * Calc MAS1_TSIZE from r10 (which has pshift encoded)
+        * tlb_enc = (pshift - 10).
+        */
+       subi    r15, r10, 10
+       mfspr   r16, SPRN_MAS1
+       rlwimi  r16, r15, 7, 20, 24
+       mtspr   SPRN_MAS1, r16
+
+       /* copy the pshift for use later */
+       mr      r14, r10
+
+       /* fall through */
+
+#endif /* CONFIG_HUGETLB_PAGE */
+
        /*
         * We set execute, because we don't have the granularity to
         * properly set this at the page level (Linux problem).
         * Many of these bits are software only.  Bits we don't set
         * here we (properly should) assume have the appropriate value.
         */
-
-       mfspr   r12, SPRN_MAS2
-#ifdef CONFIG_PTE_64BIT
-       rlwimi  r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */
-#else
-       rlwimi  r12, r11, 26, 27, 31    /* extract WIMGE from pte */
-#endif
-       mtspr   SPRN_MAS2, r12
-
+finish_tlb_load_cont:
 #ifdef CONFIG_PTE_64BIT
        rlwinm  r12, r11, 32-2, 26, 31  /* Move in perm bits */
        andi.   r10, r11, _PAGE_DIRTY
@@ -581,22 +660,40 @@ finish_tlb_load:
        andc    r12, r12, r10
 1:     rlwimi  r12, r13, 20, 0, 11     /* grab RPN[32:43] */
        rlwimi  r12, r11, 20, 12, 19    /* grab RPN[44:51] */
-       mtspr   SPRN_MAS3, r12
+2:     mtspr   SPRN_MAS3, r12
 BEGIN_MMU_FTR_SECTION
        srwi    r10, r13, 12            /* grab RPN[12:31] */
        mtspr   SPRN_MAS7, r10
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
 #else
        li      r10, (_PAGE_EXEC | _PAGE_PRESENT)
+       mr      r13, r11
        rlwimi  r10, r11, 31, 29, 29    /* extract _PAGE_DIRTY into SW */
        and     r12, r11, r10
        andi.   r10, r11, _PAGE_USER    /* Test for _PAGE_USER */
        slwi    r10, r12, 1
        or      r10, r10, r12
        iseleq  r12, r12, r10
-       rlwimi  r11, r12, 0, 20, 31     /* Extract RPN from PTE and merge with perms */
-       mtspr   SPRN_MAS3, r11
+       rlwimi  r13, r12, 0, 20, 31     /* Get RPN from PTE, merge w/ perms */
+       mtspr   SPRN_MAS3, r13
 #endif
+
+       mfspr   r12, SPRN_MAS2
+#ifdef CONFIG_PTE_64BIT
+       rlwimi  r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */
+#else
+       rlwimi  r12, r11, 26, 27, 31    /* extract WIMGE from pte */
+#endif
+#ifdef CONFIG_HUGETLB_PAGE
+       beq     6, 3f                   /* don't mask if page isn't huge */
+       li      r13, 1
+       slw     r13, r13, r14
+       subi    r13, r13, 1
+       rlwinm  r13, r13, 0, 0, 19      /* bottom bits used for WIMGE/etc */
+       andc    r12, r12, r13           /* mask off ea bits within the page */
+#endif
+3:     mtspr   SPRN_MAS2, r12
+
 #ifdef CONFIG_E200
        /* Round robin TLB1 entries assignment */
        mfspr   r12, SPRN_MAS0
@@ -622,11 +719,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
        mtspr   SPRN_MAS0,r12
 #endif /* CONFIG_E200 */
 
+tlb_write_entry:
        tlbwe
 
        /* Done...restore registers and get out of here.  */
        mfspr   r10, SPRN_SPRG_THREAD
-       lwz     r11, THREAD_NORMSAVE(3)(r10)
+#ifdef CONFIG_HUGETLB_PAGE
+       beq     6, 8f /* skip restore for 4k page faults */
+       lwz     r14, THREAD_NORMSAVE(4)(r10)
+       lwz     r15, THREAD_NORMSAVE(5)(r10)
+       lwz     r16, THREAD_NORMSAVE(6)(r10)
+       lwz     r17, THREAD_NORMSAVE(7)(r10)
+#endif
+8:     lwz     r11, THREAD_NORMSAVE(3)(r10)
        mtcr    r11
        lwz     r13, THREAD_NORMSAVE(2)(r10)
        lwz     r12, THREAD_NORMSAVE(1)(r10)
index 5ecd0401cdb18e866029cd87932350378ac9d2aa..2bc0584be81c1441b5519fae9c82e4fc2ed08bff 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/kprobes.h>
 #include <linux/percpu.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/smp.h>
index 28581f1ad2c08a8494502e2335cfeef2a295577e..d39ae606ff8db4e0cc7286cb6393ca9dace0ab4b 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/console.h>
 #include <linux/kobject.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/of_platform.h>
 #include <asm/ibmebus.h>
 #include <asm/abs_addr.h>
@@ -125,17 +127,23 @@ static void ibmebus_unmap_sg(struct device *dev,
 
 static int ibmebus_dma_supported(struct device *dev, u64 mask)
 {
-       return 1;
+       return mask == DMA_BIT_MASK(64);
+}
+
+static u64 ibmebus_dma_get_required_mask(struct device *dev)
+{
+       return DMA_BIT_MASK(64);
 }
 
 static struct dma_map_ops ibmebus_dma_ops = {
-       .alloc_coherent = ibmebus_alloc_coherent,
-       .free_coherent  = ibmebus_free_coherent,
-       .map_sg         = ibmebus_map_sg,
-       .unmap_sg       = ibmebus_unmap_sg,
-       .dma_supported  = ibmebus_dma_supported,
-       .map_page       = ibmebus_map_page,
-       .unmap_page     = ibmebus_unmap_page,
+       .alloc_coherent     = ibmebus_alloc_coherent,
+       .free_coherent      = ibmebus_free_coherent,
+       .map_sg             = ibmebus_map_sg,
+       .unmap_sg           = ibmebus_unmap_sg,
+       .dma_supported      = ibmebus_dma_supported,
+       .get_required_mask  = ibmebus_dma_get_required_mask,
+       .map_page           = ibmebus_map_page,
+       .unmap_page         = ibmebus_unmap_page,
 };
 
 static int ibmebus_match_path(struct device *dev, void *data)
index 3e2b95c6ae6733e807816bd4f49b339f2df9dd77..4f0ab85f37883b9487ea23d46dc405e79f53f163 100644 (file)
@@ -26,7 +26,7 @@ _GLOBAL(e500_idle)
        ori     r4,r4,_TLF_NAPPING      /* so when we take an exception */
        stw     r4,TI_LOCAL_FLAGS(r3)   /* it will return to our caller */
 
-#ifdef CONFIG_E500MC
+#ifdef CONFIG_PPC_E500MC
        wrteei  1
 1:     wait
 
index 2375b7eb1c7601e00c102bc538be1ebd54dc4db2..d076d465dbd1e6c5474c3efbab81ec15743d37f8 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init_task.h>
index ffafaea3d261f8f2fbeb3ee45cd58bc958e40572..12d329bcbb9825cbad17618460e22d4c2b0d5cdf 100644 (file)
@@ -12,6 +12,7 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
+#include <linux/sched.h>       /* for init_mm */
 
 #include <asm/io.h>
 #include <asm/machdep.h>
index 8dc7547c23775ecbf4442243fea98c3b443d6121..886381f32c3d45e9988a614fd3ba58b04249a52f 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/io.h>
 #include <asm/firmware.h>
index b25f6325fc7090a5e02e9731bbadd49b6c65f9dd..262791807397375612e29860ae64e5d86ee6cc6a 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/mm.h>
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/pci-bridge.h>
 
index 961bb03413f38cad337f7617b689e83f2185013b..0cfcf98aafca25e3e9cb1c210ad4f149601a9bd9 100644 (file)
@@ -501,6 +501,14 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
        tbl->it_map = page_address(page);
        memset(tbl->it_map, 0, sz);
 
+       /*
+        * Reserve page 0 so it will not be used for any mappings.
+        * This avoids buggy drivers that consider page 0 to be invalid
+        * to crash the machine or even lose data.
+        */
+       if (tbl->it_offset == 0)
+               set_bit(0, tbl->it_map);
+
        tbl->it_hint = 0;
        tbl->it_largehint = tbl->it_halfpoint;
        spin_lock_init(&tbl->it_lock);
index d281fb6f12f36e291c50c492774d8325c61b3081..5c3c46948d9400c3abe923265049e5b90994330c 100644 (file)
@@ -30,7 +30,7 @@
 
 #undef DEBUG
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/threads.h>
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
index 4d5731b2429aa605f6776a8674d6c7e4a40d5520..479752901ec6764df5f57bca5ee3136244d600bb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/notifier.h>
index 368d158d665d5e44942f403d5a3710413ece52d2..a1ed8a8c7cb42c83fc61c674735f1f7d6bbe3842 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/jump_label.h>
 #include <asm/code-patching.h>
 
+#ifdef HAVE_JUMP_LABEL
 void arch_jump_label_transform(struct jump_entry *entry,
                               enum jump_label_type type)
 {
@@ -21,3 +22,4 @@ void arch_jump_label_transform(struct jump_entry *entry,
        else
                patch_instruction(addr, PPC_INST_NOP);
 }
+#endif
index b06bdae04064f59d2c4c4c98e76304dee6ca98c8..2985338d0e10164e3b77ab12fcc3bb755a1a6fb3 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/kvm_para.h>
 #include <linux/slab.h>
 #include <linux/of.h>
@@ -131,7 +132,6 @@ static void kvm_patch_ins_b(u32 *inst, int addr)
        /* On relocatable kernels interrupts handlers and our code
           can be in different regions, so we don't patch them */
 
-       extern u32 __end_interrupts;
        if ((ulong)inst < (ulong)&__end_interrupts)
                return;
 #endif
index 2b97b80d6d7d65911f951276eec81029cda748e6..c7b5afeecaf281132e80a0b218dab62a53a7b9ea 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/pci.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/serial_reg.h>
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <asm/prom.h>
@@ -47,6 +48,24 @@ static struct __initdata of_device_id legacy_serial_parents[] = {
 static unsigned int legacy_serial_count;
 static int legacy_serial_console = -1;
 
+static unsigned int tsi_serial_in(struct uart_port *p, int offset)
+{
+       unsigned int tmp;
+       offset = offset << p->regshift;
+       if (offset == UART_IIR) {
+               tmp = readl(p->membase + (UART_IIR & ~3));
+               return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
+       } else
+               return readb(p->membase + offset);
+}
+
+static void tsi_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = offset << p->regshift;
+       if (!((offset == UART_IER) && (value & UART_IER_UUE)))
+               writeb(value, p->membase + offset);
+}
+
 static int __init add_legacy_port(struct device_node *np, int want_index,
                                  int iotype, phys_addr_t base,
                                  phys_addr_t taddr, unsigned long irq,
@@ -102,6 +121,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
                legacy_serial_ports[index].iobase = base;
        else
                legacy_serial_ports[index].mapbase = base;
+
        legacy_serial_ports[index].iotype = iotype;
        legacy_serial_ports[index].uartclk = clock;
        legacy_serial_ports[index].irq = irq;
@@ -112,6 +132,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
        legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0;
        legacy_serial_infos[index].irq_check_parent = irq_check_parent;
 
+       if (iotype == UPIO_TSI) {
+               legacy_serial_ports[index].serial_in = tsi_serial_in;
+               legacy_serial_ports[index].serial_out = tsi_serial_out;
+       }
+
        printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
               index, np->full_name);
        printk(KERN_DEBUG "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
index 583af70c4b144a47dbe06549b3df409fe46a27cf..26ccbf77dd4124958f83808b002e3a0176b3f6d4 100644 (file)
@@ -74,8 +74,7 @@ int default_machine_kexec_prepare(struct kimage *image)
        }
 
        /* We also should not overwrite the tce tables */
-       for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
-                       node = of_find_node_by_type(node, "pci")) {
+       for_each_node_by_type(node, "pci") {
                basep = of_get_property(node, "linux,tce-base", NULL);
                sizep = of_get_property(node, "linux,tce-size", NULL);
                if (basep == NULL || sizep == NULL)
index 998a100286086a289f569a0f83346df8feacd53e..7cd07b42ca1a505c9a9bfbb3802277336537a514 100644 (file)
@@ -8,6 +8,8 @@
  * kexec bits:
  * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
  * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ * PPC44x port. Copyright (C) 2011,  IBM Corporation
+ *             Author: Suzuki Poulose <suzuki@in.ibm.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -735,6 +737,175 @@ relocate_new_kernel:
        mr      r4, r30
        mr      r5, r31
 
+       li      r0, 0
+#elif defined(CONFIG_44x)  && !defined(CONFIG_PPC_47x)
+
+/*
+ * Code for setting up 1:1 mapping for PPC440x for KEXEC
+ *
+ * We cannot switch off the MMU on PPC44x.
+ * So we:
+ * 1) Invalidate all the mappings except the one we are running from.
+ * 2) Create a tmp mapping for our code in the other address space(TS) and
+ *    jump to it. Invalidate the entry we started in.
+ * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS.
+ * 4) Jump to the 1:1 mapping in original TS.
+ * 5) Invalidate the tmp mapping.
+ *
+ * - Based on the kexec support code for FSL BookE
+ * - Doesn't support 47x yet.
+ *
+ */
+       /* Save our parameters */
+       mr      r29, r3
+       mr      r30, r4
+       mr      r31, r5
+
+       /* Load our MSR_IS and TID to MMUCR for TLB search */
+       mfspr   r3,SPRN_PID
+       mfmsr   r4
+       andi.   r4,r4,MSR_IS@l
+       beq     wmmucr
+       oris    r3,r3,PPC44x_MMUCR_STS@h
+wmmucr:
+       mtspr   SPRN_MMUCR,r3
+       sync
+
+       /*
+        * Invalidate all the TLB entries except the current entry
+        * where we are running from
+        */
+       bl      0f                              /* Find our address */
+0:     mflr    r5                              /* Make it accessible */
+       tlbsx   r23,0,r5                        /* Find entry we are in */
+       li      r4,0                            /* Start at TLB entry 0 */
+       li      r3,0                            /* Set PAGEID inval value */
+1:     cmpw    r23,r4                          /* Is this our entry? */
+       beq     skip                            /* If so, skip the inval */
+       tlbwe   r3,r4,PPC44x_TLB_PAGEID         /* If not, inval the entry */
+skip:
+       addi    r4,r4,1                         /* Increment */
+       cmpwi   r4,64                           /* Are we done? */
+       bne     1b                              /* If not, repeat */
+       isync
+
+       /* Create a temp mapping and jump to it */
+       andi.   r6, r23, 1              /* Find the index to use */
+       addi    r24, r6, 1              /* r24 will contain 1 or 2 */
+
+       mfmsr   r9                      /* get the MSR */
+       rlwinm  r5, r9, 27, 31, 31      /* Extract the MSR[IS] */
+       xori    r7, r5, 1               /* Use the other address space */
+
+       /* Read the current mapping entries */
+       tlbre   r3, r23, PPC44x_TLB_PAGEID
+       tlbre   r4, r23, PPC44x_TLB_XLAT
+       tlbre   r5, r23, PPC44x_TLB_ATTRIB
+
+       /* Save our current XLAT entry */
+       mr      r25, r4
+
+       /* Extract the TLB PageSize */
+       li      r10, 1                  /* r10 will hold PageSize */
+       rlwinm  r11, r3, 0, 24, 27      /* bits 24-27 */
+
+       /* XXX: As of now we use 256M, 4K pages */
+       cmpwi   r11, PPC44x_TLB_256M
+       bne     tlb_4k
+       rotlwi  r10, r10, 28            /* r10 = 256M */
+       b       write_out
+tlb_4k:
+       cmpwi   r11, PPC44x_TLB_4K
+       bne     default
+       rotlwi  r10, r10, 12            /* r10 = 4K */
+       b       write_out
+default:
+       rotlwi  r10, r10, 10            /* r10 = 1K */
+
+write_out:
+       /*
+        * Write out the tmp 1:1 mapping for this code in other address space
+        * Fixup  EPN = RPN , TS=other address space
+        */
+       insrwi  r3, r7, 1, 23           /* Bit 23 is TS for PAGEID field */
+
+       /* Write out the tmp mapping entries */
+       tlbwe   r3, r24, PPC44x_TLB_PAGEID
+       tlbwe   r4, r24, PPC44x_TLB_XLAT
+       tlbwe   r5, r24, PPC44x_TLB_ATTRIB
+
+       subi    r11, r10, 1             /* PageOffset Mask = PageSize - 1 */
+       not     r10, r11                /* Mask for PageNum */
+
+       /* Switch to other address space in MSR */
+       insrwi  r9, r7, 1, 26           /* Set MSR[IS] = r7 */
+
+       bl      1f
+1:     mflr    r8
+       addi    r8, r8, (2f-1b)         /* Find the target offset */
+
+       /* Jump to the tmp mapping */
+       mtspr   SPRN_SRR0, r8
+       mtspr   SPRN_SRR1, r9
+       rfi
+
+2:
+       /* Invalidate the entry we were executing from */
+       li      r3, 0
+       tlbwe   r3, r23, PPC44x_TLB_PAGEID
+
+       /* attribute fields. rwx for SUPERVISOR mode */
+       li      r5, 0
+       ori     r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+       /* Create 1:1 mapping in 256M pages */
+       xori    r7, r7, 1                       /* Revert back to Original TS */
+
+       li      r8, 0                           /* PageNumber */
+       li      r6, 3                           /* TLB Index, start at 3  */
+
+next_tlb:
+       rotlwi  r3, r8, 28                      /* Create EPN (bits 0-3) */
+       mr      r4, r3                          /* RPN = EPN  */
+       ori     r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */
+       insrwi  r3, r7, 1, 23                   /* Set TS from r7 */
+
+       tlbwe   r3, r6, PPC44x_TLB_PAGEID       /* PageID field : EPN, V, SIZE */
+       tlbwe   r4, r6, PPC44x_TLB_XLAT         /* Address translation : RPN   */
+       tlbwe   r5, r6, PPC44x_TLB_ATTRIB       /* Attributes */
+
+       addi    r8, r8, 1                       /* Increment PN */
+       addi    r6, r6, 1                       /* Increment TLB Index */
+       cmpwi   r8, 8                           /* Are we done ? */
+       bne     next_tlb
+       isync
+
+       /* Jump to the new mapping 1:1 */
+       li      r9,0
+       insrwi  r9, r7, 1, 26                   /* Set MSR[IS] = r7 */
+
+       bl      1f
+1:     mflr    r8
+       and     r8, r8, r11                     /* Get our offset within page */
+       addi    r8, r8, (2f-1b)
+
+       and     r5, r25, r10                    /* Get our target PageNum */
+       or      r8, r8, r5                      /* Target jump address */
+
+       mtspr   SPRN_SRR0, r8
+       mtspr   SPRN_SRR1, r9
+       rfi
+2:
+       /* Invalidate the tmp entry we used */
+       li      r3, 0
+       tlbwe   r3, r24, PPC44x_TLB_PAGEID
+       sync
+
+       /* Restore the parameters */
+       mr      r3, r29
+       mr      r4, r30
+       mr      r5, r31
+
        li      r0, 0
 #else
        li      r0, 0
index a1cd701b5753d19f2e83b4330560c1020bcfccf2..2d275707f419db519910a5b8549a3f9f016d8eab 100644 (file)
@@ -16,7 +16,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include <linux/module.h>
 #include <linux/elf.h>
 #include <linux/moduleloader.h>
 #include <linux/err.h>
index 59dbf6abaaf3140f59b37f7c7bfabbbf3e3f2508..e1612dfb4a930eca385a841bbbc967cb90c15b11 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mod_devicetable.h>
 #include <linux/pci.h>
 #include <linux/of.h>
index 0a5a899846bb283d8632f82ca0648045828ed43e..41456ff55e14f6b1fb6868621e77650989f32d7b 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/smp.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/memblock.h>
 
 #include <asm/firmware.h>
index 32656f105250a4d6b44af65a47688aa1a1f7e687..458ed3bee663ef0d1befcc6c717cf0b689a7166f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/mm.h>
@@ -1730,6 +1731,17 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
 
        if (mode == PCI_PROBE_NORMAL)
                hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+
+       /* Configure PCI Express settings */
+       if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
+               struct pci_bus *child;
+               list_for_each_entry(child, &bus->children, node) {
+                       struct pci_dev *self = child->self;
+                       if (!self)
+                               continue;
+                       pcie_bus_configure_settings(child, self->pcie_mpss);
+               }
+       }
 }
 
 static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
index bb154511db5eb2ab484fe390973bd759a5b5fc7b..fdd1a3d951dcaf50b5e63b72901ef507b9f19a90 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/of.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/io.h>
index ab34046752bf463a232947f6f4014698e14e0f46..bcf4bf9e72d9d658d8ed3dbb0f9d10677d0c8277 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
index 478f8d78716b63eec5c13746be28178bb5d44ab5..4e69deb89b37b752bfaa74aae679ecee82667aa7 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
 
index fe0a5ad6f73e406ef338521a1badae78b33f6f64..b37d0b5a796e941fb079a737936dbb1fa29e1179 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
 
index 461499b43cff4efc29ea5996f6dafa200aaba872..a841a9d136a2fb4401b743ac42a2acad039f7e87 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/errno.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/cputable.h>
index 03b95e2c6d6549616aef1e4f0cd2747c5bb11e00..0bbc901e7efc6ad20ef694ae0241ec38c3a2e7ff 100644 (file)
@@ -487,8 +487,8 @@ static int power6_generic_events[] = {
  */
 static int power6_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
        [C(L1D)] = {            /*      RESULT_ACCESS   RESULT_MISS */
-               [C(OP_READ)] = {        0x80082,        0x80080         },
-               [C(OP_WRITE)] = {       0x80086,        0x80088         },
+               [C(OP_READ)] = {        0x280030,       0x80080         },
+               [C(OP_WRITE)] = {       0x180032,       0x80088         },
                [C(OP_PREFETCH)] = {    0x810a4,        0               },
        },
        [C(L1I)] = {            /*      RESULT_ACCESS   RESULT_MISS */
index de83d6060dda5765c427db94c2261da3e48f3fe3..1251e4d7e2627b891475cea5231c5f977ef819e7 100644 (file)
@@ -297,6 +297,8 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[])
 
 static int power7_generic_events[] = {
        [PERF_COUNT_HW_CPU_CYCLES] = 0x1e,
+       [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x100f8, /* GCT_NOSLOT_CYC */
+       [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x4000a,  /* CMPLU_STALL */
        [PERF_COUNT_HW_INSTRUCTIONS] = 2,
        [PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880,      /* LD_REF_L1_LSU*/
        [PERF_COUNT_HW_CACHE_MISSES] = 0x400f0,         /* LD_MISS_L1   */
index f5ae872a2ef0da5afc1a6c01fc7627b97121bc1f..d3114a71dd32279e5ac92eeba75244821162f202 100644 (file)
@@ -1,4 +1,4 @@
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/threads.h>
 #include <linux/smp.h>
 #include <linux/sched.h>
index 8f53954e75a3872f2ca78415634a7b8430f569c5..6457574c0b2f32fbaa800b11eeed0cbd8877a77e 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/init.h>
 #include <linux/prctl.h>
 #include <linux/init_task.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kallsyms.h>
 #include <linux/mqueue.h>
 #include <linux/hardirq.h>
@@ -486,28 +486,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
        new_thread = &new->thread;
        old_thread = &current->thread;
 
-#if defined(CONFIG_PPC_BOOK3E_64)
-       /* XXX Current Book3E code doesn't deal with kernel side DBCR0,
-        * we always hold the user values, so we set it now.
-        *
-        * However, we ensure the kernel MSR:DE is appropriately cleared too
-        * to avoid spurrious single step exceptions in the kernel.
-        *
-        * This will have to change to merge with the ppc32 code at some point,
-        * but I don't like much what ppc32 is doing today so there's some
-        * thinking needed there
-        */
-       if ((new_thread->dbcr0 | old_thread->dbcr0) & DBCR0_IDM) {
-               u32 dbcr0;
-
-               mtmsr(mfmsr() & ~MSR_DE);
-               isync();
-               dbcr0 = mfspr(SPRN_DBCR0);
-               dbcr0 = (dbcr0 & DBCR0_EDM) | new_thread->dbcr0;
-               mtspr(SPRN_DBCR0, dbcr0);
-       }
-#endif /* CONFIG_PPC64_BOOK3E */
-
 #ifdef CONFIG_PPC64
        /*
         * Collect processor utilization data per process
@@ -657,7 +635,7 @@ void show_regs(struct pt_regs * regs)
        if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
                printk("CFAR: "REG"\n", regs->orig_gpr3);
        if (trap == 0x300 || trap == 0x600)
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
                printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
 #else
                printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr);
index 174e1e96175e8b5a9153648442abb426764edc35..fa1235b0503bd9fd0ae819afc94838d7f4905005 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/delay.h>
 #include <linux/initrd.h>
 #include <linux/bitops.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kexec.h>
 #include <linux/debugfs.h>
 #include <linux/irq.h>
@@ -54,6 +54,8 @@
 #include <asm/pci-bridge.h>
 #include <asm/phyp_dump.h>
 #include <asm/kexec.h>
+#include <asm/opal.h>
+
 #include <mm/mmu_decl.h>
 
 #ifdef DEBUG
@@ -707,11 +709,23 @@ void __init early_init_devtree(void *params)
        of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
 #endif
 
+#ifdef CONFIG_PPC_POWERNV
+       /* Some machines might need OPAL info for debugging, grab it now. */
+       of_scan_flat_dt(early_init_dt_scan_opal, NULL);
+#endif
+
 #ifdef CONFIG_PHYP_DUMP
        /* scan tree to see if dump occurred during last boot */
        of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
 #endif
 
+       /* Pre-initialize the cmd_line with the content of boot_commmand_line,
+        * which will be empty except when the content of the variable has
+        * been overriden by a bootloading mechanism. This happens typically
+        * with HAL takeover
+        */
+       strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+
        /* Retrieve various informations from the /chosen node of the
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
@@ -723,12 +737,15 @@ void __init early_init_devtree(void *params)
 
        of_scan_flat_dt(early_init_dt_scan_root, NULL);
        of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
-       setup_initial_memory_limit(memstart_addr, first_memblock_size);
 
        /* Save command line for /proc/cmdline and then parse parameters */
        strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
        parse_early_param();
 
+       /* make sure we've parsed cmdline for mem= before this */
+       if (memory_limit)
+               first_memblock_size = min(first_memblock_size, memory_limit);
+       setup_initial_memory_limit(memstart_addr, first_memblock_size);
        /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
        memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
        /* If relocatable, reserve first 32k for interrupt vectors etc. */
index a909f4e9343bd05d0dd044bf940ffce5f488abb6..cc584865b3df537d7c50cfb2bda9d87a6ed24f85 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/btext.h>
 #include <asm/sections.h>
 #include <asm/machdep.h>
+#include <asm/opal.h>
 
 #include <linux/linux_logo.h>
 
@@ -139,7 +140,9 @@ struct mem_map_entry {
 
 typedef u32 cell_t;
 
-extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
+extern void __start(unsigned long r3, unsigned long r4, unsigned long r5,
+                   unsigned long r6, unsigned long r7, unsigned long r8,
+                   unsigned long r9);
 
 #ifdef CONFIG_PPC64
 extern int enter_prom(struct prom_args *args, unsigned long entry);
@@ -185,6 +188,7 @@ static unsigned long __initdata prom_tce_alloc_end;
 #define PLATFORM_LPAR          0x0001
 #define PLATFORM_POWERMAC      0x0400
 #define PLATFORM_GENERIC       0x0500
+#define PLATFORM_OPAL          0x0600
 
 static int __initdata of_platform;
 
@@ -644,7 +648,7 @@ static void __init early_cmdline_parse(void)
        }
 }
 
-#ifdef CONFIG_PPC_PSERIES
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
  * There are two methods for telling firmware what our capabilities are.
  * Newer machines have an "ibm,client-architecture-support" method on the
@@ -1274,6 +1278,284 @@ static void __init prom_init_mem(void)
        prom_printf("  ram_top      : %x\n", RELOC(ram_top));
 }
 
+static void __init prom_close_stdin(void)
+{
+       struct prom_t *_prom = &RELOC(prom);
+       ihandle val;
+
+       if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
+               call_prom("close", 1, 0, val);
+}
+
+#ifdef CONFIG_PPC_POWERNV
+
+static u64 __initdata prom_opal_size;
+static u64 __initdata prom_opal_align;
+static int __initdata prom_rtas_start_cpu;
+static u64 __initdata prom_rtas_data;
+static u64 __initdata prom_rtas_entry;
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
+static u64 __initdata prom_opal_base;
+static u64 __initdata prom_opal_entry;
+#endif
+
+/* XXX Don't change this structure without updating opal-takeover.S */
+static struct opal_secondary_data {
+       s64                             ack;    /*  0 */
+       u64                             go;     /*  8 */
+       struct opal_takeover_args       args;   /* 16 */
+} opal_secondary_data;
+
+extern char opal_secondary_entry;
+
+static void prom_query_opal(void)
+{
+       long rc;
+
+       /* We must not query for OPAL presence on a machine that
+        * supports TNK takeover (970 blades), as this uses the same
+        * h-call with different arguments and will crash
+        */
+       if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
+                                   ADDR("/tnk-memory-map")))) {
+               prom_printf("TNK takeover detected, skipping OPAL check\n");
+               return;
+       }
+
+       prom_printf("Querying for OPAL presence... ");
+       rc = opal_query_takeover(&RELOC(prom_opal_size),
+                                &RELOC(prom_opal_align));
+       prom_debug("(rc = %ld) ", rc);
+       if (rc != 0) {
+               prom_printf("not there.\n");
+               return;
+       }
+       RELOC(of_platform) = PLATFORM_OPAL;
+       prom_printf(" there !\n");
+       prom_debug("  opal_size  = 0x%lx\n", RELOC(prom_opal_size));
+       prom_debug("  opal_align = 0x%lx\n", RELOC(prom_opal_align));
+       if (RELOC(prom_opal_align) < 0x10000)
+               RELOC(prom_opal_align) = 0x10000;
+}
+
+static int prom_rtas_call(int token, int nargs, int nret, int *outputs, ...)
+{
+       struct rtas_args rtas_args;
+       va_list list;
+       int i;
+
+       rtas_args.token = token;
+       rtas_args.nargs = nargs;
+       rtas_args.nret  = nret;
+       rtas_args.rets  = (rtas_arg_t *)&(rtas_args.args[nargs]);
+       va_start(list, outputs);
+       for (i = 0; i < nargs; ++i)
+               rtas_args.args[i] = va_arg(list, rtas_arg_t);
+       va_end(list);
+
+       for (i = 0; i < nret; ++i)
+               rtas_args.rets[i] = 0;
+
+       opal_enter_rtas(&rtas_args, RELOC(prom_rtas_data),
+                       RELOC(prom_rtas_entry));
+
+       if (nret > 1 && outputs != NULL)
+               for (i = 0; i < nret-1; ++i)
+                       outputs[i] = rtas_args.rets[i+1];
+       return (nret > 0)? rtas_args.rets[0]: 0;
+}
+
+static void __init prom_opal_hold_cpus(void)
+{
+       int i, cnt, cpu, rc;
+       long j;
+       phandle node;
+       char type[64];
+       u32 servers[8];
+       struct prom_t *_prom = &RELOC(prom);
+       void *entry = (unsigned long *)&RELOC(opal_secondary_entry);
+       struct opal_secondary_data *data = &RELOC(opal_secondary_data);
+
+       prom_debug("prom_opal_hold_cpus: start...\n");
+       prom_debug("    - entry       = 0x%x\n", entry);
+       prom_debug("    - data        = 0x%x\n", data);
+
+       data->ack = -1;
+       data->go = 0;
+
+       /* look for cpus */
+       for (node = 0; prom_next_node(&node); ) {
+               type[0] = 0;
+               prom_getprop(node, "device_type", type, sizeof(type));
+               if (strcmp(type, RELOC("cpu")) != 0)
+                       continue;
+
+               /* Skip non-configured cpus. */
+               if (prom_getprop(node, "status", type, sizeof(type)) > 0)
+                       if (strcmp(type, RELOC("okay")) != 0)
+                               continue;
+
+               cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
+                            sizeof(servers));
+               if (cnt == PROM_ERROR)
+                       break;
+               cnt >>= 2;
+               for (i = 0; i < cnt; i++) {
+                       cpu = servers[i];
+                       prom_debug("CPU %d ... ", cpu);
+                       if (cpu == _prom->cpu) {
+                               prom_debug("booted !\n");
+                               continue;
+                       }
+                       prom_debug("starting ... ");
+
+                       /* Init the acknowledge var which will be reset by
+                        * the secondary cpu when it awakens from its OF
+                        * spinloop.
+                        */
+                       data->ack = -1;
+                       rc = prom_rtas_call(RELOC(prom_rtas_start_cpu), 3, 1,
+                                           NULL, cpu, entry, data);
+                       prom_debug("rtas rc=%d ...", rc);
+
+                       for (j = 0; j < 100000000 && data->ack == -1; j++) {
+                               HMT_low();
+                               mb();
+                       }
+                       HMT_medium();
+                       if (data->ack != -1)
+                               prom_debug("done, PIR=0x%x\n", data->ack);
+                       else
+                               prom_debug("timeout !\n");
+               }
+       }
+       prom_debug("prom_opal_hold_cpus: end...\n");
+}
+
+static void prom_opal_takeover(void)
+{
+       struct opal_secondary_data *data = &RELOC(opal_secondary_data);
+       struct opal_takeover_args *args = &data->args;
+       u64 align = RELOC(prom_opal_align);
+       u64 top_addr, opal_addr;
+
+       args->k_image   = (u64)RELOC(_stext);
+       args->k_size    = _end - _stext;
+       args->k_entry   = 0;
+       args->k_entry2  = 0x60;
+
+       top_addr = _ALIGN_UP(args->k_size, align);
+
+       if (RELOC(prom_initrd_start) != 0) {
+               args->rd_image = RELOC(prom_initrd_start);
+               args->rd_size = RELOC(prom_initrd_end) - args->rd_image;
+               args->rd_loc = top_addr;
+               top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
+       }
+
+       /* Pickup an address for the HAL. We want to go really high
+        * up to avoid problem with future kexecs. On the other hand
+        * we don't want to be all over the TCEs on P5IOC2 machines
+        * which are going to be up there too. We assume the machine
+        * has plenty of memory, and we ask for the HAL for now to
+        * be just below the 1G point, or above the initrd
+        */
+       opal_addr = _ALIGN_DOWN(0x40000000 - RELOC(prom_opal_size), align);
+       if (opal_addr < top_addr)
+               opal_addr = top_addr;
+       args->hal_addr = opal_addr;
+
+       /* Copy the command line to the kernel image */
+       strlcpy(RELOC(boot_command_line), RELOC(prom_cmd_line),
+               COMMAND_LINE_SIZE);
+
+       prom_debug("  k_image    = 0x%lx\n", args->k_image);
+       prom_debug("  k_size     = 0x%lx\n", args->k_size);
+       prom_debug("  k_entry    = 0x%lx\n", args->k_entry);
+       prom_debug("  k_entry2   = 0x%lx\n", args->k_entry2);
+       prom_debug("  hal_addr   = 0x%lx\n", args->hal_addr);
+       prom_debug("  rd_image   = 0x%lx\n", args->rd_image);
+       prom_debug("  rd_size    = 0x%lx\n", args->rd_size);
+       prom_debug("  rd_loc     = 0x%lx\n", args->rd_loc);
+       prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
+       prom_close_stdin();
+       mb();
+       data->go = 1;
+       for (;;)
+               opal_do_takeover(args);
+}
+
+/*
+ * Allocate room for and instantiate OPAL
+ */
+static void __init prom_instantiate_opal(void)
+{
+       phandle opal_node;
+       ihandle opal_inst;
+       u64 base, entry;
+       u64 size = 0, align = 0x10000;
+       u32 rets[2];
+
+       prom_debug("prom_instantiate_opal: start...\n");
+
+       opal_node = call_prom("finddevice", 1, 1, ADDR("/ibm,opal"));
+       prom_debug("opal_node: %x\n", opal_node);
+       if (!PHANDLE_VALID(opal_node))
+               return;
+
+       prom_getprop(opal_node, "opal-runtime-size", &size, sizeof(size));
+       if (size == 0)
+               return;
+       prom_getprop(opal_node, "opal-runtime-alignment", &align,
+                    sizeof(align));
+
+       base = alloc_down(size, align, 0);
+       if (base == 0) {
+               prom_printf("OPAL allocation failed !\n");
+               return;
+       }
+
+       opal_inst = call_prom("open", 1, 1, ADDR("/ibm,opal"));
+       if (!IHANDLE_VALID(opal_inst)) {
+               prom_printf("opening opal package failed (%x)\n", opal_inst);
+               return;
+       }
+
+       prom_printf("instantiating opal at 0x%x...", base);
+
+       if (call_prom_ret("call-method", 4, 3, rets,
+                         ADDR("load-opal-runtime"),
+                         opal_inst,
+                         base >> 32, base & 0xffffffff) != 0
+           || (rets[0] == 0 && rets[1] == 0)) {
+               prom_printf(" failed\n");
+               return;
+       }
+       entry = (((u64)rets[0]) << 32) | rets[1];
+
+       prom_printf(" done\n");
+
+       reserve_mem(base, size);
+
+       prom_debug("opal base     = 0x%x\n", base);
+       prom_debug("opal align    = 0x%x\n", align);
+       prom_debug("opal entry    = 0x%x\n", entry);
+       prom_debug("opal size     = 0x%x\n", (long)size);
+
+       prom_setprop(opal_node, "/ibm,opal", "opal-base-address",
+                    &base, sizeof(base));
+       prom_setprop(opal_node, "/ibm,opal", "opal-entry-address",
+                    &entry, sizeof(entry));
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
+       RELOC(prom_opal_base) = base;
+       RELOC(prom_opal_entry) = entry;
+#endif
+       prom_debug("prom_instantiate_opal: end...\n");
+}
+
+#endif /* CONFIG_PPC_POWERNV */
 
 /*
  * Allocate room for and instantiate RTAS
@@ -1297,10 +1579,8 @@ static void __init prom_instantiate_rtas(void)
                return;
 
        base = alloc_down(size, PAGE_SIZE, 0);
-       if (base == 0) {
-               prom_printf("RTAS allocation failed !\n");
-               return;
-       }
+       if (base == 0)
+               prom_panic("Could not allocate memory for RTAS\n");
 
        rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
        if (!IHANDLE_VALID(rtas_inst)) {
@@ -1326,6 +1606,12 @@ static void __init prom_instantiate_rtas(void)
        prom_setprop(rtas_node, "/rtas", "linux,rtas-entry",
                     &entry, sizeof(entry));
 
+#ifdef CONFIG_PPC_POWERNV
+       /* PowerVN takeover hack */
+       RELOC(prom_rtas_data) = base;
+       RELOC(prom_rtas_entry) = entry;
+       prom_getprop(rtas_node, "start-cpu", &RELOC(prom_rtas_start_cpu), 4);
+#endif
        prom_debug("rtas base     = 0x%x\n", base);
        prom_debug("rtas entry    = 0x%x\n", entry);
        prom_debug("rtas size     = 0x%x\n", (long)size);
@@ -1543,7 +1829,7 @@ static void __init prom_hold_cpus(void)
                *acknowledge = (unsigned long)-1;
 
                if (reg != _prom->cpu) {
-                       /* Primary Thread of non-boot cpu */
+                       /* Primary Thread of non-boot cpu or any thread */
                        prom_printf("starting cpu hw idx %lu... ", reg);
                        call_prom("start-cpu", 3, 0, node,
                                  secondary_hold, reg);
@@ -1652,15 +1938,6 @@ static void __init prom_init_stdout(void)
                prom_setprop(val, path, "linux,boot-display", NULL, 0);
 }
 
-static void __init prom_close_stdin(void)
-{
-       struct prom_t *_prom = &RELOC(prom);
-       ihandle val;
-
-       if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
-               call_prom("close", 1, 0, val);
-}
-
 static int __init prom_find_machine_type(void)
 {
        struct prom_t *_prom = &RELOC(prom);
@@ -1671,7 +1948,7 @@ static int __init prom_find_machine_type(void)
        int x;
 #endif
 
-       /* Look for a PowerMac */
+       /* Look for a PowerMac or a Cell */
        len = prom_getprop(_prom->root, "compatible",
                           compat, sizeof(compat)-1);
        if (len > 0) {
@@ -1697,7 +1974,11 @@ static int __init prom_find_machine_type(void)
                }
        }
 #ifdef CONFIG_PPC64
-       /* If not a mac, try to figure out if it's an IBM pSeries or any other
+       /* Try to detect OPAL */
+       if (PHANDLE_VALID(call_prom("finddevice", 1, 1, ADDR("/ibm,opal"))))
+               return PLATFORM_OPAL;
+
+       /* Try to figure out if it's an IBM pSeries or any other
         * PAPR compliant platform. We assume it is if :
         *  - /device_type is "chrp" (please, do NOT use that for future
         *    non-IBM designs !
@@ -1924,7 +2205,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
        unsigned long soff;
        unsigned char *valp;
        static char pname[MAX_PROPERTY_NAME];
-       int l, room;
+       int l, room, has_phandle = 0;
 
        dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
 
@@ -2008,19 +2289,26 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
                valp = make_room(mem_start, mem_end, l, 4);
                call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
                *mem_start = _ALIGN(*mem_start, 4);
+
+               if (!strcmp(RELOC(pname), RELOC("phandle")))
+                       has_phandle = 1;
        }
 
-       /* Add a "linux,phandle" property. */
-       soff = dt_find_string(RELOC("linux,phandle"));
-       if (soff == 0)
-               prom_printf("WARNING: Can't find string index for"
-                           " <linux-phandle> node %s\n", path);
-       else {
-               dt_push_token(OF_DT_PROP, mem_start, mem_end);
-               dt_push_token(4, mem_start, mem_end);
-               dt_push_token(soff, mem_start, mem_end);
-               valp = make_room(mem_start, mem_end, 4, 4);
-               *(u32 *)valp = node;
+       /* Add a "linux,phandle" property if no "phandle" property already
+        * existed (can happen with OPAL)
+        */
+       if (!has_phandle) {
+               soff = dt_find_string(RELOC("linux,phandle"));
+               if (soff == 0)
+                       prom_printf("WARNING: Can't find string index for"
+                                   " <linux-phandle> node %s\n", path);
+               else {
+                       dt_push_token(OF_DT_PROP, mem_start, mem_end);
+                       dt_push_token(4, mem_start, mem_end);
+                       dt_push_token(soff, mem_start, mem_end);
+                       valp = make_room(mem_start, mem_end, 4, 4);
+                       *(u32 *)valp = node;
+               }
        }
 
        /* do all our children */
@@ -2504,6 +2792,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
 #endif /* CONFIG_BLK_DEV_INITRD */
 }
 
+
 /*
  * We enter here early on, when the Open Firmware prom is still
  * handling exceptions and the MMU hash table for us.
@@ -2553,6 +2842,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         * between pSeries SMP and pSeries LPAR
         */
        RELOC(of_platform) = prom_find_machine_type();
+       prom_printf("Detected machine type: %x\n", RELOC(of_platform));
 
 #ifndef CONFIG_RELOCATABLE
        /* Bail if this is a kdump kernel. */
@@ -2565,7 +2855,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        prom_check_initrd(r3, r4);
 
-#ifdef CONFIG_PPC_PSERIES
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
        /*
         * On pSeries, inform the firmware about our capabilities
         */
@@ -2611,14 +2901,33 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
 #endif
 
        /*
-        * On non-powermacs, try to instantiate RTAS and puts all CPUs
-        * in spin-loops. PowerMacs don't have a working RTAS and use
-        * a different way to spin CPUs
+        * On non-powermacs, try to instantiate RTAS. PowerMacs don't
+        * have a usable RTAS implementation.
         */
-       if (RELOC(of_platform) != PLATFORM_POWERMAC) {
+       if (RELOC(of_platform) != PLATFORM_POWERMAC &&
+           RELOC(of_platform) != PLATFORM_OPAL)
                prom_instantiate_rtas();
+
+#ifdef CONFIG_PPC_POWERNV
+       /* Detect HAL and try instanciating it & doing takeover */
+       if (RELOC(of_platform) == PLATFORM_PSERIES_LPAR) {
+               prom_query_opal();
+               if (RELOC(of_platform) == PLATFORM_OPAL) {
+                       prom_opal_hold_cpus();
+                       prom_opal_takeover();
+               }
+       } else if (RELOC(of_platform) == PLATFORM_OPAL)
+               prom_instantiate_opal();
+#endif
+
+       /*
+        * On non-powermacs, put all CPUs in spin-loops.
+        *
+        * PowerMacs use a different mechanism to spin CPUs
+        */
+       if (RELOC(of_platform) != PLATFORM_POWERMAC &&
+           RELOC(of_platform) != PLATFORM_OPAL)
                prom_hold_cpus();
-       }
 
        /*
         * Fill in some infos for use by the kernel later on
@@ -2685,7 +2994,13 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        reloc_got2(-offset);
 #endif
 
-       __start(hdr, kbase, 0);
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
+       /* OPAL early debug gets the OPAL base & entry in r8 and r9 */
+       __start(hdr, kbase, 0, 0, 0,
+               RELOC(prom_opal_base), RELOC(prom_opal_entry));
+#else
+       __start(hdr, kbase, 0, 0, 0, 0, 0);
+#endif
 
        return 0;
 }
index 9f82f4937892201029232de04009d415f46cd80b..70f4286eaa7ab74f38e99b4526657f7044f68e65 100644 (file)
@@ -20,7 +20,9 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
 _end enter_prom memcpy memset reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr memstart_addr linux_banner"
+reloc_got2 kernstart_addr memstart_addr linux_banner _stext
+opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
+boot_command_line"
 
 NM="$1"
 OBJ="$2"
index 47187cc2cf008c38e14c09667a7fff7b436d5dee..4e1331b8eb33e5c613394e312b2799d365fa07f8 100644 (file)
@@ -2,7 +2,6 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
index 05b7dd217f6094a5e3027e2bab51ab01dfac6973..5de73dbd15c7e404a16257ae5239e9b1af293f65 100644 (file)
@@ -30,9 +30,6 @@
 #include <linux/seccomp.h>
 #include <linux/audit.h>
 #include <trace/syscall.h>
-#ifdef CONFIG_PPC32
-#include <linux/module.h>
-#endif
 #include <linux/hw_breakpoint.h>
 #include <linux/perf_event.h>
 
@@ -1497,9 +1494,14 @@ long arch_ptrace(struct task_struct *child, long request,
                if (index < PT_FPR0) {
                        tmp = ptrace_get_reg(child, (int) index);
                } else {
+                       unsigned int fpidx = index - PT_FPR0;
+
                        flush_fp_to_thread(child);
-                       tmp = ((unsigned long *)child->thread.fpr)
-                               [TS_FPRWIDTH * (index - PT_FPR0)];
+                       if (fpidx < (PT_FPSCR - PT_FPR0))
+                               tmp = ((unsigned long *)child->thread.fpr)
+                                       [fpidx * TS_FPRWIDTH];
+                       else
+                               tmp = child->thread.fpscr.val;
                }
                ret = put_user(tmp, datalp);
                break;
@@ -1525,9 +1527,14 @@ long arch_ptrace(struct task_struct *child, long request,
                if (index < PT_FPR0) {
                        ret = ptrace_put_reg(child, index, data);
                } else {
+                       unsigned int fpidx = index - PT_FPR0;
+
                        flush_fp_to_thread(child);
-                       ((unsigned long *)child->thread.fpr)
-                               [TS_FPRWIDTH * (index - PT_FPR0)] = data;
+                       if (fpidx < (PT_FPSCR - PT_FPR0))
+                               ((unsigned long *)child->thread.fpr)
+                                       [fpidx * TS_FPRWIDTH] = data;
+                       else
+                               child->thread.fpscr.val = data;
                        ret = 0;
                }
                break;
index d5ca8236315ca3b407dc51ecd67653b00f22837f..517b1d8f455b2d29761ef792fdc8da5fc745cbc7 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/delay.h>
index b1d738d128901b1b51fb6086817dce07bc9c977a..77bb77da05c1d5ad35ef17788f26cbe2878135a4 100644 (file)
@@ -12,7 +12,7 @@
 
 #undef DEBUG
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
index 209135af0a40e957fd15a166df417520df408f9e..ac761081511355ee68854ee02ade12f17ef93e18 100644 (file)
@@ -107,6 +107,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
                         PTRRELOC(&__start___lwsync_fixup),
                         PTRRELOC(&__stop___lwsync_fixup));
 
+       do_final_fixups();
+
        return KERNELBASE + offset;
 }
 
@@ -117,7 +119,7 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
  * This is called very early on the boot process, after a minimal
  * MMU environment has been set up but before MMU_init is called.
  */
-notrace void __init machine_init(unsigned long dt_ptr)
+notrace void __init machine_init(u64 dt_ptr)
 {
        lockdep_init();
 
index aebef1320ed737b75437c920d9e233cfcf4ea0ae..fb9bb46e7e881a584c1532a6768622395a5045be 100644 (file)
@@ -12,7 +12,7 @@
 
 #undef DEBUG
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
@@ -278,14 +278,14 @@ static void __init initialize_cache_info(void)
 
        DBG(" -> initialize_cache_info()\n");
 
-       for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
+       for_each_node_by_type(np, "cpu") {
                num_cpus += 1;
 
-               /* We're assuming *all* of the CPUs have the same
+               /*
+                * We're assuming *all* of the CPUs have the same
                 * d-cache and i-cache sizes... -Peter
                 */
-
-               if ( num_cpus == 1 ) {
+               if (num_cpus == 1) {
                        const u32 *sizep, *lsizep;
                        u32 size, lsize;
 
@@ -294,10 +294,13 @@ static void __init initialize_cache_info(void)
                        sizep = of_get_property(np, "d-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = of_get_property(np, "d-cache-block-size", NULL);
+                       lsizep = of_get_property(np, "d-cache-block-size",
+                                                NULL);
                        /* fallback if block size missing */
                        if (lsizep == NULL)
-                               lsizep = of_get_property(np, "d-cache-line-size", NULL);
+                               lsizep = of_get_property(np,
+                                                        "d-cache-line-size",
+                                                        NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
@@ -314,9 +317,12 @@ static void __init initialize_cache_info(void)
                        sizep = of_get_property(np, "i-cache-size", NULL);
                        if (sizep != NULL)
                                size = *sizep;
-                       lsizep = of_get_property(np, "i-cache-block-size", NULL);
+                       lsizep = of_get_property(np, "i-cache-block-size",
+                                                NULL);
                        if (lsizep == NULL)
-                               lsizep = of_get_property(np, "i-cache-line-size", NULL);
+                               lsizep = of_get_property(np,
+                                                        "i-cache-line-size",
+                                                        NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
                        if (sizep == 0 || lsizep == 0)
@@ -353,6 +359,7 @@ void __init setup_system(void)
                          &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
        do_lwsync_fixups(cur_cpu_spec->cpu_features,
                         &__start___lwsync_fixup, &__stop___lwsync_fixup);
+       do_final_fixups();
 
        /*
         * Unflatten the device-tree passed by prom_init or kexec
index 78b76dc54dfb27847a24228e1bac2e2ef804354a..836a5a19eb2c3a3e45d5cab542fdb7138a8142bd 100644 (file)
@@ -97,7 +97,7 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
        compat_sigset_t cset;
 
        switch (_NSIG_WORDS) {
-       case 4: cset.sig[5] = set->sig[3] & 0xffffffffull;
+       case 4: cset.sig[6] = set->sig[3] & 0xffffffffull;
                cset.sig[7] = set->sig[3] >> 32;
        case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
                cset.sig[5] = set->sig[2] >> 32;
index e91c736cc8428a596818957c517bfe71eaf74e76..a50b5ec281dcd70a9afcf62f8bd8966e977bb4ce 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/stddef.h>
 #include <linux/elf.h>
 #include <linux/ptrace.h>
-#include <linux/module.h>
 #include <linux/ratelimit.h>
 
 #include <asm/sigcontext.h>
index 7bf2187dfd99e3135f78225a3217d53a3a099b6e..6df70907d60aba5cf244c5dade8ea007bc30425d 100644 (file)
@@ -18,7 +18,7 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
 #define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
 #define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
+
+/* State of each CPU during hotplug phases */
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
 #else
 static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
 #define get_idle_for_cpu(x)      (idle_thread_array[(x)])
@@ -104,12 +108,25 @@ int __devinit smp_generic_kick_cpu(int nr)
         * cpu_start field to become non-zero After we set cpu_start,
         * the processor will continue on to secondary_start
         */
-       paca[nr].cpu_start = 1;
-       smp_mb();
+       if (!paca[nr].cpu_start) {
+               paca[nr].cpu_start = 1;
+               smp_mb();
+               return 0;
+       }
+
+#ifdef CONFIG_HOTPLUG_CPU
+       /*
+        * Ok it's not there, so it might be soft-unplugged, let's
+        * try to bring it back
+        */
+       per_cpu(cpu_state, nr) = CPU_UP_PREPARE;
+       smp_wmb();
+       smp_send_reschedule(nr);
+#endif /* CONFIG_HOTPLUG_CPU */
 
        return 0;
 }
-#endif
+#endif /* CONFIG_PPC64 */
 
 static irqreturn_t call_function_action(int irq, void *data)
 {
@@ -170,7 +187,7 @@ int smp_request_message_ipi(int virq, int msg)
                return 1;
        }
 #endif
-       err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
+       err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU,
                          smp_ipi_name[msg], 0);
        WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
                virq, smp_ipi_name[msg], err);
@@ -357,8 +374,6 @@ void __devinit smp_prepare_boot_cpu(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-/* State of each CPU during hotplug phases */
-static DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
 int generic_cpu_disable(void)
 {
@@ -406,6 +421,11 @@ void generic_set_cpu_dead(unsigned int cpu)
 {
        per_cpu(cpu_state, cpu) = CPU_DEAD;
 }
+
+int generic_check_cpu_restart(unsigned int cpu)
+{
+       return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
+}
 #endif
 
 struct create_idle {
index b0dbb1daa4df1a6ea309b9b79f228834c888f9cc..3d30ef1038e5e285f1fe43f1d85ace5b1c3463b4 100644 (file)
@@ -10,7 +10,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
 #include <asm/ptrace.h>
index aa17b76dd42799375ce954490526b00e5262de06..641f9adc620596e46d6b59b5f725643ce8124ad5 100644 (file)
@@ -33,6 +33,6 @@ void save_processor_state(void)
 void restore_processor_state(void)
 {
 #ifdef CONFIG_PPC32
-       switch_mmu_context(NULL, current->active_mm);
+       switch_mmu_context(current->active_mm, current->active_mm);
 #endif
 }
index 6f3f0697274e85a87aa4d0213493ecb948751eb1..168e88480223790d95f4f2e46976e93c32d926a6 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/system.h>
 #include <asm/iommu.h>
 #include <linux/irq.h>
+#include <linux/sched.h>
 #include <linux/interrupt.h>
 
 void do_after_copyback(void)
index f0f2199e64e123a0fcf96ec311b1d3a00bb196b4..ce035c1905f0c496430b8c420d29e7fffcf0066f 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nodemask.h>
 #include <linux/cpumask.h>
 #include <linux/notifier.h>
index 03b29a6759ab55b087528c9e1be70d095c2a8d2b..522bb1dfc3538ddc7b08ec3986393577edc5e9e8 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
index f19d9777d3c1825d01b9f0dde217ade0ddd80344..5459d148a0f6d792fd457bd55e2105788057169b 100644 (file)
@@ -457,7 +457,14 @@ int machine_check_e500mc(struct pt_regs *regs)
 
        if (reason & MCSR_DCPERR_MC) {
                printk("Data Cache Parity Error\n");
-               recoverable = 0;
+
+               /*
+                * In write shadow mode we auto-recover from the error, but it
+                * may still get logged and cause a machine check.  We should
+                * only treat the non-write shadow case as non-recoverable.
+                */
+               if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS))
+                       recoverable = 0;
        }
 
        if (reason & MCSR_L2MMU_MHIT) {
@@ -1291,14 +1298,12 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 
                if (user_mode(regs)) {
                        current->thread.dbcr0 &= ~DBCR0_IC;
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
                        if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
                                               current->thread.dbcr1))
                                regs->msr |= MSR_DE;
                        else
                                /* Make sure the IDM bit is off */
                                current->thread.dbcr0 &= ~DBCR0_IDM;
-#endif
                }
 
                _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
index b4607a91d1f44563d2dcf8851118de567aa88dc7..57fa2c0a531c7c56765cc4a659bf28735cac0abf 100644 (file)
@@ -69,6 +69,12 @@ void __init udbg_early_init(void)
        udbg_init_wsp();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
        udbg_init_ehv_bc();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
+       udbg_init_ps3gelic();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
+       udbg_init_debug_opal_raw();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
+       udbg_init_debug_opal_hvsi();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
index 142ab1008c3bd63aff1b99f6e0bb1726351c3212..7d14bb697d407fc93fa6fd8d2411f61c08adbcf2 100644 (file)
@@ -9,7 +9,6 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index 1b695fdc362b8b10f0551072e74b949dd04d4761..f65af61996bde1cc599737158051200329d4103e 100644 (file)
  */
 
 #include <linux/types.h>
+#include <linux/stat.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/console.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/kobject.h>
@@ -605,15 +606,20 @@ static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask)
         return dma_iommu_ops.dma_supported(dev, mask);
 }
 
-struct dma_map_ops vio_dma_mapping_ops = {
-       .alloc_coherent = vio_dma_iommu_alloc_coherent,
-       .free_coherent  = vio_dma_iommu_free_coherent,
-       .map_sg         = vio_dma_iommu_map_sg,
-       .unmap_sg       = vio_dma_iommu_unmap_sg,
-       .map_page       = vio_dma_iommu_map_page,
-       .unmap_page     = vio_dma_iommu_unmap_page,
-       .dma_supported  = vio_dma_iommu_dma_supported,
+static u64 vio_dma_get_required_mask(struct device *dev)
+{
+        return dma_iommu_ops.get_required_mask(dev);
+}
 
+struct dma_map_ops vio_dma_mapping_ops = {
+       .alloc_coherent    = vio_dma_iommu_alloc_coherent,
+       .free_coherent     = vio_dma_iommu_free_coherent,
+       .map_sg            = vio_dma_iommu_map_sg,
+       .unmap_sg          = vio_dma_iommu_unmap_sg,
+       .map_page          = vio_dma_iommu_map_page,
+       .unmap_page        = vio_dma_iommu_unmap_page,
+       .dma_supported     = vio_dma_iommu_dma_supported,
+       .get_required_mask = vio_dma_get_required_mask,
 };
 
 /**
index ca1f88b3dc596fb099c8fba2a9659fbe047592f5..7b612a76c70129488d24be5ed60bc56c523878f4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kvm_host.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/export.h>
 
 #include <asm/reg.h>
 #include <asm/cputable.h>
index f68a34d160356bbaab228bc1b59509e0af1c6f4c..a459479995c6619fd83d6731ea7baaa1c016e990 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include <asm/reg.h>
index f7f63a00ab1f5cfb5359618dffe8f58cecde42b0..a150817d6d4c7f9d03763542dacad5cf45ada096 100644 (file)
@@ -17,7 +17,7 @@
  * Authors: Alexander Graf <agraf@suse.de>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/kvm_book3s.h>
 
 #ifdef CONFIG_KVM_BOOK3S_64_HV
index 4644c7986d8020c681ec1c03c9bc747e055a335f..0cb137a9b0381f1175d5962c67aac18f566af662 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/preempt.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/fs.h>
 #include <linux/anon_inodes.h>
 #include <linux/cpumask.h>
@@ -43,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/cputhreads.h>
 #include <asm/page.h>
+#include <asm/hvcall.h>
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
index d43120355eec15b8d61a0859a7575b2d8e1e6713..286f13d601cf589f1b3ca9e9259c4fd22bb78fc4 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/preempt.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/bootmem.h>
index f422231d92353771bcf663eb6dbb9393bcb161aa..44d8829334ab2d9c1ec22606336177d36f41b3d5 100644 (file)
@@ -1263,7 +1263,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
        addi    r6,r5,VCORE_NAPPING_THREADS
 31:    lwarx   r4,0,r6
        or      r4,r4,r0
-       popcntw r7,r4
+       PPC_POPCNTW(r7,r4)
        cmpw    r7,r8
        bge     2f
        stwcx.  r4,0,r6
index d417511abfb120f6992058e26547576d570bfcd9..3c791e1eb675299c96e7b428b499e7bec4e5f434 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
@@ -150,16 +151,14 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
 #ifdef CONFIG_PPC_BOOK3S_64
        if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
                kvmppc_mmu_book3s_64_init(vcpu);
-               if (!to_book3s(vcpu)->hior_sregs)
-                       to_book3s(vcpu)->hior = 0xfff00000;
+               to_book3s(vcpu)->hior = 0xfff00000;
                to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL;
                vcpu->arch.cpu_type = KVM_CPU_3S_64;
        } else
 #endif
        {
                kvmppc_mmu_book3s_32_init(vcpu);
-               if (!to_book3s(vcpu)->hior_sregs)
-                       to_book3s(vcpu)->hior = 0;
+               to_book3s(vcpu)->hior = 0;
                to_book3s(vcpu)->msr_mask = 0xffffffffULL;
                vcpu->arch.cpu_type = KVM_CPU_3S_32;
        }
@@ -796,9 +795,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                }
        }
 
-       if (sregs->u.s.flags & KVM_SREGS_S_HIOR)
-               sregs->u.s.hior = to_book3s(vcpu)->hior;
-
        return 0;
 }
 
@@ -835,11 +831,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        /* Flush the MMU after messing with the segments */
        kvmppc_mmu_pte_flush(vcpu, 0, 0);
 
-       if (sregs->u.s.flags & KVM_SREGS_S_HIOR) {
-               to_book3s(vcpu)->hior_sregs = true;
-               to_book3s(vcpu)->hior = sregs->u.s.hior;
-       }
-
        return 0;
 }
 
index 0d843c6ba3154fe21a0abd4f857d32ee0250e2b4..607fbdf24b8484c173cc03593ffc71d968b689fe 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/kvm_host.h>
-#include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/hrtimer.h>
 #include <linux/fs.h>
@@ -209,7 +208,6 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_PPC_BOOKE_SREGS:
 #else
        case KVM_CAP_PPC_SEGSTATE:
-       case KVM_CAP_PPC_HIOR:
        case KVM_CAP_PPC_PAPR:
 #endif
        case KVM_CAP_PPC_UNSET_IRQ:
index 769b817fbb32c8d408b15af3ab7bfe8ef05db77e..08e3a3356c402f02145ef3f3c55a9627fb2cda1c 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Author: Anton Blanchard <anton@au.ibm.com>
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <asm/checksum.h>
index e91615abae6645b2d28e988ce3367a0a43d182e5..8df55fc3aad675fbafac0c2b561f01ef97700a72 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/device.h>      /* devres_*(), devm_ioremap_release() */
 #include <linux/gfp.h>
 #include <linux/io.h>          /* ioremap_prot() */
-#include <linux/module.h>      /* EXPORT_SYMBOL() */
+#include <linux/export.h>      /* EXPORT_SYMBOL() */
 
 /**
  * devm_ioremap_prot - Managed ioremap_prot()
index 0d08d0171392a4e7ec72e21226737cc458e3a98f..7a8a7487cee8dde9d06aa86fff3bd32bdd54433e 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/init.h>
 #include <asm/cputable.h>
 #include <asm/code-patching.h>
+#include <asm/page.h>
+#include <asm/sections.h>
 
 
 struct fixup_entry {
@@ -128,6 +130,27 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
        }
 }
 
+void do_final_fixups(void)
+{
+#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
+       int *src, *dest;
+       unsigned long length;
+
+       if (PHYSICAL_START == 0)
+               return;
+
+       src = (int *)(KERNELBASE + PHYSICAL_START);
+       dest = (int *)KERNELBASE;
+       length = (__end_interrupts - _stext) / sizeof(int);
+
+       while (length--) {
+               patch_instruction(dest, *src);
+               src++;
+               dest++;
+       }
+#endif
+}
+
 #ifdef CONFIG_FTR_FIXUP_SELFTEST
 
 #define check(x)       \
index 9b8182e82166aa1e431576c3098567c1e15b8fa5..a6ebba56fdd4005a92e261a9d171423bb4325413 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/stringify.h>
 #include <linux/smp.h>
 
index 45907c1dae66da343344b5e1cfe9c682afc409ff..a1060a868e6976144ce14ea47b525e6d9bc2beb0 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index 62279200d965fee6050a968da5d51dd9c28c420b..a73f0884d358d0d9095c992d6c532929f853044c 100644 (file)
@@ -171,10 +171,6 @@ static unsigned long insn_type(unsigned long speinsn)
        case EFDNABS:   ret = XA;       break;
        case EFDNEG:    ret = XA;       break;
        case EFDSUB:    ret = AB;       break;
-
-       default:
-               printk(KERN_ERR "\nOoops! SPE instruction no type found.");
-               printk(KERN_ERR "\ninst code: %08lx\n", speinsn);
        }
 
        return ret;
@@ -195,7 +191,7 @@ int do_spe_mathemu(struct pt_regs *regs)
 
        type = insn_type(speinsn);
        if (type == NOTYPE)
-               return -ENOSYS;
+               goto illegal;
 
        func = speinsn & 0x7ff;
        fc = (speinsn >> 21) & 0x1f;
@@ -212,12 +208,10 @@ int do_spe_mathemu(struct pt_regs *regs)
 
        __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
 
-#ifdef DEBUG
-       printk("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
-       printk("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
-       printk("va: %08x  %08x\n", va.wp[0], va.wp[1]);
-       printk("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
-#endif
+       pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
+       pr_debug("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
+       pr_debug("va: %08x  %08x\n", va.wp[0], va.wp[1]);
+       pr_debug("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
 
        switch (src) {
        case SPFP: {
@@ -235,10 +229,8 @@ int do_spe_mathemu(struct pt_regs *regs)
                        break;
                }
 
-#ifdef DEBUG
-               printk("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
-               printk("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
-#endif
+               pr_debug("SA: %ld %08lx %ld (%ld)\n", SA_s, SA_f, SA_e, SA_c);
+               pr_debug("SB: %ld %08lx %ld (%ld)\n", SB_s, SB_f, SB_e, SB_c);
 
                switch (func) {
                case EFSABS:
@@ -305,10 +297,10 @@ int do_spe_mathemu(struct pt_regs *regs)
                        FP_DECL_D(DB);
                        FP_CLEAR_EXCEPTIONS;
                        FP_UNPACK_DP(DB, vb.dp);
-#ifdef DEBUG
-                       printk("DB: %ld %08lx %08lx %ld (%ld)\n",
+
+                       pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
                                        DB_s, DB_f1, DB_f0, DB_e, DB_c);
-#endif
+
                        FP_CONV(S, D, 1, 2, SR, DB);
                        goto pack_s;
                }
@@ -332,9 +324,8 @@ int do_spe_mathemu(struct pt_regs *regs)
                break;
 
 pack_s:
-#ifdef DEBUG
-               printk("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
-#endif
+               pr_debug("SR: %ld %08lx %ld (%ld)\n", SR_s, SR_f, SR_e, SR_c);
+
                FP_PACK_SP(vc.wp + 1, SR);
                goto update_regs;
 
@@ -365,12 +356,10 @@ cmp_s:
                        break;
                }
 
-#ifdef DEBUG
-               printk("DA: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DA: %ld %08lx %08lx %ld (%ld)\n",
                                DA_s, DA_f1, DA_f0, DA_e, DA_c);
-               printk("DB: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DB: %ld %08lx %08lx %ld (%ld)\n",
                                DB_s, DB_f1, DB_f0, DB_e, DB_c);
-#endif
 
                switch (func) {
                case EFDABS:
@@ -438,10 +427,10 @@ cmp_s:
                        FP_DECL_S(SB);
                        FP_CLEAR_EXCEPTIONS;
                        FP_UNPACK_SP(SB, vb.wp + 1);
-#ifdef DEBUG
-                       printk("SB: %ld %08lx %ld (%ld)\n",
+
+                       pr_debug("SB: %ld %08lx %ld (%ld)\n",
                                        SB_s, SB_f, SB_e, SB_c);
-#endif
+
                        FP_CONV(D, S, 2, 1, DR, SB);
                        goto pack_d;
                }
@@ -471,10 +460,9 @@ cmp_s:
                break;
 
 pack_d:
-#ifdef DEBUG
-               printk("DR: %ld %08lx %08lx %ld (%ld)\n",
+               pr_debug("DR: %ld %08lx %08lx %ld (%ld)\n",
                                DR_s, DR_f1, DR_f0, DR_e, DR_c);
-#endif
+
                FP_PACK_DP(vc.dp, DR);
                goto update_regs;
 
@@ -511,12 +499,14 @@ cmp_d:
                        break;
                }
 
-#ifdef DEBUG
-               printk("SA0: %ld %08lx %ld (%ld)\n", SA0_s, SA0_f, SA0_e, SA0_c);
-               printk("SA1: %ld %08lx %ld (%ld)\n", SA1_s, SA1_f, SA1_e, SA1_c);
-               printk("SB0: %ld %08lx %ld (%ld)\n", SB0_s, SB0_f, SB0_e, SB0_c);
-               printk("SB1: %ld %08lx %ld (%ld)\n", SB1_s, SB1_f, SB1_e, SB1_c);
-#endif
+               pr_debug("SA0: %ld %08lx %ld (%ld)\n",
+                               SA0_s, SA0_f, SA0_e, SA0_c);
+               pr_debug("SA1: %ld %08lx %ld (%ld)\n",
+                               SA1_s, SA1_f, SA1_e, SA1_c);
+               pr_debug("SB0: %ld %08lx %ld (%ld)\n",
+                               SB0_s, SB0_f, SB0_e, SB0_c);
+               pr_debug("SB1: %ld %08lx %ld (%ld)\n",
+                               SB1_s, SB1_f, SB1_e, SB1_c);
 
                switch (func) {
                case EVFSABS:
@@ -605,10 +595,11 @@ cmp_d:
                break;
 
 pack_vs:
-#ifdef DEBUG
-               printk("SR0: %ld %08lx %ld (%ld)\n", SR0_s, SR0_f, SR0_e, SR0_c);
-               printk("SR1: %ld %08lx %ld (%ld)\n", SR1_s, SR1_f, SR1_e, SR1_c);
-#endif
+               pr_debug("SR0: %ld %08lx %ld (%ld)\n",
+                               SR0_s, SR0_f, SR0_e, SR0_c);
+               pr_debug("SR1: %ld %08lx %ld (%ld)\n",
+                               SR1_s, SR1_f, SR1_e, SR1_c);
+
                FP_PACK_SP(vc.wp, SR0);
                FP_PACK_SP(vc.wp + 1, SR1);
                goto update_regs;
@@ -646,14 +637,12 @@ update_regs:
        current->thread.evr[fc] = vc.wp[0];
        regs->gpr[fc] = vc.wp[1];
 
-#ifdef DEBUG
-       printk("ccr = %08lx\n", regs->ccr);
-       printk("cur exceptions = %08x spefscr = %08lx\n",
+       pr_debug("ccr = %08lx\n", regs->ccr);
+       pr_debug("cur exceptions = %08x spefscr = %08lx\n",
                        FP_CUR_EXCEPTIONS, __FPU_FPSCR);
-       printk("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
-       printk("va: %08x  %08x\n", va.wp[0], va.wp[1]);
-       printk("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
-#endif
+       pr_debug("vc: %08x  %08x\n", vc.wp[0], vc.wp[1]);
+       pr_debug("va: %08x  %08x\n", va.wp[0], va.wp[1]);
+       pr_debug("vb: %08x  %08x\n", vb.wp[0], vb.wp[1]);
 
        return 0;
 
@@ -661,9 +650,7 @@ illegal:
        if (have_e500_cpu_a005_erratum) {
                /* according to e500 cpu a005 erratum, reissue efp inst */
                regs->nip -= 4;
-#ifdef DEBUG
-               printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
-#endif
+               pr_debug("re-issue efp inst: %08lx\n", speinsn);
                return 0;
        }
 
@@ -685,13 +672,20 @@ int speround_handler(struct pt_regs *regs)
        type = insn_type(speinsn & 0x7ff);
        if (type == XCR) return -ENOSYS;
 
+       __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
+       pr_debug("speinsn:%08lx spefscr:%08lx\n", speinsn, __FPU_FPSCR);
+
+       /* No need to round if the result is exact */
+       if (!(__FPU_FPSCR & FP_EX_INEXACT))
+               return 0;
+
        fc = (speinsn >> 21) & 0x1f;
        s_lo = regs->gpr[fc] & SIGN_BIT_S;
        s_hi = current->thread.evr[fc] & SIGN_BIT_S;
        fgpr.wp[0] = current->thread.evr[fc];
        fgpr.wp[1] = regs->gpr[fc];
 
-       __FPU_FPSCR = mfspr(SPRN_SPEFSCR);
+       pr_debug("round fgpr: %08x  %08x\n", fgpr.wp[0], fgpr.wp[1]);
 
        switch ((speinsn >> 5) & 0x7) {
        /* Since SPE instructions on E500 core can handle round to nearest
@@ -731,6 +725,8 @@ int speround_handler(struct pt_regs *regs)
        current->thread.evr[fc] = fgpr.wp[0];
        regs->gpr[fc] = fgpr.wp[1];
 
+       pr_debug("  to fgpr: %08x  %08x\n", fgpr.wp[0], fgpr.wp[1]);
+
        return 0;
 }
 
index bdca46e0838279ba6a9e26aa106925435865b5d6..991ee813d2a8da02acae26e135ed1f770d7ee6bc 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_PPC_MM_SLICES)   += slice.o
 ifeq ($(CONFIG_HUGETLB_PAGE),y)
 obj-y                          += hugetlbpage.o
 obj-$(CONFIG_PPC_STD_MMU_64)   += hugetlbpage-hash64.o
+obj-$(CONFIG_PPC_BOOK3E_MMU)   += hugetlbpage-book3e.o
 endif
 obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
index b42f76c4948dba17b1d84efb32bb3f06790df1e0..329be36c0a8dd25aaa53749ef43c7c0087f14201 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/types.h>
 #include <linux/highmem.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <asm/tlbflush.h>
 
index f7802c8bba0a6b31be879ecf1446f474c00d52b8..66a6fd38e9cdb9df35d8dbb6206c581b7f5b550e 100644 (file)
@@ -101,17 +101,17 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
 
 /*
  * Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
- * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus
- * that support extended page sizes).  Note that while some cpus support a
- * page size of 4G, we don't allow its use here.
+ * in particular size must be a power of 4 between 4k and the max supported by
+ * an implementation; max may further be limited by what can be represented in
+ * an unsigned long (for example, 32-bit implementations cannot support a 4GB
+ * size).
  */
 static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
                unsigned long size, unsigned long flags, unsigned int pid)
 {
-       unsigned int tsize, lz;
+       unsigned int tsize;
 
-       asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (size));
-       tsize = 21 - lz;
+       tsize = __ilog2(size) - 10;
 
 #ifdef CONFIG_SMP
        if ((flags & _PAGE_NO_CACHE) == 0)
@@ -146,29 +146,36 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
        loadcam_entry(index);
 }
 
+unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
+                         phys_addr_t phys)
+{
+       unsigned int camsize = __ilog2(ram) & ~1U;
+       unsigned int align = __ffs(virt | phys) & ~1U;
+       unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
+
+       /* Convert (4^max) kB to (2^max) bytes */
+       max_cam = max_cam * 2 + 10;
+
+       if (camsize > align)
+               camsize = align;
+       if (camsize > max_cam)
+               camsize = max_cam;
+
+       return 1UL << camsize;
+}
+
 unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
 {
        int i;
        unsigned long virt = PAGE_OFFSET;
        phys_addr_t phys = memstart_addr;
        unsigned long amount_mapped = 0;
-       unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf;
-
-       /* Convert (4^max) kB to (2^max) bytes */
-       max_cam = max_cam * 2 + 10;
 
        /* Calculate CAM values */
        for (i = 0; ram && i < max_cam_idx; i++) {
-               unsigned int camsize = __ilog2(ram) & ~1U;
-               unsigned int align = __ffs(virt | phys) & ~1U;
                unsigned long cam_sz;
 
-               if (camsize > align)
-                       camsize = align;
-               if (camsize > max_cam)
-                       camsize = max_cam;
-
-               cam_sz = 1UL << camsize;
+               cam_sz = calc_cam_sz(ram, virt, phys);
                settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0);
 
                ram -= cam_sz;
index 26b2872b3d002e431fb3f423f0d7d6878ac049db..2d282186cb45b43f55044819bba1b4a5279844b6 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/sysctl.h>
+#include <linux/export.h>
 #include <linux/ctype.h>
 #include <linux/cache.h>
 #include <linux/init.h>
@@ -105,9 +106,6 @@ int mmu_kernel_ssize = MMU_SEGSIZE_256M;
 int mmu_highuser_ssize = MMU_SEGSIZE_256M;
 u16 mmu_slb_size = 64;
 EXPORT_SYMBOL_GPL(mmu_slb_size);
-#ifdef CONFIG_HUGETLB_PAGE
-unsigned int HPAGE_SHIFT;
-#endif
 #ifdef CONFIG_PPC_64K_PAGES
 int mmu_ci_restrictions;
 #endif
@@ -534,11 +532,11 @@ static unsigned long __init htab_get_table_size(void)
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-void create_section_mapping(unsigned long start, unsigned long end)
+int create_section_mapping(unsigned long start, unsigned long end)
 {
-       BUG_ON(htab_bolt_mapping(start, end, __pa(start),
+       return htab_bolt_mapping(start, end, __pa(start),
                                 pgprot_val(PAGE_KERNEL), mmu_linear_psize,
-                                mmu_kernel_ssize));
+                                mmu_kernel_ssize);
 }
 
 int 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 (file)
index 0000000..343ad0b
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * PPC Huge TLB Page Support for Book3E MMU
+ *
+ * Copyright (C) 2009 David Gibson, IBM Corporation.
+ * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
+ *
+ */
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+
+static inline int mmu_get_tsize(int psize)
+{
+       return mmu_psize_defs[psize].enc;
+}
+
+static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid)
+{
+       int found = 0;
+
+       mtspr(SPRN_MAS6, pid << 16);
+       if (mmu_has_feature(MMU_FTR_USE_TLBRSRV)) {
+               asm volatile(
+                       "li     %0,0\n"
+                       "tlbsx. 0,%1\n"
+                       "bne    1f\n"
+                       "li     %0,1\n"
+                       "1:\n"
+                       : "=&r"(found) : "r"(ea));
+       } else {
+               asm volatile(
+                       "tlbsx  0,%1\n"
+                       "mfspr  %0,0x271\n"
+                       "srwi   %0,%0,31\n"
+                       : "=&r"(found) : "r"(ea));
+       }
+
+       return found;
+}
+
+void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte)
+{
+       unsigned long mas1, mas2;
+       u64 mas7_3;
+       unsigned long psize, tsize, shift;
+       unsigned long flags;
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       int index, lz, ncams;
+       struct vm_area_struct *vma;
+#endif
+
+       if (unlikely(is_kernel_addr(ea)))
+               return;
+
+#ifdef CONFIG_PPC_MM_SLICES
+       psize = mmu_get_tsize(get_slice_psize(mm, ea));
+       tsize = mmu_get_psize(psize);
+       shift = mmu_psize_defs[psize].shift;
+#else
+       vma = find_vma(mm, ea);
+       psize = vma_mmu_pagesize(vma);  /* returns actual size in bytes */
+       asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (psize));
+       shift = 31 - lz;
+       tsize = 21 - lz;
+#endif
+
+       /*
+        * We can't be interrupted while we're setting up the MAS
+        * regusters or after we've confirmed that no tlb exists.
+        */
+       local_irq_save(flags);
+
+       if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
+               local_irq_restore(flags);
+               return;
+       }
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
+
+       /* We have to use the CAM(TLB1) on FSL parts for hugepages */
+       index = __get_cpu_var(next_tlbcam_idx);
+       mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1));
+
+       /* Just round-robin the entries and wrap when we hit the end */
+       if (unlikely(index == ncams - 1))
+               __get_cpu_var(next_tlbcam_idx) = tlbcam_index;
+       else
+               __get_cpu_var(next_tlbcam_idx)++;
+#endif
+       mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize);
+       mas2 = ea & ~((1UL << shift) - 1);
+       mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK;
+       mas7_3 = (u64)pte_pfn(pte) << PAGE_SHIFT;
+       mas7_3 |= (pte_val(pte) >> PTE_BAP_SHIFT) & MAS3_BAP_MASK;
+       if (!pte_dirty(pte))
+               mas7_3 &= ~(MAS3_SW|MAS3_UW);
+
+       mtspr(SPRN_MAS1, mas1);
+       mtspr(SPRN_MAS2, mas2);
+
+       if (mmu_has_feature(MMU_FTR_USE_PAIRED_MAS)) {
+               mtspr(SPRN_MAS7_MAS3, mas7_3);
+       } else {
+               mtspr(SPRN_MAS7, upper_32_bits(mas7_3));
+               mtspr(SPRN_MAS3, lower_32_bits(mas7_3));
+       }
+
+       asm volatile ("tlbwe");
+
+       local_irq_restore(flags);
+}
+
+void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+       struct hstate *hstate = hstate_file(vma->vm_file);
+       unsigned long tsize = huge_page_shift(hstate) - 10;
+
+       __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
+
+}
index da5eb388570210ca9aa70ba0de41444659c49d02..8558b572e55d3e6ba2ee7b5656b9eb9f9e39b5c3 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * PPC64 (POWER4) Huge TLB Page Support for Kernel.
+ * PPC Huge TLB Page Support for Kernel.
  *
  * Copyright (C) 2003 David Gibson, IBM Corporation.
+ * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
  *
  * Based on the IA-32 version:
  * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/hugetlb.h>
+#include <linux/of_fdt.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+#include <linux/moduleparam.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
+#include <asm/setup.h>
 
 #define PAGE_SHIFT_64K 16
 #define PAGE_SHIFT_16M 24
 #define PAGE_SHIFT_16G 34
 
-#define MAX_NUMBER_GPAGES      1024
+unsigned int HPAGE_SHIFT;
 
-/* Tracks the 16G pages after the device tree is scanned and before the
- * huge_boot_pages list is ready.  */
-static unsigned long gpage_freearray[MAX_NUMBER_GPAGES];
+/*
+ * Tracks gpages after the device tree is scanned and before the
+ * huge_boot_pages list is ready.  On 64-bit implementations, this is
+ * just used to track 16G pages and so is a single array.  32-bit
+ * implementations may have more than one gpage size due to limitations
+ * of the memory allocators, so we need multiple arrays
+ */
+#ifdef CONFIG_PPC64
+#define MAX_NUMBER_GPAGES      1024
+static u64 gpage_freearray[MAX_NUMBER_GPAGES];
 static unsigned nr_gpages;
-
-/* Flag to mark huge PD pointers.  This means pmd_bad() and pud_bad()
- * will choke on pointers to hugepte tables, which is handy for
- * catching screwups early. */
+#else
+#define MAX_NUMBER_GPAGES      128
+struct psize_gpages {
+       u64 gpage_list[MAX_NUMBER_GPAGES];
+       unsigned int nr_gpages;
+};
+static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT];
+#endif
 
 static inline int shift_to_mmu_psize(unsigned int shift)
 {
@@ -49,25 +66,6 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
 
 #define hugepd_none(hpd)       ((hpd).pd == 0)
 
-static inline pte_t *hugepd_page(hugepd_t hpd)
-{
-       BUG_ON(!hugepd_ok(hpd));
-       return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | 0xc000000000000000);
-}
-
-static inline unsigned int hugepd_shift(hugepd_t hpd)
-{
-       return hpd.pd & HUGEPD_SHIFT_MASK;
-}
-
-static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift)
-{
-       unsigned long idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp);
-       pte_t *dir = hugepd_page(*hpdp);
-
-       return dir + idx;
-}
-
 pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift)
 {
        pgd_t *pg;
@@ -93,7 +91,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
                        if (is_hugepd(pm))
                                hpdp = (hugepd_t *)pm;
                        else if (!pmd_none(*pm)) {
-                               return pte_offset_map(pm, ea);
+                               return pte_offset_kernel(pm, ea);
                        }
                }
        }
@@ -114,8 +112,18 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
                           unsigned long address, unsigned pdshift, unsigned pshift)
 {
-       pte_t *new = kmem_cache_zalloc(PGT_CACHE(pdshift - pshift),
-                                      GFP_KERNEL|__GFP_REPEAT);
+       struct kmem_cache *cachep;
+       pte_t *new;
+
+#ifdef CONFIG_PPC64
+       cachep = PGT_CACHE(pdshift - pshift);
+#else
+       int i;
+       int num_hugepd = 1 << (pshift - pdshift);
+       cachep = hugepte_cache;
+#endif
+
+       new = kmem_cache_zalloc(cachep, GFP_KERNEL|__GFP_REPEAT);
 
        BUG_ON(pshift > HUGEPD_SHIFT_MASK);
        BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK);
@@ -124,10 +132,31 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
                return -ENOMEM;
 
        spin_lock(&mm->page_table_lock);
+#ifdef CONFIG_PPC64
        if (!hugepd_none(*hpdp))
-               kmem_cache_free(PGT_CACHE(pdshift - pshift), new);
+               kmem_cache_free(cachep, new);
        else
-               hpdp->pd = ((unsigned long)new & ~0x8000000000000000) | pshift;
+               hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
+#else
+       /*
+        * We have multiple higher-level entries that point to the same
+        * actual pte location.  Fill in each as we go and backtrack on error.
+        * We need all of these so the DTLB pgtable walk code can find the
+        * right higher-level entry without knowing if it's a hugepage or not.
+        */
+       for (i = 0; i < num_hugepd; i++, hpdp++) {
+               if (unlikely(!hugepd_none(*hpdp)))
+                       break;
+               else
+                       hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
+       }
+       /* If we bailed from the for loop early, an error occurred, clean up */
+       if (i < num_hugepd) {
+               for (i = i - 1 ; i >= 0; i--, hpdp--)
+                       hpdp->pd = 0;
+               kmem_cache_free(cachep, new);
+       }
+#endif
        spin_unlock(&mm->page_table_lock);
        return 0;
 }
@@ -169,11 +198,132 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz
        return hugepte_offset(hpdp, addr, pdshift);
 }
 
+#ifdef CONFIG_PPC32
 /* Build list of addresses of gigantic pages.  This function is used in early
  * boot before the buddy or bootmem allocator is setup.
  */
-void add_gpage(unsigned long addr, unsigned long page_size,
-       unsigned long number_of_pages)
+void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
+{
+       unsigned int idx = shift_to_mmu_psize(__ffs(page_size));
+       int i;
+
+       if (addr == 0)
+               return;
+
+       gpage_freearray[idx].nr_gpages = number_of_pages;
+
+       for (i = 0; i < number_of_pages; i++) {
+               gpage_freearray[idx].gpage_list[i] = addr;
+               addr += page_size;
+       }
+}
+
+/*
+ * Moves the gigantic page addresses from the temporary list to the
+ * huge_boot_pages list.
+ */
+int alloc_bootmem_huge_page(struct hstate *hstate)
+{
+       struct huge_bootmem_page *m;
+       int idx = shift_to_mmu_psize(hstate->order + PAGE_SHIFT);
+       int nr_gpages = gpage_freearray[idx].nr_gpages;
+
+       if (nr_gpages == 0)
+               return 0;
+
+#ifdef CONFIG_HIGHMEM
+       /*
+        * If gpages can be in highmem we can't use the trick of storing the
+        * data structure in the page; allocate space for this
+        */
+       m = alloc_bootmem(sizeof(struct huge_bootmem_page));
+       m->phys = gpage_freearray[idx].gpage_list[--nr_gpages];
+#else
+       m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]);
+#endif
+
+       list_add(&m->list, &huge_boot_pages);
+       gpage_freearray[idx].nr_gpages = nr_gpages;
+       gpage_freearray[idx].gpage_list[nr_gpages] = 0;
+       m->hstate = hstate;
+
+       return 1;
+}
+/*
+ * Scan the command line hugepagesz= options for gigantic pages; store those in
+ * a list that we use to allocate the memory once all options are parsed.
+ */
+
+unsigned long gpage_npages[MMU_PAGE_COUNT];
+
+static int __init do_gpage_early_setup(char *param, char *val)
+{
+       static phys_addr_t size;
+       unsigned long npages;
+
+       /*
+        * The hugepagesz and hugepages cmdline options are interleaved.  We
+        * use the size variable to keep track of whether or not this was done
+        * properly and skip over instances where it is incorrect.  Other
+        * command-line parsing code will issue warnings, so we don't need to.
+        *
+        */
+       if ((strcmp(param, "default_hugepagesz") == 0) ||
+           (strcmp(param, "hugepagesz") == 0)) {
+               size = memparse(val, NULL);
+       } else if (strcmp(param, "hugepages") == 0) {
+               if (size != 0) {
+                       if (sscanf(val, "%lu", &npages) <= 0)
+                               npages = 0;
+                       gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages;
+                       size = 0;
+               }
+       }
+       return 0;
+}
+
+
+/*
+ * This function allocates physical space for pages that are larger than the
+ * buddy allocator can handle.  We want to allocate these in highmem because
+ * the amount of lowmem is limited.  This means that this function MUST be
+ * called before lowmem_end_addr is set up in MMU_init() in order for the lmb
+ * allocate to grab highmem.
+ */
+void __init reserve_hugetlb_gpages(void)
+{
+       static __initdata char cmdline[COMMAND_LINE_SIZE];
+       phys_addr_t size, base;
+       int i;
+
+       strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
+       parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup);
+
+       /*
+        * Walk gpage list in reverse, allocating larger page sizes first.
+        * Skip over unsupported sizes, or sizes that have 0 gpages allocated.
+        * When we reach the point in the list where pages are no longer
+        * considered gpages, we're done.
+        */
+       for (i = MMU_PAGE_COUNT-1; i >= 0; i--) {
+               if (mmu_psize_defs[i].shift == 0 || gpage_npages[i] == 0)
+                       continue;
+               else if (mmu_psize_to_shift(i) < (MAX_ORDER + PAGE_SHIFT))
+                       break;
+
+               size = (phys_addr_t)(1ULL << mmu_psize_to_shift(i));
+               base = memblock_alloc_base(size * gpage_npages[i], size,
+                                          MEMBLOCK_ALLOC_ANYWHERE);
+               add_gpage(base, size, gpage_npages[i]);
+       }
+}
+
+#else /* PPC64 */
+
+/* Build list of addresses of gigantic pages.  This function is used in early
+ * boot before the buddy or bootmem allocator is setup.
+ */
+void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
 {
        if (!addr)
                return;
@@ -199,19 +349,79 @@ int alloc_bootmem_huge_page(struct hstate *hstate)
        m->hstate = hstate;
        return 1;
 }
+#endif
 
 int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
 {
        return 0;
 }
 
+#ifdef CONFIG_PPC32
+#define HUGEPD_FREELIST_SIZE \
+       ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t))
+
+struct hugepd_freelist {
+       struct rcu_head rcu;
+       unsigned int index;
+       void *ptes[0];
+};
+
+static DEFINE_PER_CPU(struct hugepd_freelist *, hugepd_freelist_cur);
+
+static void hugepd_free_rcu_callback(struct rcu_head *head)
+{
+       struct hugepd_freelist *batch =
+               container_of(head, struct hugepd_freelist, rcu);
+       unsigned int i;
+
+       for (i = 0; i < batch->index; i++)
+               kmem_cache_free(hugepte_cache, batch->ptes[i]);
+
+       free_page((unsigned long)batch);
+}
+
+static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
+{
+       struct hugepd_freelist **batchp;
+
+       batchp = &__get_cpu_var(hugepd_freelist_cur);
+
+       if (atomic_read(&tlb->mm->mm_users) < 2 ||
+           cpumask_equal(mm_cpumask(tlb->mm),
+                         cpumask_of(smp_processor_id()))) {
+               kmem_cache_free(hugepte_cache, hugepte);
+               return;
+       }
+
+       if (*batchp == NULL) {
+               *batchp = (struct hugepd_freelist *)__get_free_page(GFP_ATOMIC);
+               (*batchp)->index = 0;
+       }
+
+       (*batchp)->ptes[(*batchp)->index++] = hugepte;
+       if ((*batchp)->index == HUGEPD_FREELIST_SIZE) {
+               call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback);
+               *batchp = NULL;
+       }
+}
+#endif
+
 static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift,
                              unsigned long start, unsigned long end,
                              unsigned long floor, unsigned long ceiling)
 {
        pte_t *hugepte = hugepd_page(*hpdp);
-       unsigned shift = hugepd_shift(*hpdp);
+       int i;
+
        unsigned long pdmask = ~((1UL << pdshift) - 1);
+       unsigned int num_hugepd = 1;
+
+#ifdef CONFIG_PPC64
+       unsigned int shift = hugepd_shift(*hpdp);
+#else
+       /* Note: On 32-bit the hpdp may be the first of several */
+       num_hugepd = (1 << (hugepd_shift(*hpdp) - pdshift));
+#endif
 
        start &= pdmask;
        if (start < floor)
@@ -224,9 +434,15 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif
        if (end - 1 > ceiling - 1)
                return;
 
-       hpdp->pd = 0;
+       for (i = 0; i < num_hugepd; i++, hpdp++)
+               hpdp->pd = 0;
+
        tlb->need_flush = 1;
+#ifdef CONFIG_PPC64
        pgtable_free_tlb(tlb, hugepte, pdshift - shift);
+#else
+       hugepd_free(tlb, hugepte);
+#endif
 }
 
 static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
@@ -331,18 +547,27 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
         * too.
         */
 
-       pgd = pgd_offset(tlb->mm, addr);
        do {
                next = pgd_addr_end(addr, end);
+               pgd = pgd_offset(tlb->mm, addr);
                if (!is_hugepd(pgd)) {
                        if (pgd_none_or_clear_bad(pgd))
                                continue;
                        hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
                } else {
+#ifdef CONFIG_PPC32
+                       /*
+                        * Increment next by the size of the huge mapping since
+                        * on 32-bit there may be more than one entry at the pgd
+                        * level for a single hugepage, but all of them point to
+                        * the same kmem cache that holds the hugepte.
+                        */
+                       next = addr + (1 << hugepd_shift(*(hugepd_t *)pgd));
+#endif
                        free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT,
                                          addr, next, floor, ceiling);
                }
-       } while (pgd++, addr = next, addr != end);
+       } while (addr = next, addr != end);
 }
 
 struct page *
@@ -477,17 +702,35 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                                        unsigned long len, unsigned long pgoff,
                                        unsigned long flags)
 {
+#ifdef CONFIG_PPC_MM_SLICES
        struct hstate *hstate = hstate_file(file);
        int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
 
        return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0);
+#else
+       return get_unmapped_area(file, addr, len, pgoff, flags);
+#endif
 }
 
 unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
 {
+#ifdef CONFIG_PPC_MM_SLICES
        unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
 
        return 1UL << mmu_psize_to_shift(psize);
+#else
+       if (!is_vm_hugetlb_page(vma))
+               return PAGE_SIZE;
+
+       return huge_page_size(hstate_vma(vma));
+#endif
+}
+
+static inline bool is_power_of_4(unsigned long x)
+{
+       if (is_power_of_2(x))
+               return (__ilog2(x) % 2) ? false : true;
+       return false;
 }
 
 static int __init add_huge_page_size(unsigned long long size)
@@ -497,9 +740,14 @@ static int __init add_huge_page_size(unsigned long long size)
 
        /* Check that it is a page size supported by the hardware and
         * that it fits within pagetable and slice limits. */
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       if ((size < PAGE_SIZE) || !is_power_of_4(size))
+               return -EINVAL;
+#else
        if (!is_power_of_2(size)
            || (shift > SLICE_HIGH_SHIFT) || (shift <= PAGE_SHIFT))
                return -EINVAL;
+#endif
 
        if ((mmu_psize = shift_to_mmu_psize(shift)) < 0)
                return -EINVAL;
@@ -536,6 +784,46 @@ static int __init hugepage_setup_sz(char *str)
 }
 __setup("hugepagesz=", hugepage_setup_sz);
 
+#ifdef CONFIG_FSL_BOOKE
+struct kmem_cache *hugepte_cache;
+static int __init hugetlbpage_init(void)
+{
+       int psize;
+
+       for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+               unsigned shift;
+
+               if (!mmu_psize_defs[psize].shift)
+                       continue;
+
+               shift = mmu_psize_to_shift(psize);
+
+               /* Don't treat normal page sizes as huge... */
+               if (shift != PAGE_SHIFT)
+                       if (add_huge_page_size(1ULL << shift) < 0)
+                               continue;
+       }
+
+       /*
+        * Create a kmem cache for hugeptes.  The bottom bits in the pte have
+        * size information encoded in them, so align them to allow this
+        */
+       hugepte_cache =  kmem_cache_create("hugepte-cache", sizeof(pte_t),
+                                          HUGEPD_SHIFT_MASK + 1, 0, NULL);
+       if (hugepte_cache == NULL)
+               panic("%s: Unable to create kmem cache for hugeptes\n",
+                     __func__);
+
+       /* Default hpage size = 4M */
+       if (mmu_psize_defs[MMU_PAGE_4M].shift)
+               HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift;
+       else
+               panic("%s: Unable to set default huge page size\n", __func__);
+
+
+       return 0;
+}
+#else
 static int __init hugetlbpage_init(void)
 {
        int psize;
@@ -578,15 +866,23 @@ static int __init hugetlbpage_init(void)
 
        return 0;
 }
-
+#endif
 module_init(hugetlbpage_init);
 
 void flush_dcache_icache_hugepage(struct page *page)
 {
        int i;
+       void *start;
 
        BUG_ON(!PageCompound(page));
 
-       for (i = 0; i < (1UL << compound_order(page)); i++)
-               __flush_dcache_icache(page_address(page+i));
+       for (i = 0; i < (1UL << compound_order(page)); i++) {
+               if (!PageHighMem(page)) {
+                       __flush_dcache_icache(page_address(page+i));
+               } else {
+                       start = kmap_atomic(page+i, KM_PPC_SYNC_ICACHE);
+                       __flush_dcache_icache(start);
+                       kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+               }
+       }
 }
index c77fef56dad68ad342486546ba8af68f2f5636ed..161cefde5c157823558aee1ae07b668f1a35510d 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/pagemap.h>
 #include <linux/memblock.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
+#include <linux/hugetlb.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -44,6 +46,7 @@
 #include <asm/tlb.h>
 #include <asm/sections.h>
 #include <asm/system.h>
+#include <asm/hugetlb.h>
 
 #include "mmu_decl.h"
 
@@ -123,6 +126,12 @@ void __init MMU_init(void)
        /* parse args from command line */
        MMU_setup();
 
+       /*
+        * Reserve gigantic pages for hugetlb.  This MUST occur before
+        * lowmem_end_addr is initialized below.
+        */
+       reserve_hugetlb_gpages();
+
        if (memblock.memory.cnt > 1) {
 #ifndef CONFIG_WII
                memblock.memory.cnt = 1;
index c781bbcf7338b3c23894048c6597535bd994564f..2dd6bdd31fe14f77a0bc097f746ca59e790f0b0e 100644 (file)
@@ -17,7 +17,7 @@
  *
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -34,6 +34,7 @@
 #include <linux/suspend.h>
 #include <linux/memblock.h>
 #include <linux/hugetlb.h>
+#include <linux/slab.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -123,7 +124,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
        pgdata = NODE_DATA(nid);
 
        start = (unsigned long)__va(start);
-       create_section_mapping(start, start + size);
+       if (create_section_mapping(start, start + size))
+               return -EINVAL;
 
        /* this should work for most non-highmem platforms */
        zone = pgdata->node_zones;
@@ -548,4 +550,38 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
                return;
        hash_preload(vma->vm_mm, address, access, trap);
 #endif /* CONFIG_PPC_STD_MMU */
+#if (defined(CONFIG_PPC_BOOK3E_64) || defined(CONFIG_PPC_FSL_BOOK3E)) \
+       && defined(CONFIG_HUGETLB_PAGE)
+       if (is_vm_hugetlb_page(vma))
+               book3e_hugetlb_preload(vma->vm_mm, address, *ptep);
+#endif
+}
+
+/*
+ * System memory should not be in /proc/iomem but various tools expect it
+ * (eg kdump).
+ */
+static int add_system_ram_resources(void)
+{
+       struct memblock_region *reg;
+
+       for_each_memblock(memory, reg) {
+               struct resource *res;
+               unsigned long base = reg->base;
+               unsigned long size = reg->size;
+
+               res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+               WARN_ON(!res);
+
+               if (res) {
+                       res->name = "System RAM";
+                       res->start = base;
+                       res->end = base + size - 1;
+                       res->flags = IORESOURCE_MEM;
+                       WARN_ON(request_resource(&iomem_resource, res) < 0);
+               }
+       }
+
+       return 0;
 }
+subsys_initcall(add_system_ram_resources);
index d0ee554e86e47c77d5084a7ac6d4f640e5cf763c..78fef6726e103596a1e0c5740951d09d9d7d0798 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/export.h>
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
index 3bafc3deca6d66478161cca9db8bc2fb9107173a..ca988a3d5fb250e32a8f426819acf6aee0931c93 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
 
@@ -136,8 +136,8 @@ int use_cop(unsigned long acop, struct mm_struct *mm)
        if (!mm || !acop)
                return -EINVAL;
 
-       /* We need to make sure mm_users doesn't change */
-       down_read(&mm->mmap_sem);
+       /* The page_table_lock ensures mm_users won't change under us */
+       spin_lock(&mm->page_table_lock);
        spin_lock(mm->context.cop_lockp);
 
        if (mm->context.cop_pid == COP_PID_NONE) {
@@ -164,7 +164,7 @@ int use_cop(unsigned long acop, struct mm_struct *mm)
 
 out:
        spin_unlock(mm->context.cop_lockp);
-       up_read(&mm->mmap_sem);
+       spin_unlock(&mm->page_table_lock);
 
        return ret;
 }
@@ -185,8 +185,8 @@ void drop_cop(unsigned long acop, struct mm_struct *mm)
        if (WARN_ON_ONCE(!mm))
                return;
 
-       /* We need to make sure mm_users doesn't change */
-       down_read(&mm->mmap_sem);
+       /* The page_table_lock ensures mm_users won't change under us */
+       spin_lock(&mm->page_table_lock);
        spin_lock(mm->context.cop_lockp);
 
        mm->context.acop &= ~acop;
@@ -213,7 +213,7 @@ void drop_cop(unsigned long acop, struct mm_struct *mm)
        }
 
        spin_unlock(mm->context.cop_lockp);
-       up_read(&mm->mmap_sem);
+       spin_unlock(&mm->page_table_lock);
 }
 EXPORT_SYMBOL_GPL(drop_cop);
 
index 336807de550efa1a33db56ffc5b5866c3013fbc9..5b63bd3da4a968fab738434d0a83a7db2f722dc8 100644 (file)
@@ -292,6 +292,11 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
        mm->context.id = MMU_NO_CONTEXT;
        mm->context.active = 0;
 
+#ifdef CONFIG_PPC_MM_SLICES
+       if (slice_mm_new_context(mm))
+               slice_set_user_psize(mm, mmu_virtual_psize);
+#endif
+
        return 0;
 }
 
index dd0a2589591dc0a66fffe8f7eb4d5b3a17944224..83eb5d5f53d52f51c278db4ff0f0d2d75a0f7c54 100644 (file)
@@ -142,6 +142,8 @@ extern unsigned long mmu_mapin_ram(unsigned long top);
 
 #elif defined(CONFIG_PPC_FSL_BOOK3E)
 extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
+extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
+                                phys_addr_t phys);
 #ifdef CONFIG_PPC32
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(unsigned long top);
index 2164006fe170f8e0e8a7adddd67e78803872c9e2..b22a83a91cb852b92d023529e3f1b3bf011dce38 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nodemask.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
@@ -315,7 +315,10 @@ static int __init find_min_common_depth(void)
        struct device_node *root;
        const char *vec5;
 
-       root = of_find_node_by_path("/rtas");
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               root = of_find_node_by_path("/ibm,opal");
+       else
+               root = of_find_node_by_path("/rtas");
        if (!root)
                root = of_find_node_by_path("/");
 
@@ -344,12 +347,19 @@ static int __init find_min_common_depth(void)
 
 #define VEC5_AFFINITY_BYTE     5
 #define VEC5_AFFINITY          0x80
-       chosen = of_find_node_by_path("/chosen");
-       if (chosen) {
-               vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
-               if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
-                       dbg("Using form 1 affinity\n");
-                       form1_affinity = 1;
+
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               form1_affinity = 1;
+       else {
+               chosen = of_find_node_by_path("/chosen");
+               if (chosen) {
+                       vec5 = of_get_property(chosen,
+                                              "ibm,architecture-vec-5", NULL);
+                       if (vec5 && (vec5[VEC5_AFFINITY_BYTE] &
+                                                       VEC5_AFFINITY)) {
+                               dbg("Using form 1 affinity\n");
+                               form1_affinity = 1;
+                       }
                }
        }
 
@@ -709,8 +719,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
 
 static int __init parse_numa_properties(void)
 {
-       struct device_node *cpu = NULL;
-       struct device_node *memory = NULL;
+       struct device_node *memory;
        int default_nid = 0;
        unsigned long i;
 
@@ -732,6 +741,7 @@ static int __init parse_numa_properties(void)
         * each node to be onlined must have NODE_DATA etc backing it.
         */
        for_each_present_cpu(i) {
+               struct device_node *cpu;
                int nid;
 
                cpu = of_get_cpu_node(i, NULL);
@@ -750,8 +760,8 @@ static int __init parse_numa_properties(void)
        }
 
        get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
-       memory = NULL;
-       while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+
+       for_each_node_by_type(memory, "memory") {
                unsigned long start;
                unsigned long size;
                int nid;
@@ -800,8 +810,9 @@ new_range:
        }
 
        /*
-        * Now do the same thing for each MEMBLOCK listed in the ibm,dynamic-memory
-        * property in the ibm,dynamic-reconfiguration-memory node.
+        * Now do the same thing for each MEMBLOCK listed in the
+        * ibm,dynamic-memory property in the
+        * ibm,dynamic-reconfiguration-memory node.
         */
        memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
        if (memory)
@@ -1187,10 +1198,10 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
  */
 int hot_add_node_scn_to_nid(unsigned long scn_addr)
 {
-       struct device_node *memory = NULL;
+       struct device_node *memory;
        int nid = -1;
 
-       while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+       for_each_node_by_type(memory, "memory") {
                unsigned long start, size;
                int ranges;
                const unsigned int *memcell_buf;
@@ -1214,11 +1225,12 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr)
                        break;
                }
 
-               of_node_put(memory);
                if (nid >= 0)
                        break;
        }
 
+       of_node_put(memory);
+
        return nid;
 }
 
index af40c8768a7824095878c475791053987ed57c4d..214130a4edc6bf2ff82b35bde8d955d98c75b01d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/hardirq.h>
+#include <linux/hugetlb.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
@@ -212,7 +213,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
        entry = set_access_flags_filter(entry, vma, dirty);
        changed = !pte_same(*(ptep), entry);
        if (changed) {
-               if (!(vma->vm_flags & VM_HUGETLB))
+               if (!is_vm_hugetlb_page(vma))
                        assert_pte_locked(vma->vm_mm, address);
                __ptep_set_access_flags(ptep, entry);
                flush_tlb_page_nohash(vma, address);
index 6e595f6496d428a9624f30f027f5a59bf2cfb27c..ad36ede469cc6a1248d520bd6b6915b9b8895501 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
index ba5194817f8ae67e275c49b66f4c86631c1013d4..73709f7ce92c2a1c98a7060e9ef8de00616792ad 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/pagemap.h>
 #include <linux/err.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/mman.h>
 #include <asm/mmu.h>
 #include <asm/spu.h>
index 9a445f64accd086fa549f0cd750ac999b7669eab..558e30cce33eed7017fbe3066e1868dd40a95db3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/export.h>
 
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
index 4ebb34bc01d6d7eacfd0f23b90f9c27f8f609b7f..dc4a5f385e41711317789f93771d1258d8ef890b 100644 (file)
@@ -553,24 +553,24 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
        rldicl  r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     virt_page_table_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     virt_page_table_tlb_miss_fault
 
 #ifndef CONFIG_PPC_64K_PAGES
        /* Get to PUD entry */
        rldicl  r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     virt_page_table_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     virt_page_table_tlb_miss_fault
 #endif /* CONFIG_PPC_64K_PAGES */
 
        /* Get to PMD entry */
        rldicl  r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     virt_page_table_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     virt_page_table_tlb_miss_fault
 
        /* Ok, we're all right, we can now create a kernel translation for
         * a 4K or 64K page from r16 -> r15.
@@ -802,24 +802,24 @@ htw_tlb_miss:
        rldicl  r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     htw_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     htw_tlb_miss_fault
 
 #ifndef CONFIG_PPC_64K_PAGES
        /* Get to PUD entry */
        rldicl  r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     htw_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     htw_tlb_miss_fault
 #endif /* CONFIG_PPC_64K_PAGES */
 
        /* Get to PMD entry */
        rldicl  r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
        clrrdi  r10,r11,3
        ldx     r15,r10,r15
-       cmpldi  cr0,r15,0
-       beq     htw_tlb_miss_fault
+       cmpdi   cr0,r15,0
+       bge     htw_tlb_miss_fault
 
        /* Ok, we're all right, we can now create an indirect entry for
         * a 1M or 256M page.
index d32ec643c231fa6b038d579b7112e590c03daf92..4e13d6f9023e851a3f17ff240d9076030506c99e 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
+#include <linux/hugetlb.h>
 
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 #include <asm/code-patching.h>
+#include <asm/hugetlb.h>
 
 #include "mmu_decl.h"
 
-#ifdef CONFIG_PPC_BOOK3E
+/*
+ * This struct lists the sw-supported page sizes.  The hardawre MMU may support
+ * other sizes not listed here.   The .ind field is only used on MMUs that have
+ * indirect page table entries.
+ */
+#ifdef CONFIG_PPC_BOOK3E_MMU
+#ifdef CONFIG_FSL_BOOKE
+struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
+       [MMU_PAGE_4K] = {
+               .shift  = 12,
+               .enc    = BOOK3E_PAGESZ_4K,
+       },
+       [MMU_PAGE_4M] = {
+               .shift  = 22,
+               .enc    = BOOK3E_PAGESZ_4M,
+       },
+       [MMU_PAGE_16M] = {
+               .shift  = 24,
+               .enc    = BOOK3E_PAGESZ_16M,
+       },
+       [MMU_PAGE_64M] = {
+               .shift  = 26,
+               .enc    = BOOK3E_PAGESZ_64M,
+       },
+       [MMU_PAGE_256M] = {
+               .shift  = 28,
+               .enc    = BOOK3E_PAGESZ_256M,
+       },
+       [MMU_PAGE_1G] = {
+               .shift  = 30,
+               .enc    = BOOK3E_PAGESZ_1GB,
+       },
+};
+#else
 struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
        [MMU_PAGE_4K] = {
                .shift  = 12,
@@ -77,6 +113,8 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
                .enc    = BOOK3E_PAGESZ_1GB,
        },
 };
+#endif /* CONFIG_FSL_BOOKE */
+
 static inline int mmu_get_tsize(int psize)
 {
        return mmu_psize_defs[psize].enc;
@@ -87,7 +125,7 @@ static inline int mmu_get_tsize(int psize)
        /* This isn't used on !Book3E for now */
        return 0;
 }
-#endif
+#endif /* CONFIG_PPC_BOOK3E_MMU */
 
 /* The variables below are currently only used on 64-bit Book3E
  * though this will probably be made common with other nohash
@@ -266,6 +304,11 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
 {
+#ifdef CONFIG_HUGETLB_PAGE
+       if (is_vm_hugetlb_page(vma))
+               flush_hugetlb_page(vma, vmaddr);
+#endif
+
        __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr,
                         mmu_get_tsize(mmu_virtual_psize), 0);
 }
@@ -600,13 +643,28 @@ void __cpuinit early_init_mmu_secondary(void)
 void setup_initial_memory_limit(phys_addr_t first_memblock_base,
                                phys_addr_t first_memblock_size)
 {
-       /* On Embedded 64-bit, we adjust the RMA size to match
+       /* On non-FSL Embedded 64-bit, we adjust the RMA size to match
         * the bolted TLB entry. We know for now that only 1G
         * entries are supported though that may eventually
-        * change. We crop it to the size of the first MEMBLOCK to
+        * change.
+        *
+        * on FSL Embedded 64-bit, we adjust the RMA size to match the
+        * first bolted TLB entry size.  We still limit max to 1G even if
+        * the TLB could cover more.  This is due to what the early init
+        * code is setup to do.
+        *
+        * We crop it to the size of the first MEMBLOCK to
         * avoid going over total available memory just in case...
         */
-       ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+               unsigned long linear_sz;
+               linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET,
+                                       first_memblock_base);
+               ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
+       } else
+#endif
+               ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
 
        /* Finally limit subsequent allocations */
        memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
index b5d87067a58b142cf8cb4206a9bfab74e6fbe51f..153022971daab89ad20241aecd2bcefcaf303e08 100644 (file)
@@ -32,14 +32,6 @@ config EP405
        help
          This option enables support for the EP405/EP405PC boards.
 
-config HCU4
-       bool "Hcu4"
-       depends on 40x
-       default n
-       select 405GPR
-       help
-         This option enables support for the Nestal Maschinen HCU4 board.
-
 config HOTFOOT
         bool "Hotfoot"
        depends on 40x
@@ -115,11 +107,6 @@ config PPC40x_SIMPLE
        help
          This option enables the simple PowerPC 40x platform support.
 
-# 40x specific CPU modules, selected based on the board above.
-config NP405H
-       bool
-       #depends on ASH
-
 # OAK doesn't exist but wanted to keep this around for any future 403GCX boards
 config 403GCX
        bool
index 56e89004c468cc3e43f1a8037354152be20130a2..88c22de0c85051baecd4123e3dfd0b0a9538ce9d 100644 (file)
@@ -1,4 +1,3 @@
-obj-$(CONFIG_HCU4)                             += hcu4.o
 obj-$(CONFIG_WALNUT)                           += walnut.o
 obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)      += virtex.o
 obj-$(CONFIG_EP405)                            += ep405.o
diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c
deleted file mode 100644 (file)
index 60b2afe..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Architecture- / platform-specific boot-time initialization code for
- * IBM PowerPC 4xx based boards. Adapted from original
- * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
- * <dan@net4x.com>.
- *
- * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
- *
- * Rewritten and ported to the merged powerpc tree:
- * Copyright 2007 IBM Corporation
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- *
- * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id hcu4_of_bus[] = {
-       { .compatible = "ibm,plb3", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init hcu4_device_probe(void)
-{
-       of_platform_bus_probe(NULL, hcu4_of_bus, NULL);
-       return 0;
-}
-machine_device_initcall(hcu4, hcu4_device_probe);
-
-static int __init hcu4_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "netstal,hcu4"))
-               return 0;
-
-       return 1;
-}
-
-define_machine(hcu4) {
-       .name                   = "HCU4",
-       .probe                  = hcu4_probe,
-       .progress               = udbg_progress,
-       .init_IRQ               = uic_init_tree,
-       .get_irq                = uic_get_irq,
-       .restart                = ppc4xx_reset_system,
-       .calibrate_decr         = generic_calibrate_decr,
-};
index 8f771395f424e6d345ad8e6d2a36b093aa9ea946..4cfa49901c023f069828c5b8f50a1b5028cf69bf 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of_gpio.h>
 #include <linux/of_i2c.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
index 27b0651221d157598f72fc7932bfc78b95b4d31f..b3ebce1aec075e7c699e0ead4448d631cd9722a6 100644 (file)
@@ -6,6 +6,7 @@ config PPC_MPC512x
        select PPC_CLOCK
        select PPC_PCI_CHOICE
        select FSL_PCI if PCI
+       select ARCH_WANT_OPTIONAL_GPIOLIB
 
 config MPC5121_ADS
        bool "Freescale MPC5121E ADS"
index 3dc2a8d262b8731aa4995b6c4b20621f06742fef..1d8700ff60b0ec1b35eb2f989ea8ef33e2992d07 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/clk.h>
 #include <linux/mutex.h>
index e36d6e232ae66f4bf3033e5b60363cea25e46008..846b789fb1953000d15f90f1da723f0b0d81ff43 100644 (file)
@@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
 
 /* list of the supported boards */
 static const char *board[] __initdata = {
+       "anon,charon",
        "intercontrol,digsy-mtc",
        "manroland,mucmc52",
        "manroland,uc101",
index 41f3a7eda1def670c1c12864de488788fc27ff98..369fd5457a3f2edc13dba2072be8e8384f3e6489 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/spinlock.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/mpc52xx.h>
index 6c39b9cc2fa3fe0b367d92e086a7f9b046f93700..f94f06e52762093d018b91a32b2fa243aa168c9f 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/watchdog.h>
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 #include <asm/div64.h>
 #include <asm/mpc52xx.h>
 
index 9940ce8a2d4eff3fffb9d5458a46e98683a58351..d61fb1c0c1a05cecff284de0ac89b48f4625d0a1 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/mpc52xx.h>
index 428c5e0a0e758b6b1b8b6dddbc098c507505aa17..3661bcdc326a6551b0e0a11c8d964e4b0597a619 100644 (file)
@@ -49,6 +49,9 @@ struct cpm_pin {
 };
 
 static __initdata struct cpm_pin km82xx_pins[] = {
+       /* SMC1 */
+       {2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+       {2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 
        /* SMC2 */
        {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
@@ -137,6 +140,7 @@ static void __init init_ioports(void)
        }
 
        cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
+       cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7);
        cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX);
        cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX);
        cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX);
index 73f4135f3a1a6e8780e976b83fa0afc4a73d902f..670a033264c0f1626af64f79b7b4fd23da797ec4 100644 (file)
@@ -114,18 +114,21 @@ config KMETER1
 
 endif
 
-# used for usb
+# used for usb & gpio
 config PPC_MPC831x
        bool
+       select ARCH_WANT_OPTIONAL_GPIOLIB
 
 # used for math-emu
 config PPC_MPC832x
        bool
 
-# used for usb
+# used for usb & gpio
 config PPC_MPC834x
        bool
+       select ARCH_WANT_OPTIONAL_GPIOLIB
 
-# used for usb
+# used for usb & gpio
 config PPC_MPC837x
        bool
+       select ARCH_WANT_OPTIONAL_GPIOLIB
index 70798ac911ef056b73eba4fccce9db0c157b37e8..ef6537b8ed330185393aa92f54ffc2151d6c255a 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/reboot.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 
@@ -30,6 +32,7 @@
  */
 #define MCU_REG_CTRL   0x20
 #define MCU_CTRL_POFF  0x40
+#define MCU_CTRL_BTN   0x80
 
 #define MCU_NUM_GPIO   2
 
@@ -42,13 +45,55 @@ struct mcu {
 
 static struct mcu *glob_mcu;
 
+struct task_struct *shutdown_thread;
+static int shutdown_thread_fn(void *data)
+{
+       int ret;
+       struct mcu *mcu = glob_mcu;
+
+       while (!kthread_should_stop()) {
+               ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
+               if (ret < 0)
+                       pr_err("MCU status reg read failed.\n");
+               mcu->reg_ctrl = ret;
+
+
+               if (mcu->reg_ctrl & MCU_CTRL_BTN) {
+                       i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL,
+                                                 mcu->reg_ctrl & ~MCU_CTRL_BTN);
+
+                       ctrl_alt_del();
+               }
+
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(HZ);
+       }
+
+       return 0;
+}
+
+static ssize_t show_status(struct device *d,
+                          struct device_attribute *attr, char *buf)
+{
+       int ret;
+       struct mcu *mcu = glob_mcu;
+
+       ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
+       if (ret < 0)
+               return -ENODEV;
+       mcu->reg_ctrl = ret;
+
+       return sprintf(buf, "%02x\n", ret);
+}
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+
 static void mcu_power_off(void)
 {
        struct mcu *mcu = glob_mcu;
 
        pr_info("Sending power-off request to the MCU...\n");
        mutex_lock(&mcu->lock);
-       i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL,
+       i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL,
                                  mcu->reg_ctrl | MCU_CTRL_POFF);
        mutex_unlock(&mcu->lock);
 }
@@ -130,6 +175,13 @@ static int __devinit mcu_probe(struct i2c_client *client,
                dev_info(&client->dev, "will provide power-off service\n");
        }
 
+       if (device_create_file(&client->dev, &dev_attr_status))
+               dev_err(&client->dev,
+                       "couldn't create device file for status\n");
+
+       shutdown_thread = kthread_run(shutdown_thread_fn, NULL,
+                                     "mcu-i2c-shdn");
+
        return 0;
 err:
        kfree(mcu);
@@ -141,6 +193,10 @@ static int __devexit mcu_remove(struct i2c_client *client)
        struct mcu *mcu = i2c_get_clientdata(client);
        int ret;
 
+       kthread_stop(shutdown_thread);
+
+       device_remove_file(&client->dev, &dev_attr_status);
+
        if (glob_mcu == mcu) {
                ppc_md.power_off = NULL;
                glob_mcu = NULL;
index 104faa8aa23c783da70b2dd97dac842ff8198c3c..edf66870d978b0e4a5286e37cb74e3ab13d5c5f0 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/suspend.h>
 #include <linux/fsl_devices.h>
 #include <linux/of_platform.h>
+#include <linux/export.h>
 
 #include <asm/reg.h>
 #include <asm/io.h>
index 12f5932dadc93b505d26eb4d44ea9160e2fea725..d7946be298b6fc1f842eaff3e14b4ae502924f3c 100644 (file)
@@ -171,17 +171,18 @@ config SBC8560
        help
          This option enables support for the Wind River SBC8560 board
 
-config P2040_RDB
-       bool "Freescale P2040 RDB"
+config P2041_RDB
+       bool "Freescale P2041 RDB"
        select DEFAULT_UIMAGE
        select PPC_E500MC
        select PHYS_64BIT
        select SWIOTLB
-       select MPC8xxx_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select GPIO_MPC8XXX
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
-         This option enables support for the P2040 RDB board
+         This option enables support for the P2041 RDB board
 
 config P3041_DS
        bool "Freescale P3041 DS"
@@ -189,19 +190,33 @@ config P3041_DS
        select PPC_E500MC
        select PHYS_64BIT
        select SWIOTLB
-       select MPC8xxx_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select GPIO_MPC8XXX
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
          This option enables support for the P3041 DS board
 
+config P3060_QDS
+       bool "Freescale P3060 QDS"
+       select DEFAULT_UIMAGE
+       select PPC_E500MC
+       select PHYS_64BIT
+       select SWIOTLB
+       select GPIO_MPC8XXX
+       select HAS_RAPIDIO
+       select PPC_EPAPR_HV_PIC
+       help
+         This option enables support for the P3060 QDS board
+
 config P4080_DS
        bool "Freescale P4080 DS"
        select DEFAULT_UIMAGE
        select PPC_E500MC
        select PHYS_64BIT
        select SWIOTLB
-       select MPC8xxx_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select GPIO_MPC8XXX
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
@@ -216,7 +231,8 @@ config P5020_DS
        select PPC_E500MC
        select PHYS_64BIT
        select SWIOTLB
-       select MPC8xxx_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select GPIO_MPC8XXX
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
index a971b32c5c0a3c43175b10172aebaedbc7d12b9e..bc5acb95917af5a35d6ceb561a277b4769f39483 100644 (file)
@@ -13,8 +13,9 @@ obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
 obj-$(CONFIG_P1010_RDB)   += p1010rdb.o
 obj-$(CONFIG_P1022_DS)    += p1022_ds.o
 obj-$(CONFIG_P1023_RDS)   += p1023_rds.o
-obj-$(CONFIG_P2040_RDB)   += p2040_rdb.o corenet_ds.o
+obj-$(CONFIG_P2041_RDB)   += p2041_rdb.o corenet_ds.o
 obj-$(CONFIG_P3041_DS)    += p3041_ds.o corenet_ds.o
+obj-$(CONFIG_P3060_QDS)   += p3060_qds.o corenet_ds.o
 obj-$(CONFIG_P4080_DS)    += p4080_ds.o corenet_ds.o
 obj-$(CONFIG_P5020_DS)    += p5020_ds.o corenet_ds.o
 obj-$(CONFIG_STX_GP3)    += stx_gp3.o
index 2bf99786d249580c4aaf0c138b87c0ef507802de..66cb8d64079fa9e692fdd6deac3909ab05aa67d0 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/initrd.h>
-#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
 #include <linux/of_platform.h>
index 973b3f4a4b495c3b07fe51389a1ffc02322d3973..a23a3ff634c55fdd3d949a8a2a77a8405b5b2de8 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/initrd.h>
-#include <linux/module.h>
 #include <linux/fsl_devices.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
index c01c7277888c1e3655fddd6be2dfe2da21705182..fda15716fada03eb80cbc0a4761b55a6dffbe47c 100644 (file)
@@ -129,17 +129,20 @@ static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port,
  */
 static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
 {
-       struct device_node *pixis_node;
+       struct device_node *np;
        void __iomem *pixis;
        u8 __iomem *brdcfg1;
 
-       pixis_node = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis");
-       if (!pixis_node) {
+       np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-fpga");
+       if (!np)
+               /* older device trees used "fsl,p1022ds-pixis" */
+               np = of_find_compatible_node(NULL, NULL, "fsl,p1022ds-pixis");
+       if (!np) {
                pr_err("p1022ds: missing ngPIXIS node\n");
                return;
        }
 
-       pixis = of_iomap(pixis_node, 0);
+       pixis = of_iomap(np, 0);
        if (!pixis) {
                pr_err("p1022ds: could not map ngPIXIS registers\n");
                return;
diff --git a/arch/powerpc/platforms/85xx/p2040_rdb.c b/arch/powerpc/platforms/85xx/p2040_rdb.c
deleted file mode 100644 (file)
index 32b56ac..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * P2040 RDB Setup
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/system.h>
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p2040_rdb_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P2040RDB"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P2040RDB-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p2040_rdb) {
-       .name                   = "P2040 RDB",
-       .probe                  = p2040_rdb_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-       .power_save             = e500_idle,
-};
-
-machine_device_initcall(p2040_rdb, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p2040_rdb, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/p2041_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c
new file mode 100644 (file)
index 0000000..eda6ed5
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * P2041 RDB Setup
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/phy.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include <asm/ehv_pic.h>
+
+#include "corenet_ds.h"
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2041_rdb_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+#ifdef CONFIG_SMP
+       extern struct smp_ops_t smp_85xx_ops;
+#endif
+
+       if (of_flat_dt_is_compatible(root, "fsl,P2041RDB"))
+               return 1;
+
+       /* Check if we're running under the Freescale hypervisor */
+       if (of_flat_dt_is_compatible(root, "fsl,P2041RDB-hv")) {
+               ppc_md.init_IRQ = ehv_pic_init;
+               ppc_md.get_irq = ehv_pic_get_irq;
+               ppc_md.restart = fsl_hv_restart;
+               ppc_md.power_off = fsl_hv_halt;
+               ppc_md.halt = fsl_hv_halt;
+#ifdef CONFIG_SMP
+               /*
+                * Disable the timebase sync operations because we can't write
+                * to the timebase registers under the hypervisor.
+                 */
+               smp_85xx_ops.give_timebase = NULL;
+               smp_85xx_ops.take_timebase = NULL;
+#endif
+               return 1;
+       }
+
+       return 0;
+}
+
+define_machine(p2041_rdb) {
+       .name                   = "P2041 RDB",
+       .probe                  = p2041_rdb_probe,
+       .setup_arch             = corenet_ds_setup_arch,
+       .init_IRQ               = corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+       .get_irq                = mpic_get_coreint_irq,
+       .restart                = fsl_rstcr_restart,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+       .power_save             = e500_idle,
+};
+
+machine_device_initcall(p2041_rdb, corenet_ds_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier);
+#endif
diff --git a/arch/powerpc/platforms/85xx/p3060_qds.c b/arch/powerpc/platforms/85xx/p3060_qds.c
new file mode 100644 (file)
index 0000000..081cf4a
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * P3060 QDS Setup
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/phy.h>
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include <asm/ehv_pic.h>
+#include "corenet_ds.h"
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p3060_qds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+#ifdef CONFIG_SMP
+       extern struct smp_ops_t smp_85xx_ops;
+#endif
+
+       if (of_flat_dt_is_compatible(root, "fsl,P3060QDS"))
+               return 1;
+
+       /* Check if we're running under the Freescale hypervisor */
+       if (of_flat_dt_is_compatible(root, "fsl,P3060QDS-hv")) {
+               ppc_md.init_IRQ = ehv_pic_init;
+               ppc_md.get_irq = ehv_pic_get_irq;
+               ppc_md.restart = fsl_hv_restart;
+               ppc_md.power_off = fsl_hv_halt;
+               ppc_md.halt = fsl_hv_halt;
+#ifdef CONFIG_SMP
+               /*
+                * Disable the timebase sync operations because we can't write
+                * to the timebase registers under the hypervisor.
+                */
+               smp_85xx_ops.give_timebase = NULL;
+               smp_85xx_ops.take_timebase = NULL;
+#endif
+               return 1;
+       }
+
+       return 0;
+}
+
+define_machine(p3060_qds) {
+       .name                   = "P3060 QDS",
+       .probe                  = p3060_qds_probe,
+       .setup_arch             = corenet_ds_setup_arch,
+       .init_IRQ               = corenet_ds_pic_init,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+       .get_irq                = mpic_get_coreint_irq,
+       .restart                = fsl_rstcr_restart,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+       .power_save             = e500_idle,
+};
+
+machine_device_initcall(p3060_qds, corenet_ds_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(p3060_qds, swiotlb_setup_bus_notifier);
+#endif
index d07dcb7f4ee980b9a71fb8246719ab6c0602d201..14632a971225c7b497f51e13c61c9bf2ce49db20 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/initrd.h>
-#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
 #include <linux/of_platform.h>
index 09ced72217501fdb1da38ffa0612441b40d9f6b1..cebd786dc3340be03adc63a11814574653b2688e 100644 (file)
@@ -283,7 +283,7 @@ static int __init sbc8560_bdrstcr_init(void)
 
        of_address_to_resource(np, 0, &res);
 
-       printk(KERN_INFO "sbc8560: Found BRSTCR at i/o 0x%x\n", res.start);
+       printk(KERN_INFO "sbc8560: Found BRSTCR at %pR\n", &res);
 
        brstcr = ioremap(res.start, resource_size(&res));
        if(!brstcr)
index 5b9b901f64432b2a2fd124b981d9ab1630b44c95..2df4785ffd4ee3d0307190247f6398190810525a 100644 (file)
@@ -48,10 +48,11 @@ smp_85xx_kick_cpu(int nr)
        const u64 *cpu_rel_addr;
        __iomem u32 *bptr_vaddr;
        struct device_node *np;
-       int n = 0;
+       int n = 0, hw_cpu = get_hard_smp_processor_id(nr);
        int ioremappable;
 
-       WARN_ON (nr < 0 || nr >= NR_CPUS);
+       WARN_ON(nr < 0 || nr >= NR_CPUS);
+       WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
 
        pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
 
@@ -79,7 +80,7 @@ smp_85xx_kick_cpu(int nr)
 
        local_irq_save(flags);
 
-       out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
+       out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
 #ifdef CONFIG_PPC32
        out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
 
@@ -88,7 +89,7 @@ smp_85xx_kick_cpu(int nr)
                                (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
 
        /* Wait a bit for the CPU to ack. */
-       while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
+       while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000))
                mdelay(1);
 #else
        smp_generic_kick_cpu(nr);
@@ -206,7 +207,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
        if ( !timeout )
                printk(KERN_ERR "Unable to bring down secondary cpu(s)");
 
-       for (i = 0; i < num_cpus; i++)
+       for_each_online_cpu(i)
        {
                if ( i == smp_processor_id() ) continue;
                mpic_reset_core(i);
@@ -243,6 +244,7 @@ void __init mpc85xx_smp_init(void)
                 * If left NULL, .message_pass defaults to
                 * smp_muxed_ipi_message_pass
                 */
+               smp_85xx_ops.message_pass = NULL;
                smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
        }
 
index a0b5638c5dc8bfef5cbfcc1d57b759c8f57bd387..8d6599d54ea6caadf8476cc42ba56734b1edfbcc 100644 (file)
@@ -4,6 +4,7 @@ menuconfig PPC_86xx
        depends on 6xx
        select FSL_SOC
        select ALTIVEC
+       select ARCH_WANT_OPTIONAL_GPIOLIB
        help
          The Freescale E600 SoCs have 74xx cores.
 
index 4ff7b1e7bbada2917bfd89e2950ac0c178f6a554..2a703365e664d5926ffd082df5b561a50dbcc98b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define GEF_GPIO_DIRECT                0x00
 #define GEF_GPIO_IN            0x04
index b71c650fbb11a8da0b4fff54edea8aed24cb8407..528e00ddef31ca46e1fb48c8bd2f691cffa3f178 100644 (file)
@@ -18,7 +18,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
index b9ba86191aedba2a7d50901756733addc3601998..3fe6d927ad70e928d302192d275fd0b69220af05 100644 (file)
@@ -1,5 +1,6 @@
 menu "Platform support"
 
+source "arch/powerpc/platforms/powernv/Kconfig"
 source "arch/powerpc/platforms/pseries/Kconfig"
 source "arch/powerpc/platforms/iseries/Kconfig"
 source "arch/powerpc/platforms/chrp/Kconfig"
@@ -333,16 +334,6 @@ config OF_RTC
 
 source "arch/powerpc/sysdev/bestcomm/Kconfig"
 
-config MPC8xxx_GPIO
-       bool "MPC512x/MPC8xxx GPIO support"
-       depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
-                  FSL_SOC_BOOKE || PPC_86xx
-       select GENERIC_GPIO
-       select ARCH_REQUIRE_GPIOLIB
-       help
-         Say Y here if you're going to use hardware that connects to the
-         MPC512x/831x/834x/837x/8572/8610 GPIOs.
-
 config SIMPLE_GPIO
        bool "Support for simple, memory-mapped GPIO controllers"
        depends on PPC
@@ -355,8 +346,8 @@ config SIMPLE_GPIO
          on-board peripherals.
 
 config MCU_MPC8349EMITX
-       tristate "MPC8349E-mITX MCU driver"
-       depends on I2C && PPC_83xx
+       bool "MPC8349E-mITX MCU driver"
+       depends on I2C=y && PPC_83xx
        select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
        help
index e06e39589a09e2b63e786c787484509c6149c311..fbecae0fbb49cc35aa01eb2002f61986c1ce25b9 100644 (file)
@@ -69,6 +69,7 @@ config PPC_BOOK3S_64
        bool "Server processors"
        select PPC_FPU
        select PPC_HAVE_PMU_SUPPORT
+       select SYS_SUPPORTS_HUGETLBFS
 
 config PPC_BOOK3E_64
        bool "Embedded processors"
@@ -173,6 +174,7 @@ config BOOKE
 config FSL_BOOKE
        bool
        depends on (E200 || E500) && PPC32
+       select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT
        default y
 
 # this is for common code between PPC32 & PPC64 FSL BOOKE
@@ -282,21 +284,13 @@ config PPC_MMU_NOHASH
        def_bool y
        depends on !PPC_STD_MMU
 
-config PPC_MMU_NOHASH_32
-       def_bool y
-       depends on PPC_MMU_NOHASH && PPC32
-
-config PPC_MMU_NOHASH_64
-       def_bool y
-       depends on PPC_MMU_NOHASH && PPC64
-
 config PPC_BOOK3E_MMU
        def_bool y
        depends on FSL_BOOKE || PPC_BOOK3E
 
 config PPC_MM_SLICES
        bool
-       default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES)
+       default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES)
        default n
 
 config VIRT_CPU_ACCOUNTING
index 73e2116cfeed20858b0f9509b0c66b2effe8849e..2635a22bade22b0d3211c529623860992f5b2c76 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_PPC_82xx)                += 82xx/
 obj-$(CONFIG_PPC_83xx)         += 83xx/
 obj-$(CONFIG_FSL_SOC_BOOKE)    += 85xx/
 obj-$(CONFIG_PPC_86xx)         += 86xx/
+obj-$(CONFIG_PPC_POWERNV)      += powernv/
 obj-$(CONFIG_PPC_PSERIES)      += pseries/
 obj-$(CONFIG_PPC_ISERIES)      += iseries/
 obj-$(CONFIG_PPC_MAPLE)                += maple/
index ac06903e136a2df7f9b871013878c7fcb7aed761..40a6e34793b4a795548ab73173d0c1b45f72b765 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/msi.h>
+#include <linux/export.h>
 #include <linux/of_platform.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
index 48c690ea65da36844de63f177e6d4982d4ec7fa4..852592b2b7128e0fd72b41dca54f123e827240df 100644 (file)
@@ -18,7 +18,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/rtc.h>
@@ -230,7 +230,7 @@ static int __init beat_register_event(void)
                }
                ev->virq = virq;
 
-               rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+               rc = request_irq(virq, ev->handler, 0,
                                      ev->typecode, NULL);
                if (rc != 0) {
                        printk(KERN_ERR "Beat: failed to request virtual IRQ"
index bcc17f7fe8adfaba96ba7763ae675af31fb27c15..13f52589d3a91104b00f9345d0b7568e2a068f92 100644 (file)
@@ -18,8 +18,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <linux/module.h>
-
 #include <asm/types.h>
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
index b47dfda48d0672442b212d41dd93cbaa0833e437..c1109969f24257579950b1569d7a24e000a388c2 100644 (file)
@@ -20,6 +20,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 #ifndef BEAT_HCALL
+#include <linux/string.h>
 #include "beat_syscall.h"
 
 /* defined in hvCall.S */
index bfa2c0cb3d1ed37c48cac4f5de8d22f7b8006431..d4c39e32f147d77a99dc21739e993c5ef71d6ce5 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/cpufreq.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 
 #include <asm/machdep.h>
index 3233fe84d1584bc37de268ea7ebc2349a386635c..60a07a4f9326afb7c8f538de2c45040dbe124d4b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/timer.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 
 #include <asm/processor.h>
index f75a4daa4ca2821439b17177a43a0969e1d2cf82..2bb8031303f0cdd1d1105832217686d73b0fe444 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <asm/pmi.h>
 #include <asm/prom.h>
index f3917e7a5b443dae4580cc67a8cbc3c132040c56..1428d583c238ccd270e260e131b92e3748ec7346 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/percpu.h>
 #include <linux/types.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 
index ae790ac4a589182b3f1e4a5873396cbcd71fdc6f..14be2bd358b83e1c3ac71d964e8ba92c08c0536e 100644 (file)
@@ -514,7 +514,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
        virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
                                     oirq.size);
        if (request_irq(virq, pciex_handle_internal_irq,
-                       IRQF_DISABLED, "pciex", (void *)phb)) {
+                       0, "pciex", (void *)phb)) {
                pr_err("PCIEXC:Failed to request irq\n");
                goto error;
        }
index d58d9bae4b9bf16260257f3c9037bf2ee99bea6e..1d5a4d8ddad9dd221f110ba3768db00134055bad 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/cpu.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
index 7f92096fe9685ca02659433082c6c1b58038db86..23bc9db4317e80a869c3a47074ef20b0b08f6c02 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/cpufreq.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/atomic.h>
index 3e4eba603e6b6162fbbdb71679f2f37656dbd40a..96a433dd2d64ea6568afbb7abb863bfe7819c927 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
index 26a067122a54705ab07840269a6a9b4e9b9f41a5..592c3d51b8178e5af2b2c8b552ebbfde177e4323 100644 (file)
@@ -412,8 +412,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
                        IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT));
        BUG_ON(virq == NO_IRQ);
 
-       ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED,
-                       iommu->name, iommu);
+       ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu);
        BUG_ON(ret);
 
        /* set the IOC segment table origin register (and turn on the iommu) */
@@ -1159,6 +1158,26 @@ static int __init setup_iommu_fixed(char *str)
 }
 __setup("iommu_fixed=", setup_iommu_fixed);
 
+static u64 cell_dma_get_required_mask(struct device *dev)
+{
+       struct dma_map_ops *dma_ops;
+
+       if (!dev->dma_mask)
+               return 0;
+
+       if (!iommu_fixed_disabled &&
+                       cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR)
+               return DMA_BIT_MASK(64);
+
+       dma_ops = get_dma_ops(dev);
+       if (dma_ops->get_required_mask)
+               return dma_ops->get_required_mask(dev);
+
+       WARN_ONCE(1, "no get_required_mask in %p ops", dma_ops);
+
+       return DMA_BIT_MASK(64);
+}
+
 static int __init cell_iommu_init(void)
 {
        struct device_node *np;
@@ -1175,6 +1194,7 @@ static int __init cell_iommu_init(void)
 
        /* Setup various ppc_md. callbacks */
        ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
+       ppc_md.dma_get_required_mask = cell_dma_get_required_mask;
        ppc_md.tce_build = tce_build_cell;
        ppc_md.tce_free = tce_free_cell;
 
index 69ed0d7f164673f069073231bed32e3ba72bd014..59c1a1694104f0a4048e23b75535fe4eaa4f0068 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/types.h>
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/irq_regs.h>
 #include <asm/machdep.h>
@@ -391,7 +392,7 @@ static int __init cbe_init_pm_irq(void)
                }
 
                rc = request_irq(irq, cbe_pm_irq,
-                                IRQF_DISABLED, "cbe-pmu-0", NULL);
+                                0, "cbe-pmu-0", NULL);
                if (rc) {
                        printk("ERROR: Request for irq on node %d failed\n",
                               node);
index 51e290126bc13c3b731734664d079638e9b5fd35..7f9b6742f8b65889e5d90db2a0cb2f752eac301e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/console.h>
index c73cf4c43fc2ff25527d7754a5136e9140a0ad30..0fc9b7256126612ac51691fcb41fc7a65d52fd0c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
+#include <linux/export.h>
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/reboot.h>
index f2e1dfe4bf318ec5e43d316508161abb462e6b99..f5c5c762d5a3df8d971e737c9f4863735b3bf125 100644 (file)
@@ -15,7 +15,6 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
index 3675da73623f156fb86528b8d9132b7399d72a17..e94d3ecdd8bbc7ceff338c2016272103d5bbf2d4 100644 (file)
@@ -442,8 +442,7 @@ static int spu_request_irqs(struct spu *spu)
                snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0",
                         spu->number);
                ret = request_irq(spu->irqs[0], spu_irq_class_0,
-                                 IRQF_DISABLED,
-                                 spu->irq_c0, spu);
+                                 0, spu->irq_c0, spu);
                if (ret)
                        goto bail0;
        }
@@ -451,8 +450,7 @@ static int spu_request_irqs(struct spu *spu)
                snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1",
                         spu->number);
                ret = request_irq(spu->irqs[1], spu_irq_class_1,
-                                 IRQF_DISABLED,
-                                 spu->irq_c1, spu);
+                                 0, spu->irq_c1, spu);
                if (ret)
                        goto bail1;
        }
@@ -460,8 +458,7 @@ static int spu_request_irqs(struct spu *spu)
                snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2",
                         spu->number);
                ret = request_irq(spu->irqs[2], spu_irq_class_2,
-                                 IRQF_DISABLED,
-                                 spu->irq_c2, spu);
+                                 0, spu->irq_c2, spu);
                if (ret)
                        goto bail2;
        }
index fec1495e6b12f98a8a12e9c9436fa2f2fdc76782..75d613313f10c4acceccd75199693730b1b9bbaa 100644 (file)
@@ -5,7 +5,7 @@
 #undef DEBUG
 
 #include <linux/kallsyms.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/syscalls.h>
 
 #include <asm/spu.h>
index d06ba87f1a19e8b6d40906d330446395ffeec0d3..641e7273d75ae687335716c5b4e87c9afcdb98c7 100644 (file)
@@ -22,7 +22,7 @@
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/spu.h>
 #include <asm/spu_csa.h>
index 4e5c91489c0294c049f81fe3178fe2e682c4bb58..2bb6977c0a5aeee65b2f83400af8198fded3c543 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/list.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/ptrace.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
index 34d156959f39943c4984a4d9fc2c4775340a81e4..afdf857c318fe44792acfb0c013e5625d66e8f2a 100644 (file)
@@ -21,7 +21,8 @@
 
 #undef DEBUG
 
-#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/notifier.h>
 #include <asm/spu.h>
 #include "spufs/spufs.h"
 
index 121aec353f268b007c558258acd206821efd13e8..66d33724f16e2cd759c07088f4900e9690a40fe8 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/ptrace.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
index 64eb15b22040aec7f005b0d70f264318f7b650a7..6e8a9ef8590eb4136667bddb81803c1ec5f2a268 100644 (file)
@@ -21,7 +21,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index bf4d41d8fa148f8a101a46ed04842e2482619a8d..9c6790d17eda17e7dc87cbaf67f8f8d5d59db044 100644 (file)
@@ -22,9 +22,9 @@
 
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
+#include <linux/sched.h>
 #include <asm/spu.h>
 #include <asm/spu_csa.h>
 #include "spufs.h"
index 6cf3ec62852776ef78f3daa5864ad1615af36c8f..03c5fce2a5b38b57105877608f8ddfa2a8512a5d 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
index a4dd3ae7223ac3100da4fb48f1e87d545ba7e609..8cb6260cc80fa66231a4e7d5205ebb94e3a9b9a2 100644 (file)
@@ -21,7 +21,6 @@
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 
 #include <asm/spu.h>
 #include <asm/spu_csa.h>
index fb59c46e9e9eea5946ca12aac0cfb325b1c774ca..0cfece4cf6ef36dd9e892654ffad946346ea82f8 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <linux/fs.h>
 #include <linux/ioctl.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pagemap.h>
 #include <linux/poll.h>
 #include <linux/ptrace.h>
index 64f8540b832c32bc703b37498965985465bf6903..8655c4cbefc283298685a125aba4a36782d37af0 100644 (file)
@@ -18,7 +18,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index 32cb4e66d2cd032220dd110c5a3a803bb066cf4f..965d381abd75c100bcb88c71ff6fb1f9b4e3ad6b 100644 (file)
@@ -22,7 +22,6 @@
 
 #undef DEBUG
 
-#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index 3df9a36eb2f58efe6bcda41f7d27cf5861ac4e5b..dde35551e744257e6c0fddca57111d5a24d527b5 100644 (file)
@@ -32,7 +32,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/sched.h>
index 609e016e92d02ff9f3f5e030caf816afc543eae4..71a5b5207266dfa4c35fb1ce734bccb32e21cf89 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
index 524d971a1478eabfe0a24dc8a24a64252e23ad98..5a8f50a9afa7a02583175906d683678fdc6223a0 100644 (file)
@@ -87,10 +87,6 @@ config MV64X60
 config MPC10X_OPENPIC
        bool
 
-config MPC10X_STORE_GATHERING
-       bool "Enable MPC10x store gathering"
-       depends on MPC10X_BRIDGE
-
 config GAMECUBE_COMMON
        bool
 
index 487bda0d18d86d46a07f85378c1d27fe276c8928..2e9bcf6444c8dc9c59ad23a98fcd38c6c5f17d0e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/tty.h>
 #include <linux/serial_core.h>
 #include <linux/of_platform.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
index 1cb907c9435909e6fd96f909663941a4d1a15c27..f8f33e16c6b616aec46a72233517038a8c2f47c3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/kdev_t.h>
 #include <linux/console.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
index f0475f0b1853378b838d97049147c6504e78bfd0..f62a0c5fa670d80f0007553b0e069ae9c6fd6d80 100644 (file)
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/iseries/hv_lp_config.h>
 #include "it_lp_naca.h"
 
index d8b76335bd13d1d9f89dda4861bd928dccbf7703..2f3d9110248c4f55a2df0a8976965add870815a0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include <asm/iommu.h>
index 2430848b98e7835fb7a52acb9d0200f8fa1d9e54..997e234fb8b714cf4b646f491bb43132fa5c23bd 100644 (file)
@@ -6,7 +6,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/hw_irq.h>
 #include <asm/iseries/hv_call_sc.h>
index 98bd2d37038ad57475d0c6e14a5069bef66e801d..00e0ec813a1c980a65359dc10619697ddcf1879e 100644 (file)
@@ -8,7 +8,6 @@
  */
 #include <linux/types.h>
 #include <linux/threads.h>
-#include <linux/module.h>
 #include <linux/bitops.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
index b0f8a857ec02d356d1f4a88f8e21cfbcd8b4f66f..202e22798d30aebe0078b29b48e86bd45a3649d4 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/system.h>
 #include <asm/paca.h>
index 62dabe3c2bfa0ac247354346cd6ce255c0d90a22..254c1fc3d8dd131d45be22ca2779ae29c59e1c41 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/proc_fs.h>
 #include <linux/dma-mapping.h>
 #include <linux/bcd.h>
index ab3962b0d246b586f9b406769acd9e39cd712482..c75412884625f53cd0add4b5b8348238748d0ad1 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/ratelimit.h>
index c25a0815c26b2c93ee12c4b4a8319b0ba577659c..ea0acbd8966ddc846b5fb3b113f39190bb64d22d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/param.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/seq_file.h>
 #include <linux/kdev_t.h>
 #include <linux/kexec.h>
index 8bda9be06fa012c290448d62581cecfa30529b03..7e2a5515ed765856b71772d41c44b98717e8ba7c 100644 (file)
@@ -15,7 +15,6 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
index b6db7cef83b46d19ceff11fab07e660911380426..04be62d368a6d29fa7eb390ba53d2fe7aecd85a8 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/firmware.h>
 #include <asm/vio.h>
index 2376069cdc148f33d1812fd89335fcd4bbf21033..40dad0840eb3f234d65da3ba43922a563e9718b7 100644 (file)
@@ -27,7 +27,7 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
index 5b3388b9f9117b4a6114f7724797038ad3d28869..4c372047c94e86e24b2219eb353dab56f91cbbb4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
index c16537bc0c6e12b6a7a5b7f6d49ba59f4e63bf7f..95d00173029f52c498902a586a24917f09e99d4b 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/cpufreq.h>
 #include <linux/timer.h>
+#include <linux/module.h>
 
 #include <asm/hw_irq.h>
 #include <asm/io.h>
index 756123bf06ac2c7ee2eac1f3efb813acffa2394b..f3defd8a28069af474718e40017ac3a8359e79e7 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/sched.h>
 
 #include <asm/pasemi_dma.h>
 
index 7c858e6f843c1821c5900f7f6de872e05b6ac397..6f35582105544396ca584f908e6cb2dbef548dfc 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/console.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/of_platform.h>
 #include <linux/gfp.h>
index c2f3e861f5ea20406d502245cf2561756a647f29..a00096b1c713429be3cbe4a512e83cd66fcf6ee9 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/atomic.h>
+#include <linux/export.h>
 #include <asm/prom.h>
 #include <asm/backlight.h>
 
index df423993f17503997d4ba6e808a0f7754078548e..63d82bbc05e9c4f0307be5f88ccb826844dcc7fd 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/ioport.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <asm/sections.h>
 #include <asm/errno.h>
index e9c8a607268e5bb95622024af7dec47ee1ed179f..996c5ff7824b7b3342e1bce1ce46d44db06e8491 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/delay.h>
index 695443bfdb089f83711b51c46dee58fb039ca028..54d227127c9f10839d79f639e6e8f98c7257fbdc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *  Todo: - add support for the OF persistent properties
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 #include <linux/string.h>
index 7667db448aa73cc58aacaf72e74fa0c5a2339fc6..901bfbddc3ddcecea0e1d0dc35082ebb9d98d6ef 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/syscore_ops.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <linux/module.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
@@ -273,7 +272,6 @@ static struct irqaction xmon_action = {
 
 static struct irqaction gatwick_cascade_action = {
        .handler        = gatwick_action,
-       .flags          = IRQF_DISABLED,
        .name           = "cascade",
 };
 
index a028f08309d64fcec51fd7b86f3d3b49d8bf263b..96580b189ec21446f6b6240aea32effc9b571aad 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
+#include <linux/export.h>
 #include <linux/user.h>
 #include <linux/tty.h>
 #include <linux/string.h>
index 9a521dc8e485101637e4de9f948d427ec286e362..9b6a820bdd7dccb7f618f325206eec324b058d95 100644 (file)
@@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void)
 
        if (psurge_secondary_virq)
                rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
-                       IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+                       IRQF_PERCPU, "IPI", NULL);
 
        if (rc)
                pr_err("Failed to setup secondary cpu IPI\n");
@@ -408,7 +408,7 @@ static int __init smp_psurge_kick_cpu(int nr)
 
 static struct irqaction psurge_irqaction = {
        .handler = psurge_ipi_intr,
-       .flags = IRQF_DISABLED|IRQF_PERCPU,
+       .flags = IRQF_PERCPU,
        .name = "primary IPI",
 };
 
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
new file mode 100644 (file)
index 0000000..74fea5c
--- /dev/null
@@ -0,0 +1,16 @@
+config PPC_POWERNV
+       depends on PPC64 && PPC_BOOK3S
+       bool "IBM PowerNV (Non-Virtualized) platform support"
+       select PPC_NATIVE
+       select PPC_XICS
+       select PPC_ICP_NATIVE
+       select PPC_P7_NAP
+       select PPC_PCI_CHOICE if EMBEDDED
+       default y
+
+config PPC_POWERNV_RTAS
+       depends on PPC_POWERNV
+       bool "Support for RTAS based PowerNV platforms such as BML"
+       default y
+       select PPC_ICS_RTAS
+       select PPC_RTAS
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
new file mode 100644 (file)
index 0000000..3185300
--- /dev/null
@@ -0,0 +1,5 @@
+obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o
+obj-y                  += opal-rtc.o opal-nvram.o
+
+obj-$(CONFIG_SMP)      += smp.o
+obj-$(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 (file)
index 0000000..3f83e1a
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * PowerNV nvram code.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+
+#include <asm/opal.h>
+#include <asm/machdep.h>
+
+static unsigned int nvram_size;
+
+static ssize_t opal_nvram_size(void)
+{
+       return nvram_size;
+}
+
+static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index)
+{
+       s64 rc;
+       int off;
+
+       if (*index >= nvram_size)
+               return 0;
+       off = *index;
+       if ((off + count) > nvram_size)
+               count = nvram_size - off;
+       rc = opal_read_nvram(__pa(buf), count, off);
+       if (rc != OPAL_SUCCESS)
+               return -EIO;
+       *index += count;
+       return count;
+}
+
+static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
+{
+       s64 rc = OPAL_BUSY;
+       int off;
+
+       if (*index >= nvram_size)
+               return 0;
+       off = *index;
+       if ((off + count) > nvram_size)
+               count = nvram_size - off;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_write_nvram(__pa(buf), count, off);
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+       }
+       *index += count;
+       return count;
+}
+
+void __init opal_nvram_init(void)
+{
+       struct device_node *np;
+       const u32 *nbytes_p;
+
+       np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram");
+       if (np == NULL)
+               return;
+
+       nbytes_p = of_get_property(np, "#bytes", NULL);
+       if (!nbytes_p) {
+               of_node_put(np);
+               return;
+       }
+       nvram_size = *nbytes_p;
+
+       printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size);
+       of_node_put(np);
+
+       ppc_md.nvram_read = opal_nvram_read;
+       ppc_md.nvram_write = opal_nvram_write;
+       ppc_md.nvram_size = opal_nvram_size;
+}
+
diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c
new file mode 100644 (file)
index 0000000..2aa7641
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * PowerNV Real Time Clock.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+
+#include <asm/opal.h>
+#include <asm/firmware.h>
+
+static void opal_to_tm(u32 y_m_d, u64 h_m_s_ms, struct rtc_time *tm)
+{
+       tm->tm_year     = ((bcd2bin(y_m_d >> 24) * 100) +
+                          bcd2bin((y_m_d >> 16) & 0xff)) - 1900;
+       tm->tm_mon      = bcd2bin((y_m_d >> 8) & 0xff) - 1;
+       tm->tm_mday     = bcd2bin(y_m_d & 0xff);
+       tm->tm_hour     = bcd2bin((h_m_s_ms >> 56) & 0xff);
+       tm->tm_min      = bcd2bin((h_m_s_ms >> 48) & 0xff);
+       tm->tm_sec      = bcd2bin((h_m_s_ms >> 40) & 0xff);
+
+        GregorianDay(tm);
+}
+
+unsigned long __init opal_get_boot_time(void)
+{
+       struct rtc_time tm;
+       u32 y_m_d;
+       u64 h_m_s_ms;
+       long rc = OPAL_BUSY;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+               else
+                       mdelay(10);
+       }
+       if (rc != OPAL_SUCCESS)
+               return 0;
+       opal_to_tm(y_m_d, h_m_s_ms, &tm);
+       return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+                     tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
+void opal_get_rtc_time(struct rtc_time *tm)
+{
+       long rc = OPAL_BUSY;
+       u32 y_m_d;
+       u64 h_m_s_ms;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+               else
+                       mdelay(10);
+       }
+       if (rc != OPAL_SUCCESS)
+               return;
+       opal_to_tm(y_m_d, h_m_s_ms, tm);
+}
+
+int opal_set_rtc_time(struct rtc_time *tm)
+{
+       long rc = OPAL_BUSY;
+       u32 y_m_d = 0;
+       u64 h_m_s_ms = 0;
+
+       y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24;
+       y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16;
+       y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8;
+       y_m_d |= ((u32)bin2bcd(tm->tm_mday));
+
+       h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56;
+       h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48;
+       h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_rtc_write(y_m_d, h_m_s_ms);
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+               else
+                       mdelay(10);
+       }
+       return rc == OPAL_SUCCESS ? 0 : -EIO;
+}
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S
new file mode 100644 (file)
index 0000000..77b48b2
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * PowerNV OPAL takeover assembly code, for use by prom_init.c
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/hvcall.h>
+#include <asm/asm-offsets.h>
+#include <asm/opal.h>
+
+#define STK_PARAM(i)   (48 + ((i)-3)*8)
+
+#define H_HAL_TAKEOVER                 0x5124
+#define H_HAL_TAKEOVER_QUERY_MAGIC     -1
+
+       .text
+_GLOBAL(opal_query_takeover)
+       mfcr    r0
+       stw     r0,8(r1)
+       std     r3,STK_PARAM(r3)(r1)
+       std     r4,STK_PARAM(r4)(r1)
+       li      r3,H_HAL_TAKEOVER
+       li      r4,H_HAL_TAKEOVER_QUERY_MAGIC
+       HVSC
+       ld      r10,STK_PARAM(r3)(r1)
+       std     r4,0(r10)
+       ld      r10,STK_PARAM(r4)(r1)
+       std     r5,0(r10)
+       lwz     r0,8(r1)
+       mtcrf   0xff,r0
+       blr
+
+_GLOBAL(opal_do_takeover)
+       mfcr    r0
+       stw     r0,8(r1)
+       mflr    r0
+       std     r0,16(r1)
+       bl      __opal_do_takeover
+       ld      r0,16(r1)
+       mtlr    r0
+       lwz     r0,8(r1)
+       mtcrf   0xff,r0
+       blr
+
+__opal_do_takeover:
+       ld      r4,0(r3)
+       ld      r5,0x8(r3)
+       ld      r6,0x10(r3)
+       ld      r7,0x18(r3)
+       ld      r8,0x20(r3)
+       ld      r9,0x28(r3)
+       ld      r10,0x30(r3)
+       ld      r11,0x38(r3)
+       li      r3,H_HAL_TAKEOVER
+       HVSC
+       blr
+
+       .globl opal_secondary_entry
+opal_secondary_entry:
+       mr      r31,r3
+       mfmsr   r11
+       li      r12,(MSR_SF | MSR_ISF)@highest
+       sldi    r12,r12,48
+       or      r11,r11,r12
+       mtmsrd  r11
+       isync
+       mfspr   r4,SPRN_PIR
+       std     r4,0(r3)
+1:     HMT_LOW
+       ld      r4,8(r3)
+       cmpli   cr0,r4,0
+       beq     1b
+       HMT_MEDIUM
+1:     addi    r3,r31,16
+       bl      __opal_do_takeover
+       b       1b
+
+_GLOBAL(opal_enter_rtas)
+       mflr    r0
+       std     r0,16(r1)
+        stdu   r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
+
+       /* Because PROM is running in 32b mode, it clobbers the high order half
+        * of all registers that it saves.  We therefore save those registers
+        * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
+       */
+       SAVE_GPR(2, r1)
+       SAVE_GPR(13, r1)
+       SAVE_8GPRS(14, r1)
+       SAVE_10GPRS(22, r1)
+       mfcr    r10
+       mfmsr   r11
+       std     r10,_CCR(r1)
+       std     r11,_MSR(r1)
+
+       /* Get the PROM entrypoint */
+       mtlr    r5
+
+       /* Switch MSR to 32 bits mode
+        */
+        li      r12,1
+        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
+        andc    r11,r11,r12
+        li      r12,1
+        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
+        andc    r11,r11,r12
+        mtmsrd  r11
+        isync
+
+       /* Enter RTAS here... */
+       blrl
+
+       /* Just make sure that r1 top 32 bits didn't get
+        * corrupt by OF
+        */
+       rldicl  r1,r1,0,32
+
+       /* Restore the MSR (back to 64 bits) */
+       ld      r0,_MSR(r1)
+       MTMSRD(r0)
+        isync
+
+       /* Restore other registers */
+       REST_GPR(2, r1)
+       REST_GPR(13, r1)
+       REST_8GPRS(14, r1)
+       REST_10GPRS(22, r1)
+       ld      r4,_CCR(r1)
+       mtcr    r4
+
+        addi   r1,r1,PROM_FRAME_SIZE
+       ld      r0,16(r1)
+       mtlr    r0
+       blr
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
new file mode 100644 (file)
index 0000000..4a3f46d
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * PowerNV OPAL API wrappers
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/hvcall.h>
+#include <asm/asm-offsets.h>
+#include <asm/opal.h>
+
+/* TODO:
+ *
+ * - Trace irqs in/off (needs saving/restoring all args, argh...)
+ * - Get r11 feed up by Dave so I can have better register usage
+ */
+#define OPAL_CALL(name, token)         \
+ _GLOBAL(name);                                \
+       mflr    r0;                     \
+       mfcr    r12;                    \
+       std     r0,16(r1);              \
+       std     r12,8(r1);              \
+       std     r1,PACAR1(r13);         \
+       li      r0,0;                   \
+       mfmsr   r12;                    \
+       ori     r0,r0,MSR_EE;           \
+       std     r12,PACASAVEDMSR(r13);  \
+       andc    r12,r12,r0;             \
+       mtmsrd  r12,1;                  \
+       LOAD_REG_ADDR(r0,.opal_return); \
+       mtlr    r0;                     \
+       li      r0,MSR_DR|MSR_IR;       \
+       andc    r12,r12,r0;             \
+       li      r0,token;               \
+       mtspr   SPRN_HSRR1,r12;         \
+       LOAD_REG_ADDR(r11,opal);        \
+       ld      r12,8(r11);             \
+       ld      r2,0(r11);              \
+       mtspr   SPRN_HSRR0,r12;         \
+       hrfid
+
+_STATIC(opal_return)
+       ld      r2,PACATOC(r13);
+       ld      r4,8(r1);
+       ld      r5,16(r1);
+       ld      r6,PACASAVEDMSR(r13);
+       mtspr   SPRN_SRR0,r5;
+       mtspr   SPRN_SRR1,r6;
+       mtcr    r4;
+       rfid
+
+OPAL_CALL(opal_console_write,                  OPAL_CONSOLE_WRITE);
+OPAL_CALL(opal_console_read,                   OPAL_CONSOLE_READ);
+OPAL_CALL(opal_console_write_buffer_space,     OPAL_CONSOLE_WRITE_BUFFER_SPACE);
+OPAL_CALL(opal_rtc_read,                       OPAL_RTC_READ);
+OPAL_CALL(opal_rtc_write,                      OPAL_RTC_WRITE);
+OPAL_CALL(opal_cec_power_down,                 OPAL_CEC_POWER_DOWN);
+OPAL_CALL(opal_cec_reboot,                     OPAL_CEC_REBOOT);
+OPAL_CALL(opal_read_nvram,                     OPAL_READ_NVRAM);
+OPAL_CALL(opal_write_nvram,                    OPAL_WRITE_NVRAM);
+OPAL_CALL(opal_handle_interrupt,               OPAL_HANDLE_INTERRUPT);
+OPAL_CALL(opal_poll_events,                    OPAL_POLL_EVENTS);
+OPAL_CALL(opal_pci_set_hub_tce_memory,         OPAL_PCI_SET_HUB_TCE_MEMORY);
+OPAL_CALL(opal_pci_set_phb_tce_memory,         OPAL_PCI_SET_PHB_TCE_MEMORY);
+OPAL_CALL(opal_pci_config_read_byte,           OPAL_PCI_CONFIG_READ_BYTE);
+OPAL_CALL(opal_pci_config_read_half_word,      OPAL_PCI_CONFIG_READ_HALF_WORD);
+OPAL_CALL(opal_pci_config_read_word,           OPAL_PCI_CONFIG_READ_WORD);
+OPAL_CALL(opal_pci_config_write_byte,          OPAL_PCI_CONFIG_WRITE_BYTE);
+OPAL_CALL(opal_pci_config_write_half_word,     OPAL_PCI_CONFIG_WRITE_HALF_WORD);
+OPAL_CALL(opal_pci_config_write_word,          OPAL_PCI_CONFIG_WRITE_WORD);
+OPAL_CALL(opal_set_xive,                       OPAL_SET_XIVE);
+OPAL_CALL(opal_get_xive,                       OPAL_GET_XIVE);
+OPAL_CALL(opal_register_exception_handler,     OPAL_REGISTER_OPAL_EXCEPTION_HANDLER);
+OPAL_CALL(opal_pci_eeh_freeze_status,          OPAL_PCI_EEH_FREEZE_STATUS);
+OPAL_CALL(opal_pci_eeh_freeze_clear,           OPAL_PCI_EEH_FREEZE_CLEAR);
+OPAL_CALL(opal_pci_shpc,                       OPAL_PCI_SHPC);
+OPAL_CALL(opal_pci_phb_mmio_enable,            OPAL_PCI_PHB_MMIO_ENABLE);
+OPAL_CALL(opal_pci_set_phb_mem_window,         OPAL_PCI_SET_PHB_MEM_WINDOW);
+OPAL_CALL(opal_pci_map_pe_mmio_window,         OPAL_PCI_MAP_PE_MMIO_WINDOW);
+OPAL_CALL(opal_pci_set_phb_table_memory,       OPAL_PCI_SET_PHB_TABLE_MEMORY);
+OPAL_CALL(opal_pci_set_pe,                     OPAL_PCI_SET_PE);
+OPAL_CALL(opal_pci_set_peltv,                  OPAL_PCI_SET_PELTV);
+OPAL_CALL(opal_pci_set_mve,                    OPAL_PCI_SET_MVE);
+OPAL_CALL(opal_pci_set_mve_enable,             OPAL_PCI_SET_MVE_ENABLE);
+OPAL_CALL(opal_pci_get_xive_reissue,           OPAL_PCI_GET_XIVE_REISSUE);
+OPAL_CALL(opal_pci_set_xive_reissue,           OPAL_PCI_SET_XIVE_REISSUE);
+OPAL_CALL(opal_pci_set_xive_pe,                        OPAL_PCI_SET_XIVE_PE);
+OPAL_CALL(opal_get_xive_source,                        OPAL_GET_XIVE_SOURCE);
+OPAL_CALL(opal_get_msi_32,                     OPAL_GET_MSI_32);
+OPAL_CALL(opal_get_msi_64,                     OPAL_GET_MSI_64);
+OPAL_CALL(opal_start_cpu,                      OPAL_START_CPU);
+OPAL_CALL(opal_query_cpu_status,               OPAL_QUERY_CPU_STATUS);
+OPAL_CALL(opal_write_oppanel,                  OPAL_WRITE_OPPANEL);
+OPAL_CALL(opal_pci_map_pe_dma_window,          OPAL_PCI_MAP_PE_DMA_WINDOW);
+OPAL_CALL(opal_pci_map_pe_dma_window_real,     OPAL_PCI_MAP_PE_DMA_WINDOW_REAL);
+OPAL_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 (file)
index 0000000..aaa0dba
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * PowerNV OPAL high level interfaces
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/interrupt.h>
+#include <asm/opal.h>
+#include <asm/firmware.h>
+
+#include "powernv.h"
+
+struct opal {
+       u64 base;
+       u64 entry;
+} opal;
+
+static struct device_node *opal_node;
+static DEFINE_SPINLOCK(opal_write_lock);
+extern u64 opal_mc_secondary_handler[];
+
+int __init early_init_dt_scan_opal(unsigned long node,
+                                  const char *uname, int depth, void *data)
+{
+       const void *basep, *entryp;
+       unsigned long basesz, entrysz;
+       u64 glue;
+
+       if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
+               return 0;
+
+       basep  = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
+       entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
+
+       if (!basep || !entryp)
+               return 1;
+
+       opal.base = of_read_number(basep, basesz/4);
+       opal.entry = of_read_number(entryp, entrysz/4);
+
+       pr_debug("OPAL Base  = 0x%llx (basep=%p basesz=%ld)\n",
+                opal.base, basep, basesz);
+       pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n",
+                opal.entry, entryp, entrysz);
+
+       powerpc_firmware_features |= FW_FEATURE_OPAL;
+       if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
+               powerpc_firmware_features |= FW_FEATURE_OPALv2;
+               printk("OPAL V2 detected !\n");
+       } else {
+               printk("OPAL V1 detected !\n");
+       }
+
+       /* Hookup some exception handlers. We use the fwnmi area at 0x7000
+        * to provide the glue space to OPAL
+        */
+       glue = 0x7000;
+       opal_register_exception_handler(OPAL_MACHINE_CHECK_HANDLER,
+                                       __pa(opal_mc_secondary_handler[0]),
+                                       glue);
+       glue += 128;
+       opal_register_exception_handler(OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
+                                       0, glue);
+       glue += 128;
+       opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
+
+       return 1;
+}
+
+int opal_get_chars(uint32_t vtermno, char *buf, int count)
+{
+       s64 len, rc;
+       u64 evt;
+
+       if (!opal.entry)
+               return -ENODEV;
+       opal_poll_events(&evt);
+       if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0)
+               return 0;
+       len = count;
+       rc = opal_console_read(vtermno, &len, buf);
+       if (rc == OPAL_SUCCESS)
+               return len;
+       return 0;
+}
+
+int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
+{
+       int written = 0;
+       s64 len, rc;
+       unsigned long flags;
+       u64 evt;
+
+       if (!opal.entry)
+               return -ENODEV;
+
+       /* We want put_chars to be atomic to avoid mangling of hvsi
+        * packets. To do that, we first test for room and return
+        * -EAGAIN if there isn't enough.
+        *
+        * Unfortunately, opal_console_write_buffer_space() doesn't
+        * appear to work on opal v1, so we just assume there is
+        * enough room and be done with it
+        */
+       spin_lock_irqsave(&opal_write_lock, flags);
+       if (firmware_has_feature(FW_FEATURE_OPALv2)) {
+               rc = opal_console_write_buffer_space(vtermno, &len);
+               if (rc || len < total_len) {
+                       spin_unlock_irqrestore(&opal_write_lock, flags);
+                       /* Closed -> drop characters */
+                       if (rc)
+                               return total_len;
+                       opal_poll_events(&evt);
+                       return -EAGAIN;
+               }
+       }
+
+       /* We still try to handle partial completions, though they
+        * should no longer happen.
+        */
+       rc = OPAL_BUSY;
+       while(total_len > 0 && (rc == OPAL_BUSY ||
+                               rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
+               len = total_len;
+               rc = opal_console_write(vtermno, &len, data);
+               if (rc == OPAL_SUCCESS) {
+                       total_len -= len;
+                       data += len;
+                       written += len;
+               }
+               /* This is a bit nasty but we need that for the console to
+                * flush when there aren't any interrupts. We will clean
+                * things a bit later to limit that to synchronous path
+                * such as the kernel console and xmon/udbg
+                */
+               do
+                       opal_poll_events(&evt);
+               while(rc == OPAL_SUCCESS && (evt & OPAL_EVENT_CONSOLE_OUTPUT));
+       }
+       spin_unlock_irqrestore(&opal_write_lock, flags);
+       return written;
+}
+
+int opal_machine_check(struct pt_regs *regs)
+{
+       struct opal_machine_check_event *opal_evt = get_paca()->opal_mc_evt;
+       struct opal_machine_check_event evt;
+       const char *level, *sevstr, *subtype;
+       static const char *opal_mc_ue_types[] = {
+               "Indeterminate",
+               "Instruction fetch",
+               "Page table walk ifetch",
+               "Load/Store",
+               "Page table walk Load/Store",
+       };
+       static const char *opal_mc_slb_types[] = {
+               "Indeterminate",
+               "Parity",
+               "Multihit",
+       };
+       static const char *opal_mc_erat_types[] = {
+               "Indeterminate",
+               "Parity",
+               "Multihit",
+       };
+       static const char *opal_mc_tlb_types[] = {
+               "Indeterminate",
+               "Parity",
+               "Multihit",
+       };
+
+       /* Copy the event structure and release the original */
+       evt = *opal_evt;
+       opal_evt->in_use = 0;
+
+       /* Print things out */
+       if (evt.version != OpalMCE_V1) {
+               pr_err("Machine Check Exception, Unknown event version %d !\n",
+                      evt.version);
+               return 0;
+       }
+       switch(evt.severity) {
+       case OpalMCE_SEV_NO_ERROR:
+               level = KERN_INFO;
+               sevstr = "Harmless";
+               break;
+       case OpalMCE_SEV_WARNING:
+               level = KERN_WARNING;
+               sevstr = "";
+               break;
+       case OpalMCE_SEV_ERROR_SYNC:
+               level = KERN_ERR;
+               sevstr = "Severe";
+               break;
+       case OpalMCE_SEV_FATAL:
+       default:
+               level = KERN_ERR;
+               sevstr = "Fatal";
+               break;
+       }
+
+       printk("%s%s Machine check interrupt [%s]\n", level, sevstr,
+              evt.disposition == OpalMCE_DISPOSITION_RECOVERED ?
+              "Recovered" : "[Not recovered");
+       printk("%s  Initiator: %s\n", level,
+              evt.initiator == OpalMCE_INITIATOR_CPU ? "CPU" : "Unknown");
+       switch(evt.error_type) {
+       case OpalMCE_ERROR_TYPE_UE:
+               subtype = evt.u.ue_error.ue_error_type <
+                       ARRAY_SIZE(opal_mc_ue_types) ?
+                       opal_mc_ue_types[evt.u.ue_error.ue_error_type]
+                       : "Unknown";
+               printk("%s  Error type: UE [%s]\n", level, subtype);
+               if (evt.u.ue_error.effective_address_provided)
+                       printk("%s    Effective address: %016llx\n",
+                              level, evt.u.ue_error.effective_address);
+               if (evt.u.ue_error.physical_address_provided)
+                       printk("%s      Physial address: %016llx\n",
+                              level, evt.u.ue_error.physical_address);
+               break;
+       case OpalMCE_ERROR_TYPE_SLB:
+               subtype = evt.u.slb_error.slb_error_type <
+                       ARRAY_SIZE(opal_mc_slb_types) ?
+                       opal_mc_slb_types[evt.u.slb_error.slb_error_type]
+                       : "Unknown";
+               printk("%s  Error type: SLB [%s]\n", level, subtype);
+               if (evt.u.slb_error.effective_address_provided)
+                       printk("%s    Effective address: %016llx\n",
+                              level, evt.u.slb_error.effective_address);
+               break;
+       case OpalMCE_ERROR_TYPE_ERAT:
+               subtype = evt.u.erat_error.erat_error_type <
+                       ARRAY_SIZE(opal_mc_erat_types) ?
+                       opal_mc_erat_types[evt.u.erat_error.erat_error_type]
+                       : "Unknown";
+               printk("%s  Error type: ERAT [%s]\n", level, subtype);
+               if (evt.u.erat_error.effective_address_provided)
+                       printk("%s    Effective address: %016llx\n",
+                              level, evt.u.erat_error.effective_address);
+               break;
+       case OpalMCE_ERROR_TYPE_TLB:
+               subtype = evt.u.tlb_error.tlb_error_type <
+                       ARRAY_SIZE(opal_mc_tlb_types) ?
+                       opal_mc_tlb_types[evt.u.tlb_error.tlb_error_type]
+                       : "Unknown";
+               printk("%s  Error type: TLB [%s]\n", level, subtype);
+               if (evt.u.tlb_error.effective_address_provided)
+                       printk("%s    Effective address: %016llx\n",
+                              level, evt.u.tlb_error.effective_address);
+               break;
+       default:
+       case OpalMCE_ERROR_TYPE_UNKNOWN:
+               printk("%s  Error type: Unknown\n", level);
+               break;
+       }
+       return evt.severity == OpalMCE_SEV_FATAL ? 0 : 1;
+}
+
+static irqreturn_t opal_interrupt(int irq, void *data)
+{
+       uint64_t events;
+
+       opal_handle_interrupt(virq_to_hw(irq), &events);
+
+       /* XXX TODO: Do something with the events */
+
+       return IRQ_HANDLED;
+}
+
+static int __init opal_init(void)
+{
+       struct device_node *np, *consoles;
+       const u32 *irqs;
+       int rc, i, irqlen;
+
+       opal_node = of_find_node_by_path("/ibm,opal");
+       if (!opal_node) {
+               pr_warn("opal: Node not found\n");
+               return -ENODEV;
+       }
+       if (firmware_has_feature(FW_FEATURE_OPALv2))
+               consoles = of_find_node_by_path("/ibm,opal/consoles");
+       else
+               consoles = of_node_get(opal_node);
+
+       /* Register serial ports */
+       for_each_child_of_node(consoles, np) {
+               if (strcmp(np->name, "serial"))
+                       continue;
+               of_platform_device_create(np, NULL, NULL);
+       }
+       of_node_put(consoles);
+
+       /* Find all OPAL interrupts and request them */
+       irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
+       pr_debug("opal: Found %d interrupts reserved for OPAL\n",
+                irqs ? (irqlen / 4) : 0);
+       for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
+               unsigned int hwirq = be32_to_cpup(irqs);
+               unsigned int irq = irq_create_mapping(NULL, hwirq);
+               if (irq == NO_IRQ) {
+                       pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
+                       continue;
+               }
+               rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
+               if (rc)
+                       pr_warning("opal: Error %d requesting irq %d"
+                                  " (0x%x)\n", rc, irq, hwirq);
+       }
+       return 0;
+}
+subsys_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 (file)
index 0000000..4c80f7c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Support PCI/PCIe on PowerNV platforms
+ *
+ * Currently supports only P5IOC2
+ *
+ * Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/msi.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/opal.h>
+#include <asm/iommu.h>
+#include <asm/tce.h>
+#include <asm/abs_addr.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/* For now, use a fixed amount of TCE memory for each p5ioc2
+ * hub, 16M will do
+ */
+#define P5IOC2_TCE_MEMORY      0x01000000
+
+#ifdef CONFIG_PCI_MSI
+static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
+                                   unsigned int hwirq, unsigned int is_64,
+                                   struct msi_msg *msg)
+{
+       if (WARN_ON(!is_64))
+               return -ENXIO;
+       msg->data = hwirq - phb->msi_base;
+       msg->address_hi = 0x10000000;
+       msg->address_lo = 0;
+
+       return 0;
+}
+
+static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
+{
+       unsigned int bmap_size;
+       const __be32 *prop = of_get_property(phb->hose->dn,
+                                            "ibm,opal-msi-ranges", NULL);
+       if (!prop)
+               return;
+
+       /* Don't do MSI's on p5ioc2 PCI-X are they are not properly
+        * verified in HW
+        */
+       if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix"))
+               return;
+       phb->msi_base = be32_to_cpup(prop);
+       phb->msi_count = be32_to_cpup(prop + 1);
+       bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long);
+       phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL);
+       if (!phb->msi_map) {
+               pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
+                      phb->hose->global_number);
+               return;
+       }
+       phb->msi_setup = pnv_pci_p5ioc2_msi_setup;
+       phb->msi32_support = 0;
+       pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
+               phb->msi_count, phb->msi_base);
+}
+#else
+static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { }
+#endif /* CONFIG_PCI_MSI */
+
+static void __devinit pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
+                                                  struct pci_dev *pdev)
+{
+       if (phb->p5ioc2.iommu_table.it_map == NULL)
+               iommu_init_table(&phb->p5ioc2.iommu_table, phb->hose->node);
+
+       set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table);
+}
+
+static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np,
+                                          void *tce_mem, u64 tce_size)
+{
+       struct pnv_phb *phb;
+       const u64 *prop64;
+       u64 phb_id;
+       int64_t rc;
+       static int primary = 1;
+
+       pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name);
+
+       prop64 = of_get_property(np, "ibm,opal-phbid", NULL);
+       if (!prop64) {
+               pr_err("  Missing \"ibm,opal-phbid\" property !\n");
+               return;
+       }
+       phb_id = be64_to_cpup(prop64);
+       pr_devel("  PHB-ID  : 0x%016llx\n", phb_id);
+       pr_devel("  TCE AT  : 0x%016lx\n", __pa(tce_mem));
+       pr_devel("  TCE SZ  : 0x%016llx\n", tce_size);
+
+       rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size);
+       if (rc != OPAL_SUCCESS) {
+               pr_err("  Failed to set TCE memory, OPAL error %lld\n", rc);
+               return;
+       }
+
+       phb = alloc_bootmem(sizeof(struct pnv_phb));
+       if (phb) {
+               memset(phb, 0, sizeof(struct pnv_phb));
+               phb->hose = pcibios_alloc_controller(np);
+       }
+       if (!phb || !phb->hose) {
+               pr_err("  Failed to allocate PCI controller\n");
+               return;
+       }
+
+       spin_lock_init(&phb->lock);
+       phb->hose->first_busno = 0;
+       phb->hose->last_busno = 0xff;
+       phb->hose->private_data = phb;
+       phb->opal_id = phb_id;
+       phb->type = PNV_PHB_P5IOC2;
+
+       phb->regs = of_iomap(np, 0);
+
+       if (phb->regs == NULL)
+               pr_err("  Failed to map registers !\n");
+       else {
+               pr_devel("  P_BUID     = 0x%08x\n", in_be32(phb->regs + 0x100));
+               pr_devel("  P_IOSZ     = 0x%08x\n", in_be32(phb->regs + 0x1b0));
+               pr_devel("  P_IO_ST    = 0x%08x\n", in_be32(phb->regs + 0x1e0));
+               pr_devel("  P_MEM1_H   = 0x%08x\n", in_be32(phb->regs + 0x1a0));
+               pr_devel("  P_MEM1_L   = 0x%08x\n", in_be32(phb->regs + 0x190));
+               pr_devel("  P_MSZ1_L   = 0x%08x\n", in_be32(phb->regs + 0x1c0));
+               pr_devel("  P_MEM_ST   = 0x%08x\n", in_be32(phb->regs + 0x1d0));
+               pr_devel("  P_MEM2_H   = 0x%08x\n", in_be32(phb->regs + 0x2c0));
+               pr_devel("  P_MEM2_L   = 0x%08x\n", in_be32(phb->regs + 0x2b0));
+               pr_devel("  P_MSZ2_H   = 0x%08x\n", in_be32(phb->regs + 0x2d0));
+               pr_devel("  P_MSZ2_L   = 0x%08x\n", in_be32(phb->regs + 0x2e0));
+       }
+
+       /* Interpret the "ranges" property */
+       /* This also maps the I/O region and sets isa_io/mem_base */
+       pci_process_bridge_OF_ranges(phb->hose, np, primary);
+       primary = 0;
+
+       phb->hose->ops = &pnv_pci_ops;
+
+       /* Setup MSI support */
+       pnv_pci_init_p5ioc2_msis(phb);
+
+       /* Setup TCEs */
+       phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup;
+       pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table,
+                                 tce_mem, tce_size, 0);
+}
+
+void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
+{
+       struct device_node *phbn;
+       const u64 *prop64;
+       u64 hub_id;
+       void *tce_mem;
+       uint64_t tce_per_phb;
+       int64_t rc;
+       int phb_count = 0;
+
+       pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name);
+
+       prop64 = of_get_property(np, "ibm,opal-hubid", NULL);
+       if (!prop64) {
+               pr_err(" Missing \"ibm,opal-hubid\" property !\n");
+               return;
+       }
+       hub_id = be64_to_cpup(prop64);
+       pr_info(" HUB-ID : 0x%016llx\n", hub_id);
+
+       /* Currently allocate 16M of TCE memory for every Hub
+        *
+        * XXX TODO: Make it chip local if possible
+        */
+       tce_mem = __alloc_bootmem(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY,
+                                 __pa(MAX_DMA_ADDRESS));
+       if (!tce_mem) {
+               pr_err(" Failed to allocate TCE Memory !\n");
+               return;
+       }
+       pr_debug(" TCE    : 0x%016lx..0x%016lx\n",
+               __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1);
+       rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem),
+                                       P5IOC2_TCE_MEMORY);
+       if (rc != OPAL_SUCCESS) {
+               pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc);
+               return;
+       }
+
+       /* Count child PHBs */
+       for_each_child_of_node(np, phbn) {
+               if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
+                   of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
+                       phb_count++;
+       }
+
+       /* Calculate how much TCE space we can give per PHB */
+       tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
+       pr_info(" Allocating %lld MB of TCE memory per PHB\n",
+               tce_per_phb >> 20);
+
+       /* Initialize PHBs */
+       for_each_child_of_node(np, phbn) {
+               if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
+                   of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) {
+                       pnv_pci_init_p5ioc2_phb(phbn, tce_mem, tce_per_phb);
+                       tce_mem += tce_per_phb;
+               }
+       }
+}
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
new file mode 100644 (file)
index 0000000..85bb66d
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Support PCI/PCIe on PowerNV platforms
+ *
+ * Currently supports only P5IOC2
+ *
+ * Copyright 2011 Benjamin Herrenschmidt, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/msi.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/opal.h>
+#include <asm/iommu.h>
+#include <asm/tce.h>
+#include <asm/abs_addr.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/* Delay in usec */
+#define PCI_RESET_DELAY_US     3000000
+
+#define cfg_dbg(fmt...)        do { } while(0)
+//#define cfg_dbg(fmt...)      printk(fmt)
+
+#ifdef CONFIG_PCI_MSI
+static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
+{
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct pnv_phb *phb = hose->private_data;
+
+       return (phb && phb->msi_map) ? 0 : -ENODEV;
+}
+
+static unsigned int pnv_get_one_msi(struct pnv_phb *phb)
+{
+       unsigned int id;
+
+       spin_lock(&phb->lock);
+       id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next);
+       if (id >= phb->msi_count && phb->msi_next)
+               id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0);
+       if (id >= phb->msi_count) {
+               spin_unlock(&phb->lock);
+               return 0;
+       }
+       __set_bit(id, phb->msi_map);
+       spin_unlock(&phb->lock);
+       return id + phb->msi_base;
+}
+
+static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq)
+{
+       unsigned int id;
+
+       if (WARN_ON(hwirq < phb->msi_base ||
+                   hwirq >= (phb->msi_base + phb->msi_count)))
+               return;
+       id = hwirq - phb->msi_base;
+       spin_lock(&phb->lock);
+       __clear_bit(id, phb->msi_map);
+       spin_unlock(&phb->lock);
+}
+
+static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct pnv_phb *phb = hose->private_data;
+       struct msi_desc *entry;
+       struct msi_msg msg;
+       unsigned int hwirq, virq;
+       int rc;
+
+       if (WARN_ON(!phb))
+               return -ENODEV;
+
+       list_for_each_entry(entry, &pdev->msi_list, list) {
+               if (!entry->msi_attrib.is_64 && !phb->msi32_support) {
+                       pr_warn("%s: Supports only 64-bit MSIs\n",
+                               pci_name(pdev));
+                       return -ENXIO;
+               }
+               hwirq = pnv_get_one_msi(phb);
+               if (!hwirq) {
+                       pr_warn("%s: Failed to find a free MSI\n",
+                               pci_name(pdev));
+                       return -ENOSPC;
+               }
+               virq = irq_create_mapping(NULL, hwirq);
+               if (virq == NO_IRQ) {
+                       pr_warn("%s: Failed to map MSI to linux irq\n",
+                               pci_name(pdev));
+                       pnv_put_msi(phb, hwirq);
+                       return -ENOMEM;
+               }
+               rc = phb->msi_setup(phb, pdev, hwirq, entry->msi_attrib.is_64,
+                                   &msg);
+               if (rc) {
+                       pr_warn("%s: Failed to setup MSI\n", pci_name(pdev));
+                       irq_dispose_mapping(virq);
+                       pnv_put_msi(phb, hwirq);
+                       return rc;
+               }
+               irq_set_msi_desc(virq, entry);
+               write_msi_msg(virq, &msg);
+       }
+       return 0;
+}
+
+static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
+{
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct pnv_phb *phb = hose->private_data;
+       struct msi_desc *entry;
+
+       if (WARN_ON(!phb))
+               return;
+
+       list_for_each_entry(entry, &pdev->msi_list, list) {
+               if (entry->irq == NO_IRQ)
+                       continue;
+               irq_set_msi_desc(entry->irq, NULL);
+               pnv_put_msi(phb, virq_to_hw(entry->irq));
+               irq_dispose_mapping(entry->irq);
+       }
+}
+#endif /* CONFIG_PCI_MSI */
+
+static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus,
+                                    u32 bdfn)
+{
+       s64     rc;
+       u8      fstate;
+       u16     pcierr;
+       u32     pe_no;
+
+       /* Get PE# if we support IODA */
+       pe_no = phb->bdfn_to_pe ? phb->bdfn_to_pe(phb, bus, bdfn & 0xff) : 0;
+
+       /* Read freeze status */
+       rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
+                                       NULL);
+       if (rc) {
+               pr_warning("PCI %d: Failed to read EEH status for PE#%d,"
+                          " err %lld\n", phb->hose->global_number, pe_no, rc);
+               return;
+       }
+       cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n",
+               bdfn, pe_no, fstate);
+       if (fstate != 0) {
+               rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
+                                             OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+               if (rc) {
+                       pr_warning("PCI %d: Failed to clear EEH freeze state"
+                                  " for PE#%d, err %lld\n",
+                                  phb->hose->global_number, pe_no, rc);
+               }
+       }
+}
+
+static int pnv_pci_read_config(struct pci_bus *bus,
+                              unsigned int devfn,
+                              int where, int size, u32 *val)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       struct pnv_phb *phb = hose->private_data;
+       u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
+       s64 rc;
+
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       switch (size) {
+       case 1: {
+               u8 v8;
+               rc = opal_pci_config_read_byte(phb->opal_id, bdfn, where, &v8);
+               *val = (rc == OPAL_SUCCESS) ? v8 : 0xff;
+               break;
+       }
+       case 2: {
+               u16 v16;
+               rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where,
+                                                  &v16);
+               *val = (rc == OPAL_SUCCESS) ? v16 : 0xffff;
+               break;
+       }
+       case 4: {
+               u32 v32;
+               rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32);
+               *val = (rc == OPAL_SUCCESS) ? v32 : 0xffffffff;
+               break;
+       }
+       default:
+               return PCIBIOS_FUNC_NOT_SUPPORTED;
+       }
+       cfg_dbg("pnv_pci_read_config bus: %x devfn: %x +%x/%x -> %08x\n",
+               bus->number, devfn, where, size, *val);
+
+       /* Check if the PHB got frozen due to an error (no response) */
+       pnv_pci_config_check_eeh(phb, bus, bdfn);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int pnv_pci_write_config(struct pci_bus *bus,
+                               unsigned int devfn,
+                               int where, int size, u32 val)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       struct pnv_phb *phb = hose->private_data;
+       u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
+
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n",
+               bus->number, devfn, where, size, val);
+       switch (size) {
+       case 1:
+               opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
+               break;
+       case 2:
+               opal_pci_config_write_half_word(phb->opal_id, bdfn, where, val);
+               break;
+       case 4:
+               opal_pci_config_write_word(phb->opal_id, bdfn, where, val);
+               break;
+       default:
+               return PCIBIOS_FUNC_NOT_SUPPORTED;
+       }
+       /* Check if the PHB got frozen due to an error (no response) */
+       pnv_pci_config_check_eeh(phb, bus, bdfn);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops pnv_pci_ops = {
+       .read = pnv_pci_read_config,
+       .write = pnv_pci_write_config,
+};
+
+static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
+                        unsigned long uaddr, enum dma_data_direction direction,
+                        struct dma_attrs *attrs)
+{
+       u64 proto_tce;
+       u64 *tcep;
+       u64 rpn;
+
+       proto_tce = TCE_PCI_READ; // Read allowed
+
+       if (direction != DMA_TO_DEVICE)
+               proto_tce |= TCE_PCI_WRITE;
+
+       tcep = ((u64 *)tbl->it_base) + index;
+
+       while (npages--) {
+               /* can't move this out since we might cross LMB boundary */
+               rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+               *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+
+               uaddr += TCE_PAGE_SIZE;
+               tcep++;
+       }
+       return 0;
+}
+
+static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
+{
+       u64 *tcep = ((u64 *)tbl->it_base) + index;
+
+       while (npages--)
+               *(tcep++) = 0;
+}
+
+void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
+                              void *tce_mem, u64 tce_size,
+                              u64 dma_offset)
+{
+       tbl->it_blocksize = 16;
+       tbl->it_base = (unsigned long)tce_mem;
+       tbl->it_offset = dma_offset >> IOMMU_PAGE_SHIFT;
+       tbl->it_index = 0;
+       tbl->it_size = tce_size >> 3;
+       tbl->it_busno = 0;
+       tbl->it_type = TCE_PCI;
+}
+
+static struct iommu_table * __devinit
+pnv_pci_setup_bml_iommu(struct pci_controller *hose)
+{
+       struct iommu_table *tbl;
+       const __be64 *basep;
+       const __be32 *sizep;
+
+       basep = of_get_property(hose->dn, "linux,tce-base", NULL);
+       sizep = of_get_property(hose->dn, "linux,tce-size", NULL);
+       if (basep == NULL || sizep == NULL) {
+               pr_err("PCI: %s has missing tce entries !\n", hose->dn->full_name);
+               return NULL;
+       }
+       tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node);
+       if (WARN_ON(!tbl))
+               return NULL;
+       pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)),
+                                 be32_to_cpup(sizep), 0);
+       iommu_init_table(tbl, hose->node);
+       return tbl;
+}
+
+static void __devinit pnv_pci_dma_fallback_setup(struct pci_controller *hose,
+                                                struct pci_dev *pdev)
+{
+       struct device_node *np = pci_bus_to_OF_node(hose->bus);
+       struct pci_dn *pdn;
+
+       if (np == NULL)
+               return;
+       pdn = PCI_DN(np);
+       if (!pdn->iommu_table)
+               pdn->iommu_table = pnv_pci_setup_bml_iommu(hose);
+       if (!pdn->iommu_table)
+               return;
+       set_iommu_table_base(&pdev->dev, pdn->iommu_table);
+}
+
+static void __devinit pnv_pci_dma_dev_setup(struct pci_dev *pdev)
+{
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct pnv_phb *phb = hose->private_data;
+
+       /* If we have no phb structure, try to setup a fallback based on
+        * the device-tree (RTAS PCI for example)
+        */
+       if (phb && phb->dma_dev_setup)
+               phb->dma_dev_setup(phb, pdev);
+       else
+               pnv_pci_dma_fallback_setup(hose, pdev);
+}
+
+static int pnv_pci_probe_mode(struct pci_bus *bus)
+{
+       struct pci_controller *hose = pci_bus_to_host(bus);
+       const __be64 *tstamp;
+       u64 now, target;
+
+
+       /* We hijack this as a way to ensure we have waited long
+        * enough since the reset was lifted on the PCI bus
+        */
+       if (bus != hose->bus)
+               return PCI_PROBE_NORMAL;
+       tstamp = of_get_property(hose->dn, "reset-clear-timestamp", NULL);
+       if (!tstamp || !*tstamp)
+               return PCI_PROBE_NORMAL;
+
+       now = mftb() / tb_ticks_per_usec;
+       target = (be64_to_cpup(tstamp) / tb_ticks_per_usec)
+               + PCI_RESET_DELAY_US;
+
+       pr_devel("pci %04d: Reset target: 0x%llx now: 0x%llx\n",
+                hose->global_number, target, now);
+
+       if (now < target)
+               msleep((target - now + 999) / 1000);
+
+       return PCI_PROBE_NORMAL;
+}
+
+void __init pnv_pci_init(void)
+{
+       struct device_node *np;
+
+       pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
+
+       /* We do not want to just probe */
+       pci_probe_only = 0;
+
+       /* OPAL absent, try POPAL first then RTAS detection of PHBs */
+       if (!firmware_has_feature(FW_FEATURE_OPAL)) {
+#ifdef CONFIG_PPC_POWERNV_RTAS
+               init_pci_config_tokens();
+               find_and_init_phbs();
+#endif /* CONFIG_PPC_POWERNV_RTAS */
+       } else {
+               /* OPAL is here, do our normal stuff */
+
+               /* Look for p5ioc2 IO-Hubs */
+               for_each_compatible_node(np, NULL, "ibm,p5ioc2")
+                       pnv_pci_init_p5ioc2_hub(np);
+       }
+
+       /* Setup the linkage between OF nodes and PHBs */
+       pci_devs_phb_init();
+
+       /* Configure IOMMU DMA hooks */
+       ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
+       ppc_md.tce_build = pnv_tce_build;
+       ppc_md.tce_free = pnv_tce_free;
+       ppc_md.pci_probe_mode = pnv_pci_probe_mode;
+       set_pci_dma_ops(&dma_iommu_ops);
+
+       /* Configure MSIs */
+#ifdef CONFIG_PCI_MSI
+       ppc_md.msi_check_device = pnv_msi_check_device;
+       ppc_md.setup_msi_irqs = pnv_setup_msi_irqs;
+       ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
+#endif
+}
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
new file mode 100644 (file)
index 0000000..d4dbc49
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __POWERNV_PCI_H
+#define __POWERNV_PCI_H
+
+struct pci_dn;
+
+enum pnv_phb_type {
+       PNV_PHB_P5IOC2,
+       PNV_PHB_IODA1,
+       PNV_PHB_IODA2,
+};
+
+struct pnv_phb {
+       struct pci_controller   *hose;
+       enum pnv_phb_type       type;
+       u64                     opal_id;
+       void __iomem            *regs;
+       spinlock_t              lock;
+
+#ifdef CONFIG_PCI_MSI
+       unsigned long           *msi_map;
+       unsigned int            msi_base;
+       unsigned int            msi_count;
+       unsigned int            msi_next;
+       unsigned int            msi32_support;
+#endif
+       int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev,
+                        unsigned int hwirq, unsigned int is_64,
+                        struct msi_msg *msg);
+       void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
+       void (*fixup_phb)(struct pci_controller *hose);
+       u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
+
+       union {
+               struct {
+                       struct iommu_table iommu_table;
+               } p5ioc2;
+       };
+};
+
+extern struct pci_ops pnv_pci_ops;
+
+extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
+                                     void *tce_mem, u64 tce_size,
+                                     u64 dma_offset);
+extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
+
+
+#endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h
new file mode 100644 (file)
index 0000000..8a9df7f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _POWERNV_H
+#define _POWERNV_H
+
+#ifdef CONFIG_SMP
+extern void pnv_smp_init(void);
+#else
+static inline void pnv_smp_init(void) { }
+#endif
+
+#ifdef CONFIG_PCI
+extern void pnv_pci_init(void);
+#else
+static inline void pnv_pci_init(void) { }
+#endif
+
+#endif /* _POWERNV_H */
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
new file mode 100644 (file)
index 0000000..467bd4a
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * PowerNV setup code.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/cpu.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/bug.h>
+
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/xics.h>
+#include <asm/rtas.h>
+#include <asm/opal.h>
+#include <asm/xics.h>
+
+#include "powernv.h"
+
+static void __init pnv_setup_arch(void)
+{
+       /* Initialize SMP */
+       pnv_smp_init();
+
+       /* Setup PCI */
+       pnv_pci_init();
+
+       /* Setup RTC and NVRAM callbacks */
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               opal_nvram_init();
+
+       /* Enable NAP mode */
+       powersave_nap = 1;
+
+       /* XXX PMCS */
+}
+
+static void __init pnv_init_early(void)
+{
+#ifdef CONFIG_HVC_OPAL
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               hvc_opal_init_early();
+       else
+#endif
+               add_preferred_console("hvc", 0, NULL);
+}
+
+static void __init pnv_init_IRQ(void)
+{
+       xics_init();
+
+       WARN_ON(!ppc_md.get_irq);
+}
+
+static void pnv_show_cpuinfo(struct seq_file *m)
+{
+       struct device_node *root;
+       const char *model = "";
+
+       root = of_find_node_by_path("/");
+       if (root)
+               model = of_get_property(root, "model", NULL);
+       seq_printf(m, "machine\t\t: PowerNV %s\n", model);
+       if (firmware_has_feature(FW_FEATURE_OPALv2))
+               seq_printf(m, "firmware\t: OPAL v2\n");
+       else if (firmware_has_feature(FW_FEATURE_OPAL))
+               seq_printf(m, "firmware\t: OPAL v1\n");
+       else
+               seq_printf(m, "firmware\t: BML\n");
+       of_node_put(root);
+}
+
+static void  __noreturn pnv_restart(char *cmd)
+{
+       long rc = OPAL_BUSY;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_cec_reboot();
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+               else
+                       mdelay(10);
+       }
+       for (;;)
+               opal_poll_events(NULL);
+}
+
+static void __noreturn pnv_power_off(void)
+{
+       long rc = OPAL_BUSY;
+
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_cec_power_down(0);
+               if (rc == OPAL_BUSY_EVENT)
+                       opal_poll_events(NULL);
+               else
+                       mdelay(10);
+       }
+       for (;;)
+               opal_poll_events(NULL);
+}
+
+static void __noreturn pnv_halt(void)
+{
+       pnv_power_off();
+}
+
+static void pnv_progress(char *s, unsigned short hex)
+{
+}
+
+#ifdef CONFIG_KEXEC
+static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+       xics_kexec_teardown_cpu(secondary);
+}
+#endif /* CONFIG_KEXEC */
+
+static void __init pnv_setup_machdep_opal(void)
+{
+       ppc_md.get_boot_time = opal_get_boot_time;
+       ppc_md.get_rtc_time = opal_get_rtc_time;
+       ppc_md.set_rtc_time = opal_set_rtc_time;
+       ppc_md.restart = pnv_restart;
+       ppc_md.power_off = pnv_power_off;
+       ppc_md.halt = pnv_halt;
+       ppc_md.machine_check_exception = opal_machine_check;
+}
+
+#ifdef CONFIG_PPC_POWERNV_RTAS
+static void __init pnv_setup_machdep_rtas(void)
+{
+       if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) {
+               ppc_md.get_boot_time = rtas_get_boot_time;
+               ppc_md.get_rtc_time = rtas_get_rtc_time;
+               ppc_md.set_rtc_time = rtas_set_rtc_time;
+       }
+       ppc_md.restart = rtas_restart;
+       ppc_md.power_off = rtas_power_off;
+       ppc_md.halt = rtas_halt;
+}
+#endif /* CONFIG_PPC_POWERNV_RTAS */
+
+static int __init pnv_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (!of_flat_dt_is_compatible(root, "ibm,powernv"))
+               return 0;
+
+       hpte_init_native();
+
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               pnv_setup_machdep_opal();
+#ifdef CONFIG_PPC_POWERNV_RTAS
+       else if (rtas.base)
+               pnv_setup_machdep_rtas();
+#endif /* CONFIG_PPC_POWERNV_RTAS */
+
+       pr_debug("PowerNV detected !\n");
+
+       return 1;
+}
+
+define_machine(powernv) {
+       .name                   = "PowerNV",
+       .probe                  = pnv_probe,
+       .init_early             = pnv_init_early,
+       .setup_arch             = pnv_setup_arch,
+       .init_IRQ               = pnv_init_IRQ,
+       .show_cpuinfo           = pnv_show_cpuinfo,
+       .progress               = pnv_progress,
+       .power_save             = power7_idle,
+       .calibrate_decr         = generic_calibrate_decr,
+#ifdef CONFIG_KEXEC
+       .kexec_cpu_down         = pnv_kexec_cpu_down,
+#endif
+};
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
new file mode 100644 (file)
index 0000000..e877366
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * SMP support for PowerNV machines.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/cpu.h>
+
+#include <asm/irq.h>
+#include <asm/smp.h>
+#include <asm/paca.h>
+#include <asm/machdep.h>
+#include <asm/cputable.h>
+#include <asm/firmware.h>
+#include <asm/system.h>
+#include <asm/rtas.h>
+#include <asm/vdso_datapage.h>
+#include <asm/cputhreads.h>
+#include <asm/xics.h>
+#include <asm/opal.h>
+
+#include "powernv.h"
+
+#ifdef DEBUG
+#include <asm/udbg.h>
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+static void __cpuinit pnv_smp_setup_cpu(int cpu)
+{
+       if (cpu != boot_cpuid)
+               xics_setup_cpu();
+}
+
+static int pnv_smp_cpu_bootable(unsigned int nr)
+{
+       /* Special case - we inhibit secondary thread startup
+        * during boot if the user requests it.
+        */
+       if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
+               if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
+                       return 0;
+               if (smt_enabled_at_boot
+                   && cpu_thread_in_core(nr) >= smt_enabled_at_boot)
+                       return 0;
+       }
+
+       return 1;
+}
+
+int __devinit pnv_smp_kick_cpu(int nr)
+{
+       unsigned int pcpu = get_hard_smp_processor_id(nr);
+       unsigned long start_here = __pa(*((unsigned long *)
+                                         generic_secondary_smp_init));
+       long rc;
+
+       BUG_ON(nr < 0 || nr >= NR_CPUS);
+
+       /* On OPAL v2 the CPU are still spinning inside OPAL itself,
+        * get them back now
+        */
+       if (firmware_has_feature(FW_FEATURE_OPALv2)) {
+               pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
+               rc = opal_start_cpu(pcpu, start_here);
+               if (rc != OPAL_SUCCESS)
+                       pr_warn("OPAL Error %ld starting CPU %d\n",
+                               rc, nr);
+       }
+       return smp_generic_kick_cpu(nr);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int pnv_smp_cpu_disable(void)
+{
+       int cpu = smp_processor_id();
+
+       /* This is identical to pSeries... might consolidate by
+        * moving migrate_irqs_away to a ppc_md with default to
+        * the generic fixup_irqs. --BenH.
+        */
+       set_cpu_online(cpu, false);
+       vdso_data->processorCount--;
+       if (cpu == boot_cpuid)
+               boot_cpuid = cpumask_any(cpu_online_mask);
+       xics_migrate_irqs_away();
+       return 0;
+}
+
+static void pnv_smp_cpu_kill_self(void)
+{
+       unsigned int cpu;
+
+       /* If powersave_nap is enabled, use NAP mode, else just
+        * spin aimlessly
+        */
+       if (!powersave_nap) {
+               generic_mach_cpu_die();
+               return;
+       }
+
+       /* Standard hot unplug procedure */
+       local_irq_disable();
+       idle_task_exit();
+       current->active_mm = NULL; /* for sanity */
+       cpu = smp_processor_id();
+       DBG("CPU%d offline\n", cpu);
+       generic_set_cpu_dead(cpu);
+       smp_wmb();
+
+       /* We don't want to take decrementer interrupts while we are offline,
+        * so clear LPCR:PECE1. We keep PECE2 enabled.
+        */
+       mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
+       while (!generic_check_cpu_restart(cpu)) {
+               power7_idle();
+               if (!generic_check_cpu_restart(cpu)) {
+                       DBG("CPU%d Unexpected exit while offline !\n", cpu);
+                       /* We may be getting an IPI, so we re-enable
+                        * interrupts to process it, it will be ignored
+                        * since we aren't online (hopefully)
+                        */
+                       local_irq_enable();
+                       local_irq_disable();
+               }
+       }
+       mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
+       DBG("CPU%d coming online...\n", cpu);
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static struct smp_ops_t pnv_smp_ops = {
+       .message_pass   = smp_muxed_ipi_message_pass,
+       .cause_ipi      = NULL, /* Filled at runtime by xics_smp_probe() */
+       .probe          = xics_smp_probe,
+       .kick_cpu       = pnv_smp_kick_cpu,
+       .setup_cpu      = pnv_smp_setup_cpu,
+       .cpu_bootable   = pnv_smp_cpu_bootable,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_disable    = pnv_smp_cpu_disable,
+       .cpu_die        = generic_cpu_die,
+#endif /* CONFIG_HOTPLUG_CPU */
+};
+
+/* This is called very early during platform setup_arch */
+void __init pnv_smp_init(void)
+{
+       smp_ops = &pnv_smp_ops;
+
+       /* XXX We don't yet have a proper entry point from HAL, for
+        * now we rely on kexec-style entry from BML
+        */
+
+#ifdef CONFIG_PPC_RTAS
+       /* Non-lpar has additional take/give timebase */
+       if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
+               smp_ops->give_timebase = rtas_give_timebase;
+               smp_ops->take_timebase = rtas_take_timebase;
+       }
+#endif /* CONFIG_PPC_RTAS */
+
+#ifdef CONFIG_HOTPLUG_CPU
+       ppc_md.cpu_die  = pnv_smp_cpu_kill_self;
+#endif
+}
index f0536c7cda9f26056cdb2404a3094ca42207feb4..1547f66235d969db77b675a41c9decdf02672f45 100644 (file)
@@ -21,12 +21,3 @@ config PREP_RESIDUAL
          or pass the 'noresidual' option to the kernel.
 
          If you are running a PReP system, say Y here, otherwise say N.
-
-config PROC_PREPRESIDUAL
-       bool "Support for reading of PReP Residual Data in /proc"
-       depends on PREP_RESIDUAL && PROC_FS
-       help
-         Enabling this option will create a /proc/residual file which allows
-         you to get at the residual data on PReP systems.  You will need a tool
-         (lsresidual) to parse it.  If you aren't on a PReP system, you don't
-         want this.
index dfe316b161a9a16c658632da5002135e5443af97..476d9d9b24058d705b481cdf7285e4c76b339cb1 100644 (file)
@@ -148,4 +148,16 @@ config PS3_LPM
          profiling support of the Cell processor with programs like
          oprofile and perfmon2, then say Y or M, otherwise say N.
 
+config PS3GELIC_UDBG
+       bool "PS3 udbg output via UDP broadcasts on Ethernet"
+       depends on PPC_PS3
+       help
+         Enables udbg early debugging output by sending broadcast UDP
+         via the Ethernet port (UDP port number 18194).
+
+         This driver uses a trivial implementation and is independent
+         from the main network driver.
+
+         If in doubt, say N here.
+
 endmenu
index ac1bdf844ecabaf26abcc3b8b2e42e5d31743619..02b9e636dab758f54dcb7c0bd0c1f51fdecebc34 100644 (file)
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
 obj-y += interrupt.o exports.o os-area.o
 obj-y += system-bus.o
 
+obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPU_BASE) += spu.o
 obj-y += device-init.o
index 6c4b5837fc8ab27965e66a1ca55689f92bbce975..3f175e8aedb499c4a94427d3c9a6028895c533df 100644 (file)
@@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data)
 
        spin_lock_init(&dev.lock);
 
-       res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
+       res = request_irq(irq, ps3_notification_interrupt, 0,
                          "ps3_notification", &dev);
        if (res) {
                pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
index a7e8ffd24a651b2a7cd8c0b11e8776b217627511..7df5b7d8fc6663449dd8cc6215917f0a9aa81eb8 100644 (file)
@@ -18,8 +18,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <linux/module.h>
-
 #define LV1_CALL(name, in, out, num)                          \
   extern s64 _lv1_##name(LV1_##in##_IN_##out##_OUT_ARG_DECL); \
   EXPORT_SYMBOL(_lv1_##name);
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
new file mode 100644 (file)
index 0000000..20b46a1
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * udbg debug output routine via GELIC UDP broadcasts
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/udbg.h>
+#include <asm/lv1call.h>
+
+#define GELIC_BUS_ID 1
+#define GELIC_DEVICE_ID 0
+#define GELIC_DEBUG_PORT 18194
+#define GELIC_MAX_MESSAGE_SIZE 1000
+
+#define GELIC_LV1_GET_MAC_ADDRESS 1
+#define GELIC_LV1_GET_VLAN_ID 4
+#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
+
+#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
+#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
+
+#define GELIC_DESCR_TX_DMA_IKE 0x00080000
+#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
+#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
+                                      GELIC_DESCR_TX_DMA_IKE | \
+                                      GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+static u64 bus_addr;
+
+struct gelic_descr {
+       /* as defined by the hardware */
+       __be32 buf_addr;
+       __be32 buf_size;
+       __be32 next_descr_addr;
+       __be32 dmac_cmd_status;
+       __be32 result_size;
+       __be32 valid_size;      /* all zeroes for tx */
+       __be32 data_status;
+       __be32 data_error;      /* all zeroes for tx */
+} __attribute__((aligned(32)));
+
+struct debug_block {
+       struct gelic_descr descr;
+       u8 pkt[1520];
+} __packed;
+
+struct ethhdr {
+       u8 dest[6];
+       u8 src[6];
+       u16 type;
+} __packed;
+
+struct vlantag {
+       u16 vlan;
+       u16 subtype;
+} __packed;
+
+struct iphdr {
+       u8 ver_len;
+       u8 dscp_ecn;
+       u16 total_length;
+       u16 ident;
+       u16 frag_off_flags;
+       u8 ttl;
+       u8 proto;
+       u16 checksum;
+       u32 src;
+       u32 dest;
+} __packed;
+
+struct udphdr {
+       u16 src;
+       u16 dest;
+       u16 len;
+       u16 checksum;
+} __packed;
+
+static __iomem struct ethhdr *h_eth;
+static __iomem struct vlantag *h_vlan;
+static __iomem struct iphdr *h_ip;
+static __iomem struct udphdr *h_udp;
+
+static __iomem char *pmsg;
+static __iomem char *pmsgc;
+
+static __iomem struct debug_block dbg __attribute__((aligned(32)));
+
+static int header_size;
+
+static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
+                       u64 *real_bus_addr)
+{
+       s64 result;
+       u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
+       u64 real_end = real_addr + len;
+       u64 map_start = real_addr & ~0xfff;
+       u64 map_end = (real_end + 0xfff) & ~0xfff;
+       u64 bus_addr = 0;
+
+       u64 flags = 0xf800000000000000UL;
+
+       result = lv1_allocate_device_dma_region(bus_id, dev_id,
+                                               map_end - map_start, 12, 0,
+                                               &bus_addr);
+       if (result)
+               lv1_panic(0);
+
+       result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
+                                          bus_addr, map_end - map_start,
+                                          flags);
+       if (result)
+               lv1_panic(0);
+
+       *real_bus_addr = bus_addr + real_addr - map_start;
+}
+
+static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
+{
+       s64 result;
+       u64 real_bus_addr;
+
+       real_bus_addr = bus_addr & ~0xfff;
+       len += bus_addr - real_bus_addr;
+       len = (len + 0xfff) & ~0xfff;
+
+       result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
+                                            len);
+       if (result)
+               return result;
+
+       return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
+}
+
+static void gelic_debug_init(void)
+{
+       s64 result;
+       u64 v2;
+       u64 mac;
+       u64 vlan_id;
+
+       result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
+       if (result)
+               lv1_panic(0);
+
+       map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
+                   &bus_addr);
+
+       memset(&dbg, 0, sizeof(dbg));
+
+       dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
+
+       wmb();
+
+       result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+                                GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
+                                &mac, &v2);
+       if (result)
+               lv1_panic(0);
+
+       mac <<= 16;
+
+       h_eth = (struct ethhdr *)dbg.pkt;
+
+       memset(&h_eth->dest, 0xff, 6);
+       memcpy(&h_eth->src, &mac, 6);
+
+       header_size = sizeof(struct ethhdr);
+
+       result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+                                GELIC_LV1_GET_VLAN_ID,
+                                GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
+                                &vlan_id, &v2);
+       if (!result) {
+               h_eth->type = 0x8100;
+
+               header_size += sizeof(struct vlantag);
+               h_vlan = (struct vlantag *)(h_eth + 1);
+               h_vlan->vlan = vlan_id;
+               h_vlan->subtype = 0x0800;
+               h_ip = (struct iphdr *)(h_vlan + 1);
+       } else {
+               h_eth->type = 0x0800;
+               h_ip = (struct iphdr *)(h_eth + 1);
+       }
+
+       header_size += sizeof(struct iphdr);
+       h_ip->ver_len = 0x45;
+       h_ip->ttl = 10;
+       h_ip->proto = 0x11;
+       h_ip->src = 0x00000000;
+       h_ip->dest = 0xffffffff;
+
+       header_size += sizeof(struct udphdr);
+       h_udp = (struct udphdr *)(h_ip + 1);
+       h_udp->src = GELIC_DEBUG_PORT;
+       h_udp->dest = GELIC_DEBUG_PORT;
+
+       pmsgc = pmsg = (char *)(h_udp + 1);
+}
+
+static void gelic_debug_shutdown(void)
+{
+       if (bus_addr)
+               unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
+                             bus_addr, sizeof(dbg));
+       lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
+}
+
+static void gelic_sendbuf(int msgsize)
+{
+       u16 *p;
+       u32 sum;
+       int i;
+
+       dbg.descr.buf_size = header_size + msgsize;
+       h_ip->total_length = msgsize + sizeof(struct udphdr) +
+                            sizeof(struct iphdr);
+       h_udp->len = msgsize + sizeof(struct udphdr);
+
+       h_ip->checksum = 0;
+       sum = 0;
+       p = (u16 *)h_ip;
+       for (i = 0; i < 5; i++)
+               sum += *p++;
+       h_ip->checksum = ~(sum + (sum >> 16));
+
+       dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+                                   GELIC_DESCR_TX_DMA_FRAME_TAIL;
+       dbg.descr.result_size = 0;
+       dbg.descr.data_status = 0;
+
+       wmb();
+
+       lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
+
+       while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
+              GELIC_DESCR_DMA_CARDOWNED)
+               cpu_relax();
+}
+
+static void ps3gelic_udbg_putc(char ch)
+{
+       *pmsgc++ = ch;
+       if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
+               gelic_sendbuf(pmsgc-pmsg);
+               pmsgc = pmsg;
+       }
+}
+
+void __init udbg_init_ps3gelic(void)
+{
+       gelic_debug_init();
+       udbg_putc = ps3gelic_udbg_putc;
+}
+
+void udbg_shutdown_ps3gelic(void)
+{
+       udbg_putc = NULL;
+       gelic_debug_shutdown();
+}
+EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
index 600ed2c0ed5937ce31980eb5e3d8d9db2c1196ed..1d6f4f478fe293ebd06313aa1077c1019507473d 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/irq.h>
 
 #include <asm/machdep.h>
@@ -88,6 +88,7 @@ struct ps3_private {
        struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
        u64 ppe_id;
        u64 thread_id;
+       unsigned long ipi_mask;
 };
 
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
@@ -144,7 +145,11 @@ static void ps3_chip_unmask(struct irq_data *d)
 static void ps3_chip_eoi(struct irq_data *d)
 {
        const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
-       lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
+
+       /* non-IPIs are EOIed here. */
+
+       if (!test_bit(63 - d->irq, &pd->ipi_mask))
+               lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
 }
 
 /**
@@ -691,6 +696,16 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
                cpu, virq, pd->bmp.ipi_debug_brk_mask);
 }
 
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq)
+{
+       struct ps3_private *pd = &per_cpu(ps3_private, cpu);
+
+       set_bit(63 - virq, &pd->ipi_mask);
+
+       DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__,
+               cpu, virq, pd->ipi_mask);
+}
+
 static unsigned int ps3_get_irq(void)
 {
        struct ps3_private *pd = &__get_cpu_var(ps3_private);
@@ -720,6 +735,12 @@ static unsigned int ps3_get_irq(void)
                BUG();
        }
 #endif
+
+       /* IPIs are EOIed here. */
+
+       if (test_bit(63 - plug, &pd->ipi_mask))
+               lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug);
+
        return plug;
 }
 
index c2045880e674afc91a5295711042f4722c6aa510..72714ad278424a250c887e02635c3d5ef37b5979 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/memory_hotplug.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
index 5b759b66959833d60d1fe0f3cc524d0a3b023e2a..56d26bc4fd413d1a727e57b463da8c0816e1d117 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/fs.h>
 #include <linux/syscalls.h>
+#include <linux/export.h>
 #include <linux/ctype.h>
 #include <linux/memblock.h>
 #include <linux/of.h>
index 9a196a88eda794d6d07f50abefaebc7a21902427..1a633ed0fe98744d8994d7e6367180a11ab59a96 100644 (file)
@@ -43,6 +43,7 @@ void ps3_mm_shutdown(void);
 void ps3_init_IRQ(void);
 void ps3_shutdown_IRQ(int cpu);
 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
+void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq);
 
 /* smp */
 
index 5e304c292f68e1e22e3fff9dd3527ae8a5f1bcd1..ca40f6afd35d5a0ed6043008740761558769e6fb 100644 (file)
@@ -184,7 +184,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index,
        enum ps3_bus_type *bus_type)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -199,7 +199,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index,
        unsigned int *num_dev)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -239,7 +239,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index,
        unsigned int dev_index, enum ps3_dev_type *dev_type)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -256,8 +256,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index,
        enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
 {
        int result;
-       u64 v1;
-       u64 v2;
+       u64 v1 = 0;
+       u64 v2 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -275,7 +275,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index,
        enum ps3_reg_type *reg_type)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -615,7 +615,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
        unsigned int dev_index, unsigned int *num_regions)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("bus", bus_index),
@@ -631,7 +631,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
        unsigned int *region_id)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
            make_first_field("bus", bus_index),
@@ -786,7 +786,7 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
 int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -805,7 +805,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
 int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -827,8 +827,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
        enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
 {
        int result;
-       u64 v1;
-       u64 v2;
+       u64 v1 = 0;
+       u64 v2 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -854,7 +854,7 @@ static int ps3_repository_read_boot_dat_address(u64 *address)
 int ps3_repository_read_boot_dat_size(unsigned int *size)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -869,7 +869,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size)
 int ps3_repository_read_vuart_av_port(unsigned int *port)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -884,7 +884,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port)
 int ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_CURRENT,
                make_first_field("bi", 0),
@@ -919,7 +919,7 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
 int ps3_repository_read_num_be(unsigned int *num_be)
 {
        int result;
-       u64 v1;
+       u64 v1 = 0;
 
        result = read_node(PS3_LPAR_ID_PME,
                make_first_field("ben", 0),
index 149bea2ce58370b606fc51132760123d1bebadba..e8ec1b2bfffd2a7b2f5eff77d57dc5ee872b27df 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/fs.h>
 #include <linux/root_dev.h>
 #include <linux/console.h>
+#include <linux/export.h>
 #include <linux/bootmem.h>
 
 #include <asm/machdep.h>
index 4c44794faac0b344ac50663ed12122519c37b53d..efc1cd8c034ac7f47135f7af1e1582d9e722984b 100644 (file)
@@ -59,46 +59,49 @@ static void ps3_smp_message_pass(int cpu, int msg)
 
 static int ps3_smp_probe(void)
 {
-       return 2;
-}
+       int cpu;
 
-static void __init ps3_smp_setup_cpu(int cpu)
-{
-       int result;
-       unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
-       int i;
+       for (cpu = 0; cpu < 2; cpu++) {
+               int result;
+               unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
+               int i;
 
-       DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+               DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
 
-       /*
-        * Check assumptions on ps3_ipi_virqs[] indexing. If this
-        * check fails, then a different mapping of PPC_MSG_
-        * to index needs to be setup.
-        */
+               /*
+               * Check assumptions on ps3_ipi_virqs[] indexing. If this
+               * check fails, then a different mapping of PPC_MSG_
+               * to index needs to be setup.
+               */
 
-       BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
-       BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
-       BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
-       BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK   != 3);
+               BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
+               BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
+               BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
+               BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK   != 3);
 
-       for (i = 0; i < MSG_COUNT; i++) {
-               result = ps3_event_receive_port_setup(cpu, &virqs[i]);
+               for (i = 0; i < MSG_COUNT; i++) {
+                       result = ps3_event_receive_port_setup(cpu, &virqs[i]);
 
-               if (result)
-                       continue;
+                       if (result)
+                               continue;
 
-               DBG("%s:%d: (%d, %d) => virq %u\n",
-                       __func__, __LINE__, cpu, i, virqs[i]);
+                       DBG("%s:%d: (%d, %d) => virq %u\n",
+                               __func__, __LINE__, cpu, i, virqs[i]);
 
-               result = smp_request_message_ipi(virqs[i], i);
+                       result = smp_request_message_ipi(virqs[i], i);
 
-               if (result)
-                       virqs[i] = NO_IRQ;
-       }
+                       if (result)
+                               virqs[i] = NO_IRQ;
+                       else
+                               ps3_register_ipi_irq(cpu, virqs[i]);
+               }
 
-       ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
+               ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
 
-       DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
+               DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
+       }
+
+       return 2;
 }
 
 void ps3_smp_cleanup_cpu(int cpu)
@@ -121,7 +124,6 @@ static struct smp_ops_t ps3_smp_ops = {
        .probe          = ps3_smp_probe,
        .message_pass   = ps3_smp_message_pass,
        .kick_cpu       = smp_generic_kick_cpu,
-       .setup_cpu      = ps3_smp_setup_cpu,
 };
 
 void smp_init_ps3(void)
index 375a9f92158d48d5a7996d5ace60f7c551bf4ff4..451fad1c92a84aff71598842961999ce6a8f4db8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mmzone.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 
index 23083c397528408e182b2e2cd8be6d5078aafdab..880eb9ce22c52784f8c8993e291dfb5f7a7c3cc3 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/slab.h>
@@ -695,12 +695,18 @@ static int ps3_dma_supported(struct device *_dev, u64 mask)
        return mask >= DMA_BIT_MASK(32);
 }
 
+static u64 ps3_dma_get_required_mask(struct device *_dev)
+{
+       return DMA_BIT_MASK(32);
+}
+
 static struct dma_map_ops ps3_sb_dma_ops = {
        .alloc_coherent = ps3_alloc_coherent,
        .free_coherent = ps3_free_coherent,
        .map_sg = ps3_sb_map_sg,
        .unmap_sg = ps3_sb_unmap_sg,
        .dma_supported = ps3_dma_supported,
+       .get_required_mask = ps3_dma_get_required_mask,
        .map_page = ps3_sb_map_page,
        .unmap_page = ps3_unmap_page,
 };
@@ -711,6 +717,7 @@ static struct dma_map_ops ps3_ioc0_dma_ops = {
        .map_sg = ps3_ioc0_map_sg,
        .unmap_sg = ps3_ioc0_unmap_sg,
        .dma_supported = ps3_dma_supported,
+       .get_required_mask = ps3_dma_get_required_mask,
        .map_page = ps3_ioc0_map_page,
        .unmap_page = ps3_unmap_page,
 };
index 05cf4769b88cd0e6f0fc7292a2f4a394d84a27e7..c81f6bb9c10fc0ae33b57e134735d4a8fa12a25c 100644 (file)
@@ -15,6 +15,7 @@ config PPC_PSERIES
        select PPC_UDBG_16550
        select PPC_NATIVE
        select PPC_PCI_CHOICE if EXPERT
+       select ZLIB_DEFLATE
        default y
 
 config PPC_SPLPAR
index e9be25bc571bbb254b91ceea6639ff6ee0f053ef..0f1b706506ed67d5ead6250051ba282f170d2ede 100644 (file)
@@ -112,6 +112,7 @@ void dlpar_free_cc_nodes(struct device_node *dn)
        dlpar_free_one_cc_node(dn);
 }
 
+#define COMPLETE       0
 #define NEXT_SIBLING    1
 #define NEXT_CHILD      2
 #define NEXT_PROPERTY   3
@@ -158,6 +159,9 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
                spin_unlock(&rtas_data_buf_lock);
 
                switch (rc) {
+               case COMPLETE:
+                       break;
+
                case NEXT_SIBLING:
                        dn = dlpar_parse_cc_node(ccwa);
                        if (!dn)
index ada6e07532ecf8919987e33818d69330ea0c760b..565869022e3d4e54c603cc6b2f79afb7fe6c2bd2 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/sched.h>       /* for init_mm */
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/pci.h>
@@ -29,6 +30,7 @@
 #include <linux/rbtree.h>
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/of.h>
 
 #include <linux/atomic.h>
@@ -1338,7 +1340,7 @@ static const struct file_operations proc_eeh_operations = {
 static int __init eeh_init_proc(void)
 {
        if (machine_is(pseries))
-               proc_create("ppc64/eeh", 0, NULL, &proc_eeh_operations);
+               proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
        return 0;
 }
 __initcall(eeh_init_proc);
index 2ec500c130b5173ab497f6e51dc2eac7d860a407..d2383cfb6dfd34f86b6f8e3d79437f06506c7273 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
index 23982c7892d2a2abb470a74558a764f68045bca9..eb744ee234daebae5fe2a2d54fcf7fbacd41e4a4 100644 (file)
@@ -23,6 +23,7 @@
  * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
  */
 #include <linux/pci.h>
+#include <linux/stat.h>
 #include <asm/ppc-pci.h>
 #include <asm/pci-bridge.h>
 
index 83a3ca2fd2823a3101744b847cc09d5f0fb1eb33..c986d08d0807d91a36c7a927cdbd807ba3ed1276 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/sched.h>       /* for idle_task_exit */
 #include <linux/cpu.h>
 #include <asm/system.h>
 #include <asm/prom.h>
index 041e87ca189314cebd032320cf7df53c6fcf2888..b344f94b040091b60eac57a80c5218a2e5071ebc 100644 (file)
@@ -24,7 +24,8 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/errno.h>
 #include <asm/hvcall.h>
 #include <asm/hvconsole.h>
 #include "plpar_wrappers.h"
index 2c4dd1fb833331239ebeacf77d59cb8672bdf4ad..1a709bc48ce18c89acca256e56d2930ad661f58f 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
index 01faab9456ca198ded600519b4a887e5dd8b7efb..b719d9709730e577af3671a562f5ab415d7daacd 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
+#include <linux/sched.h>       /* for show_stack */
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -939,14 +940,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        if (ret) {
                dev_info(&dev->dev, "failed to map direct window for %s: %d\n",
                         dn->full_name, ret);
-               goto out_clear_window;
+               goto out_free_window;
        }
 
        ret = prom_add_property(pdn, win64);
        if (ret) {
                dev_err(&dev->dev, "unable to add dma window property for %s: %d",
                         pdn->full_name, ret);
-               goto out_clear_window;
+               goto out_free_window;
        }
 
        window->device = pdn;
@@ -958,6 +959,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        dma_addr = of_read_number(&create.addr_hi, 2);
        goto out_unlock;
 
+out_free_window:
+       kfree(window);
+
 out_clear_window:
        remove_ddw(pdn);
 
@@ -1077,12 +1081,38 @@ check_mask:
        return 0;
 }
 
+static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
+{
+       if (!dev->dma_mask)
+               return 0;
+
+       if (!disable_ddw && dev_is_pci(dev)) {
+               struct pci_dev *pdev = to_pci_dev(dev);
+               struct device_node *dn;
+
+               dn = pci_device_to_OF_node(pdev);
+
+               /* search upwards for ibm,dma-window */
+               for (; dn && PCI_DN(dn) && !PCI_DN(dn)->iommu_table;
+                               dn = dn->parent)
+                       if (of_get_property(dn, "ibm,dma-window", NULL))
+                               break;
+               /* if there is a ibm,ddw-applicable property require 64 bits */
+               if (dn && PCI_DN(dn) &&
+                               of_get_property(dn, "ibm,ddw-applicable", NULL))
+                       return DMA_BIT_MASK(64);
+       }
+
+       return dma_iommu_ops.get_required_mask(dev);
+}
+
 #else  /* CONFIG_PCI */
 #define pci_dma_bus_setup_pSeries      NULL
 #define pci_dma_dev_setup_pSeries      NULL
 #define pci_dma_bus_setup_pSeriesLP    NULL
 #define pci_dma_dev_setup_pSeriesLP    NULL
 #define dma_set_mask_pSeriesLP         NULL
+#define dma_get_required_mask_pSeriesLP        NULL
 #endif /* !CONFIG_PCI */
 
 static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
@@ -1186,6 +1216,7 @@ void iommu_init_early_pSeries(void)
                ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
                ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
                ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
+               ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP;
        } else {
                ppc_md.tce_build = tce_build_pSeries;
                ppc_md.tce_free  = tce_free_pSeries;
index c9a29dae8c0538359e60a3a377484277770c1bc3..27a49508b410711beebff40be49524c28ee3bddc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
 #include <linux/console.h>
+#include <linux/export.h>
 #include <asm/processor.h>
 #include <asm/mmu.h>
 #include <asm/page.h>
index 3e7f651e50ac9bbec2f76f7d31923bdba725b52f..029a562af3738070d5d612dbad13c3819f970642 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/kobject.h>
 #include <linux/smp.h>
+#include <linux/stat.h>
 #include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/delay.h>
index 00cc3a0948852ccc0429af5cf3910a6dbb621cf3..a76b22844d18b63cc87f33720009ea3e567f28e9 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/kmsg_dump.h>
+#include <linux/ctype.h>
+#include <linux/zlib.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 #include <asm/rtas.h>
@@ -78,8 +80,41 @@ static struct kmsg_dumper nvram_kmsg_dumper = {
 #define NVRAM_RTAS_READ_TIMEOUT 5              /* seconds */
 static unsigned long last_unread_rtas_event;   /* timestamp */
 
-/* We preallocate oops_buf during init to avoid kmalloc during oops/panic. */
-static char *oops_buf;
+/*
+ * For capturing and compressing an oops or panic report...
+
+ * big_oops_buf[] holds the uncompressed text we're capturing.
+ *
+ * oops_buf[] holds the compressed text, preceded by a prefix.
+ * The prefix is just a u16 holding the length of the compressed* text.
+ * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
+ * to NVRAM.
+ *
+ * oops_len points to the prefix.  oops_data points to the compressed text.
+ *
+ * +- oops_buf
+ * |           +- oops_data
+ * v           v
+ * +------------+-----------------------------------------------+
+ * | length    | text                                          |
+ * | (2 bytes) | (oops_data_sz bytes)                          |
+ * +------------+-----------------------------------------------+
+ * ^
+ * +- oops_len
+ *
+ * We preallocate these buffers during init to avoid kmalloc during oops/panic.
+ */
+static size_t big_oops_buf_sz;
+static char *big_oops_buf, *oops_buf;
+static u16 *oops_len;
+static char *oops_data;
+static size_t oops_data_sz;
+
+/* Compression parameters */
+#define COMPR_LEVEL 6
+#define WINDOW_BITS 12
+#define MEM_LEVEL 4
+static struct z_stream_s stream;
 
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
 {
@@ -387,11 +422,44 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
                                                sizeof(rtas_log_partition));
        }
        oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL);
+       if (!oops_buf) {
+               pr_err("nvram: No memory for %s partition\n",
+                                               oops_log_partition.name);
+               return;
+       }
+       oops_len = (u16*) oops_buf;
+       oops_data = oops_buf + sizeof(u16);
+       oops_data_sz = oops_log_partition.size - sizeof(u16);
+
+       /*
+        * Figure compression (preceded by elimination of each line's <n>
+        * severity prefix) will reduce the oops/panic report to at most
+        * 45% of its original size.
+        */
+       big_oops_buf_sz = (oops_data_sz * 100) / 45;
+       big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
+       if (big_oops_buf) {
+               stream.workspace = kmalloc(zlib_deflate_workspacesize(
+                               WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
+               if (!stream.workspace) {
+                       pr_err("nvram: No memory for compression workspace; "
+                               "skipping compression of %s partition data\n",
+                               oops_log_partition.name);
+                       kfree(big_oops_buf);
+                       big_oops_buf = NULL;
+               }
+       } else {
+               pr_err("No memory for uncompressed %s data; "
+                       "skipping compression\n", oops_log_partition.name);
+               stream.workspace = NULL;
+       }
+
        rc = kmsg_dump_register(&nvram_kmsg_dumper);
        if (rc != 0) {
                pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);
                kfree(oops_buf);
-               return;
+               kfree(big_oops_buf);
+               kfree(stream.workspace);
        }
 }
 
@@ -473,7 +541,83 @@ static int clobbering_unread_rtas_event(void)
                                                NVRAM_RTAS_READ_TIMEOUT);
 }
 
-/* our kmsg_dump callback */
+/* Squeeze out each line's <n> severity prefix. */
+static size_t elide_severities(char *buf, size_t len)
+{
+       char *in, *out, *buf_end = buf + len;
+       /* Assume a <n> at the very beginning marks the start of a line. */
+       int newline = 1;
+
+       in = out = buf;
+       while (in < buf_end) {
+               if (newline && in+3 <= buf_end &&
+                               *in == '<' && isdigit(in[1]) && in[2] == '>') {
+                       in += 3;
+                       newline = 0;
+               } else {
+                       newline = (*in == '\n');
+                       *out++ = *in++;
+               }
+       }
+       return out - buf;
+}
+
+/* Derived from logfs_compress() */
+static int nvram_compress(const void *in, void *out, size_t inlen,
+                                                       size_t outlen)
+{
+       int err, ret;
+
+       ret = -EIO;
+       err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
+                                               MEM_LEVEL, Z_DEFAULT_STRATEGY);
+       if (err != Z_OK)
+               goto error;
+
+       stream.next_in = in;
+       stream.avail_in = inlen;
+       stream.total_in = 0;
+       stream.next_out = out;
+       stream.avail_out = outlen;
+       stream.total_out = 0;
+
+       err = zlib_deflate(&stream, Z_FINISH);
+       if (err != Z_STREAM_END)
+               goto error;
+
+       err = zlib_deflateEnd(&stream);
+       if (err != Z_OK)
+               goto error;
+
+       if (stream.total_out >= stream.total_in)
+               goto error;
+
+       ret = stream.total_out;
+error:
+       return ret;
+}
+
+/* Compress the text from big_oops_buf into oops_buf. */
+static int zip_oops(size_t text_len)
+{
+       int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
+                                                               oops_data_sz);
+       if (zipped_len < 0) {
+               pr_err("nvram: compression failed; returned %d\n", zipped_len);
+               pr_err("nvram: logging uncompressed oops/panic report\n");
+               return -1;
+       }
+       *oops_len = (u16) zipped_len;
+       return 0;
+}
+
+/*
+ * This is our kmsg_dump callback, called after an oops or panic report
+ * has been written to the printk buffer.  We want to capture as much
+ * of the printk buffer as possible.  First, capture as much as we can
+ * that we think will compress sufficiently to fit in the lnx,oops-log
+ * partition.  If that's too much, go back and capture uncompressed text.
+ */
 static void oops_to_nvram(struct kmsg_dumper *dumper,
                enum kmsg_dump_reason reason,
                const char *old_msgs, unsigned long old_len,
@@ -482,6 +626,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
        static unsigned int oops_count = 0;
        static bool panicking = false;
        size_t text_len;
+       unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
+       int rc = -1;
 
        switch (reason) {
        case KMSG_DUMP_RESTART:
@@ -509,8 +655,19 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
        if (clobbering_unread_rtas_event())
                return;
 
-       text_len = capture_last_msgs(old_msgs, old_len, new_msgs, new_len,
-                                       oops_buf, oops_log_partition.size);
+       if (big_oops_buf) {
+               text_len = capture_last_msgs(old_msgs, old_len,
+                       new_msgs, new_len, big_oops_buf, big_oops_buf_sz);
+               text_len = elide_severities(big_oops_buf, text_len);
+               rc = zip_oops(text_len);
+       }
+       if (rc != 0) {
+               text_len = capture_last_msgs(old_msgs, old_len,
+                               new_msgs, new_len, oops_data, oops_data_sz);
+               err_type = ERR_TYPE_KERNEL_PANIC;
+               *oops_len = (u16) text_len;
+       }
+
        (void) nvram_write_os_partition(&oops_log_partition, oops_buf,
-               (int) text_len, ERR_TYPE_KERNEL_PANIC, ++oops_count);
+               (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
 }
index 3bf4488aaec6537ce6983965bee978209fb7be4e..55d4ec1bd1ac6234531127c867749aa5bba3ca68 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
index 41c24c146d6a9e8f06403272944a116860091ce3..342797fc0f9c5f6e276993b6cf704380c1b3e464 100644 (file)
@@ -1,7 +1,10 @@
 #ifndef _PSERIES_PLPAR_WRAPPERS_H
 #define _PSERIES_PLPAR_WRAPPERS_H
 
+#include <linux/string.h>
+
 #include <asm/hvcall.h>
+#include <asm/paca.h>
 #include <asm/page.h>
 
 /* Get state of physical CPU from query_cpu_stopped */
index 0969fd98c4faa8741e7e18f445755b8ad9048322..c3408ca8855ed665d6e38e0c03a5cc57098df9f9 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/pci.h>
 #include <linux/utsname.h>
 #include <linux/adb.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/seq_file.h>
index 4e44c4dcd11c0cc077ca29ddae6bd4d6a6fe9462..26e93fd4c62b4e8d0037ab31fb6209cb788b1340 100644 (file)
@@ -14,7 +14,6 @@
 
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
index a8ca289ff2673676ec55c671adc21bdc367a4440..d3de0849f29645520e9537569156d6b022f732a4 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/delay.h>
 #include <linux/suspend.h>
+#include <linux/stat.h>
 #include <asm/firmware.h>
 #include <asm/hvcall.h>
 #include <asm/machdep.h>
index c3c48eb62cc1b24dd206b9987cf1d5ce634d044a..bd560c786ed654f76b6703d2b6eb1e37cc717923 100644 (file)
@@ -1,5 +1,12 @@
 config PPC_WSP
        bool
+       select PPC_A2
+       select PPC_SCOM
+       select PPC_XICS
+       select PPC_ICP_NATIVE
+       select PCI
+       select PPC_IO_WORKAROUNDS if PCI
+       select PPC_INDIRECT_PIO if PCI
        default n
 
 menu "WSP platform selection"
@@ -7,13 +14,9 @@ menu "WSP platform selection"
 
 config PPC_PSR2
        bool "PSR-2 platform"
-       select PPC_A2
        select GENERIC_TBSYNC
-       select PPC_SCOM
        select EPAPR_BOOT
        select PPC_WSP
-       select PPC_XICS
-       select PPC_ICP_NATIVE
        default y
 
 endmenu
@@ -21,8 +24,3 @@ endmenu
 config PPC_A2_DD2
        bool "Support for DD2 based A2/WSP systems"
        depends on PPC_A2
-
-config WORKAROUND_ERRATUM_463
-       depends on PPC_A2_DD2
-       bool "Workaround erratum 463"
-       default y
index 095be73d6cd42814d36f07cf563e16d77b67f955..a1486b436f02d528ffbf78c44e42dba3e4012a66 100644 (file)
@@ -4,3 +4,5 @@ obj-y                           += setup.o ics.o
 obj-$(CONFIG_PPC_PSR2)         += psr2.o opb_pic.o
 obj-$(CONFIG_PPC_WSP)          += scom_wsp.o
 obj-$(CONFIG_SMP)              += smp.o scom_smp.o
+obj-$(CONFIG_PCI)              += wsp_pci.o
+obj-$(CONFIG_PCI_MSI)          += msi.o
\ No newline at end of file
index e53bd9e7b1251fdd9fceee26f9b9f1d84781d0b5..57687439254310f8521bd3da217df1b380be64ba 100644 (file)
@@ -710,3 +710,51 @@ void __init wsp_init_irq(void)
        /* We need to patch our irq chip's EOI to point to the right ICP */
        wsp_irq_chip.irq_eoi = icp_ops->eoi;
 }
+
+#ifdef CONFIG_PCI_MSI
+static void wsp_ics_msi_unmask_irq(struct irq_data *d)
+{
+       wsp_chip_unmask_irq(d);
+       unmask_msi_irq(d);
+}
+
+static unsigned int wsp_ics_msi_startup(struct irq_data *d)
+{
+       wsp_ics_msi_unmask_irq(d);
+       return 0;
+}
+
+static void wsp_ics_msi_mask_irq(struct irq_data *d)
+{
+       mask_msi_irq(d);
+       wsp_chip_mask_irq(d);
+}
+
+/*
+ * we do it this way because we reassinge default EOI handling in
+ * irq_init() above
+ */
+static void wsp_ics_eoi(struct irq_data *data)
+{
+       wsp_irq_chip.irq_eoi(data);
+}
+
+static struct irq_chip wsp_ics_msi = {
+       .name = "WSP ICS MSI",
+       .irq_startup = wsp_ics_msi_startup,
+       .irq_mask = wsp_ics_msi_mask_irq,
+       .irq_unmask = wsp_ics_msi_unmask_irq,
+       .irq_eoi = wsp_ics_eoi,
+       .irq_set_affinity = wsp_chip_set_affinity
+};
+
+void wsp_ics_set_msi_chip(unsigned int irq)
+{
+       irq_set_chip(irq, &wsp_ics_msi);
+}
+
+void wsp_ics_set_std_chip(unsigned int irq)
+{
+       irq_set_chip(irq, &wsp_irq_chip);
+}
+#endif /* CONFIG_PCI_MSI */
index e34d53102640f140479182afd339d95e2af3a387..07b644e0cf97eb91d18f2d0c599e398a22db13a8 100644 (file)
@@ -17,4 +17,9 @@ extern void wsp_init_irq(void);
 extern int wsp_ics_alloc_irq(struct device_node *dn, int num);
 extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq);
 
+#ifdef CONFIG_PCI_MSI
+extern void wsp_ics_set_msi_chip(unsigned int irq);
+extern void wsp_ics_set_std_chip(unsigned int irq);
+#endif /* CONFIG_PCI_MSI */
+
 #endif /* __ICS_H */
diff --git a/arch/powerpc/platforms/wsp/msi.c b/arch/powerpc/platforms/wsp/msi.c
new file mode 100644 (file)
index 0000000..380882f
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include "msi.h"
+#include "ics.h"
+#include "wsp_pci.h"
+
+/* Magic addresses for 32 & 64-bit MSIs with hardcoded MVE 0 */
+#define MSI_ADDR_32            0xFFFF0000ul
+#define MSI_ADDR_64            0x1000000000000000ul
+
+int wsp_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+       struct pci_controller *phb;
+       struct msi_desc *entry;
+       struct msi_msg msg;
+       unsigned int virq;
+       int hwirq;
+
+       phb = pci_bus_to_host(dev->bus);
+       if (!phb)
+               return -ENOENT;
+
+       entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
+       if (entry->msi_attrib.is_64) {
+               msg.address_lo = 0;
+               msg.address_hi = MSI_ADDR_64 >> 32;
+       } else {
+               msg.address_lo = MSI_ADDR_32;
+               msg.address_hi = 0;
+       }
+
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               hwirq = wsp_ics_alloc_irq(phb->dn, 1);
+               if (hwirq < 0) {
+                       dev_warn(&dev->dev, "wsp_msi: hwirq alloc failed!\n");
+                       return hwirq;
+               }
+
+               virq = irq_create_mapping(NULL, hwirq);
+               if (virq == NO_IRQ) {
+                       dev_warn(&dev->dev, "wsp_msi: virq alloc failed!\n");
+                       return -1;
+               }
+
+               dev_dbg(&dev->dev, "wsp_msi: allocated irq %#x/%#x\n",
+                       hwirq, virq);
+
+               wsp_ics_set_msi_chip(virq);
+               irq_set_msi_desc(virq, entry);
+               msg.data = hwirq & XIVE_ADDR_MASK;
+               write_msi_msg(virq, &msg);
+       }
+
+       return 0;
+}
+
+void wsp_teardown_msi_irqs(struct pci_dev *dev)
+{
+       struct pci_controller *phb;
+       struct msi_desc *entry;
+       int hwirq;
+
+       phb = pci_bus_to_host(dev->bus);
+
+       dev_dbg(&dev->dev, "wsp_msi: tearing down msi irqs\n");
+
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               if (entry->irq == NO_IRQ)
+                       continue;
+
+               irq_set_msi_desc(entry->irq, NULL);
+               wsp_ics_set_std_chip(entry->irq);
+
+               hwirq = virq_to_hw(entry->irq);
+               /* In this order to avoid racing with irq_create_mapping() */
+               irq_dispose_mapping(entry->irq);
+               wsp_ics_free_irq(phb->dn, hwirq);
+       }
+}
+
+void wsp_setup_phb_msi(struct pci_controller *phb)
+{
+       /* Create a single MVE at offset 0 that matches everything */
+       out_be64(phb->cfg_data + PCIE_REG_IODA_ADDR, PCIE_REG_IODA_AD_TBL_MVT);
+       out_be64(phb->cfg_data + PCIE_REG_IODA_DATA0, 1ull << 63);
+
+       ppc_md.setup_msi_irqs = wsp_setup_msi_irqs;
+       ppc_md.teardown_msi_irqs = wsp_teardown_msi_irqs;
+}
diff --git a/arch/powerpc/platforms/wsp/msi.h b/arch/powerpc/platforms/wsp/msi.h
new file mode 100644 (file)
index 0000000..0ab27b7
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2011 Michael Ellerman, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __WSP_MSI_H
+#define __WSP_MSI_H
+
+#ifdef CONFIG_PCI_MSI
+extern void wsp_setup_phb_msi(struct pci_controller *phb);
+#else
+static inline void wsp_setup_phb_msi(struct pci_controller *phb) { }
+#endif
+
+#endif /* __WSP_MSI_H */
index 40f28916ff6c014c2134339e5b3a92c12ce4affc..166f2e4b4bee91cadc298dc6540aecb9b2bcd0d9 100644 (file)
@@ -63,6 +63,10 @@ static void __init psr2_setup_arch(void)
 #ifdef CONFIG_SMP
        a2_setup_smp();
 #endif
+#ifdef CONFIG_PCI
+       wsp_setup_pci();
+#endif
+
 }
 
 static int __init psr2_probe(void)
index 7c3e087fd2f2bff8a35e075beca6b95b1a8014ba..33479818f62a20981fb617c75bd0b53da4b4c737 100644 (file)
@@ -3,6 +3,9 @@
 
 #include <asm/wsp.h>
 
+/* Devtree compatible strings for major devices */
+#define PCIE_COMPATIBLE     "ibm,wsp-pciex"
+
 extern void wsp_setup_pci(void);
 extern void scom_init_wsp(void);
 
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c
new file mode 100644 (file)
index 0000000..e0262cd
--- /dev/null
@@ -0,0 +1,1133 @@
+/*
+ * Copyright 2010 Ben Herrenschmidt, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/debugfs.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/iommu.h>
+#include <asm/io-workarounds.h>
+
+#include "wsp.h"
+#include "wsp_pci.h"
+#include "msi.h"
+
+
+/* Max number of TVTs for one table. Only 32-bit tables can use
+ * multiple TVTs and so the max currently supported is thus 8
+ * since only 2G of DMA space is supported
+ */
+#define MAX_TABLE_TVT_COUNT            8
+
+struct wsp_dma_table {
+       struct list_head        link;
+       struct iommu_table      table;
+       struct wsp_phb  *phb;
+       struct page             *tces[MAX_TABLE_TVT_COUNT];
+};
+
+/* We support DMA regions from 0...2G in 32bit space (no support for
+ * 64-bit DMA just yet). Each device gets a separate TCE table (TVT
+ * entry) with validation enabled (though not supported by SimiCS
+ * just yet).
+ *
+ * To simplify things, we divide this 2G space into N regions based
+ * on the constant below which could be turned into a tunable eventually
+ *
+ * We then assign dynamically those regions to devices as they show up.
+ *
+ * We use a bitmap as an allocator for these.
+ *
+ * Tables are allocated/created dynamically as devices are discovered,
+ * multiple TVT entries are used if needed
+ *
+ * When 64-bit DMA support is added we should simply use a separate set
+ * of larger regions (the HW supports 64 TVT entries). We can
+ * additionally create a bypass region in 64-bit space for performances
+ * though that would have a cost in term of security.
+ *
+ * If you set NUM_DMA32_REGIONS to 1, then a single table is shared
+ * for all devices and bus/dev/fn validation is disabled
+ *
+ * Note that a DMA32 region cannot be smaller than 256M so the max
+ * supported here for now is 8. We don't yet support sharing regions
+ * between multiple devices so the max number of devices supported
+ * is MAX_TABLE_TVT_COUNT.
+ */
+#define NUM_DMA32_REGIONS      1
+
+struct wsp_phb {
+       struct pci_controller   *hose;
+
+       /* Lock controlling access to the list of dma tables.
+        * It does -not- protect against dma_* operations on
+        * those tables, those should be stopped before an entry
+        * is removed from the list.
+        *
+        * The lock is also used for error handling operations
+        */
+       spinlock_t              lock;
+       struct list_head        dma_tables;
+       unsigned long           dma32_map;
+       unsigned long           dma32_base;
+       unsigned int            dma32_num_regions;
+       unsigned long           dma32_region_size;
+
+       /* Debugfs stuff */
+       struct dentry           *ddir;
+
+       struct list_head        all;
+};
+static LIST_HEAD(wsp_phbs);
+
+//#define cfg_debug(fmt...)    pr_debug(fmt)
+#define cfg_debug(fmt...)
+
+
+static int wsp_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+                                 int offset, int len, u32 *val)
+{
+       struct pci_controller *hose;
+       int suboff;
+       u64 addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (offset >= 0x1000)
+               return  PCIBIOS_BAD_REGISTER_NUMBER;
+       addr = PCIE_REG_CA_ENABLE |
+               ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT |
+               ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT |
+               ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT;
+       suboff = offset & 3;
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+
+       switch (len) {
+       case 1:
+               addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA)
+                       >> (suboff << 3)) & 0xff;
+               cfg_debug("read 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, *val);
+               break;
+       case 2:
+               addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               *val = (in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA)
+                       >> (suboff << 3)) & 0xffff;
+               cfg_debug("read 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, *val);
+               break;
+       default:
+               addr |= 0xful << PCIE_REG_CA_BE_SHIFT;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               *val = in_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA);
+               cfg_debug("read 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, *val);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int wsp_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+                                  int offset, int len, u32 val)
+{
+       struct pci_controller *hose;
+       int suboff;
+       u64 addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (offset >= 0x1000)
+               return  PCIBIOS_BAD_REGISTER_NUMBER;
+       addr = PCIE_REG_CA_ENABLE |
+               ((u64)bus->number) << PCIE_REG_CA_BUS_SHIFT |
+               ((u64)devfn) << PCIE_REG_CA_FUNC_SHIFT |
+               ((u64)offset & ~3) << PCIE_REG_CA_REG_SHIFT;
+       suboff = offset & 3;
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       switch (len) {
+       case 1:
+               addr |= (0x8ul >> suboff) << PCIE_REG_CA_BE_SHIFT;
+               val <<= suboff << 3;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
+               cfg_debug("write 1 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%02x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, val);
+               break;
+       case 2:
+               addr |= (0xcul >> suboff) << PCIE_REG_CA_BE_SHIFT;
+               val <<= suboff << 3;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
+               cfg_debug("write 2 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%04x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, val);
+               break;
+       default:
+               addr |= 0xful << PCIE_REG_CA_BE_SHIFT;
+               out_be64(hose->cfg_data + PCIE_REG_CONFIG_ADDRESS, addr);
+               out_le32(hose->cfg_data + PCIE_REG_CONFIG_DATA, val);
+               cfg_debug("write 4 %02x:%02x:%02x + %02x/%x addr=0x%llx val=%08x\n",
+                         bus->number, devfn >> 3, devfn & 7,
+                         offset, suboff, addr, val);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops wsp_pcie_pci_ops =
+{
+       .read = wsp_pcie_read_config,
+       .write = wsp_pcie_write_config,
+};
+
+#define TCE_SHIFT              12
+#define TCE_PAGE_SIZE          (1 << TCE_SHIFT)
+#define TCE_PCI_WRITE          0x2              /* write from PCI allowed */
+#define TCE_PCI_READ           0x1              /* read from PCI allowed */
+#define TCE_RPN_MASK           0x3fffffffffful  /* 42-bit RPN (4K pages) */
+#define TCE_RPN_SHIFT          12
+
+//#define dma_debug(fmt...)    pr_debug(fmt)
+#define dma_debug(fmt...)
+
+static int tce_build_wsp(struct iommu_table *tbl, long index, long npages,
+                          unsigned long uaddr, enum dma_data_direction direction,
+                          struct dma_attrs *attrs)
+{
+       struct wsp_dma_table *ptbl = container_of(tbl,
+                                                   struct wsp_dma_table,
+                                                   table);
+       u64 proto_tce;
+       u64 *tcep;
+       u64 rpn;
+
+       proto_tce = TCE_PCI_READ;
+#ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
+       proto_tce |= TCE_PCI_WRITE;
+#else
+       if (direction != DMA_TO_DEVICE)
+               proto_tce |= TCE_PCI_WRITE;
+#endif
+
+       /* XXX Make this faster by factoring out the page address for
+        * within a TCE table
+        */
+       while (npages--) {
+               /* We don't use it->base as the table can be scattered */
+               tcep = (u64 *)page_address(ptbl->tces[index >> 16]);
+               tcep += (index & 0xffff);
+
+               /* can't move this out since we might cross LMB boundary */
+               rpn = __pa(uaddr) >> TCE_SHIFT;
+               *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+
+               dma_debug("[DMA] TCE %p set to 0x%016llx (dma addr: 0x%lx)\n",
+                         tcep, *tcep, (tbl->it_offset + index) << IOMMU_PAGE_SHIFT);
+
+               uaddr += TCE_PAGE_SIZE;
+               index++;
+       }
+       return 0;
+}
+
+static void tce_free_wsp(struct iommu_table *tbl, long index, long npages)
+{
+       struct wsp_dma_table *ptbl = container_of(tbl,
+                                                   struct wsp_dma_table,
+                                                   table);
+#ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
+       struct pci_controller *hose = ptbl->phb->hose;
+#endif
+       u64 *tcep;
+
+       /* XXX Make this faster by factoring out the page address for
+        * within a TCE table. Also use line-kill option to kill multiple
+        * TCEs at once
+        */
+       while (npages--) {
+               /* We don't use it->base as the table can be scattered */
+               tcep = (u64 *)page_address(ptbl->tces[index >> 16]);
+               tcep += (index & 0xffff);
+               dma_debug("[DMA] TCE %p cleared\n", tcep);
+               *tcep = 0;
+#ifndef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
+               /* Don't write there since it would pollute other MMIO accesses */
+               out_be64(hose->cfg_data + PCIE_REG_TCE_KILL,
+                        PCIE_REG_TCEKILL_SINGLE | PCIE_REG_TCEKILL_PS_4K |
+                        (__pa(tcep) & PCIE_REG_TCEKILL_ADDR_MASK));
+#endif
+               index++;
+       }
+}
+
+static struct wsp_dma_table *wsp_pci_create_dma32_table(struct wsp_phb *phb,
+                                                           unsigned int region,
+                                                           struct pci_dev *validate)
+{
+       struct pci_controller *hose = phb->hose;
+       unsigned long size = phb->dma32_region_size;
+       unsigned long addr = phb->dma32_region_size * region + phb->dma32_base;
+       struct wsp_dma_table *tbl;
+       int tvts_per_table, i, tvt, nid;
+       unsigned long flags;
+
+       nid = of_node_to_nid(phb->hose->dn);
+
+       /* Calculate how many TVTs are needed */
+       tvts_per_table = size / 0x10000000;
+       if (tvts_per_table == 0)
+               tvts_per_table = 1;
+
+       /* Calculate the base TVT index. We know all tables have the same
+        * size so we just do a simple multiply here
+        */
+       tvt = region * tvts_per_table;
+
+       pr_debug("         Region : %d\n", region);
+       pr_debug("      DMA range : 0x%08lx..0x%08lx\n", addr, addr + size - 1);
+       pr_debug(" Number of TVTs : %d\n", tvts_per_table);
+       pr_debug("       Base TVT : %d\n", tvt);
+       pr_debug("         Node   : %d\n", nid);
+
+       tbl = kzalloc_node(sizeof(struct wsp_dma_table), GFP_KERNEL, nid);
+       if (!tbl)
+               return ERR_PTR(-ENOMEM);
+       tbl->phb = phb;
+
+       /* Create as many TVTs as needed, each represents 256M at most */
+       for (i = 0; i < tvts_per_table; i++) {
+               u64 tvt_data1, tvt_data0;
+
+               /* Allocate table. We use a 4K TCE size for now always so
+                * one table is always 8 * (258M / 4K) == 512K
+                */
+               tbl->tces[i] = alloc_pages_node(nid, GFP_KERNEL, get_order(0x80000));
+               if (tbl->tces[i] == NULL)
+                       goto fail;
+               memset(page_address(tbl->tces[i]), 0, 0x80000);
+
+               pr_debug(" TCE table %d at : %p\n", i, page_address(tbl->tces[i]));
+
+               /* Table size. We currently set it to be the whole 256M region */
+               tvt_data0 = 2ull << IODA_TVT0_TCE_TABLE_SIZE_SHIFT;
+               /* IO page size set to 4K */
+               tvt_data1 = 1ull << IODA_TVT1_IO_PAGE_SIZE_SHIFT;
+               /* Shift in the address */
+               tvt_data0 |= __pa(page_address(tbl->tces[i])) << IODA_TVT0_TTA_SHIFT;
+
+               /* Validation stuff. We only validate fully bus/dev/fn for now
+                * one day maybe we can group devices but that isn't the case
+                * at the moment
+                */
+               if (validate) {
+                       tvt_data0 |= IODA_TVT0_BUSNUM_VALID_MASK;
+                       tvt_data0 |= validate->bus->number;
+                       tvt_data1 |= IODA_TVT1_DEVNUM_VALID;
+                       tvt_data1 |= ((u64)PCI_SLOT(validate->devfn))
+                               << IODA_TVT1_DEVNUM_VALUE_SHIFT;
+                       tvt_data1 |= IODA_TVT1_FUNCNUM_VALID;
+                       tvt_data1 |= ((u64)PCI_FUNC(validate->devfn))
+                               << IODA_TVT1_FUNCNUM_VALUE_SHIFT;
+               }
+
+               /* XX PE number is always 0 for now */
+
+               /* Program the values using the PHB lock */
+               spin_lock_irqsave(&phb->lock, flags);
+               out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR,
+                        (tvt + i) | PCIE_REG_IODA_AD_TBL_TVT);
+               out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, tvt_data1);
+               out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, tvt_data0);
+               spin_unlock_irqrestore(&phb->lock, flags);
+       }
+
+       /* Init bits and pieces */
+       tbl->table.it_blocksize = 16;
+       tbl->table.it_offset = addr >> IOMMU_PAGE_SHIFT;
+       tbl->table.it_size = size >> IOMMU_PAGE_SHIFT;
+
+       /*
+        * It's already blank but we clear it anyway.
+        * Consider an aditiona interface that makes cleaing optional
+        */
+       iommu_init_table(&tbl->table, nid);
+
+       list_add(&tbl->link, &phb->dma_tables);
+       return tbl;
+
+ fail:
+       pr_debug("  Failed to allocate a 256M TCE table !\n");
+       for (i = 0; i < tvts_per_table; i++)
+               if (tbl->tces[i])
+                       __free_pages(tbl->tces[i], get_order(0x80000));
+       kfree(tbl);
+       return ERR_PTR(-ENOMEM);
+}
+
+static void __devinit wsp_pci_dma_dev_setup(struct pci_dev *pdev)
+{
+       struct dev_archdata *archdata = &pdev->dev.archdata;
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct wsp_phb *phb = hose->private_data;
+       struct wsp_dma_table *table = NULL;
+       unsigned long flags;
+       int i;
+
+       /* Don't assign an iommu table to a bridge */
+       if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+               return;
+
+       pr_debug("%s: Setting up DMA...\n", pci_name(pdev));
+
+       spin_lock_irqsave(&phb->lock, flags);
+
+       /* If only one region, check if it already exist */
+       if (phb->dma32_num_regions == 1) {
+               spin_unlock_irqrestore(&phb->lock, flags);
+               if (list_empty(&phb->dma_tables))
+                       table = wsp_pci_create_dma32_table(phb, 0, NULL);
+               else
+                       table = list_first_entry(&phb->dma_tables,
+                                                struct wsp_dma_table,
+                                                link);
+       } else {
+               /* else find a free region */
+               for (i = 0; i < phb->dma32_num_regions && !table; i++) {
+                       if (__test_and_set_bit(i, &phb->dma32_map))
+                               continue;
+                       spin_unlock_irqrestore(&phb->lock, flags);
+                       table = wsp_pci_create_dma32_table(phb, i, pdev);
+               }
+       }
+
+       /* Check if we got an error */
+       if (IS_ERR(table)) {
+               pr_err("%s: Failed to create DMA table, err %ld !\n",
+                      pci_name(pdev), PTR_ERR(table));
+               return;
+       }
+
+       /* Or a valid table */
+       if (table) {
+               pr_info("%s: Setup iommu: 32-bit DMA region 0x%08lx..0x%08lx\n",
+                       pci_name(pdev),
+                       table->table.it_offset << IOMMU_PAGE_SHIFT,
+                       (table->table.it_offset << IOMMU_PAGE_SHIFT)
+                       + phb->dma32_region_size - 1);
+               archdata->dma_data.iommu_table_base = &table->table;
+               return;
+       }
+
+       /* Or no room */
+       spin_unlock_irqrestore(&phb->lock, flags);
+       pr_err("%s: Out of DMA space !\n", pci_name(pdev));
+}
+
+static void __init wsp_pcie_configure_hw(struct pci_controller *hose)
+{
+       u64 val;
+       int i;
+
+#define DUMP_REG(x) \
+       pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x))
+
+#ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS
+       /* WSP DD1 has a bogus class code by default in the PCI-E
+        * root complex's built-in P2P bridge */
+       val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1);
+       pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val);
+       out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1,
+                (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8));
+       pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1));
+#endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */
+
+#ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS
+       /* XXX Disable TCE caching, it doesn't work on DD1 */
+       out_be64(hose->cfg_data + 0xe50,
+                in_be64(hose->cfg_data + 0xe50) | (3ull << 62));
+       printk("PCI-E DEBUG CONTROL 5 = 0x%llx\n", in_be64(hose->cfg_data + 0xe50));
+#endif
+
+       /* Configure M32A and IO. IO is hard wired to be 1M for now */
+       out_be64(hose->cfg_data + PCIE_REG_IO_BASE_ADDR, hose->io_base_phys);
+       out_be64(hose->cfg_data + PCIE_REG_IO_BASE_MASK,
+                (~(hose->io_resource.end - hose->io_resource.start)) &
+                0x3fffffff000ul);
+       out_be64(hose->cfg_data + PCIE_REG_IO_START_ADDR, 0 | 1);
+
+       out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_ADDR,
+                hose->mem_resources[0].start);
+       printk("Want to write to M32A_BASE_MASK : 0x%llx\n",
+                (~(hose->mem_resources[0].end -
+                   hose->mem_resources[0].start)) & 0x3ffffff0000ul);
+       out_be64(hose->cfg_data + PCIE_REG_M32A_BASE_MASK,
+                (~(hose->mem_resources[0].end -
+                   hose->mem_resources[0].start)) & 0x3ffffff0000ul);
+       out_be64(hose->cfg_data + PCIE_REG_M32A_START_ADDR,
+                (hose->mem_resources[0].start - hose->pci_mem_offset) | 1);
+
+       /* Clear all TVT entries
+        *
+        * XX Might get TVT count from device-tree
+        */
+       for (i = 0; i < IODA_TVT_COUNT; i++) {
+               out_be64(hose->cfg_data + PCIE_REG_IODA_ADDR,
+                        PCIE_REG_IODA_AD_TBL_TVT | i);
+               out_be64(hose->cfg_data + PCIE_REG_IODA_DATA1, 0);
+               out_be64(hose->cfg_data + PCIE_REG_IODA_DATA0, 0);
+       }
+
+       /* Kill the TCE cache */
+       out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG,
+                in_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG) |
+                PCIE_REG_PHBC_64B_TCE_EN);
+
+       /* Enable 32 & 64-bit MSIs, IO space and M32A */
+       val = PCIE_REG_PHBC_32BIT_MSI_EN |
+             PCIE_REG_PHBC_IO_EN |
+             PCIE_REG_PHBC_64BIT_MSI_EN |
+             PCIE_REG_PHBC_M32A_EN;
+       if (iommu_is_off)
+               val |= PCIE_REG_PHBC_DMA_XLATE_BYPASS;
+       pr_debug("Will write config: 0x%llx\n", val);
+       out_be64(hose->cfg_data + PCIE_REG_PHB_CONFIG, val);
+
+       /* Enable error reporting */
+       out_be64(hose->cfg_data + 0xe00,
+                in_be64(hose->cfg_data + 0xe00) | 0x0008000000000000ull);
+
+       /* Mask an error that's generated when doing config space probe
+        *
+        * XXX Maybe we should only mask it around config space cycles... that or
+        * ignore it when we know we had a config space cycle recently ?
+        */
+       out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS_MASK, 0x8000000000000000ull);
+       out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS_MASK, 0x8000000000000000ull);
+
+       /* Enable UTL errors, for now, all of them got to UTL irq 1
+        *
+        * We similarily mask one UTL error caused apparently during normal
+        * probing. We also mask the link up error
+        */
+       out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_ERR_SEV, 0);
+       out_be64(hose->cfg_data + PCIE_UTL_RC_ERR_SEVERITY, 0);
+       out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_ERROR_SEV, 0);
+       out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_IRQ_EN, 0xffffffff00000000ull);
+       out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_IRQ_EN, 0xff5fffff00000000ull);
+       out_be64(hose->cfg_data + PCIE_UTL_EP_ERR_IRQ_EN, 0xffffffff00000000ull);
+
+       DUMP_REG(PCIE_REG_IO_BASE_ADDR);
+       DUMP_REG(PCIE_REG_IO_BASE_MASK);
+       DUMP_REG(PCIE_REG_IO_START_ADDR);
+       DUMP_REG(PCIE_REG_M32A_BASE_ADDR);
+       DUMP_REG(PCIE_REG_M32A_BASE_MASK);
+       DUMP_REG(PCIE_REG_M32A_START_ADDR);
+       DUMP_REG(PCIE_REG_M32B_BASE_ADDR);
+       DUMP_REG(PCIE_REG_M32B_BASE_MASK);
+       DUMP_REG(PCIE_REG_M32B_START_ADDR);
+       DUMP_REG(PCIE_REG_M64_BASE_ADDR);
+       DUMP_REG(PCIE_REG_M64_BASE_MASK);
+       DUMP_REG(PCIE_REG_M64_START_ADDR);
+       DUMP_REG(PCIE_REG_PHB_CONFIG);
+}
+
+static void wsp_pci_wait_io_idle(struct wsp_phb *phb, unsigned long port)
+{
+       u64 val;
+       int i;
+
+       for (i = 0; i < 10000; i++) {
+               val = in_be64(phb->hose->cfg_data + 0xe08);
+               if ((val & 0x1900000000000000ull) == 0x0100000000000000ull)
+                       return;
+               udelay(1);
+       }
+       pr_warning("PCI IO timeout on domain %d port 0x%lx\n",
+                  phb->hose->global_number, port);
+}
+
+#define DEF_PCI_AC_RET_pio(name, ret, at, al, aa)              \
+static ret wsp_pci_##name at                                   \
+{                                                              \
+       struct iowa_bus *bus;                                   \
+       struct wsp_phb *phb;                                    \
+       unsigned long flags;                                    \
+       ret rval;                                               \
+       bus = iowa_pio_find_bus(aa);                            \
+       WARN_ON(!bus);                                          \
+       phb = bus->private;                                     \
+       spin_lock_irqsave(&phb->lock, flags);                   \
+       wsp_pci_wait_io_idle(phb, aa);                          \
+       rval = __do_##name al;                                  \
+       spin_unlock_irqrestore(&phb->lock, flags);              \
+       return rval;                                            \
+}
+
+#define DEF_PCI_AC_NORET_pio(name, at, al, aa)                 \
+static void wsp_pci_##name at                                  \
+{                                                              \
+       struct iowa_bus *bus;                                   \
+       struct wsp_phb *phb;                                    \
+       unsigned long flags;                                    \
+       bus = iowa_pio_find_bus(aa);                            \
+       WARN_ON(!bus);                                          \
+       phb = bus->private;                                     \
+       spin_lock_irqsave(&phb->lock, flags);                   \
+       wsp_pci_wait_io_idle(phb, aa);                          \
+       __do_##name al;                                         \
+       spin_unlock_irqrestore(&phb->lock, flags);              \
+}
+
+#define DEF_PCI_AC_RET_mem(name, ret, at, al, aa)
+#define DEF_PCI_AC_NORET_mem(name, at, al, aa)
+
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)           \
+       DEF_PCI_AC_RET_##space(name, ret, at, al, aa)
+
+#define DEF_PCI_AC_NORET(name, at, al, space, aa)              \
+       DEF_PCI_AC_NORET_##space(name, at, al, aa)              \
+
+
+#include <asm/io-defs.h>
+
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+
+static struct ppc_pci_io wsp_pci_iops = {
+       .inb = wsp_pci_inb,
+       .inw = wsp_pci_inw,
+       .inl = wsp_pci_inl,
+       .outb = wsp_pci_outb,
+       .outw = wsp_pci_outw,
+       .outl = wsp_pci_outl,
+       .insb = wsp_pci_insb,
+       .insw = wsp_pci_insw,
+       .insl = wsp_pci_insl,
+       .outsb = wsp_pci_outsb,
+       .outsw = wsp_pci_outsw,
+       .outsl = wsp_pci_outsl,
+};
+
+static int __init wsp_setup_one_phb(struct device_node *np)
+{
+       struct pci_controller *hose;
+       struct wsp_phb *phb;
+
+       pr_info("PCI: Setting up PCIe host bridge 0x%s\n", np->full_name);
+
+       phb = zalloc_maybe_bootmem(sizeof(struct wsp_phb), GFP_KERNEL);
+       if (!phb)
+               return -ENOMEM;
+       hose = pcibios_alloc_controller(np);
+       if (!hose) {
+               /* Can't really free the phb */
+               return -ENOMEM;
+       }
+       hose->private_data = phb;
+       phb->hose = hose;
+
+       INIT_LIST_HEAD(&phb->dma_tables);
+       spin_lock_init(&phb->lock);
+
+       /* XXX Use bus-range property ? */
+       hose->first_busno = 0;
+       hose->last_busno = 0xff;
+
+       /* We use cfg_data as the address for the whole bridge MMIO space
+        */
+       hose->cfg_data = of_iomap(hose->dn, 0);
+
+       pr_debug("PCIe registers mapped at 0x%p\n", hose->cfg_data);
+
+       /* Get the ranges of the device-tree */
+       pci_process_bridge_OF_ranges(hose, np, 0);
+
+       /* XXX Force re-assigning of everything for now */
+       pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC |
+                     PCI_ENABLE_PROC_DOMAINS);
+       pci_probe_only = 0;
+
+       /* Calculate how the TCE space is divided */
+       phb->dma32_base         = 0;
+       phb->dma32_num_regions  = NUM_DMA32_REGIONS;
+       if (phb->dma32_num_regions > MAX_TABLE_TVT_COUNT) {
+               pr_warning("IOMMU: Clamped to %d DMA32 regions\n",
+                          MAX_TABLE_TVT_COUNT);
+               phb->dma32_num_regions = MAX_TABLE_TVT_COUNT;
+       }
+       phb->dma32_region_size  = 0x80000000 / phb->dma32_num_regions;
+
+       BUG_ON(!is_power_of_2(phb->dma32_region_size));
+
+       /* Setup config ops */
+       hose->ops = &wsp_pcie_pci_ops;
+
+       /* Configure the HW */
+       wsp_pcie_configure_hw(hose);
+
+       /* Instanciate IO workarounds */
+       iowa_register_bus(hose, &wsp_pci_iops, NULL, phb);
+#ifdef CONFIG_PCI_MSI
+       wsp_setup_phb_msi(hose);
+#endif
+
+       /* Add to global list */
+       list_add(&phb->all, &wsp_phbs);
+
+       return 0;
+}
+
+void __init wsp_setup_pci(void)
+{
+       struct device_node *np;
+       int rc;
+
+       /* Find host bridges */
+       for_each_compatible_node(np, "pciex", PCIE_COMPATIBLE) {
+               rc = wsp_setup_one_phb(np);
+               if (rc)
+                       pr_err("Failed to setup PCIe bridge %s, rc=%d\n",
+                              np->full_name, rc);
+       }
+
+       /* Establish device-tree linkage */
+       pci_devs_phb_init();
+
+       /* Set DMA ops to use TCEs */
+       if (iommu_is_off) {
+               pr_info("PCI-E: Disabled TCEs, using direct DMA\n");
+               set_pci_dma_ops(&dma_direct_ops);
+       } else {
+               ppc_md.pci_dma_dev_setup = wsp_pci_dma_dev_setup;
+               ppc_md.tce_build = tce_build_wsp;
+               ppc_md.tce_free = tce_free_wsp;
+               set_pci_dma_ops(&dma_iommu_ops);
+       }
+}
+
+#define err_debug(fmt...)      pr_debug(fmt)
+//#define err_debug(fmt...)
+
+static int __init wsp_pci_get_err_irq_no_dt(struct device_node *np)
+{
+       const u32 *prop;
+       int hw_irq;
+
+       /* Ok, no interrupts property, let's try to find our child P2P */
+       np = of_get_next_child(np, NULL);
+       if (np == NULL)
+               return 0;
+
+       /* Grab it's interrupt map */
+       prop = of_get_property(np, "interrupt-map", NULL);
+       if (prop == NULL)
+               return 0;
+
+       /* Grab one of the interrupts in there, keep the low 4 bits */
+       hw_irq = prop[5] & 0xf;
+
+       /* 0..4 for PHB 0 and 5..9 for PHB 1 */
+       if (hw_irq < 5)
+               hw_irq = 4;
+       else
+               hw_irq = 9;
+       hw_irq |= prop[5] & ~0xf;
+
+       err_debug("PCI: Using 0x%x as error IRQ for %s\n",
+                 hw_irq, np->parent->full_name);
+       return irq_create_mapping(NULL, hw_irq);
+}
+
+static const struct {
+       u32 offset;
+       const char *name;
+} wsp_pci_regs[] = {
+#define DREG(x) { PCIE_REG_##x, #x }
+#define DUTL(x) { PCIE_UTL_##x, "UTL_" #x }
+       /* Architected registers except CONFIG_ and IODA
+         * to avoid side effects
+        */
+       DREG(DMA_CHAN_STATUS),
+       DREG(CPU_LOADSTORE_STATUS),
+       DREG(LOCK0),
+       DREG(LOCK1),
+       DREG(PHB_CONFIG),
+       DREG(IO_BASE_ADDR),
+       DREG(IO_BASE_MASK),
+       DREG(IO_START_ADDR),
+       DREG(M32A_BASE_ADDR),
+       DREG(M32A_BASE_MASK),
+       DREG(M32A_START_ADDR),
+       DREG(M32B_BASE_ADDR),
+       DREG(M32B_BASE_MASK),
+       DREG(M32B_START_ADDR),
+       DREG(M64_BASE_ADDR),
+       DREG(M64_BASE_MASK),
+       DREG(M64_START_ADDR),
+       DREG(TCE_KILL),
+       DREG(LOCK2),
+       DREG(PHB_GEN_CAP),
+       DREG(PHB_TCE_CAP),
+       DREG(PHB_IRQ_CAP),
+       DREG(PHB_EEH_CAP),
+       DREG(PAPR_ERR_INJ_CONTROL),
+       DREG(PAPR_ERR_INJ_ADDR),
+       DREG(PAPR_ERR_INJ_MASK),
+
+       /* UTL core regs */
+       DUTL(SYS_BUS_CONTROL),
+       DUTL(STATUS),
+       DUTL(SYS_BUS_AGENT_STATUS),
+       DUTL(SYS_BUS_AGENT_ERR_SEV),
+       DUTL(SYS_BUS_AGENT_IRQ_EN),
+       DUTL(SYS_BUS_BURST_SZ_CONF),
+       DUTL(REVISION_ID),
+       DUTL(OUT_POST_HDR_BUF_ALLOC),
+       DUTL(OUT_POST_DAT_BUF_ALLOC),
+       DUTL(IN_POST_HDR_BUF_ALLOC),
+       DUTL(IN_POST_DAT_BUF_ALLOC),
+       DUTL(OUT_NP_BUF_ALLOC),
+       DUTL(IN_NP_BUF_ALLOC),
+       DUTL(PCIE_TAGS_ALLOC),
+       DUTL(GBIF_READ_TAGS_ALLOC),
+
+       DUTL(PCIE_PORT_CONTROL),
+       DUTL(PCIE_PORT_STATUS),
+       DUTL(PCIE_PORT_ERROR_SEV),
+       DUTL(PCIE_PORT_IRQ_EN),
+       DUTL(RC_STATUS),
+       DUTL(RC_ERR_SEVERITY),
+       DUTL(RC_IRQ_EN),
+       DUTL(EP_STATUS),
+       DUTL(EP_ERR_SEVERITY),
+       DUTL(EP_ERR_IRQ_EN),
+       DUTL(PCI_PM_CTRL1),
+       DUTL(PCI_PM_CTRL2),
+
+       /* PCIe stack regs */
+       DREG(SYSTEM_CONFIG1),
+       DREG(SYSTEM_CONFIG2),
+       DREG(EP_SYSTEM_CONFIG),
+       DREG(EP_FLR),
+       DREG(EP_BAR_CONFIG),
+       DREG(LINK_CONFIG),
+       DREG(PM_CONFIG),
+       DREG(DLP_CONTROL),
+       DREG(DLP_STATUS),
+       DREG(ERR_REPORT_CONTROL),
+       DREG(SLOT_CONTROL1),
+       DREG(SLOT_CONTROL2),
+       DREG(UTL_CONFIG),
+       DREG(BUFFERS_CONFIG),
+       DREG(ERROR_INJECT),
+       DREG(SRIOV_CONFIG),
+       DREG(PF0_SRIOV_STATUS),
+       DREG(PF1_SRIOV_STATUS),
+       DREG(PORT_NUMBER),
+       DREG(POR_SYSTEM_CONFIG),
+
+       /* Internal logic regs */
+       DREG(PHB_VERSION),
+       DREG(RESET),
+       DREG(PHB_CONTROL),
+       DREG(PHB_TIMEOUT_CONTROL1),
+       DREG(PHB_QUIESCE_DMA),
+       DREG(PHB_DMA_READ_TAG_ACTV),
+       DREG(PHB_TCE_READ_TAG_ACTV),
+
+       /* FIR registers */
+       DREG(LEM_FIR_ACCUM),
+       DREG(LEM_FIR_AND_MASK),
+       DREG(LEM_FIR_OR_MASK),
+       DREG(LEM_ACTION0),
+       DREG(LEM_ACTION1),
+       DREG(LEM_ERROR_MASK),
+       DREG(LEM_ERROR_AND_MASK),
+       DREG(LEM_ERROR_OR_MASK),
+
+       /* Error traps registers */
+       DREG(PHB_ERR_STATUS),
+       DREG(PHB_ERR_STATUS),
+       DREG(PHB_ERR1_STATUS),
+       DREG(PHB_ERR_INJECT),
+       DREG(PHB_ERR_LEM_ENABLE),
+       DREG(PHB_ERR_IRQ_ENABLE),
+       DREG(PHB_ERR_FREEZE_ENABLE),
+       DREG(PHB_ERR_SIDE_ENABLE),
+       DREG(PHB_ERR_LOG_0),
+       DREG(PHB_ERR_LOG_1),
+       DREG(PHB_ERR_STATUS_MASK),
+       DREG(PHB_ERR1_STATUS_MASK),
+       DREG(MMIO_ERR_STATUS),
+       DREG(MMIO_ERR1_STATUS),
+       DREG(MMIO_ERR_INJECT),
+       DREG(MMIO_ERR_LEM_ENABLE),
+       DREG(MMIO_ERR_IRQ_ENABLE),
+       DREG(MMIO_ERR_FREEZE_ENABLE),
+       DREG(MMIO_ERR_SIDE_ENABLE),
+       DREG(MMIO_ERR_LOG_0),
+       DREG(MMIO_ERR_LOG_1),
+       DREG(MMIO_ERR_STATUS_MASK),
+       DREG(MMIO_ERR1_STATUS_MASK),
+       DREG(DMA_ERR_STATUS),
+       DREG(DMA_ERR1_STATUS),
+       DREG(DMA_ERR_INJECT),
+       DREG(DMA_ERR_LEM_ENABLE),
+       DREG(DMA_ERR_IRQ_ENABLE),
+       DREG(DMA_ERR_FREEZE_ENABLE),
+       DREG(DMA_ERR_SIDE_ENABLE),
+       DREG(DMA_ERR_LOG_0),
+       DREG(DMA_ERR_LOG_1),
+       DREG(DMA_ERR_STATUS_MASK),
+       DREG(DMA_ERR1_STATUS_MASK),
+
+       /* Debug and Trace registers */
+       DREG(PHB_DEBUG_CONTROL0),
+       DREG(PHB_DEBUG_STATUS0),
+       DREG(PHB_DEBUG_CONTROL1),
+       DREG(PHB_DEBUG_STATUS1),
+       DREG(PHB_DEBUG_CONTROL2),
+       DREG(PHB_DEBUG_STATUS2),
+       DREG(PHB_DEBUG_CONTROL3),
+       DREG(PHB_DEBUG_STATUS3),
+       DREG(PHB_DEBUG_CONTROL4),
+       DREG(PHB_DEBUG_STATUS4),
+       DREG(PHB_DEBUG_CONTROL5),
+       DREG(PHB_DEBUG_STATUS5),
+
+       /* Don't seem to exist ...
+       DREG(PHB_DEBUG_CONTROL6),
+       DREG(PHB_DEBUG_STATUS6),
+       */
+};
+
+static int wsp_pci_regs_show(struct seq_file *m, void *private)
+{
+       struct wsp_phb *phb = m->private;
+       struct pci_controller *hose = phb->hose;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) {
+               /* Skip write-only regs */
+               if (wsp_pci_regs[i].offset == 0xc08 ||
+                   wsp_pci_regs[i].offset == 0xc10 ||
+                   wsp_pci_regs[i].offset == 0xc38 ||
+                   wsp_pci_regs[i].offset == 0xc40)
+                       continue;
+               seq_printf(m, "0x%03x: 0x%016llx %s\n",
+                          wsp_pci_regs[i].offset,
+                          in_be64(hose->cfg_data + wsp_pci_regs[i].offset),
+                          wsp_pci_regs[i].name);
+       }
+       return 0;
+}
+
+static int wsp_pci_regs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, wsp_pci_regs_show, inode->i_private);
+}
+
+static const struct file_operations wsp_pci_regs_fops = {
+       .open = wsp_pci_regs_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int wsp_pci_reg_set(void *data, u64 val)
+{
+       out_be64((void __iomem *)data, val);
+       return 0;
+}
+
+static int wsp_pci_reg_get(void *data, u64 *val)
+{
+       *val = in_be64((void __iomem *)data);
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(wsp_pci_reg_fops, wsp_pci_reg_get, wsp_pci_reg_set, "0x%llx\n");
+
+static irqreturn_t wsp_pci_err_irq(int irq, void *dev_id)
+{
+       struct wsp_phb *phb = dev_id;
+       struct pci_controller *hose = phb->hose;
+       irqreturn_t handled = IRQ_NONE;
+       struct wsp_pcie_err_log_data ed;
+
+       pr_err("PCI: Error interrupt on %s (PHB %d)\n",
+              hose->dn->full_name, hose->global_number);
+ again:
+       memset(&ed, 0, sizeof(ed));
+
+       /* Read and clear UTL errors */
+       ed.utl_sys_err = in_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS);
+       if (ed.utl_sys_err)
+               out_be64(hose->cfg_data + PCIE_UTL_SYS_BUS_AGENT_STATUS, ed.utl_sys_err);
+       ed.utl_port_err = in_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS);
+       if (ed.utl_port_err)
+               out_be64(hose->cfg_data + PCIE_UTL_PCIE_PORT_STATUS, ed.utl_port_err);
+       ed.utl_rc_err = in_be64(hose->cfg_data + PCIE_UTL_RC_STATUS);
+       if (ed.utl_rc_err)
+               out_be64(hose->cfg_data + PCIE_UTL_RC_STATUS, ed.utl_rc_err);
+
+       /* Read and clear main trap errors */
+       ed.phb_err = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS);
+       if (ed.phb_err) {
+               ed.phb_err1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS);
+               ed.phb_log0 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_0);
+               ed.phb_log1 = in_be64(hose->cfg_data + PCIE_REG_PHB_ERR_LOG_1);
+               out_be64(hose->cfg_data + PCIE_REG_PHB_ERR1_STATUS, 0);
+               out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_STATUS, 0);
+       }
+       ed.mmio_err = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS);
+       if (ed.mmio_err) {
+               ed.mmio_err1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS);
+               ed.mmio_log0 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_0);
+               ed.mmio_log1 = in_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_LOG_1);
+               out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR1_STATUS, 0);
+               out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_STATUS, 0);
+       }
+       ed.dma_err = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS);
+       if (ed.dma_err) {
+               ed.dma_err1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS);
+               ed.dma_log0 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_0);
+               ed.dma_log1 = in_be64(hose->cfg_data + PCIE_REG_DMA_ERR_LOG_1);
+               out_be64(hose->cfg_data + PCIE_REG_DMA_ERR1_STATUS, 0);
+               out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_STATUS, 0);
+       }
+
+       /* Now print things out */
+       if (ed.phb_err) {
+               pr_err("   PHB Error Status      : 0x%016llx\n", ed.phb_err);
+               pr_err("   PHB First Error Status: 0x%016llx\n", ed.phb_err1);
+               pr_err("   PHB Error Log 0       : 0x%016llx\n", ed.phb_log0);
+               pr_err("   PHB Error Log 1       : 0x%016llx\n", ed.phb_log1);
+       }
+       if (ed.mmio_err) {
+               pr_err("  MMIO Error Status      : 0x%016llx\n", ed.mmio_err);
+               pr_err("  MMIO First Error Status: 0x%016llx\n", ed.mmio_err1);
+               pr_err("  MMIO Error Log 0       : 0x%016llx\n", ed.mmio_log0);
+               pr_err("  MMIO Error Log 1       : 0x%016llx\n", ed.mmio_log1);
+       }
+       if (ed.dma_err) {
+               pr_err("   DMA Error Status      : 0x%016llx\n", ed.dma_err);
+               pr_err("   DMA First Error Status: 0x%016llx\n", ed.dma_err1);
+               pr_err("   DMA Error Log 0       : 0x%016llx\n", ed.dma_log0);
+               pr_err("   DMA Error Log 1       : 0x%016llx\n", ed.dma_log1);
+       }
+       if (ed.utl_sys_err)
+               pr_err("   UTL Sys Error Status  : 0x%016llx\n", ed.utl_sys_err);
+       if (ed.utl_port_err)
+               pr_err("   UTL Port Error Status : 0x%016llx\n", ed.utl_port_err);
+       if (ed.utl_rc_err)
+               pr_err("   UTL RC Error Status   : 0x%016llx\n", ed.utl_rc_err);
+
+       /* Interrupts are caused by the error traps. If we had any error there
+        * we loop again in case the UTL buffered some new stuff between
+        * going there and going to the traps
+        */
+       if (ed.dma_err || ed.mmio_err || ed.phb_err) {
+               handled = IRQ_HANDLED;
+               goto again;
+       }
+       return handled;
+}
+
+static void __init wsp_setup_pci_err_reporting(struct wsp_phb *phb)
+{
+       struct pci_controller *hose = phb->hose;
+       int err_irq, i, rc;
+       char fname[16];
+
+       /* Create a debugfs file for that PHB */
+       sprintf(fname, "phb%d", phb->hose->global_number);
+       phb->ddir = debugfs_create_dir(fname, powerpc_debugfs_root);
+
+       /* Some useful debug output */
+       if (phb->ddir) {
+               struct dentry *d = debugfs_create_dir("regs", phb->ddir);
+               char tmp[64];
+
+               for (i = 0; i < ARRAY_SIZE(wsp_pci_regs); i++) {
+                       sprintf(tmp, "%03x_%s", wsp_pci_regs[i].offset,
+                               wsp_pci_regs[i].name);
+                       debugfs_create_file(tmp, 0600, d,
+                                           hose->cfg_data + wsp_pci_regs[i].offset,
+                                           &wsp_pci_reg_fops);
+               }
+               debugfs_create_file("all_regs", 0600, phb->ddir, phb, &wsp_pci_regs_fops);
+       }
+
+       /* Find the IRQ number for that PHB */
+       err_irq = irq_of_parse_and_map(hose->dn, 0);
+       if (err_irq == 0)
+               /* XXX Error IRQ lacking from device-tree */
+               err_irq = wsp_pci_get_err_irq_no_dt(hose->dn);
+       if (err_irq == 0) {
+               pr_err("PCI: Failed to fetch error interrupt for %s\n",
+                      hose->dn->full_name);
+               return;
+       }
+       /* Request it */
+       rc = request_irq(err_irq, wsp_pci_err_irq, 0, "wsp_pci error", phb);
+       if (rc) {
+               pr_err("PCI: Failed to request interrupt for %s\n",
+                      hose->dn->full_name);
+       }
+       /* Enable interrupts for all errors for now */
+       out_be64(hose->cfg_data + PCIE_REG_PHB_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
+       out_be64(hose->cfg_data + PCIE_REG_MMIO_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
+       out_be64(hose->cfg_data + PCIE_REG_DMA_ERR_IRQ_ENABLE, 0xffffffffffffffffull);
+}
+
+/*
+ * This is called later to hookup with the error interrupt
+ */
+static int __init wsp_setup_pci_late(void)
+{
+       struct wsp_phb *phb;
+
+       list_for_each_entry(phb, &wsp_phbs, all)
+               wsp_setup_pci_err_reporting(phb);
+
+       return 0;
+}
+arch_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 (file)
index 0000000..52e9bd9
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2010 Ben Herrenschmidt, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __WSP_PCI_H
+#define __WSP_PCI_H
+
+/* Architected registers */
+#define PCIE_REG_DMA_CHAN_STATUS       0x110
+#define PCIE_REG_CPU_LOADSTORE_STATUS  0x120
+
+#define PCIE_REG_CONFIG_DATA           0x130
+#define PCIE_REG_LOCK0                 0x138
+#define PCIE_REG_CONFIG_ADDRESS                0x140
+#define   PCIE_REG_CA_ENABLE                   0x8000000000000000ull
+#define          PCIE_REG_CA_BUS_MASK                  0x0ff0000000000000ull
+#define   PCIE_REG_CA_BUS_SHIFT                        (20+32)
+#define   PCIE_REG_CA_DEV_MASK                 0x000f800000000000ull
+#define   PCIE_REG_CA_DEV_SHIFT                        (15+32)
+#define   PCIE_REG_CA_FUNC_MASK                        0x0000700000000000ull
+#define   PCIE_REG_CA_FUNC_SHIFT               (12+32)
+#define   PCIE_REG_CA_REG_MASK                 0x00000fff00000000ull
+#define   PCIE_REG_CA_REG_SHIFT                        ( 0+32)
+#define   PCIE_REG_CA_BE_MASK                  0x00000000f0000000ull
+#define   PCIE_REG_CA_BE_SHIFT                 (   28)
+#define PCIE_REG_LOCK1                 0x148
+
+#define PCIE_REG_PHB_CONFIG            0x160
+#define   PCIE_REG_PHBC_64B_TCE_EN             0x2000000000000000ull
+#define   PCIE_REG_PHBC_MMIO_DMA_FREEZE_EN     0x1000000000000000ull
+#define   PCIE_REG_PHBC_32BIT_MSI_EN           0x0080000000000000ull
+#define   PCIE_REG_PHBC_M64_EN                 0x0040000000000000ull
+#define   PCIE_REG_PHBC_IO_EN                  0x0008000000000000ull
+#define   PCIE_REG_PHBC_64BIT_MSI_EN           0x0002000000000000ull
+#define   PCIE_REG_PHBC_M32A_EN                        0x0000800000000000ull
+#define   PCIE_REG_PHBC_M32B_EN                        0x0000400000000000ull
+#define   PCIE_REG_PHBC_MSI_PE_VALIDATE                0x0000200000000000ull
+#define   PCIE_REG_PHBC_DMA_XLATE_BYPASS       0x0000100000000000ull
+
+#define PCIE_REG_IO_BASE_ADDR          0x170
+#define PCIE_REG_IO_BASE_MASK          0x178
+#define PCIE_REG_IO_START_ADDR         0x180
+
+#define PCIE_REG_M32A_BASE_ADDR                0x190
+#define PCIE_REG_M32A_BASE_MASK                0x198
+#define PCIE_REG_M32A_START_ADDR       0x1a0
+
+#define PCIE_REG_M32B_BASE_ADDR                0x1b0
+#define PCIE_REG_M32B_BASE_MASK                0x1b8
+#define PCIE_REG_M32B_START_ADDR       0x1c0
+
+#define PCIE_REG_M64_BASE_ADDR         0x1e0
+#define PCIE_REG_M64_BASE_MASK         0x1e8
+#define PCIE_REG_M64_START_ADDR                0x1f0
+
+#define PCIE_REG_TCE_KILL              0x210
+#define   PCIE_REG_TCEKILL_SINGLE      0x8000000000000000ull
+#define   PCIE_REG_TCEKILL_ADDR_MASK   0x000003fffffffff8ull
+#define   PCIE_REG_TCEKILL_PS_4K       0
+#define   PCIE_REG_TCEKILL_PS_64K      1
+#define   PCIE_REG_TCEKILL_PS_16M      2
+#define   PCIE_REG_TCEKILL_PS_16G      3
+
+#define PCIE_REG_IODA_ADDR             0x220
+#define   PCIE_REG_IODA_AD_AUTOINC     0x8000000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_MVT     0x0005000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_PELT    0x0006000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_PESTA   0x0007000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_PESTB   0x0008000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_TVT     0x0009000000000000ull
+#define   PCIE_REG_IODA_AD_TBL_TCE     0x000a000000000000ull
+#define PCIE_REG_IODA_DATA0            0x228
+#define PCIE_REG_IODA_DATA1            0x230
+
+#define PCIE_REG_LOCK2                 0x240
+
+#define PCIE_REG_PHB_GEN_CAP           0x250
+#define PCIE_REG_PHB_TCE_CAP           0x258
+#define PCIE_REG_PHB_IRQ_CAP           0x260
+#define PCIE_REG_PHB_EEH_CAP           0x268
+
+#define PCIE_REG_PAPR_ERR_INJ_CONTROL  0x2b0
+#define PCIE_REG_PAPR_ERR_INJ_ADDR     0x2b8
+#define PCIE_REG_PAPR_ERR_INJ_MASK     0x2c0
+
+
+#define PCIE_REG_SYS_CFG1              0x600
+#define   PCIE_REG_SYS_CFG1_CLASS_CODE 0x0000000000ffffffull
+
+#define IODA_TVT0_TTA_MASK             0x000fffffffff0000ull
+#define IODA_TVT0_TTA_SHIFT            4
+#define IODA_TVT0_BUSNUM_VALID_MASK    0x000000000000e000ull
+#define IODA_TVT0_TCE_TABLE_SIZE_MASK  0x0000000000001f00ull
+#define IODA_TVT0_TCE_TABLE_SIZE_SHIFT 8
+#define IODA_TVT0_BUSNUM_VALUE_MASK    0x00000000000000ffull
+#define IODA_TVT0_BUSNUM_VALID_SHIFT   0
+#define IODA_TVT1_DEVNUM_VALID         0x2000000000000000ull
+#define IODA_TVT1_DEVNUM_VALUE_MASK    0x1f00000000000000ull
+#define IODA_TVT1_DEVNUM_VALUE_SHIFT   56
+#define IODA_TVT1_FUNCNUM_VALID                0x0008000000000000ull
+#define IODA_TVT1_FUNCNUM_VALUE_MASK   0x0007000000000000ull
+#define IODA_TVT1_FUNCNUM_VALUE_SHIFT  48
+#define IODA_TVT1_IO_PAGE_SIZE_MASK    0x00001f0000000000ull
+#define IODA_TVT1_IO_PAGE_SIZE_SHIFT   40
+#define IODA_TVT1_PE_NUMBER_MASK       0x000000000000003full
+#define IODA_TVT1_PE_NUMBER_SHIFT      0
+
+#define IODA_TVT_COUNT                 64
+
+/* UTL Core registers */
+#define PCIE_UTL_SYS_BUS_CONTROL       0x400
+#define PCIE_UTL_STATUS                        0x408
+#define PCIE_UTL_SYS_BUS_AGENT_STATUS  0x410
+#define PCIE_UTL_SYS_BUS_AGENT_ERR_SEV 0x418
+#define PCIE_UTL_SYS_BUS_AGENT_IRQ_EN  0x420
+#define PCIE_UTL_SYS_BUS_BURST_SZ_CONF 0x440
+#define PCIE_UTL_REVISION_ID           0x448
+
+#define PCIE_UTL_OUT_POST_HDR_BUF_ALLOC        0x4c0
+#define PCIE_UTL_OUT_POST_DAT_BUF_ALLOC        0x4d0
+#define PCIE_UTL_IN_POST_HDR_BUF_ALLOC 0x4e0
+#define PCIE_UTL_IN_POST_DAT_BUF_ALLOC 0x4f0
+#define PCIE_UTL_OUT_NP_BUF_ALLOC      0x500
+#define PCIE_UTL_IN_NP_BUF_ALLOC       0x510
+#define PCIE_UTL_PCIE_TAGS_ALLOC       0x520
+#define PCIE_UTL_GBIF_READ_TAGS_ALLOC  0x530
+
+#define PCIE_UTL_PCIE_PORT_CONTROL     0x540
+#define PCIE_UTL_PCIE_PORT_STATUS      0x548
+#define PCIE_UTL_PCIE_PORT_ERROR_SEV   0x550
+#define PCIE_UTL_PCIE_PORT_IRQ_EN      0x558
+#define PCIE_UTL_RC_STATUS             0x560
+#define PCIE_UTL_RC_ERR_SEVERITY       0x568
+#define PCIE_UTL_RC_IRQ_EN             0x570
+#define PCIE_UTL_EP_STATUS             0x578
+#define PCIE_UTL_EP_ERR_SEVERITY       0x580
+#define PCIE_UTL_EP_ERR_IRQ_EN         0x588
+
+#define PCIE_UTL_PCI_PM_CTRL1          0x590
+#define PCIE_UTL_PCI_PM_CTRL2          0x598
+
+/* PCIe stack registers */
+#define PCIE_REG_SYSTEM_CONFIG1                0x600
+#define PCIE_REG_SYSTEM_CONFIG2                0x608
+#define PCIE_REG_EP_SYSTEM_CONFIG      0x618
+#define PCIE_REG_EP_FLR                        0x620
+#define PCIE_REG_EP_BAR_CONFIG         0x628
+#define PCIE_REG_LINK_CONFIG           0x630
+#define PCIE_REG_PM_CONFIG             0x640
+#define PCIE_REG_DLP_CONTROL           0x650
+#define PCIE_REG_DLP_STATUS            0x658
+#define PCIE_REG_ERR_REPORT_CONTROL    0x660
+#define PCIE_REG_SLOT_CONTROL1         0x670
+#define PCIE_REG_SLOT_CONTROL2         0x678
+#define PCIE_REG_UTL_CONFIG            0x680
+#define PCIE_REG_BUFFERS_CONFIG                0x690
+#define PCIE_REG_ERROR_INJECT          0x698
+#define PCIE_REG_SRIOV_CONFIG          0x6a0
+#define PCIE_REG_PF0_SRIOV_STATUS      0x6a8
+#define PCIE_REG_PF1_SRIOV_STATUS      0x6b0
+#define PCIE_REG_PORT_NUMBER           0x700
+#define PCIE_REG_POR_SYSTEM_CONFIG     0x708
+
+/* PHB internal logic registers */
+#define PCIE_REG_PHB_VERSION           0x800
+#define PCIE_REG_RESET                 0x808
+#define PCIE_REG_PHB_CONTROL           0x810
+#define PCIE_REG_PHB_TIMEOUT_CONTROL1  0x878
+#define PCIE_REG_PHB_QUIESCE_DMA       0x888
+#define PCIE_REG_PHB_DMA_READ_TAG_ACTV 0x900
+#define PCIE_REG_PHB_TCE_READ_TAG_ACTV 0x908
+
+/* FIR registers */
+#define PCIE_REG_LEM_FIR_ACCUM         0xc00
+#define PCIE_REG_LEM_FIR_AND_MASK      0xc08
+#define PCIE_REG_LEM_FIR_OR_MASK       0xc10
+#define PCIE_REG_LEM_ACTION0           0xc18
+#define PCIE_REG_LEM_ACTION1           0xc20
+#define PCIE_REG_LEM_ERROR_MASK                0xc30
+#define PCIE_REG_LEM_ERROR_AND_MASK    0xc38
+#define PCIE_REG_LEM_ERROR_OR_MASK     0xc40
+
+/* PHB Error registers */
+#define PCIE_REG_PHB_ERR_STATUS                0xc80
+#define PCIE_REG_PHB_ERR1_STATUS       0xc88
+#define PCIE_REG_PHB_ERR_INJECT                0xc90
+#define PCIE_REG_PHB_ERR_LEM_ENABLE    0xc98
+#define PCIE_REG_PHB_ERR_IRQ_ENABLE    0xca0
+#define PCIE_REG_PHB_ERR_FREEZE_ENABLE 0xca8
+#define PCIE_REG_PHB_ERR_SIDE_ENABLE   0xcb8
+#define PCIE_REG_PHB_ERR_LOG_0         0xcc0
+#define PCIE_REG_PHB_ERR_LOG_1         0xcc8
+#define PCIE_REG_PHB_ERR_STATUS_MASK   0xcd0
+#define PCIE_REG_PHB_ERR1_STATUS_MASK  0xcd8
+
+#define PCIE_REG_MMIO_ERR_STATUS       0xd00
+#define PCIE_REG_MMIO_ERR1_STATUS      0xd08
+#define PCIE_REG_MMIO_ERR_INJECT       0xd10
+#define PCIE_REG_MMIO_ERR_LEM_ENABLE   0xd18
+#define PCIE_REG_MMIO_ERR_IRQ_ENABLE   0xd20
+#define PCIE_REG_MMIO_ERR_FREEZE_ENABLE        0xd28
+#define PCIE_REG_MMIO_ERR_SIDE_ENABLE  0xd38
+#define PCIE_REG_MMIO_ERR_LOG_0                0xd40
+#define PCIE_REG_MMIO_ERR_LOG_1                0xd48
+#define PCIE_REG_MMIO_ERR_STATUS_MASK  0xd50
+#define PCIE_REG_MMIO_ERR1_STATUS_MASK 0xd58
+
+#define PCIE_REG_DMA_ERR_STATUS                0xd80
+#define PCIE_REG_DMA_ERR1_STATUS       0xd88
+#define PCIE_REG_DMA_ERR_INJECT                0xd90
+#define PCIE_REG_DMA_ERR_LEM_ENABLE    0xd98
+#define PCIE_REG_DMA_ERR_IRQ_ENABLE    0xda0
+#define PCIE_REG_DMA_ERR_FREEZE_ENABLE 0xda8
+#define PCIE_REG_DMA_ERR_SIDE_ENABLE   0xdb8
+#define PCIE_REG_DMA_ERR_LOG_0         0xdc0
+#define PCIE_REG_DMA_ERR_LOG_1         0xdc8
+#define PCIE_REG_DMA_ERR_STATUS_MASK   0xdd0
+#define PCIE_REG_DMA_ERR1_STATUS_MASK  0xdd8
+
+/* Shortcuts for access to the above using the PHB definitions
+ * with an offset
+ */
+#define PCIE_REG_ERR_PHB_OFFSET                0x0
+#define PCIE_REG_ERR_MMIO_OFFSET       0x80
+#define PCIE_REG_ERR_DMA_OFFSET                0x100
+
+/* Debug and Trace registers */
+#define PCIE_REG_PHB_DEBUG_CONTROL0    0xe00
+#define PCIE_REG_PHB_DEBUG_STATUS0     0xe08
+#define PCIE_REG_PHB_DEBUG_CONTROL1    0xe10
+#define PCIE_REG_PHB_DEBUG_STATUS1     0xe18
+#define PCIE_REG_PHB_DEBUG_CONTROL2    0xe20
+#define PCIE_REG_PHB_DEBUG_STATUS2     0xe28
+#define PCIE_REG_PHB_DEBUG_CONTROL3    0xe30
+#define PCIE_REG_PHB_DEBUG_STATUS3     0xe38
+#define PCIE_REG_PHB_DEBUG_CONTROL4    0xe40
+#define PCIE_REG_PHB_DEBUG_STATUS4     0xe48
+#define PCIE_REG_PHB_DEBUG_CONTROL5    0xe50
+#define PCIE_REG_PHB_DEBUG_STATUS5     0xe58
+#define PCIE_REG_PHB_DEBUG_CONTROL6    0xe60
+#define PCIE_REG_PHB_DEBUG_STATUS6     0xe68
+
+/* Definition for PCIe errors */
+struct wsp_pcie_err_log_data {
+       __u64   phb_err;
+       __u64   phb_err1;
+       __u64   phb_log0;
+       __u64   phb_log1;
+       __u64   mmio_err;
+       __u64   mmio_err1;
+       __u64   mmio_log0;
+       __u64   mmio_log1;
+       __u64   dma_err;
+       __u64   dma_err1;
+       __u64   dma_log0;
+       __u64   dma_log1;
+       __u64   utl_sys_err;
+       __u64   utl_port_err;
+       __u64   utl_rc_err;
+       __u64   unused;
+};
+
+#endif /* __WSP_PCI_H */
index cf736ca0cf051bd9192fd190bea664c1a64b5427..84e13253aec5ca7f9ed6c021e1d1585ead0213de 100644 (file)
@@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI)         += fsl_pci.o $(fsl-msi-obj-y)
 obj-$(CONFIG_FSL_PMC)          += fsl_pmc.o
 obj-$(CONFIG_FSL_LBC)          += fsl_lbc.o
 obj-$(CONFIG_FSL_GTM)          += fsl_gtm.o
-obj-$(CONFIG_MPC8xxx_GPIO)     += mpc8xxx_gpio.o
 obj-$(CONFIG_FSL_85XX_CACHE_SRAM)      += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
 obj-$(CONFIG_SIMPLE_GPIO)      += simple_gpio.o
 obj-$(CONFIG_FSL_RIO)          += fsl_rio.o
index 1225012a681a01de66f5b80bdaf117451f2052d2..b6db23e085fbca5e6b1bc47ad9d0ec441d48e11f 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/err.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
index d55d0ad0deab937f28780e1673052b96d3b44439..bf6c7cc0a6afd55cbb9da1afae5f8add42e82f30 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Author: Scott Wood <scottwood@freescale.com>
  *
- * Copyright 2007 Freescale Semiconductor, Inc.
+ * Copyright 2007-2008,2010 Freescale Semiconductor, Inc.
  *
  * Some parts derived from commproc.c/cpm2_common.c, which is:
  * Copyright (c) 1997 Dan error_act (dmalek@jlc.net)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/of_device.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 
@@ -146,6 +147,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
        spin_lock_irqsave(&cpm_muram_lock, flags);
        cpm_muram_info.alignment = align;
        start = rh_alloc(&cpm_muram_info, size, "commproc");
+       memset(cpm_muram_addr(start), 0, size);
        spin_unlock_irqrestore(&cpm_muram_lock, flags);
 
        return start;
index bb44aa9fd47028cabab4b57a472867e0f77f9136..1bd0eba4d3555b2a89c6b19bbc6241e8ba6db6f4 100644 (file)
@@ -20,6 +20,7 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <asm/prom.h>
 #include <asm/dcr.h>
 
index af1a5df46b3e54ff75bb392b97ff26e8f1e72b4f..b6731e4a6646e16e81c62de273d8a6cd579b1ca7 100644 (file)
@@ -280,6 +280,7 @@ void __init ehv_pic_init(void)
 
        if (!ehv_pic->irqhost) {
                of_node_put(np);
+               kfree(ehv_pic);
                return;
        }
 
index 7dd2885321ad112cf88592e299d77ac4b2359d9b..02cf1e7e77fc6a7bcf4a734d15099e8e4dcc25bc 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/fsl_gtm.h>
 
 #define GTCFR_STP(x)           ((x) & 1 ? 1 << 5 : 1 << 1)
index d917573cf1a854183d425053b479ed6423ae0c3c..d5c3c90ee6981a14d40da0175f3d3ddc0c0f77f4 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
 #include <linux/spinlock.h>
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/mod_devicetable.h>
@@ -327,6 +328,7 @@ static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
 err:
        iounmap(fsl_lbc_ctrl_dev->regs);
        kfree(fsl_lbc_ctrl_dev);
+       fsl_lbc_ctrl_dev = NULL;
        return ret;
 }
 
index 419a77239bd7a31833952024ffaae3d3587160a3..e5c344d336ea68639b733d8a4913c0c5f4a5ccd5 100644 (file)
@@ -30,7 +30,7 @@ LIST_HEAD(msi_head);
 
 struct fsl_msi_feature {
        u32 fsl_pic_ip;
-       u32 msiir_offset;
+       u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */
 };
 
 struct fsl_msi_cascade_data {
@@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
 {
        struct fsl_msi *msi_data = fsl_msi_data;
        struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-       u64 base = fsl_pci_immrbar_base(hose);
+       u64 address; /* Physical address of the MSIIR */
+       int len;
+       const u64 *reg;
+
+       /* If the msi-address-64 property exists, then use it */
+       reg = of_get_property(hose->dn, "msi-address-64", &len);
+       if (reg && (len == sizeof(u64)))
+               address = be64_to_cpup(reg);
+       else
+               address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset;
 
-       msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
-       msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
+       msg->address_lo = lower_32_bits(address);
+       msg->address_hi = upper_32_bits(address);
 
        msg->data = hwirq;
 
@@ -296,7 +305,7 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
        }
 
        msi->msi_virqs[irq_index] = virt_msir;
-       cascade_data->index = offset + irq_index;
+       cascade_data->index = offset;
        cascade_data->msi_data = msi;
        irq_set_handler_data(virt_msir, cascade_data);
        irq_set_chained_handler(virt_msir, fsl_msi_cascade);
@@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
        msi->irqhost->host_data = msi;
 
-       msi->msi_addr_hi = 0x0;
-       msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
+       msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff);
 
        rc = fsl_msi_init_allocator(msi);
        if (rc) {
@@ -376,8 +384,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
                goto error_out;
        }
 
-       if (!p)
+       if (!p) {
                p = all_avail;
+               len = sizeof(all_avail);
+       }
 
        for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) {
                if (p[i * 2] % IRQS_PER_MSI_REG ||
@@ -393,7 +403,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
                count = p[i * 2 + 1] / IRQS_PER_MSI_REG;
 
                for (j = 0; j < count; j++, irq_index++) {
-                       err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index);
+                       err = fsl_msi_setup_hwirq(msi, dev, offset + j, irq_index);
                        if (err)
                                goto error_out;
                }
index 624580c252d75029a9f551f53a6c8efca973c4bd..1313abbc52008eca1d13d7e20dadda0ea5192e74 100644 (file)
@@ -28,8 +28,7 @@ struct fsl_msi {
 
        unsigned long cascade_irq;
 
-       u32 msi_addr_lo;
-       u32 msi_addr_hi;
+       u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
        void __iomem *msi_regs;
        u32 feature;
        int msi_virqs[NR_MSI_REG];
index f122e8961d32282676179fda517038c38b001126..592a0f8d527a10fdfb61aa9c407b94f4b0aa8168 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index 2d66275e489fbc88f130664b84eab979f1c39485..e8f385fbf54967abb88aaa81261e2672037fe294 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
index 34e12f9995fe79ec5859435d563b8881f37baf26..96f815a55dfd289ec09797a2b329a197573cacea 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/export.h>
 
 unsigned int
 mpc5xxx_get_bus_frequency(struct device_node *node)
index 22e48e2d71f107a59f6cb308393655eb39de0e64..2ca0a85fcce9581a751e246b466ed10f3f0b3a85 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/sched.h>
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
deleted file mode 100644 (file)
index fb4963a..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * GPIOs on MPC512x/8349/8572/8610 and compatible
- *
- * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#define MPC8XXX_GPIO_PINS      32
-
-#define GPIO_DIR               0x00
-#define GPIO_ODR               0x04
-#define GPIO_DAT               0x08
-#define GPIO_IER               0x0c
-#define GPIO_IMR               0x10
-#define GPIO_ICR               0x14
-#define GPIO_ICR2              0x18
-
-struct mpc8xxx_gpio_chip {
-       struct of_mm_gpio_chip mm_gc;
-       spinlock_t lock;
-
-       /*
-        * shadowed data register to be able to clear/set output pins in
-        * open drain mode safely
-        */
-       u32 data;
-       struct irq_host *irq;
-       void *of_dev_id_data;
-};
-
-static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
-{
-       return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
-}
-
-static inline struct mpc8xxx_gpio_chip *
-to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
-{
-       return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
-}
-
-static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
-       mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
-}
-
-/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
- * defined as output cannot be determined by reading GPDAT register,
- * so we use shadow data register instead. The status of input pins
- * is determined by reading GPDAT register.
- */
-static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
-       u32 val;
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
-       val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
-
-       return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
-}
-
-static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-
-       return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
-}
-
-static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
-       if (val)
-               mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
-       else
-               mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
-
-       out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
-
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
-       clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
-
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-
-       return 0;
-}
-
-static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-       unsigned long flags;
-
-       mpc8xxx_gpio_set(gc, gpio, val);
-
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
-       setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
-
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-
-       return 0;
-}
-
-static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
-{
-       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
-       if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
-               return irq_create_mapping(mpc8xxx_gc->irq, offset);
-       else
-               return -ENXIO;
-}
-
-static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-       unsigned int mask;
-
-       mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
-       if (mask)
-               generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
-                                                    32 - ffs(mask)));
-}
-
-static void mpc8xxx_irq_unmask(struct irq_data *d)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
-       setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static void mpc8xxx_irq_mask(struct irq_data *d)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
-       clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-
-       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static void mpc8xxx_irq_ack(struct irq_data *d)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-
-       out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-}
-
-static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-       unsigned long flags;
-
-       switch (flow_type) {
-       case IRQ_TYPE_EDGE_FALLING:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-               setbits32(mm->regs + GPIO_ICR,
-                         mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-               break;
-
-       case IRQ_TYPE_EDGE_BOTH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-               clrbits32(mm->regs + GPIO_ICR,
-                         mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
-       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-       unsigned long gpio = irqd_to_hwirq(d);
-       void __iomem *reg;
-       unsigned int shift;
-       unsigned long flags;
-
-       if (gpio < 16) {
-               reg = mm->regs + GPIO_ICR;
-               shift = (15 - gpio) * 2;
-       } else {
-               reg = mm->regs + GPIO_ICR2;
-               shift = (15 - (gpio % 16)) * 2;
-       }
-
-       switch (flow_type) {
-       case IRQ_TYPE_EDGE_FALLING:
-       case IRQ_TYPE_LEVEL_LOW:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-               clrsetbits_be32(reg, 3 << shift, 2 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-               break;
-
-       case IRQ_TYPE_EDGE_RISING:
-       case IRQ_TYPE_LEVEL_HIGH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-               clrsetbits_be32(reg, 3 << shift, 1 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-               break;
-
-       case IRQ_TYPE_EDGE_BOTH:
-               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-               clrbits32(reg, 3 << shift);
-               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct irq_chip mpc8xxx_irq_chip = {
-       .name           = "mpc8xxx-gpio",
-       .irq_unmask     = mpc8xxx_irq_unmask,
-       .irq_mask       = mpc8xxx_irq_mask,
-       .irq_ack        = mpc8xxx_irq_ack,
-       .irq_set_type   = mpc8xxx_irq_set_type,
-};
-
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
-                               irq_hw_number_t hw)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
-
-       if (mpc8xxx_gc->of_dev_id_data)
-               mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
-
-       irq_set_chip_data(virq, h->host_data);
-       irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
-       irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
-       return 0;
-}
-
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
-                                 const u32 *intspec, unsigned int intsize,
-                                 irq_hw_number_t *out_hwirq,
-                                 unsigned int *out_flags)
-
-{
-       /* interrupt sense values coming from the device tree equal either
-        * EDGE_FALLING or EDGE_BOTH
-        */
-       *out_hwirq = intspec[0];
-       *out_flags = intspec[1];
-
-       return 0;
-}
-
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
-       .map    = mpc8xxx_gpio_irq_map,
-       .xlate  = mpc8xxx_gpio_irq_xlate,
-};
-
-static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
-       { .compatible = "fsl,mpc8349-gpio", },
-       { .compatible = "fsl,mpc8572-gpio", },
-       { .compatible = "fsl,mpc8610-gpio", },
-       { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
-       { .compatible = "fsl,qoriq-gpio",   },
-       {}
-};
-
-static void __init mpc8xxx_add_controller(struct device_node *np)
-{
-       struct mpc8xxx_gpio_chip *mpc8xxx_gc;
-       struct of_mm_gpio_chip *mm_gc;
-       struct gpio_chip *gc;
-       const struct of_device_id *id;
-       unsigned hwirq;
-       int ret;
-
-       mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
-       if (!mpc8xxx_gc) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       spin_lock_init(&mpc8xxx_gc->lock);
-
-       mm_gc = &mpc8xxx_gc->mm_gc;
-       gc = &mm_gc->gc;
-
-       mm_gc->save_regs = mpc8xxx_gpio_save_regs;
-       gc->ngpio = MPC8XXX_GPIO_PINS;
-       gc->direction_input = mpc8xxx_gpio_dir_in;
-       gc->direction_output = mpc8xxx_gpio_dir_out;
-       if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
-               gc->get = mpc8572_gpio_get;
-       else
-               gc->get = mpc8xxx_gpio_get;
-       gc->set = mpc8xxx_gpio_set;
-       gc->to_irq = mpc8xxx_gpio_to_irq;
-
-       ret = of_mm_gpiochip_add(np, mm_gc);
-       if (ret)
-               goto err;
-
-       hwirq = irq_of_parse_and_map(np, 0);
-       if (hwirq == NO_IRQ)
-               goto skip_irq;
-
-       mpc8xxx_gc->irq =
-               irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
-                              &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
-       if (!mpc8xxx_gc->irq)
-               goto skip_irq;
-
-       id = of_match_node(mpc8xxx_gpio_ids, np);
-       if (id)
-               mpc8xxx_gc->of_dev_id_data = id->data;
-
-       mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
-       /* ack and mask all irqs */
-       out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
-       out_be32(mm_gc->regs + GPIO_IMR, 0);
-
-       irq_set_handler_data(hwirq, mpc8xxx_gc);
-       irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
-
-skip_irq:
-       return;
-
-err:
-       pr_err("%s: registration failed with status %d\n",
-              np->full_name, ret);
-       kfree(mpc8xxx_gc);
-
-       return;
-}
-
-static int __init mpc8xxx_add_gpiochips(void)
-{
-       struct device_node *np;
-
-       for_each_matching_node(np, mpc8xxx_gpio_ids)
-               mpc8xxx_add_controller(np);
-
-       return 0;
-}
-arch_initcall(mpc8xxx_add_gpiochips);
index d5d3ff3d757e6085d146ce1fb020e254fe331db1..8c7e8528e7c44cfe8f84db927f5ed454a7f99715 100644 (file)
@@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d)
         * IPIs are marked IRQ_PER_CPU. This has the side effect of
         * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
         * applying to them. We EOI them late to avoid re-entering.
-        * We mark IPI's with IRQF_DISABLED as they must run with
-        * irqs disabled.
         */
        mpic_eoi(mpic);
 }
@@ -1285,13 +1283,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
                           mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
                           | MPIC_GREG_GCONF_MCK);
 
-       /* Read feature register, calculate num CPUs and, for non-ISU
-        * MPICs, num sources as well. On ISU MPICs, sources are counted
-        * as ISUs are added
+       /*
+        * Read feature register.  For non-ISU MPICs, num sources as well. On
+        * ISU MPICs, sources are counted as ISUs are added
         */
        greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
-       mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK)
-                         >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
        if (isu_size == 0) {
                if (flags & MPIC_BROKEN_FRR_NIRQS)
                        mpic->num_sources = mpic->irq_count;
@@ -1301,10 +1297,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
                                 >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
        }
 
+       /*
+        * The MPIC driver will crash if there are more cores than we
+        * can initialize, so we may as well catch that problem here.
+        */
+       BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
+
        /* Map the per-CPU registers */
-       for (i = 0; i < mpic->num_cpus; i++) {
-               mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
-                        MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
+       for_each_possible_cpu(i) {
+               unsigned int cpu = get_hard_smp_processor_id(i);
+
+               mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
+                        MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
                         0x1000);
        }
 
@@ -1343,7 +1347,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
        }
        printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
               " max %d CPUs\n",
-              name, vers, (unsigned long long)paddr, mpic->num_cpus);
+              name, vers, (unsigned long long)paddr, num_possible_cpus());
        printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
               mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
 
@@ -1742,6 +1746,7 @@ void mpic_reset_core(int cpu)
        struct mpic *mpic = mpic_primary;
        u32 pir;
        int cpuid = get_hard_smp_processor_id(cpu);
+       int i;
 
        /* Set target bit for core reset */
        pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
@@ -1753,6 +1758,15 @@ void mpic_reset_core(int cpu)
        pir &= ~(1 << cpuid);
        mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
        mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
+
+       /* Perform 15 EOI on each reset core to clear pending interrupts.
+        * This is required for FSL CoreNet based devices */
+       if (mpic->flags & MPIC_FSL) {
+               for (i = 0; i < 15; i++) {
+                       _mpic_write(mpic->reg_type, &mpic->cpuregs[cpuid],
+                                     MPIC_CPU_EOI, 0);
+               }
+       }
 }
 #endif /* CONFIG_SMP */
 
index 77bb3f4d530a305f1301eb6fc571ecddfb37c5f8..b0037cefaadad20a42454bfe2b476289423da85f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/stat.h>
 #include <linux/pci.h>
 
 #include <asm/prom.h>
index 8ce4fc3d98281a46285571a93b4f8ce51a95e34d..8f0465422b1e3f2255fbee4d6402f87642d9a8d9 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <linux/workqueue.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
index 367af02418514b8cbdfdea8f57286308a035eeca..1c2d7af17bbe2f3501ff95060e119ced1ed565e8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/msi.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <asm/prom.h>
 #include <asm/hw_irq.h>
 #include <asm/ppc-pci.h>
index dbfe96bc878a2578c9171266012323b085e6c8b6..862f11b3821e8eb1abab33e3c1b8ad939dd86197 100644 (file)
@@ -834,7 +834,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np)
        return 3;
 }
 
-static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        u32 val = 1 << 24;
 
@@ -872,12 +872,12 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
        return ppc4xx_pciex_port_reset_sdr(port);
 }
 
-static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        return ppc440spe_pciex_init_port_hw(port);
 }
 
-static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        int rc = ppc440spe_pciex_init_port_hw(port);
 
@@ -936,7 +936,7 @@ static int __init ppc460ex_pciex_core_init(struct device_node *np)
        return 2;
 }
 
-static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        u32 val;
        u32 utlset1;
@@ -1092,6 +1092,10 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
        mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
        mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
 
+       /* Set HSS PRBS enabled */
+       mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130);
+       mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130);
+
        udelay(100);
 
        /* De-assert PLLRESET */
@@ -1122,7 +1126,7 @@ static int __init ppc460sx_pciex_core_init(struct device_node *np)
        return 2;
 }
 
-static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
 
        if (port->endpoint)
@@ -1132,9 +1136,6 @@ static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
                dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
                                0, 0x01000000);
 
-       /*Gen-1*/
-       mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
-
        dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
                        (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
                        PESDRx_RCSSET_RSTPYN);
@@ -1148,14 +1149,42 @@ static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
 {
        /* Max 128 Bytes */
        out_be32 (port->utl_base + PEUTL_PBBSZ,   0x00000000);
+       /* Assert VRB and TXE - per datasheet turn off addr validation */
+       out_be32(port->utl_base + PEUTL_PCTL,  0x80800000);
        return 0;
 }
 
+static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port)
+{
+       void __iomem *mbase;
+       int attempt = 50;
+
+       port->link = 0;
+
+       mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000);
+       if (mbase == NULL) {
+               printk(KERN_ERR "%s: Can't map internal config space !",
+                       port->node->full_name);
+               goto done;
+       }
+
+       while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA)
+                       & PECFG_460SX_DLLSTA_LINKUP))) {
+               attempt--;
+               mdelay(10);
+       }
+       if (attempt)
+               port->link = 1;
+done:
+       iounmap(mbase);
+
+}
+
 static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = {
        .core_init      = ppc460sx_pciex_core_init,
        .port_init_hw   = ppc460sx_pciex_init_port_hw,
        .setup_utl      = ppc460sx_pciex_init_utl,
-       .check_link     = ppc4xx_pciex_check_link_sdr,
+       .check_link     = ppc460sx_pciex_check_link,
 };
 
 #endif /* CONFIG_44x */
@@ -1189,7 +1218,7 @@ static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port)
        mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000);
 }
 
-static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        u32 val;
 
@@ -1338,15 +1367,15 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
        if (rc != 0)
                return rc;
 
-       if (ppc4xx_pciex_hwops->check_link)
-               ppc4xx_pciex_hwops->check_link(port);
-
        /*
         * Initialize mapping: disable all regions and configure
         * CFG and REG regions based on resources in the device tree
         */
        ppc4xx_pciex_port_init_mapping(port);
 
+       if (ppc4xx_pciex_hwops->check_link)
+               ppc4xx_pciex_hwops->check_link(port);
+
        /*
         * Map UTL
         */
@@ -1360,13 +1389,23 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
                ppc4xx_pciex_hwops->setup_utl(port);
 
        /*
-        * Check for VC0 active and assert RDY.
+        * Check for VC0 active or PLL Locked and assert RDY.
         */
        if (port->sdr_base) {
-               if (port->link &&
-                   ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
-                                            1 << 16, 1 << 16, 5000)) {
-                       printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
+               if (of_device_is_compatible(port->node,
+                               "ibm,plb-pciex-460sx")){
+                       if (port->link && ppc4xx_pciex_wait_on_sdr(port,
+                                       PESDRn_RCSSTS,
+                                       1 << 12, 1 << 12, 5000)) {
+                               printk(KERN_INFO "PCIE%d: PLL not locked\n",
+                                               port->index);
+                               port->link = 0;
+                       }
+               } else if (port->link &&
+                       ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
+                               1 << 16, 1 << 16, 5000)) {
+                       printk(KERN_INFO "PCIE%d: VC0 not active\n",
+                                       port->index);
                        port->link = 0;
                }
 
@@ -1573,8 +1612,15 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port    *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff);
-               /* Note that 3 here means enabled | single region */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3);
+               /*Enabled and single region */
+               if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+                       dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
+                               sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
+               else
+                       dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL,
+                               sa | DCRO_PEGPL_OMR1MSKL_UOT
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        case 1:
                out_le32(mbase + PECFG_POM1LAH, pciah);
@@ -1582,8 +1628,8 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port     *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff);
-               /* Note that 3 here means enabled | single region */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3);
+               dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL,
+                               sa | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        case 2:
                out_le32(mbase + PECFG_POM2LAH, pciah);
@@ -1592,7 +1638,9 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port     *port,
                dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal);
                dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff);
                /* Note that 3 here means enabled | IO space !!! */
-               dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, sa | 3);
+               dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL,
+                               sa | DCRO_PEGPL_OMR3MSKL_IO
+                                       | DCRO_PEGPL_OMRxMSKL_VAL);
                break;
        }
 
@@ -1693,6 +1741,9 @@ static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port,
                if (res->flags & IORESOURCE_PREFETCH)
                        sa |= 0x8;
 
+               if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+                       sa |= PCI_BASE_ADDRESS_MEM_TYPE_64;
+
                out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
                out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa));
 
@@ -1854,6 +1905,10 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
        }
        out_le16(mbase + 0x202, val);
 
+       /* Enable Bus master, memory, and io space */
+       if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx"))
+               out_le16(mbase + 0x204, 0x7);
+
        if (!port->endpoint) {
                /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
                out_le32(mbase + 0x208, 0x06040001);
index c39a134e86843594abb4ea753203d271399dfc88..32ce763a375a4c80867ac0b7c5f9ea85d2422032 100644 (file)
 #define PECFG_POM2LAL          0x390
 #define PECFG_POM2LAH          0x394
 
+/* 460sx only */
+#define PECFG_460SX_DLLSTA     0x3f8
+
+/* 460sx Bit Mappings */
+#define PECFG_460SX_DLLSTA_LINKUP       0x00000010
+#define DCRO_PEGPL_460SX_OMR1MSKL_UOT   0x00000004
+
+/* PEGPL Bit Mappings */
+#define DCRO_PEGPL_OMRxMSKL_VAL         0x00000001
+#define DCRO_PEGPL_OMR1MSKL_UOT         0x00000002
+#define DCRO_PEGPL_OMR3MSKL_IO  0x00000002
+
 /* SDR Bit Mappings */
 #define PESDRx_RCSSET_HLDPLB   0x10000000
 #define PESDRx_RCSSET_RSTGU    0x01000000
index d3d6ce3c33b4740507dbfd0fdacdbd85e984047d..0debcc31ad7005084cb952025ff6fe6d9960f528 100644 (file)
@@ -115,7 +115,7 @@ static int __init ppc4xx_l2c_probe(void)
        }
 
        /* Install error handler */
-       if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) {
+       if (request_irq(irq, l2c_error_handler, 0, "L2C", 0) < 0) {
                printk(KERN_ERR "Cannot install L2C error handler"
                       ", cache is not enabled\n");
                of_node_put(np);
index 36bf845df12779622d20c76733115488b1b60887..e23f23cf9f5c85d5e6295f4393c1db9e733a816f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/qe.h>
 
 struct qe_gpio_chip {
index 3363fbc964f86c1d42676116f813a2ac71b9e0e2..ceb09cbd2329e782fe00a5c3e1326d217ab3e92b 100644 (file)
@@ -216,7 +216,7 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
        /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
           that the BRG divisor must be even if you're not using divide-by-16
           mode. */
-       if (!div16 && (divisor & 1))
+       if (!div16 && (divisor & 1) && (divisor > 3))
                divisor++;
 
        tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
index fa589b21dbcdd7ccfa97fefab11ea4f5ab853218..04677505f20f52d2aab914a8ee7a3af9a4aaf572 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/errno.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
index 25fbbfaa837d6aa4b9161af3e8293d641d3ea32a..fba02440d122580e1dae6b4d0e99f644865f688b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/stddef.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/io.h>
 #include <asm/immap_qe.h>
index e1d6a13401578cc99a6bcda1ae9aebffd9b5ec02..524c0ead941d3eeed799ad83bad9b8b36fda890b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/stddef.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/io.h>
 #include <asm/immap_qe.h>
index 8105462078eb1596353f4525940cf2c2cc4c6278..9162828f5da7351c88c9afcf99ab82eabb7ecbdf 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <asm/immap_qe.h>
 #include <asm/qe.h>
index c1879ebfd4f48081d7f9864f6a8aeaf1769aae50..9afba924e94f92154da751671b1115ade6413321 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/mc146818rtc.h>
 
 #include <asm/prom.h>
index b2593ce30c9b1447426b2b191aa8af19554ca100..49a3ece1c6b3589971872bf4d440cab1e609d764 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/prom.h>
 #include <asm/scom.h>
 
index b6defda5ccc90834c732b946cd29334ae3c75249..ff5e73230a365933bb826bd36a20c8506d88026d 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
index 9f51f97abb5ddc2014b41b291591f7ec110a73fd..2370e1c633795fbb328a32e7878b860f34232288 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/of_net.h>
index b75a6059337f71a20444a20cc800fc7ab9ad96a2..c606aa8ba60aced2240fd3fb9522e802ffc34b85 100644 (file)
@@ -4,3 +4,4 @@ obj-y                           += xics-common.o
 obj-$(CONFIG_PPC_ICP_NATIVE)   += icp-native.o
 obj-$(CONFIG_PPC_ICP_HV)       += icp-hv.o
 obj-$(CONFIG_PPC_ICS_RTAS)     += ics-rtas.o
+obj-$(CONFIG_PPC_POWERNV)      += ics-opal.o
index 50e32afe392e1b734c9b86629b67c9460b66f705..4c79b6fbee1c07fefc49fcdc094e94eede95bc59 100644 (file)
@@ -276,7 +276,7 @@ static const struct icp_ops icp_native_ops = {
 #endif
 };
 
-int icp_native_init(void)
+int __init icp_native_init(void)
 {
        struct device_node *np;
        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 (file)
index 0000000..f7e8609
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * ICS backend for OPAL managed interrupts.
+ *
+ * Copyright 2011 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/msi.h>
+
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/xics.h>
+#include <asm/opal.h>
+#include <asm/firmware.h>
+
+static int ics_opal_mangle_server(int server)
+{
+       /* No link for now */
+       return server << 2;
+}
+
+static int ics_opal_unmangle_server(int server)
+{
+       /* No link for now */
+       return server >> 2;
+}
+
+static void ics_opal_unmask_irq(struct irq_data *d)
+{
+       unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+       int64_t rc;
+       int server;
+
+       pr_devel("ics-hal: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq);
+
+       if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+               return;
+
+       server = xics_get_irq_server(d->irq, d->affinity, 0);
+       server = ics_opal_mangle_server(server);
+
+       rc = opal_set_xive(hw_irq, server, DEFAULT_PRIORITY);
+       if (rc != OPAL_SUCCESS)
+               pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
+                      " error %lld\n",
+                      __func__, d->irq, hw_irq, server, rc);
+}
+
+static unsigned int ics_opal_startup(struct irq_data *d)
+{
+#ifdef CONFIG_PCI_MSI
+       /*
+        * The generic MSI code returns with the interrupt disabled on the
+        * card, using the MSI mask bits. Firmware doesn't appear to unmask
+        * at that level, so we do it here by hand.
+        */
+       if (d->msi_desc)
+               unmask_msi_irq(d);
+#endif
+
+       /* unmask it */
+       ics_opal_unmask_irq(d);
+       return 0;
+}
+
+static void ics_opal_mask_real_irq(unsigned int hw_irq)
+{
+       int server = ics_opal_mangle_server(xics_default_server);
+       int64_t rc;
+
+       if (hw_irq == XICS_IPI)
+               return;
+
+       /* Have to set XIVE to 0xff to be able to remove a slot */
+       rc = opal_set_xive(hw_irq, server, 0xff);
+       if (rc != OPAL_SUCCESS)
+               pr_err("%s: opal_set_xive(0xff) irq=%u returned %lld\n",
+                      __func__, hw_irq, rc);
+}
+
+static void ics_opal_mask_irq(struct irq_data *d)
+{
+       unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+
+       pr_devel("ics-hal: mask virq %d [hw 0x%x]\n", d->irq, hw_irq);
+
+       if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+               return;
+       ics_opal_mask_real_irq(hw_irq);
+}
+
+static int ics_opal_set_affinity(struct irq_data *d,
+                                const struct cpumask *cpumask,
+                                bool force)
+{
+       unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+       int16_t server;
+       int8_t priority;
+       int64_t rc;
+       int wanted_server;
+
+       if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+               return -1;
+
+       rc = opal_get_xive(hw_irq, &server, &priority);
+       if (rc != OPAL_SUCCESS) {
+               pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
+                      " error %lld\n",
+                      __func__, d->irq, hw_irq, server, rc);
+               return -1;
+       }
+
+       wanted_server = xics_get_irq_server(d->irq, cpumask, 1);
+       if (wanted_server < 0) {
+               char cpulist[128];
+               cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
+               pr_warning("%s: No online cpus in the mask %s for irq %d\n",
+                          __func__, cpulist, d->irq);
+               return -1;
+       }
+       server = ics_opal_mangle_server(wanted_server);
+
+       pr_devel("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n",
+                d->irq, hw_irq, wanted_server, server);
+
+       rc = opal_set_xive(hw_irq, server, priority);
+       if (rc != OPAL_SUCCESS) {
+               pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
+                      " error %lld\n",
+                      __func__, d->irq, hw_irq, server, rc);
+               return -1;
+       }
+       return 0;
+}
+
+static struct irq_chip ics_opal_irq_chip = {
+       .name = "OPAL ICS",
+       .irq_startup = ics_opal_startup,
+       .irq_mask = ics_opal_mask_irq,
+       .irq_unmask = ics_opal_unmask_irq,
+       .irq_eoi = NULL, /* Patched at init time */
+       .irq_set_affinity = ics_opal_set_affinity
+};
+
+static int ics_opal_map(struct ics *ics, unsigned int virq);
+static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec);
+static long ics_opal_get_server(struct ics *ics, unsigned long vec);
+
+static int ics_opal_host_match(struct ics *ics, struct device_node *node)
+{
+       return 1;
+}
+
+/* Only one global & state struct ics */
+static struct ics ics_hal = {
+       .map            = ics_opal_map,
+       .mask_unknown   = ics_opal_mask_unknown,
+       .get_server     = ics_opal_get_server,
+       .host_match     = ics_opal_host_match,
+};
+
+static int ics_opal_map(struct ics *ics, unsigned int virq)
+{
+       unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
+       int64_t rc;
+       int16_t server;
+       int8_t priority;
+
+       if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
+               return -EINVAL;
+
+       /* Check if HAL knows about this interrupt */
+       rc = opal_get_xive(hw_irq, &server, &priority);
+       if (rc != OPAL_SUCCESS)
+               return -ENXIO;
+
+       irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq);
+       irq_set_chip_data(virq, &ics_hal);
+
+       return 0;
+}
+
+static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec)
+{
+       int64_t rc;
+       int16_t server;
+       int8_t priority;
+
+       /* Check if HAL knows about this interrupt */
+       rc = opal_get_xive(vec, &server, &priority);
+       if (rc != OPAL_SUCCESS)
+               return;
+
+       ics_opal_mask_real_irq(vec);
+}
+
+static long ics_opal_get_server(struct ics *ics, unsigned long vec)
+{
+       int64_t rc;
+       int16_t server;
+       int8_t priority;
+
+       /* Check if HAL knows about this interrupt */
+       rc = opal_get_xive(vec, &server, &priority);
+       if (rc != OPAL_SUCCESS)
+               return -1;
+       return ics_opal_unmangle_server(server);
+}
+
+int __init ics_opal_init(void)
+{
+       if (!firmware_has_feature(FW_FEATURE_OPAL))
+               return -ENODEV;
+
+       /* We need to patch our irq chip's EOI to point to the
+        * right ICP
+        */
+       ics_opal_irq_chip.irq_eoi = icp_ops->eoi;
+
+       /* Register ourselves */
+       xics_register_ics(&ics_hal);
+
+       pr_info("ICS OPAL backend registered\n");
+
+       return 0;
+}
index 445c5a01b766a3b5e17749adc50eecb578f2f2e8..63762c672a0372b7f2eb5469c85c63cd5617402a 100644 (file)
@@ -134,11 +134,10 @@ static void xics_request_ipi(void)
        BUG_ON(ipi == NO_IRQ);
 
        /*
-        * IPIs are marked IRQF_DISABLED as they must run with irqs
-        * disabled, and PERCPU.  The handler was set in map.
+        * IPIs are marked IRQF_PERCPU. The handler was set in map.
         */
        BUG_ON(request_irq(ipi, icp_ops->ipi_action,
-                          IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL));
+                          IRQF_PERCPU, "IPI", NULL));
 }
 
 int __init xics_smp_probe(void)
@@ -409,14 +408,10 @@ void __init xics_init(void)
        int rc = -1;
 
        /* Fist locate ICP */
-#ifdef CONFIG_PPC_ICP_HV
        if (firmware_has_feature(FW_FEATURE_LPAR))
                rc = icp_hv_init();
-#endif
-#ifdef CONFIG_PPC_ICP_NATIVE
        if (rc < 0)
                rc = icp_native_init();
-#endif
        if (rc < 0) {
                pr_warning("XICS: Cannot find a Presentation Controller !\n");
                return;
@@ -429,9 +424,9 @@ void __init xics_init(void)
        xics_ipi_chip.irq_eoi = icp_ops->eoi;
 
        /* Now locate ICS */
-#ifdef CONFIG_PPC_ICS_RTAS
        rc = ics_rtas_init();
-#endif
+       if (rc < 0)
+               rc = ics_opal_init();
        if (rc < 0)
                pr_warning("XICS: Cannot find a Source Controller !\n");
 
index 42541bbcc7fa551b81254f9e4068870b0596a35c..03a217ae3be007949967c6fc15e35aa9bb51ab7c 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/delay.h>
 #include <linux/kallsyms.h>
 #include <linux/cpumask.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -340,8 +340,8 @@ int cpus_are_in_xmon(void)
 
 static inline int unrecoverable_excp(struct pt_regs *regs)
 {
-#ifdef CONFIG_4xx
-       /* We have no MSR_RI bit on 4xx, so we simply return false */
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOK3E)
+       /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
        return 0;
 #else
        return ((regs->msr & MSR_RI) == 0);
index a9fbd43395f71814d85a284a63900dc5a7dcc018..373679b3744a7992c7009281c1747b3aeb38157a 100644 (file)
@@ -572,6 +572,7 @@ config KEXEC
 config CRASH_DUMP
        bool "kernel crash dumps"
        depends on 64BIT
+       select KEXEC
        help
          Generate crash dump after being started by kexec.
          Crash dump kernels are loaded in the main kernel with kexec-tools
index 49676771bd66a278e73db7a2430612a57a1cf6a1..ffd1ac255f19444d838e58b2fb2ef2b716b02f77 100644 (file)
@@ -368,9 +368,12 @@ static inline int crypt_s390_func_available(int func,
 
        if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
                return 0;
-       if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
+
+       if (facility_mask & CRYPT_S390_MSA3 &&
+           (!test_facility(2) || !test_facility(76)))
                return 0;
-       if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
+       if (facility_mask & CRYPT_S390_MSA4 &&
+           (!test_facility(2) || !test_facility(77)))
                return 0;
 
        switch (func & CRYPT_S390_OP_MASK) {
index 48884f89ab92b13380a0cfdfa65b9b40e326490a..bd37d09b9d3c8cfacbc39f512ed8eb354d3049e0 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <crypto/internal/hash.h>
+#include <linux/module.h>
 #include "sha.h"
 #include "crypt_s390.h"
 
index 24e18473d926548ec3e54732093902178a6838e9..b0c235cb6ad5c79d42414a863508e0c37db8337d 100644 (file)
@@ -47,7 +47,7 @@ struct sca_block {
 #define KVM_HPAGE_MASK(x)      (~(KVM_HPAGE_SIZE(x) - 1))
 #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
-#define CPUSTAT_HOST       0x80000000
+#define CPUSTAT_STOPPED    0x80000000
 #define CPUSTAT_WAIT       0x10000000
 #define CPUSTAT_ECALL_PEND 0x08000000
 #define CPUSTAT_STOP_INT   0x04000000
@@ -139,6 +139,7 @@ struct kvm_vcpu_stat {
        u32 instruction_stfl;
        u32 instruction_tprot;
        u32 instruction_sigp_sense;
+       u32 instruction_sigp_sense_running;
        u32 instruction_sigp_external_call;
        u32 instruction_sigp_emergency;
        u32 instruction_sigp_stop;
index 34ede0ea85a9d0ae6d03a8c52b3bb3f43cb4e1ac..4f289ff0b7fe27b7de54d8886b6aee0b8890066f 100644 (file)
@@ -593,14 +593,16 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
        unsigned long address, bits;
        unsigned char skey;
 
+       if (!pte_present(*ptep))
+               return pgste;
        address = pte_val(*ptep) & PAGE_MASK;
        skey = page_get_storage_key(address);
        bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
        /* Clear page changed & referenced bit in the storage key */
-       if (bits) {
-               skey ^= bits;
-               page_set_storage_key(address, skey, 1);
-       }
+       if (bits & _PAGE_CHANGED)
+               page_set_storage_key(address, skey ^ bits, 1);
+       else if (bits)
+               page_reset_referenced(address);
        /* Transfer page changed & referenced bit to guest bits in pgste */
        pgste_val(pgste) |= bits << 48;         /* RCP_GR_BIT & RCP_GC_BIT */
        /* Get host changed & referenced bits from pgste */
@@ -625,6 +627,8 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 #ifdef CONFIG_PGSTE
        int young;
 
+       if (!pte_present(*ptep))
+               return pgste;
        young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
        /* Transfer page referenced bit to pte software bit (host view) */
        if (young || (pgste_val(pgste) & RCP_HR_BIT))
@@ -638,13 +642,15 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 
 }
 
-static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste)
+static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste, pte_t entry)
 {
 #ifdef CONFIG_PGSTE
        unsigned long address;
        unsigned long okey, nkey;
 
-       address = pte_val(*ptep) & PAGE_MASK;
+       if (!pte_present(entry))
+               return;
+       address = pte_val(entry) & PAGE_MASK;
        okey = nkey = page_get_storage_key(address);
        nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
        /* Set page access key and fetch protection bit from pgste */
@@ -712,7 +718,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 
        if (mm_has_pgste(mm)) {
                pgste = pgste_get_lock(ptep);
-               pgste_set_pte(ptep, pgste);
+               pgste_set_pte(ptep, pgste, entry);
                *ptep = entry;
                pgste_set_unlock(ptep, pgste);
        } else
index 5a099714df0459b9470e3d158e0b163bf8ce770b..097183c70407a81e9147697a37c880a6008b4ed1 100644 (file)
@@ -82,6 +82,7 @@ extern unsigned int user_mode;
 #define MACHINE_FLAG_LPAR      (1UL << 12)
 #define MACHINE_FLAG_SPP       (1UL << 13)
 #define MACHINE_FLAG_TOPOLOGY  (1UL << 14)
+#define MACHINE_FLAG_STCKF     (1UL << 15)
 
 #define MACHINE_IS_VM          (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
 #define MACHINE_IS_KVM         (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -100,6 +101,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_PFMF       (0)
 #define MACHINE_HAS_SPP                (0)
 #define MACHINE_HAS_TOPOLOGY   (0)
+#define MACHINE_HAS_STCKF      (0)
 #else /* __s390x__ */
 #define MACHINE_HAS_IEEE       (1)
 #define MACHINE_HAS_CSP                (1)
@@ -111,6 +113,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_PFMF       (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
 #define MACHINE_HAS_SPP                (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
 #define MACHINE_HAS_TOPOLOGY   (S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
+#define MACHINE_HAS_STCKF      (S390_lowcore.machine_flags & MACHINE_FLAG_STCKF)
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE      (32UL<<20)
index d610bef9c5e91a425ad01a683525f46ba0c055e1..c447a27a7fdb109be95edf0d6884026df6e895ce 100644 (file)
@@ -90,7 +90,7 @@ static inline unsigned long long get_clock_fast(void)
 {
        unsigned long long clk;
 
-       if (test_facility(25))
+       if (MACHINE_HAS_STCKF)
                asm volatile(".insn     s,0xb27c0000,%0" : "=Q" (clk) : : "cc");
        else
                clk = get_clock();
index 404bdb9671b4f5c8d03d2391e93abf26e5b38a59..58de4c91c333358000779b283efdad2de1ebe445 100644 (file)
 #define __NR_clock_adjtime     337
 #define __NR_syncfs            338
 #define __NR_setns             339
-#define NR_syscalls 340
+#define __NR_process_vm_readv  340
+#define __NR_process_vm_writev 341
+#define NR_syscalls 342
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 5006a1d9f5d0ed6d3abd95f3cca652d87689dcef..18c51df9fe06c5ed98f785fb6af86655c025e887 100644 (file)
@@ -1627,3 +1627,23 @@ ENTRY(sys_setns_wrapper)
        lgfr    %r2,%r2                 # int
        lgfr    %r3,%r3                 # int
        jg      sys_setns
+
+ENTRY(compat_sys_process_vm_readv_wrapper)
+       lgfr    %r2,%r2                 # compat_pid_t
+       llgtr   %r3,%r3                 # struct compat_iovec __user *
+       llgfr   %r4,%r4                 # unsigned long
+       llgtr   %r5,%r5                 # struct compat_iovec __user *
+       llgfr   %r6,%r6                 # unsigned long
+       llgf    %r0,164(%r15)           # unsigned long
+       stg     %r0,160(%r15)
+       jg      sys_process_vm_readv
+
+ENTRY(compat_sys_process_vm_writev_wrapper)
+       lgfr    %r2,%r2                 # compat_pid_t
+       llgtr   %r3,%r3                 # struct compat_iovec __user *
+       llgfr   %r4,%r4                 # unsigned long
+       llgtr   %r5,%r5                 # struct compat_iovec __user *
+       llgfr   %r6,%r6                 # unsigned long
+       llgf    %r0,164(%r15)           # unsigned long
+       stg     %r0,160(%r15)
+       jg      sys_process_vm_writev
index 37394b3413e2776dfd24586f0578045e488bd054..c9ffe002519715d64ddc16d2a2caafcbf47cb8b2 100644 (file)
@@ -390,6 +390,8 @@ static __init void detect_machine_facilities(void)
                S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
        if (test_facility(40))
                S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
+       if (test_facility(25))
+               S390_lowcore.machine_flags |= MACHINE_FLAG_STCKF;
 #endif
 }
 
index 44cc06bedf77b0985fc93a67582f9ece7b016bf5..b987ab2c1541afb1866e11949c156e6b62c9b67c 100644 (file)
@@ -18,26 +18,15 @@ struct insn {
 } __packed;
 
 struct insn_args {
-       unsigned long *target;
-       struct insn *insn;
-       ssize_t size;
+       struct jump_entry *entry;
+       enum jump_label_type type;
 };
 
-static int __arch_jump_label_transform(void *data)
+static void __jump_label_transform(struct jump_entry *entry,
+                                  enum jump_label_type type)
 {
-       struct insn_args *args = data;
-       int rc;
-
-       rc = probe_kernel_write(args->target, args->insn, args->size);
-       WARN_ON_ONCE(rc < 0);
-       return 0;
-}
-
-void arch_jump_label_transform(struct jump_entry *entry,
-                              enum jump_label_type type)
-{
-       struct insn_args args;
        struct insn insn;
+       int rc;
 
        if (type == JUMP_LABEL_ENABLE) {
                /* brcl 15,offset */
@@ -49,11 +38,33 @@ void arch_jump_label_transform(struct jump_entry *entry,
                insn.offset = 0;
        }
 
-       args.target = (void *) entry->code;
-       args.insn = &insn;
-       args.size = JUMP_LABEL_NOP_SIZE;
+       rc = probe_kernel_write((void *)entry->code, &insn, JUMP_LABEL_NOP_SIZE);
+       WARN_ON_ONCE(rc < 0);
+}
 
-       stop_machine(__arch_jump_label_transform, &args, NULL);
+static int __sm_arch_jump_label_transform(void *data)
+{
+       struct insn_args *args = data;
+
+       __jump_label_transform(args->entry, args->type);
+       return 0;
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+                              enum jump_label_type type)
+{
+       struct insn_args args;
+
+       args.entry = entry;
+       args.type = type;
+
+       stop_machine(__sm_arch_jump_label_transform, &args, NULL);
+}
+
+void arch_jump_label_transform_static(struct jump_entry *entry,
+                                     enum jump_label_type type)
+{
+       __jump_label_transform(entry, type);
 }
 
 #endif
index 450931a45b684b2044106921a66a4702e1eb93f1..573bc29551ef471fee58b89d02df0ea0ff956503 100644 (file)
@@ -296,13 +296,6 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                     ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
                        /* Invalid psw mask. */
                        return -EINVAL;
-               if (addr == (addr_t) &dummy->regs.psw.addr)
-                       /*
-                        * The debugger changed the instruction address,
-                        * reset system call restart, see signal.c:do_signal
-                        */
-                       task_thread_info(child)->system_call = 0;
-
                *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
@@ -614,11 +607,6 @@ static int __poke_user_compat(struct task_struct *child,
                        /* Transfer 31 bit amode bit to psw mask. */
                        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
                                (__u64)(tmp & PSW32_ADDR_AMODE);
-                       /*
-                        * The debugger changed the instruction address,
-                        * reset system call restart, see signal.c:do_signal
-                        */
-                       task_thread_info(child)->system_call = 0;
                } else {
                        /* gpr 0-15 */
                        *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
@@ -905,6 +893,14 @@ static int s390_last_break_get(struct task_struct *target,
        return 0;
 }
 
+static int s390_last_break_set(struct task_struct *target,
+                              const struct user_regset *regset,
+                              unsigned int pos, unsigned int count,
+                              const void *kbuf, const void __user *ubuf)
+{
+       return 0;
+}
+
 #endif
 
 static int s390_system_call_get(struct task_struct *target,
@@ -951,6 +947,7 @@ static const struct user_regset s390_regsets[] = {
                .size = sizeof(long),
                .align = sizeof(long),
                .get = s390_last_break_get,
+               .set = s390_last_break_set,
        },
 #endif
        [REGSET_SYSTEM_CALL] = {
@@ -1116,6 +1113,14 @@ static int s390_compat_last_break_get(struct task_struct *target,
        return 0;
 }
 
+static int s390_compat_last_break_set(struct task_struct *target,
+                                     const struct user_regset *regset,
+                                     unsigned int pos, unsigned int count,
+                                     const void *kbuf, const void __user *ubuf)
+{
+       return 0;
+}
+
 static const struct user_regset s390_compat_regsets[] = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
@@ -1139,6 +1144,7 @@ static const struct user_regset s390_compat_regsets[] = {
                .size = sizeof(long),
                .align = sizeof(long),
                .get = s390_compat_last_break_get,
+               .set = s390_compat_last_break_set,
        },
        [REGSET_SYSTEM_CALL] = {
                .core_note_type = NT_S390_SYSTEM_CALL,
index 8ac6bfa2786cbe139d9964b1f4ab374e4302e2e8..e54c4ff8abaaa3d1a34efd34decd0d12c713e4ef 100644 (file)
@@ -211,6 +211,8 @@ static void __init setup_zfcpdump(unsigned int console_devno)
 
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return;
+       if (OLDMEM_BASE)
+               return;
        if (console_devno != -1)
                sprintf(str, " cio_ignore=all,!0.0.%04x,!0.0.%04x",
                        ipl_info.data.fcp.dev_id.devno, console_devno);
@@ -482,7 +484,7 @@ static void __init setup_memory_end(void)
 
 
 #ifdef CONFIG_ZFCPDUMP
-       if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
+       if (ipl_info.type == IPL_TYPE_FCP_DUMP && !OLDMEM_BASE) {
                memory_end = ZFCPDUMP_HSA_SIZE;
                memory_end_set = 1;
        }
@@ -577,7 +579,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size,
                *msg = "first memory chunk must be at least crashkernel size";
                return 0;
        }
-       if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
+       if (OLDMEM_BASE && crash_size == OLDMEM_SIZE)
                return OLDMEM_BASE;
 
        for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
index 05a85bc14c98a2556e86bf40cec7e76de2dc2423..7f6f9f35454518f091e4fb86e3d39e46c8aaf391 100644 (file)
@@ -460,9 +460,9 @@ void do_signal(struct pt_regs *regs)
                                                     regs->svc_code >> 16);
                                break;
                        }
-                       /* No longer in a system call */
-                       clear_thread_flag(TIF_SYSCALL);
                }
+               /* No longer in a system call */
+               clear_thread_flag(TIF_SYSCALL);
 
                if ((is_compat_task() ?
                     handle_signal32(signr, &ka, &info, oldset, regs) :
@@ -486,6 +486,7 @@ void do_signal(struct pt_regs *regs)
        }
 
        /* No handlers present - check for system call restart */
+       clear_thread_flag(TIF_SYSCALL);
        if (current_thread_info()->system_call) {
                regs->svc_code = current_thread_info()->system_call;
                switch (regs->gprs[2]) {
@@ -500,9 +501,6 @@ void do_signal(struct pt_regs *regs)
                        regs->gprs[2] = regs->orig_gpr2;
                        set_thread_flag(TIF_SYSCALL);
                        break;
-               default:
-                       clear_thread_flag(TIF_SYSCALL);
-                       break;
                }
        }
 
index 73eb08c874fb450ef6ba0464d4aa4ca845bb6911..bcab2f04ba581f7648426a1790485d53626d8fda 100644 (file)
@@ -348,3 +348,5 @@ SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at
 SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper)
 SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper)
 SYSCALL(sys_setns,sys_setns,sys_setns_wrapper)
+SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */
+SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper)
index 77b8942b9a153af398cf9cf0e2dfd8eb7c5629ef..fdb5b8cb260f683e1f4559f95c006a7838690f60 100644 (file)
@@ -68,8 +68,10 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
        return mask;
 }
 
-static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
-                            struct mask_info *book, struct mask_info *core)
+static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
+                                         struct mask_info *book,
+                                         struct mask_info *core,
+                                         int z10)
 {
        unsigned int cpu;
 
@@ -88,10 +90,16 @@ static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
                        cpu_book_id[lcpu] = book->id;
 #endif
                        cpumask_set_cpu(lcpu, &core->mask);
-                       cpu_core_id[lcpu] = core->id;
+                       if (z10) {
+                               cpu_core_id[lcpu] = rcpu;
+                               core = core->next;
+                       } else {
+                               cpu_core_id[lcpu] = core->id;
+                       }
                        smp_cpu_polarization[lcpu] = tl_cpu->pp;
                }
        }
+       return core;
 }
 
 static void clear_masks(void)
@@ -123,18 +131,41 @@ static void tl_to_cores(struct sysinfo_15_1_x *info)
 {
 #ifdef CONFIG_SCHED_BOOK
        struct mask_info *book = &book_info;
+       struct cpuid cpu_id;
 #else
        struct mask_info *book = NULL;
 #endif
        struct mask_info *core = &core_info;
        union topology_entry *tle, *end;
+       int z10 = 0;
 
-
+#ifdef CONFIG_SCHED_BOOK
+       get_cpu_id(&cpu_id);
+       z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
+#endif
        spin_lock_irq(&topology_lock);
        clear_masks();
        tle = info->tle;
        end = (union topology_entry *)((unsigned long)info + info->length);
        while (tle < end) {
+#ifdef CONFIG_SCHED_BOOK
+               if (z10) {
+                       switch (tle->nl) {
+                       case 1:
+                               book = book->next;
+                               book->id = tle->container.id;
+                               break;
+                       case 0:
+                               core = add_cpus_to_mask(&tle->cpu, book, core, z10);
+                               break;
+                       default:
+                               clear_masks();
+                               goto out;
+                       }
+                       tle = next_tle(tle);
+                       continue;
+               }
+#endif
                switch (tle->nl) {
 #ifdef CONFIG_SCHED_BOOK
                case 2:
@@ -147,7 +178,7 @@ static void tl_to_cores(struct sysinfo_15_1_x *info)
                        core->id = tle->container.id;
                        break;
                case 0:
-                       add_cpus_to_mask(&tle->cpu, book, core);
+                       add_cpus_to_mask(&tle->cpu, book, core, z10);
                        break;
                default:
                        clear_masks();
@@ -328,8 +359,8 @@ void __init s390_init_cpu_topology(void)
        for (i = 0; i < TOPOLOGY_NR_MAG; i++)
                printk(" %d", info->mag[i]);
        printk(" / %d\n", info->mnest);
-       alloc_masks(info, &core_info, 2);
+       alloc_masks(info, &core_info, 1);
 #ifdef CONFIG_SCHED_BOOK
-       alloc_masks(info, &book_info, 3);
+       alloc_masks(info, &book_info, 2);
 #endif
 }
index 56fe6bc81fee45804a61c37fb189ccf73a0b72e8..e4c79ebb40e628850fd230fc94a0c7fdc77aaeb1 100644 (file)
@@ -43,6 +43,8 @@ SECTIONS
 
        NOTES :text :note
 
+       .dummy : { *(.dummy) } :data
+
        RODATA
 
 #ifdef CONFIG_SHARED_KERNEL
index 87cedd61be0467fdd4085308e55967acb9210ef3..8943e82cd4d94248ef8708839d6c7e0d99e324f9 100644 (file)
@@ -70,7 +70,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
                return -EOPNOTSUPP;
        }
 
-       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+       atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM;
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_IPL;
        vcpu->run->s390_reset_flags |= KVM_S390_RESET_CPU_INIT;
index c7c51898984ef78e64b761ad8c6f9256fa71f30b..02434543eabbede6e5e2fbc17f8e649f5a19871a 100644 (file)
@@ -132,7 +132,6 @@ static int handle_stop(struct kvm_vcpu *vcpu)
        int rc = 0;
 
        vcpu->stat.exit_stop_request++;
-       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
        spin_lock_bh(&vcpu->arch.local_int.lock);
        if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
                vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
@@ -149,6 +148,8 @@ static int handle_stop(struct kvm_vcpu *vcpu)
        }
 
        if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
+               atomic_set_mask(CPUSTAT_STOPPED,
+                               &vcpu->arch.sie_block->cpuflags);
                vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
                VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
                rc = -EOPNOTSUPP;
index 87c16705b381396f796e7fbacbb079d62cab8d9d..278ee009ce6570a9d4049a095def51b17fb164d5 100644 (file)
@@ -252,6 +252,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
                        offsetof(struct _lowcore, restart_psw), sizeof(psw_t));
                if (rc == -EFAULT)
                        exception = 1;
+               atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
                break;
 
        case KVM_S390_PROGRAM_INT:
index 0bd3bea1e4cdfc40069a474d37f74459903803ce..d1c445732451b6d1bd1c4b95db3d6467ff629c68 100644 (file)
@@ -65,6 +65,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "instruction_stfl", VCPU_STAT(instruction_stfl) },
        { "instruction_tprot", VCPU_STAT(instruction_tprot) },
        { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
+       { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
        { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
        { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
        { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
@@ -127,6 +128,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        switch (ext) {
        case KVM_CAP_S390_PSW:
        case KVM_CAP_S390_GMAP:
+       case KVM_CAP_SYNC_MMU:
                r = 1;
                break;
        default:
@@ -270,10 +272,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        restore_fp_regs(&vcpu->arch.guest_fpregs);
        restore_access_regs(vcpu->arch.guest_acrs);
        gmap_enable(vcpu->arch.gmap);
+       atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+       atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
        gmap_disable(vcpu->arch.gmap);
        save_fp_regs(&vcpu->arch.guest_fpregs);
        save_access_regs(vcpu->arch.guest_acrs);
@@ -301,7 +305,9 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
-       atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
+       atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
+                                                   CPUSTAT_SM |
+                                                   CPUSTAT_STOPPED);
        vcpu->arch.sie_block->ecb   = 6;
        vcpu->arch.sie_block->eca   = 0xC1002001U;
        vcpu->arch.sie_block->fac   = (int) (long) facilities;
@@ -428,7 +434,7 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
 {
        int rc = 0;
 
-       if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
+       if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
                rc = -EBUSY;
        else {
                vcpu->run->psw_mask = psw.mask;
@@ -501,7 +507,7 @@ rerun_vcpu:
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
-       atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
+       atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
 
        BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
 
index 391626361084e363cfd2f0f4251dd652ebc16a58..d02638959922aba41712d16d6dfb20f86f87ec8b 100644 (file)
@@ -336,6 +336,7 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
        u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0;
        u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0;
        struct vm_area_struct *vma;
+       unsigned long user_address;
 
        vcpu->stat.instruction_tprot++;
 
@@ -349,9 +350,14 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
                return -EOPNOTSUPP;
 
 
+       /* we must resolve the address without holding the mmap semaphore.
+        * This is ok since the userspace hypervisor is not supposed to change
+        * the mapping while the guest queries the memory. Otherwise the guest
+        * might crash or get wrong info anyway. */
+       user_address = (unsigned long) __guestaddr_to_user(vcpu, address1);
+
        down_read(&current->mm->mmap_sem);
-       vma = find_vma(current->mm,
-                       (unsigned long) __guestaddr_to_user(vcpu, address1));
+       vma = find_vma(current->mm, user_address);
        if (!vma) {
                up_read(&current->mm->mmap_sem);
                return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
index f815118835f3c3221932c5e01c86847cc1ec9ba8..0a7941d74bc68b30b9121090aeb96111c86058b7 100644 (file)
 #define SIGP_SET_PREFIX        0x0d
 #define SIGP_STORE_STATUS_ADDR 0x0e
 #define SIGP_SET_ARCH          0x12
+#define SIGP_SENSE_RUNNING     0x15
 
 /* cpu status bits */
 #define SIGP_STAT_EQUIPMENT_CHECK   0x80000000UL
+#define SIGP_STAT_NOT_RUNNING      0x00000400UL
 #define SIGP_STAT_INCORRECT_STATE   0x00000200UL
 #define SIGP_STAT_INVALID_PARAMETER 0x00000100UL
 #define SIGP_STAT_EXT_CALL_PENDING  0x00000080UL
@@ -57,8 +59,8 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
        spin_lock(&fi->lock);
        if (fi->local_int[cpu_addr] == NULL)
                rc = 3; /* not operational */
-       else if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
-                & CPUSTAT_RUNNING) {
+       else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                 & CPUSTAT_STOPPED)) {
                *reg &= 0xffffffff00000000UL;
                rc = 1; /* status stored */
        } else {
@@ -251,7 +253,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
 
        spin_lock_bh(&li->lock);
        /* cpu must be in stopped state */
-       if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) {
+       if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
                rc = 1; /* incorrect state */
                *reg &= SIGP_STAT_INCORRECT_STATE;
                kfree(inti);
@@ -275,6 +277,38 @@ out_fi:
        return rc;
 }
 
+static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
+                               unsigned long *reg)
+{
+       int rc;
+       struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
+
+       if (cpu_addr >= KVM_MAX_VCPUS)
+               return 3; /* not operational */
+
+       spin_lock(&fi->lock);
+       if (fi->local_int[cpu_addr] == NULL)
+               rc = 3; /* not operational */
+       else {
+               if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                   & CPUSTAT_RUNNING) {
+                       /* running */
+                       rc = 1;
+               } else {
+                       /* not running */
+                       *reg &= 0xffffffff00000000UL;
+                       *reg |= SIGP_STAT_NOT_RUNNING;
+                       rc = 0;
+               }
+       }
+       spin_unlock(&fi->lock);
+
+       VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", cpu_addr,
+                  rc);
+
+       return rc;
+}
+
 int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
 {
        int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
@@ -331,6 +365,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
                rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
                                       &vcpu->arch.guest_gprs[r1]);
                break;
+       case SIGP_SENSE_RUNNING:
+               vcpu->stat.instruction_sigp_sense_running++;
+               rc = __sigp_sense_running(vcpu, cpu_addr,
+                                         &vcpu->arch.guest_gprs[r1]);
+               break;
        case SIGP_RESTART:
                vcpu->stat.instruction_sigp_restart++;
                /* user space must know about restart */
index 1766def5bc3fc7f4717904313c69b2a7879b6d86..a9a301866b3c1846f37792aa371620e2b3004415 100644 (file)
@@ -587,8 +587,13 @@ static void pfault_interrupt(unsigned int ext_int_code,
                } else {
                        /* Completion interrupt was faster than initial
                         * interrupt. Set pfault_wait to -1 so the initial
-                        * interrupt doesn't put the task to sleep. */
-                       tsk->thread.pfault_wait = -1;
+                        * interrupt doesn't put the task to sleep.
+                        * If the task is not running, ignore the completion
+                        * interrupt since it must be a leftover of a PFAULT
+                        * CANCEL operation which didn't remove all pending
+                        * completion interrupts. */
+                       if (tsk->state == TASK_RUNNING)
+                               tsk->thread.pfault_wait = -1;
                }
                put_task_struct(tsk);
        } else {
index 59b663109d9024af9728547208b74a56d5d2d6a2..d4b9fb4d0042d1176729a5b55567a4325b1c139f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pfn.h>
 #include <linux/poison.h>
 #include <linux/initrd.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 #include <asm/processor.h>
 #include <asm/system.h>
index 288add8d168f05f8181f3a7d0eee61ecda89ce82..df169e84db4ed689361431c2044512af1289557b 100644 (file)
@@ -52,16 +52,6 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_CLOCKEVENTS
        def_bool y
 
-config SCHED_NO_NO_OMIT_FRAME_POINTER
-       def_bool y
-
-config GENERIC_SYSCALL_TABLE
-       def_bool y
-
-config SCORE_L1_CACHE_SHIFT
-       int
-       default "4"
-
 menu "Kernel type"
 
 config 32BIT
@@ -96,15 +86,6 @@ config STACKTRACE_SUPPORT
 
 source "init/Kconfig"
 
-config PROBE_INITRD_HEADER
-       bool "Probe initrd header created by addinitrd"
-       depends on BLK_DEV_INITRD
-       help
-         Probe initrd header at the last page of kernel image.
-         Say Y here if you are using arch/score/boot/addinitrd.c to
-         add initrd or initramfs image to the kernel image.
-         Otherwise, say N.
-
 config MMU
        def_bool y
 
index 1ee631d3725eab14286bad5e303ac4c25a716653..83cc704770d7488e489945655dcb3634285a9123 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/stat.h>
 #include <linux/sysdev.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
index 194231cb5a70e48a9d27fd82c65f55e85bc640a5..c2691afe8f79c9e08e402dae2f31a5231e34c6f5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 
 unsigned long PCIBIOS_MIN_IO = 0x0000;
 unsigned long PCIBIOS_MIN_MEM = 0;
index 0dca9a5c6be6f91b9a800b2f9bcca7fcf1f6e1fe..15d970328f717c929d25287a09b14af181e23d9c 100644 (file)
@@ -151,8 +151,13 @@ typedef struct page *pgtable_t;
 #endif /* !__ASSEMBLY__ */
 
 #ifdef CONFIG_UNCACHED_MAPPING
+#if defined(CONFIG_29BIT)
+#define UNCAC_ADDR(addr)       P2SEGADDR(addr)
+#define CAC_ADDR(addr)         P1SEGADDR(addr)
+#else
 #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + uncached_start)
 #define CAC_ADDR(addr)         ((addr) - uncached_start + PAGE_OFFSET)
+#endif
 #else
 #define UNCAC_ADDR(addr)       ((addr))
 #define CAC_ADDR(addr)         ((addr))
index 3432008d28880d360d6764a04fb257c86f291505..152b8627a18440b4c54954a8c652edb59ff9bb1c 100644 (file)
 #define __NR_syncfs            362
 #define __NR_sendmmsg          363
 #define __NR_setns             364
+#define __NR_process_vm_readv  365
+#define __NR_process_vm_writev 366
 
-#define NR_syscalls 365
+#define NR_syscalls 367
 
 #ifdef __KERNEL__
 
index ec9898665f23fbbb2f1da713a5f875dd677ee5c2..c330c23db5a0675283b6ed0df52ef4e381ef0343 100644 (file)
 #define __NR_syncfs            373
 #define __NR_sendmmsg          374
 #define __NR_setns             375
+#define __NR_process_vm_readv  376
+#define __NR_process_vm_writev 377
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 376
+#define NR_syscalls 378
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index a43124e608c3719b52501c56553c69651a0cd698..0bd744f9a3b7051c966266b47f13172bb0d4b4a6 100644 (file)
@@ -176,10 +176,12 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups,
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xfffe8000,
        .flags          = UPF_BOOT_AUTOCONF,
-       .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+                         SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           =  { 192, 192, 192, 192 },
+       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif0_device = {
@@ -193,10 +195,12 @@ static struct platform_device scif0_device = {
 static struct plat_sci_port scif1_platform_data = {
        .mapbase        = 0xfffe8800,
        .flags          = UPF_BOOT_AUTOCONF,
-       .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+                         SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           =  { 196, 196, 196, 196 },
+       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif1_device = {
@@ -210,10 +214,12 @@ static struct platform_device scif1_device = {
 static struct plat_sci_port scif2_platform_data = {
        .mapbase        = 0xfffe9000,
        .flags          = UPF_BOOT_AUTOCONF,
-       .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+                         SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           =  { 200, 200, 200, 200 },
+       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif2_device = {
@@ -227,10 +233,12 @@ static struct platform_device scif2_device = {
 static struct plat_sci_port scif3_platform_data = {
        .mapbase        = 0xfffe9800,
        .flags          = UPF_BOOT_AUTOCONF,
-       .scscr          = SCSCR_RE | SCSCR_TE | SCSCR_REIE,
+       .scscr          = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE |
+                         SCSCR_REIE,
        .scbrr_algo_id  = SCBRR_ALGO_2,
        .type           = PORT_SCIF,
        .irqs           =  { 204, 204, 204, 204 },
+       .regtype        = SCIx_SH2_SCIF_FIFODATA_REGTYPE,
 };
 
 static struct platform_device scif3_device = {
index e4469e7233cbc9d9f5252029d8947622c0159043..1cc257c9b1e311b806ed2defaa36b6db9ea5c920 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/suspend.h>
 #include <linux/cpuidle.h>
+#include <linux/export.h>
 #include <asm/suspend.h>
 #include <asm/uaccess.h>
 #include <asm/hwblk.h>
@@ -25,11 +26,12 @@ static unsigned long cpuidle_mode[] = {
 };
 
 static int cpuidle_sleep_enter(struct cpuidle_device *dev,
-                              struct cpuidle_state *state)
+                               struct cpuidle_driver *drv,
+                               int index)
 {
        unsigned long allowed_mode = arch_hwblk_sleep_mode();
        ktime_t before, after;
-       int requested_state = state - &dev->states[0];
+       int requested_state = index;
        int allowed_state;
        int k;
 
@@ -46,11 +48,13 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
         */
        k = min_t(int, allowed_state, requested_state);
 
-       dev->last_state = &dev->states[k];
        before = ktime_get();
        sh_mobile_call_standby(cpuidle_mode[k]);
        after = ktime_get();
-       return ktime_to_ns(ktime_sub(after, before)) >> 10;
+
+       dev->last_residency = (int)ktime_to_ns(ktime_sub(after, before)) >> 10;
+
+       return k;
 }
 
 static struct cpuidle_device cpuidle_dev;
@@ -62,19 +66,19 @@ static struct cpuidle_driver cpuidle_driver = {
 void sh_mobile_setup_cpuidle(void)
 {
        struct cpuidle_device *dev = &cpuidle_dev;
+       struct cpuidle_driver *drv = &cpuidle_driver;
        struct cpuidle_state *state;
        int i;
 
-       cpuidle_register_driver(&cpuidle_driver);
 
        for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
-               dev->states[i].name[0] = '\0';
-               dev->states[i].desc[0] = '\0';
+               drv->states[i].name[0] = '\0';
+               drv->states[i].desc[0] = '\0';
        }
 
        i = CPUIDLE_DRIVER_STATE_START;
 
-       state = &dev->states[i++];
+       state = &drv->states[i++];
        snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
        strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
        state->exit_latency = 1;
@@ -84,10 +88,10 @@ void sh_mobile_setup_cpuidle(void)
        state->flags |= CPUIDLE_FLAG_TIME_VALID;
        state->enter = cpuidle_sleep_enter;
 
-       dev->safe_state = state;
+       drv->safe_state_index = i-1;
 
        if (sh_mobile_sleep_supported & SUSP_SH_SF) {
-               state = &dev->states[i++];
+               state = &drv->states[i++];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
                strncpy(state->desc, "SuperH Sleep Mode [SF]",
                        CPUIDLE_DESC_LEN);
@@ -100,7 +104,7 @@ void sh_mobile_setup_cpuidle(void)
        }
 
        if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
-               state = &dev->states[i++];
+               state = &drv->states[i++];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
                strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
                        CPUIDLE_DESC_LEN);
@@ -112,7 +116,10 @@ void sh_mobile_setup_cpuidle(void)
                state->enter = cpuidle_sleep_enter;
        }
 
+       drv->state_count = i;
        dev->state_count = i;
 
+       cpuidle_register_driver(&cpuidle_driver);
+
        cpuidle_register_device(dev);
 }
index 2ee21a47b5af6e1aac2889712c69848b7194f317..10b14e3a7eb8142bd88a81ddd9c3a9cb96941a36 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/perf_event.h>
+#include <linux/export.h>
 #include <asm/processor.h>
 
 struct cpu_hw_events {
index 293e39c59c00522c08e99a9877fcafc36836152b..ee56a9b1a981679a6968d89f232729f4f8ed012f 100644 (file)
@@ -382,3 +382,5 @@ ENTRY(sys_call_table)
        .long sys_syncfs
        .long sys_sendmmsg
        .long sys_setns
+       .long sys_process_vm_readv      /* 365 */
+       .long sys_process_vm_writev
index ceb34b94afa9cb08c6f396cbd29c84d937375c2d..9af7de26fb7153ac1dffca0aedc32a822e1cde5e 100644 (file)
@@ -402,3 +402,5 @@ sys_call_table:
        .long sys_syncfs
        .long sys_sendmmsg
        .long sys_setns                 /* 375 */
+       .long sys_process_vm_readv
+       .long sys_process_vm_writev
index ecc2d3d0f54a3bd142500fae47b207ad421ee699..4649a6ff0cfefa1f64e7ce91dd2105f15ac8eccd 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/topology.h>
 #include <linux/node.h>
 #include <linux/nodemask.h>
+#include <linux/export.h>
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
index c9dbace35b16014f8cafcc6d2bbf247abd26c8ea..939ca0f356f6a79bd7ee34905dd42b96533ac7bc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/memblock.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <asm/mmu_context.h>
 #include <asm/mmzone.h>
 #include <asm/kexec.h>
index 1a6f20d4e7e6b4648aed89fb7c986a672770ad29..f92602e86607cb094f04ead294b8a3d6f6decdcf 100644 (file)
@@ -560,12 +560,7 @@ config SUN_OPENPROMFS
          Only choose N if you know in advance that you will not need to modify
          OpenPROM settings on the running system.
 
-# Makefile helpers
-config SPARC32_PCI
-       bool
-       default y
-       depends on SPARC32 && PCI
-
+# Makefile helper
 config SPARC64_PCI
        bool
        default y
index 5b31a8e89823699fbe5f99ebf6eb8d34bac8cb46..a790cc657476320831f9753ad0fd2aff9264ca0a 100644 (file)
@@ -431,10 +431,6 @@ extern unsigned long *sparc_valid_addr_bitmap;
 #define kern_addr_valid(addr) \
        (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma,
-                             unsigned long from, unsigned long pfn,
-                             unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -443,6 +439,22 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma,
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                          unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+                                    unsigned long from, unsigned long pfn,
+                                    unsigned long size, pgprot_t prot)
+{
+       unsigned long long offset, space, phys_base;
+
+       offset = ((unsigned long long) GET_PFN(pfn)) << PAGE_SHIFT;
+       space = GET_IOSPACE(pfn);
+       phys_base = offset | (space << 32ULL);
+
+       return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
 ({                                                                       \
index adf89329af59a653f8694f05df291f2c91475506..38ebb2c601374a386192c061b50ea171c4f83373 100644 (file)
@@ -757,10 +757,6 @@ static inline bool kern_addr_valid(unsigned long addr)
 
 extern int page_in_phys_avail(unsigned long paddr);
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                              unsigned long pfn,
-                              unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -769,6 +765,22 @@ extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffffffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+                          unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+                                    unsigned long from, unsigned long pfn,
+                                    unsigned long size, pgprot_t prot)
+{
+       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+       int space = GET_IOSPACE(pfn);
+       unsigned long phys_base;
+
+       phys_base = offset | (((unsigned long) space) << 32UL);
+
+       return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
index e8ba95399643399592e3699f756e374701f61518..e2f46705a21032dc36ae35b59c0c5f5893e1d958 100644 (file)
@@ -40,7 +40,6 @@ struct winsize {
 };
 
 #ifdef __KERNEL__
-#include <linux/module.h>
 
 /*
  * c_cc characters in the termio structure.  Oh, how I love being
index 6260d5deeabca0a009526078a87d1628d960f905..c7cb0af0eb59cb6dfb8a94e6c6fcdd330a7af29d 100644 (file)
 #define __NR_syncfs            335
 #define __NR_sendmmsg          336
 #define __NR_setns             337
+#define __NR_process_vm_readv  338
+#define __NR_process_vm_writev 339
 
-#define NR_syscalls            338
+#define NR_syscalls            340
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
index caef9deb5866f6d87a6fd3d72cb0bc4b25719080..812e10bbb0b332cf648f747884f93d1b3bc22073 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/oplib.h>
index acf5151f3c1d7b9ffe24012bbe0d0047107dec1f..f7ea8f0327199ebc8a22e9f4fe663a1794410b7c 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/spinlock.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/export.h>
 #include <asm/oplib.h>
 #include <asm/io.h>
 #include <asm/auxio.h>
index 89aa4eb20cf5b47b5819077796c34e47f3ca9c7c..57073e56ba9e4ac43c7ebee2bfae3b7fe2a9f1dc 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/console.h>
 
 #include <asm/btext.h>
index 7eef3f7419637f84a544ae04ce420a9e5c1e2e88..38d48a59879c1d2718f2c58eda37d42a8af5938e 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/of_device.h>
index ba9b1cec4e6b1edba5aafc765da4b693a91c9da6..2d1819641769fca63bad5c086bccd7006a8444ef 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
index 9323eafccb937749ab02427cfff92f45642d04a5..e4de74c2c9b0d8082c80f57d757ef7577fbb8b0d 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2009 Hong H. Pham <hong.pham@windriver.com>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index e1ba8ee21b9a316c7ab31b866fcf5f717614bdf8..b667aa6f28f648610aa0efe0c17d08c75c57daa8 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 
index 77dbf6d45fafc175e6b602f316cb7ace8a2bb52f..e306fb08ee5e1fab217823321460d94deac5cb75 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1999  David S. Miller (davem@redhat.com)
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
index e27f8ea8656e3e4b9b1c799a6d170cc9739e2cb2..0c218e4c0881fba70c1748e6a4c295e0db280652 100644 (file)
@@ -42,6 +42,9 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
 
 #else /* CONFIG_SPARC32 */
+
+#include <asm/trap_block.h>
+
 struct popc_3insn_patch_entry {
        unsigned int    addr;
        unsigned int    insns[3];
@@ -57,6 +60,10 @@ extern struct popc_6insn_patch_entry __popc_6insn_patch,
        __popc_6insn_patch_end;
 
 extern void __init per_cpu_patch(void);
+extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
+                                   struct sun4v_1insn_patch_entry *);
+extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
+                                   struct sun4v_2insn_patch_entry *);
 extern void __init sun4v_patch(void);
 extern void __init boot_cpu_id_too_large(int cpu);
 extern unsigned int dcache_parity_tl1_occurred;
index c2d055d8ba9e273ed8e996c7133b553e75ffcbc7..8593672838fde52d133e2597e25753c19f12394c 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 
 #include <asm/hypervisor.h>
index 52a15fe2db19766288da0625e788d528359f27c2..9167db40720e2f8cf00f1d2cae6701c0520b1efc 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/oplib.h>
 #include <asm/idprom.h>
index 6f01e8c83197e6d62c8c8646279e0c76b1606831..4643d68713fa48d415d2aff92e1c86315ff91f6f 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/device.h>
index 9b89d842913c0da9166be2f07e9cc4c330d40ea9..b2668afd1c347a928e1ed682a44fcf7386317891 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 #include <asm/cacheflush.h>
 #include <asm/cpudata.h>
index 0dd8422a469cc3a035fcd98fa47ee9e9a682f7a1..d45b710ea7e429eb86c5fbcb1c7fb55c5a2a1f6a 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (C) 1998  Jakub Jelinek    (jj@ultra.linux.cz)
  */
 
-#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/linkage.h>
 #include <linux/ptrace.h>
index ea2dafc93d780fd0b89e390af3d4aca7c106fdf7..971fd435a281767d80bd75db250afad41b847745 100644 (file)
@@ -36,12 +36,4 @@ void arch_jump_label_transform(struct jump_entry *entry,
        put_online_cpus();
 }
 
-void arch_jump_label_text_poke_early(jump_label_t addr)
-{
-       u32 *insn_p = (u32 *) (unsigned long) addr;
-
-       *insn_p = 0x01000000;
-       flushi(insn_p);
-}
-
 #endif
index 732b0bce6001c887f1ce4ad850691d4b3a112033..435e406fdec3893a24753494eea408434d6810c8 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
index d17255a2bbac142be0f3fe3b1e5e4a60d49a363e..a19c8a063683205c35792991efad03fe961f8140 100644 (file)
@@ -4,7 +4,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
index a8a9a275037d1bb6ede006148af3f5c266d9d44e..f1cf6ef011a724b8f45dbff51dc09002b841637b 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/of_device.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <asm/leon.h>
 #include <asm/leon_pci.h>
 
index fad1bd07cb56d76608d5545716e074cb99c77608..b1bc38853a3da82200dfacb5c5b0a2439c9ac4b8 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/leon.h>
 #include <asm/vaddrs.h>
index acaebb63c4fd4b7a7f42e0fc6d40befe799168c3..6dc796280589221f12526111647e20a9eb0911fc 100644 (file)
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/bootmem.h>
+#include <linux/export.h>
 
 #include <asm/cpudata.h>
 #include <asm/hypervisor.h>
 #include <asm/mdesc.h>
 #include <asm/prom.h>
+#include <asm/uaccess.h>
 #include <asm/oplib.h>
 #include <asm/smp.h>
 
index da0c6c70ccb2c0a783043c151bd82d3dc289d86a..e5519870c3d9ab43b516c5994568af974664d616 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/processor.h>
 #include <asm/spitfire.h>
 
+#include "entry.h"
+
 #ifdef CONFIG_SPARC64
 
 #include <linux/jump_label.h>
@@ -203,6 +205,29 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
 }
 
 #ifdef CONFIG_SPARC64
+static void do_patch_sections(const Elf_Ehdr *hdr,
+                             const Elf_Shdr *sechdrs)
+{
+       const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL;
+       char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+       for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+               if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name))
+                       sun4v_1insn = s;
+               if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name))
+                       sun4v_2insn = s;
+       }
+
+       if (sun4v_1insn && tlb_type == hypervisor) {
+               void *p = (void *) sun4v_1insn->sh_addr;
+               sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size);
+       }
+       if (sun4v_2insn && tlb_type == hypervisor) {
+               void *p = (void *) sun4v_2insn->sh_addr;
+               sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size);
+       }
+}
+
 int module_finalize(const Elf_Ehdr *hdr,
                    const Elf_Shdr *sechdrs,
                    struct module *me)
@@ -210,6 +235,8 @@ int module_finalize(const Elf_Ehdr *hdr,
        /* make jump label nops */
        jump_label_apply_nops(me);
 
+       do_patch_sections(hdr, sechdrs);
+
        /* Cheetah's I-cache is fully coherent.  */
        if (tlb_type == spitfire) {
                unsigned long va;
index 300f810142f57e82cce5984a56d9e5e920aebb7d..c76fe0b5bd94aa09df0a206ed2ddd385eeac5c8d 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/nmi.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kprobes.h>
 #include <linux/kernel_stat.h>
 #include <linux/reboot.h>
index a312af40ea84024081d843697c400636bb3ef673..4ee8ce0d5d8d53b686ad03085e2761598eeb9814 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
index 3bb2eace58cf0b4ea5ec2f08b34228904b335074..7a3be6f6737a0e4ce6beeeec1be866c9b65e747a 100644 (file)
@@ -2,13 +2,14 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mod_devicetable.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <asm/spitfire.h>
 
 #include "of_device_common.h"
 
index cb15bbf8a201478608672f85f55dc53f7b62247b..de199bf0cb051c6e695296d8b8ab392efd00c7c6 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mod_devicetable.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
index 8aa0d44085860f67cf4f454a8a4c4de5d03d2207..31111e35281e395b98104ef4b57ed0e062398cb0 100644 (file)
@@ -8,7 +8,7 @@
  * with minor modifications, see there for credits.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/sched.h>
index d29a32fcc5e44c4a48f94e0be43dd42701a2c4b7..188f935276fd75c407dc162c53fe06ffe58cfe3d 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/msi.h>
+#include <linux/export.h>
 #include <linux/irq.h>
 #include <linux/of_device.h>
 
index 86ae08d9b6ee4e6db66abaa30065072a1dc7338f..f4d29e15ce715c4fb1c476dc3eec780e148835fb 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/of_device.h>
index d1840dbdaa2fef0179e55c06b24830246e397fc0..3efaa4644d600e4aea88c0867df05ae1baee6008 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/of_device.h>
index f030b02eddddd18f04db1c268735c37f040ca0e2..13d4aa20b5a5d7f16a6da42fdce1b7e5825eec23 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/of_device.h>
 
index b01a06e9ae4efc71a54384a2f3500643cd6ea65f..b272cda35a0125904bc6f17eb1c5d14054dec24e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
+#include <linux/export.h>
 #include <linux/log2.h>
 #include <linux/of_device.h>
 
index 1aaf8c180be5d82544df54983ccaaa4ef5c7c071..fcc148effaac3d3085c9fcc9b6b02c89bc926e88 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 
 #include <asm/irq.h>
 #include <asm/oplib.h>
index 343b0f9e2e7b704678e6f1d4b83609fe19cd6bbe..a24072a49270ea17e2cb5ee1a3da57eafd1e8352 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2009 David S. Miller (davem@davemloft.net)
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 
@@ -13,6 +13,7 @@
 #include <asm/pil.h>
 #include <asm/pcr.h>
 #include <asm/nmi.h>
+#include <asm/spitfire.h>
 
 /* This code is shared between various users of the performance
  * counters.  Users will be oprofile, pseudo-NMI watchdog, and the
index 6a585d393580d38d651f5053e08bded4081c6bba..0e3202239ff5b7b1e13441ca1017fb672c9d33d8 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/oplib.h>
index cb4c0f57c024d46aef2e6078bfdd7030f9ba1f4b..0d39075063b2d1f82a54c248d036575fdbd4e901 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
index d959cd0a4aa4c520f3dba28e6b1cb6060726c100..3739a06a76cbfdbd93a0dde7bf0494e6b8e74285 100644 (file)
@@ -12,7 +12,7 @@
 #include <stdarg.h>
 
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
index 5ce3d15a99b0fc13016ab143967a4aa1df8ba478..b51cbb9e87dcbe8ae036d692d834ca5ebcaa9fee 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
-#include <linux/module.h>
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
index 86597d9867fd3768dcca56ec3a9263db1deed6fc..340c5b976d280ba9948dd5b4774759d4baf401be 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 #include <linux/memblock.h>
 #include <linux/of.h>
 
index ed25834328f4674f19dd7196fcc19153a337fd14..46614807a57f45150f89dbb1cb5ee115beaad28c 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
index ef89d3d697486c43da3cc86659b5c68e9f1ecbbe..006a42dd200700430b6befc4b5844ac63df199ca 100644 (file)
@@ -4,7 +4,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/reboot.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pm.h>
 
 #include <asm/system.h>
index a161b9c77f055617553fb32a2e25fdac279922f0..1271b3a27d4ef4722834d89d16c6ad42373a27d1 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
index 3e3e2914c70b87648fb3c139e000ace1c2b3b8df..fe1e3fc31bc580f7a41e9e73406f191e9e8e8f76 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/kdebug.h>
+#include <linux/export.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index c965595aa7e968c8a28e0cfce8f8cd9158db3e0f..a854a1c240ffe1eff016a3324ecfccd1dd63ce4c 100644 (file)
@@ -234,40 +234,50 @@ void __init per_cpu_patch(void)
        }
 }
 
-void __init sun4v_patch(void)
+void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *start,
+                            struct sun4v_1insn_patch_entry *end)
 {
-       extern void sun4v_hvapi_init(void);
-       struct sun4v_1insn_patch_entry *p1;
-       struct sun4v_2insn_patch_entry *p2;
-
-       if (tlb_type != hypervisor)
-               return;
+       while (start < end) {
+               unsigned long addr = start->addr;
 
-       p1 = &__sun4v_1insn_patch;
-       while (p1 < &__sun4v_1insn_patch_end) {
-               unsigned long addr = p1->addr;
-
-               *(unsigned int *) (addr +  0) = p1->insn;
+               *(unsigned int *) (addr +  0) = start->insn;
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
 
-               p1++;
+               start++;
        }
+}
 
-       p2 = &__sun4v_2insn_patch;
-       while (p2 < &__sun4v_2insn_patch_end) {
-               unsigned long addr = p2->addr;
+void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
+                            struct sun4v_2insn_patch_entry *end)
+{
+       while (start < end) {
+               unsigned long addr = start->addr;
 
-               *(unsigned int *) (addr +  0) = p2->insns[0];
+               *(unsigned int *) (addr +  0) = start->insns[0];
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  0));
 
-               *(unsigned int *) (addr +  4) = p2->insns[1];
+               *(unsigned int *) (addr +  4) = start->insns[1];
                wmb();
                __asm__ __volatile__("flush     %0" : : "r" (addr +  4));
 
-               p2++;
+               start++;
        }
+}
+
+void __init sun4v_patch(void)
+{
+       extern void sun4v_hvapi_init(void);
+
+       if (tlb_type != hypervisor)
+               return;
+
+       sun4v_patch_1insn_range(&__sun4v_1insn_patch,
+                               &__sun4v_1insn_patch_end);
+
+       sun4v_patch_2insn_range(&__sun4v_2insn_patch,
+                               &__sun4v_2insn_patch_end);
 
        sun4v_hvapi_init();
 }
index 2caa556db86dc44818521233c5ba7aad226ca186..023b8860dc9704330391b1db6a8eaf2ea117d32e 100644 (file)
@@ -822,21 +822,23 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-void do_signal32(sigset_t *oldset, struct pt_regs * regs,
-                int restart_syscall, unsigned long orig_i0)
+void do_signal32(sigset_t *oldset, struct pt_regs * regs)
 {
        struct k_sigaction ka;
+       unsigned long orig_i0;
+       int restart_syscall;
        siginfo_t info;
        int signr;
        
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       /* If the debugger messes with the program counter, it clears
-        * the "in syscall" bit, directing us to not perform a syscall
-        * restart.
-        */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       orig_i0 = 0;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
 
        if (signr > 0) {
                if (restart_syscall)
index 8ce247ac04cc0d905abd7d7e1d5de20073ce654a..d54c6e53aba00323fda9f01c95aae0f001352fb9 100644 (file)
@@ -519,10 +519,26 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        siginfo_t info;
        int signr;
 
+       /* It's a lot of work and synchronization to add a new ptrace
+        * register for GDB to save and restore in order to get
+        * orig_i0 correct for syscall restarts when debugging.
+        *
+        * Although it should be the case that most of the global
+        * registers are volatile across a system call, glibc already
+        * depends upon that fact that we preserve them.  So we can't
+        * just use any global register to save away the orig_i0 value.
+        *
+        * In particular %g2, %g3, %g4, and %g5 are all assumed to be
+        * preserved across a system call trap by various pieces of
+        * code in glibc.
+        *
+        * %g7 is used as the "thread register".   %g6 is not used in
+        * any fixed manner.  %g6 is used as a scratch register and
+        * a compiler temporary, but it's value is never used across
+        * a system call.  Therefore %g6 is usable for orig_i0 storage.
+        */
        if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
-               restart_syscall = 1;
-       else
-               restart_syscall = 0;
+               regs->u_regs[UREG_G6] = orig_i0;
 
        if (test_thread_flag(TIF_RESTORE_SIGMASK))
                oldset = &current->saved_sigmask;
@@ -535,8 +551,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
         * the software "in syscall" bit, directing us to not perform
         * a syscall restart.
         */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
+
 
        if (signr > 0) {
                if (restart_syscall)
index a2b81598d90562695abefa70b8c66ea11832341c..f0836cd0e2f243ffb3c1df37ff02cc31488850b7 100644 (file)
@@ -529,11 +529,27 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
        siginfo_t info;
        int signr;
        
+       /* It's a lot of work and synchronization to add a new ptrace
+        * register for GDB to save and restore in order to get
+        * orig_i0 correct for syscall restarts when debugging.
+        *
+        * Although it should be the case that most of the global
+        * registers are volatile across a system call, glibc already
+        * depends upon that fact that we preserve them.  So we can't
+        * just use any global register to save away the orig_i0 value.
+        *
+        * In particular %g2, %g3, %g4, and %g5 are all assumed to be
+        * preserved across a system call trap by various pieces of
+        * code in glibc.
+        *
+        * %g7 is used as the "thread register".   %g6 is not used in
+        * any fixed manner.  %g6 is used as a scratch register and
+        * a compiler temporary, but it's value is never used across
+        * a system call.  Therefore %g6 is usable for orig_i0 storage.
+        */
        if (pt_regs_is_syscall(regs) &&
-           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
-               restart_syscall = 1;
-       } else
-               restart_syscall = 0;
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
+               regs->u_regs[UREG_G6] = orig_i0;
 
        if (current_thread_info()->status & TS_RESTORE_SIGMASK)
                oldset = &current->saved_sigmask;
@@ -542,22 +558,20 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 
 #ifdef CONFIG_COMPAT
        if (test_thread_flag(TIF_32BIT)) {
-               extern void do_signal32(sigset_t *, struct pt_regs *,
-                                       int restart_syscall,
-                                       unsigned long orig_i0);
-               do_signal32(oldset, regs, restart_syscall, orig_i0);
+               extern void do_signal32(sigset_t *, struct pt_regs *);
+               do_signal32(oldset, regs);
                return;
        }
 #endif 
 
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       /* If the debugger messes with the program counter, it clears
-        * the software "in syscall" bit, directing us to not perform
-        * a syscall restart.
-        */
-       if (restart_syscall && !pt_regs_is_syscall(regs))
-               restart_syscall = 0;
+       restart_syscall = 0;
+       if (pt_regs_is_syscall(regs) &&
+           (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+               restart_syscall = 1;
+               orig_i0 = regs->u_regs[UREG_G6];
+       }
 
        if (signr > 0) {
                if (restart_syscall)
index e7dc508c38eb47dd1f77bee9a125687287c2856a..b19570d41a39eab11e7b60d2146aec678d0c8621 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/types.h>
 #include <linux/thread_info.h>
 #include <linux/uaccess.h>
+#include <linux/errno.h>
 
 #include <asm/sigcontext.h>
 #include <asm/fpumacro.h>
index 4a442c32e11787f223cac53dfaf345ec78b02b5c..75607724d290bb42c568d2dc27d5d8e4dd1a0cbc 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net)
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
index 83b47ab02d9611f0789c5b6eb8c13f39c8ce078e..12ff09824cd9f6b9f7a5f89ab1a5c9d9f88504d8 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
index 3e08153496305c59d090045f05388272dc927b78..e78386a0029f6972a9d18979c0bfc3ea296b89f8 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
 #include <linux/ftrace.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <asm/ptrace.h>
 #include <asm/stacktrace.h>
 
index 170cd8e8eb2a25d178d0b949380ebf56c640ed86..29c478ffed9154f3e4207e8cbb9d325803025a5d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
 #include <linux/quota.h>
-#include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
index 908b47a5ee2431cca7294ae1b81b961586838964..441521ad8a3febfc9a91f7dbc5cdabb01690d591 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/ipc.h>
 #include <linux/personality.h>
 #include <linux/random.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 #include <asm/uaccess.h>
 #include <asm/utrap.h>
index 09d8ec454450bcfcbfa3ef7e041305c5fe1a7501..63402f9e9f51f75622f9132e0b8f5372bcc806c1 100644 (file)
@@ -84,4 +84,4 @@ sys_call_table:
 /*320*/        .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
 /*325*/        .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/        .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-/*335*/        .long sys_syncfs, sys_sendmmsg, sys_setns
+/*335*/        .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
index edbec45d46884c9e1d33ab92be65119f0137369d..db86b1a0e9a9ff8a8e8129a88cd32982288e0ad3 100644 (file)
@@ -85,7 +85,7 @@ sys_call_table32:
 /*320*/        .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
        .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
 /*330*/        .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
-       .word sys_syncfs, compat_sys_sendmmsg, sys_setns
+       .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
 
 #endif /* CONFIG_COMPAT */
 
@@ -162,4 +162,4 @@ sys_call_table:
 /*320*/        .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
        .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/        .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-       .word sys_syncfs, sys_sendmmsg, sys_setns
+       .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
index 1db6b18964d22cef79a22330fec92e22b3df7c98..e861072b9c52b0cbabcc84f9af3d3e525ee35eb1 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
index c0490c7bbde0ffd187c6f0b1838108cbf9e5cd2e..591f20ca9e4815726ec748b76a423fa7d95181e1 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/kdebug.h>
+#include <linux/export.h>
 
 #include <asm/delay.h>
 #include <asm/system.h>
index 7efbb2f9e77ff63d9a18be9f44f166cd04f05bda..4d043a1b2492b062416eced20f64b8f11ee0b07d 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/system.h>
index 3cb1def9806c307df84a8da15f33dbc484255c51..f67e28ef598cae92e660d93afb42a4241dc66dc4 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
+#include <linux/export.h>
 #include <linux/init.h>
 
 #include <asm/mdesc.h>
index 29348ea139c33a7b1221bd0ce484a99ca3255f9d..f8e7dd53e1c7d7f62912f22100445e323b77afe5 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
index e3cda21b5ee994200b7d09e7e14c33704363e67c..301421c11291c6a0c8ef01a1af18da17453c9d35 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_SPARC64)   += ultra.o tlb.o tsb.o gup.o
 obj-y                   += fault_$(BITS).o
 obj-y                   += init_$(BITS).o
 obj-$(CONFIG_SPARC32)   += loadmmu.o
-obj-y                   += generic_$(BITS).o
 obj-$(CONFIG_SPARC32)   += extable.o btfixup.o srmmu.o iommu.o io-unit.o
 obj-$(CONFIG_SPARC32)   += hypersparc.o viking.o tsunami.o swift.o
 obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
index aa1c1b1ce5cc05ce4daa3f67161b565a1101ea4c..8023fd7e77b50c67e07a3830bc0e4b5e0571b746 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/smp.h>
 #include <linux/perf_event.h>
 #include <linux/interrupt.h>
-#include <linux/module.h>
 #include <linux/kdebug.h>
 
 #include <asm/system.h>
diff --git a/arch/sparc/mm/generic_32.c b/arch/sparc/mm/generic_32.c
deleted file mode 100644 (file)
index e6067b7..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * generic.c: Generic Sparc mm routines that are not dependent upon
- *            MMU type but are Sparc specific.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/pagemap.h>
-
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-
-/* Remap IO memory, the same way as remap_pfn_range(), but use
- * the obio memory space.
- *
- * They use a pgprot that sets PAGE_IO and does not check the
- * mem_map table as this is independent of normal memory.
- */
-static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PMD_MASK;
-       end = address + size;
-       if (end > PMD_SIZE)
-               end = PMD_SIZE;
-       do {
-               set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space));
-               address += PAGE_SIZE;
-               offset += PAGE_SIZE;
-               pte++;
-       } while (address < end);
-}
-
-static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PGDIR_MASK;
-       end = address + size;
-       if (end > PGDIR_SIZE)
-               end = PGDIR_SIZE;
-       offset -= address;
-       do {
-               pte_t *pte = pte_alloc_map(mm, NULL, pmd, address);
-               if (!pte)
-                       return -ENOMEM;
-               io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space);
-               address = (address + PMD_SIZE) & PMD_MASK;
-               pmd++;
-       } while (address < end);
-       return 0;
-}
-
-int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                      unsigned long pfn, unsigned long size, pgprot_t prot)
-{
-       int error = 0;
-       pgd_t * dir;
-       unsigned long beg = from;
-       unsigned long end = from + size;
-       struct mm_struct *mm = vma->vm_mm;
-       int space = GET_IOSPACE(pfn);
-       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
-
-       /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-       vma->vm_pgoff = (offset >> PAGE_SHIFT) |
-               ((unsigned long)space << 28UL);
-
-       offset -= from;
-       dir = pgd_offset(mm, from);
-       flush_cache_range(vma, beg, end);
-
-       while (from < end) {
-               pmd_t *pmd = pmd_alloc(mm, dir, from);
-               error = -ENOMEM;
-               if (!pmd)
-                       break;
-               error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space);
-               if (error)
-                       break;
-               from = (from + PGDIR_SIZE) & PGDIR_MASK;
-               dir++;
-       }
-
-       flush_tlb_range(vma, beg, end);
-       return error;
-}
-EXPORT_SYMBOL(io_remap_pfn_range);
diff --git a/arch/sparc/mm/generic_64.c b/arch/sparc/mm/generic_64.c
deleted file mode 100644 (file)
index 3cb00df..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * generic.c: Generic Sparc mm routines that are not dependent upon
- *            MMU type but are Sparc specific.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/pagemap.h>
-
-#include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/tlbflush.h>
-
-/* Remap IO memory, the same way as remap_pfn_range(), but use
- * the obio memory space.
- *
- * They use a pgprot that sets PAGE_IO and does not check the
- * mem_map table as this is independent of normal memory.
- */
-static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte,
-                                     unsigned long address,
-                                     unsigned long size,
-                                     unsigned long offset, pgprot_t prot,
-                                     int space)
-{
-       unsigned long end;
-
-       /* clear hack bit that was used as a write_combine side-effect flag */
-       offset &= ~0x1UL;
-       address &= ~PMD_MASK;
-       end = address + size;
-       if (end > PMD_SIZE)
-               end = PMD_SIZE;
-       do {
-               pte_t entry;
-               unsigned long curend = address + PAGE_SIZE;
-               
-               entry = mk_pte_io(offset, prot, space, PAGE_SIZE);
-               if (!(address & 0xffff)) {
-                       if (PAGE_SIZE < (4 * 1024 * 1024) &&
-                           !(address & 0x3fffff) &&
-                           !(offset & 0x3ffffe) &&
-                           end >= address + 0x400000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 4 * 1024 * 1024);
-                               curend = address + 0x400000;
-                               offset += 0x400000;
-                       } else if (PAGE_SIZE < (512 * 1024) &&
-                                  !(address & 0x7ffff) &&
-                                  !(offset & 0x7fffe) &&
-                                  end >= address + 0x80000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 512 * 1024 * 1024);
-                               curend = address + 0x80000;
-                               offset += 0x80000;
-                       } else if (PAGE_SIZE < (64 * 1024) &&
-                                  !(offset & 0xfffe) &&
-                                  end >= address + 0x10000) {
-                               entry = mk_pte_io(offset, prot, space,
-                                                 64 * 1024);
-                               curend = address + 0x10000;
-                               offset += 0x10000;
-                       } else
-                               offset += PAGE_SIZE;
-               } else
-                       offset += PAGE_SIZE;
-
-               if (pte_write(entry))
-                       entry = pte_mkdirty(entry);
-               do {
-                       BUG_ON(!pte_none(*pte));
-                       set_pte_at(mm, address, pte, entry);
-                       address += PAGE_SIZE;
-                       pte_val(entry) += PAGE_SIZE;
-                       pte++;
-               } while (address < curend);
-       } while (address < end);
-}
-
-static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PGDIR_MASK;
-       end = address + size;
-       if (end > PGDIR_SIZE)
-               end = PGDIR_SIZE;
-       offset -= address;
-       do {
-               pte_t *pte = pte_alloc_map(mm, NULL, pmd, address);
-               if (!pte)
-                       return -ENOMEM;
-               io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space);
-               pte_unmap(pte);
-               address = (address + PMD_SIZE) & PMD_MASK;
-               pmd++;
-       } while (address < end);
-       return 0;
-}
-
-static inline int io_remap_pud_range(struct mm_struct *mm, pud_t * pud, unsigned long address, unsigned long size,
-       unsigned long offset, pgprot_t prot, int space)
-{
-       unsigned long end;
-
-       address &= ~PUD_MASK;
-       end = address + size;
-       if (end > PUD_SIZE)
-               end = PUD_SIZE;
-       offset -= address;
-       do {
-               pmd_t *pmd = pmd_alloc(mm, pud, address);
-               if (!pud)
-                       return -ENOMEM;
-               io_remap_pmd_range(mm, pmd, address, end - address, address + offset, prot, space);
-               address = (address + PUD_SIZE) & PUD_MASK;
-               pud++;
-       } while (address < end);
-       return 0;
-}
-
-int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-               unsigned long pfn, unsigned long size, pgprot_t prot)
-{
-       int error = 0;
-       pgd_t * dir;
-       unsigned long beg = from;
-       unsigned long end = from + size;
-       struct mm_struct *mm = vma->vm_mm;
-       int space = GET_IOSPACE(pfn);
-       unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
-       unsigned long phys_base;
-
-       phys_base = offset | (((unsigned long) space) << 32UL);
-
-       /* See comment in mm/memory.c remap_pfn_range */
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-       vma->vm_pgoff = phys_base >> PAGE_SHIFT;
-
-       offset -= from;
-       dir = pgd_offset(mm, from);
-       flush_cache_range(vma, beg, end);
-
-       while (from < end) {
-               pud_t *pud = pud_alloc(mm, dir, from);
-               error = -ENOMEM;
-               if (!pud)
-                       break;
-               error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space);
-               if (error)
-                       break;
-               from = (from + PGDIR_SIZE) & PGDIR_MASK;
-               dir++;
-       }
-
-       flush_tlb_range(vma, beg, end);
-       return error;
-}
-EXPORT_SYMBOL(io_remap_pfn_range);
index 4730eac0747b50491876a0bc7e3c2c348c02b067..77140a02c86a6f73d012b593c1c1d02aa9401394 100644 (file)
@@ -24,6 +24,7 @@
  */
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/export.h>
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
index f4e97646ce23140781a143f47a66c7ebca578bcf..07e14535375cba42a6c23a0d8d78b343bccfcc95 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
index 94e9a511de849c925bcf28841368ce278feade0c..f80f8ceabc67abd6ef57fce76cb1a224f53204c8 100644 (file)
@@ -74,16 +74,6 @@ enum {
  */
 void tile_irq_activate(unsigned int irq, int tile_irq_type);
 
-/*
- * For onboard, non-PCI (e.g. TILE_IRQ_PERCPU) devices, drivers know
- * how to use enable/disable_percpu_irq() to manage interrupts on each
- * core.  We can't use the generic enable/disable_irq() because they
- * use a single reference count per irq, rather than per cpu per irq.
- */
-void enable_percpu_irq(unsigned int irq);
-void disable_percpu_irq(unsigned int irq);
-
-
 void setup_irq_regs(void);
 
 #endif /* _ASM_TILE_IRQ_H */
index aa0134db2dd683e4f2bde38823bcabc931f7d8ef..02e62806501256ad63f322d26461bd34f8bcc4e9 100644 (file)
@@ -152,14 +152,13 @@ void tile_dev_intr(struct pt_regs *regs, int intnum)
  * Remove an irq from the disabled mask.  If we're in an interrupt
  * context, defer enabling the HW interrupt until we leave.
  */
-void enable_percpu_irq(unsigned int irq)
+static void tile_irq_chip_enable(struct irq_data *d)
 {
-       get_cpu_var(irq_disable_mask) &= ~(1UL << irq);
+       get_cpu_var(irq_disable_mask) &= ~(1UL << d->irq);
        if (__get_cpu_var(irq_depth) == 0)
-               unmask_irqs(1UL << irq);
+               unmask_irqs(1UL << d->irq);
        put_cpu_var(irq_disable_mask);
 }
-EXPORT_SYMBOL(enable_percpu_irq);
 
 /*
  * Add an irq to the disabled mask.  We disable the HW interrupt
@@ -167,13 +166,12 @@ EXPORT_SYMBOL(enable_percpu_irq);
  * in an interrupt context, the return path is careful to avoid
  * unmasking a newly disabled interrupt.
  */
-void disable_percpu_irq(unsigned int irq)
+static void tile_irq_chip_disable(struct irq_data *d)
 {
-       get_cpu_var(irq_disable_mask) |= (1UL << irq);
-       mask_irqs(1UL << irq);
+       get_cpu_var(irq_disable_mask) |= (1UL << d->irq);
+       mask_irqs(1UL << d->irq);
        put_cpu_var(irq_disable_mask);
 }
-EXPORT_SYMBOL(disable_percpu_irq);
 
 /* Mask an interrupt. */
 static void tile_irq_chip_mask(struct irq_data *d)
@@ -209,6 +207,8 @@ static void tile_irq_chip_eoi(struct irq_data *d)
 
 static struct irq_chip tile_irq_chip = {
        .name = "tile_irq_chip",
+       .irq_enable = tile_irq_chip_enable,
+       .irq_disable = tile_irq_chip_disable,
        .irq_ack = tile_irq_chip_ack,
        .irq_eoi = tile_irq_chip_eoi,
        .irq_mask = tile_irq_chip_mask,
index 658f2ce426a44ef5fefab5852cfbe05dc796953b..b3ed19f8779c4a9058ea818bc8fb31a6a75ef34b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <asm/tlbflush.h>
 #include <asm/homecache.h>
 
index 2a8014cb1ff52f0ef3e24a58a5e20ddcfeb3c8cc..9d610d3fb11e9ac93c6e17875cff26257fa89e46 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/sections.h>
index b671a86f45152155bf0170504bdf2511112cdfb0..602908268093cf53397df895e68e240cc601d552 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/cpu.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
+#include <linux/stat.h>
 #include <hv/hypervisor.h>
 
 /* Return a string queried from the hypervisor, truncated to page size. */
index a87d2a859ba97de91db6e8769cb8ecb1bcd78e49..2a81d32de0da518989e5a5118ab91b77774e3e7f 100644 (file)
@@ -39,6 +39,9 @@ EXPORT_SYMBOL(finv_user_asm);
 EXPORT_SYMBOL(current_text_addr);
 EXPORT_SYMBOL(dump_stack);
 
+/* arch/tile/kernel/head.S */
+EXPORT_SYMBOL(empty_zero_page);
+
 /* arch/tile/lib/, various memcpy files */
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__copy_to_user_inatomic);
index cbe6f4f9eca3c93c43039be31238fdeb56ee36dc..1cc6ae477c98b59711c29deb5674e50c63c96be3 100644 (file)
@@ -449,9 +449,12 @@ void homecache_free_pages(unsigned long addr, unsigned int order)
        VM_BUG_ON(!virt_addr_valid((void *)addr));
        page = virt_to_page((void *)addr);
        if (put_page_testzero(page)) {
-               int pages = (1 << order);
                homecache_change_page_home(page, order, initial_page_home());
-               while (pages--)
-                       __free_page(page++);
+               if (order == 0) {
+                       free_hot_cold_page(page, 0);
+               } else {
+                       init_page_count(page);
+                       __free_pages(page, order);
+               }
        }
 }
index e57dcce9bfda4da6ea6be362a542bf891289f0c0..942ed6174f1d073e565d52e5dc074c7e84d3b533 100644 (file)
@@ -237,13 +237,13 @@ menu "PKUnity NetBook-0916 Features"
 
 config I2C_BATTERY_BQ27200
        tristate "I2C Battery BQ27200 Support"
-       select PUV3_I2C
+       select I2C_PUV3
        select POWER_SUPPLY
        select BATTERY_BQ27x00
 
 config I2C_EEPROM_AT24
        tristate "I2C EEPROMs AT24 support"
-       select PUV3_I2C
+       select I2C_PUV3
        select MISC_DEVICES
        select EEPROM_AT24
 
index ae2ec334c3c61473ffa6b7b5cf8695c8d64c322b..1a36262398435ff9f9f224cab74da1a3d2bb0233 100644 (file)
@@ -44,18 +44,4 @@ config DEBUG_OCD
          Say Y here if you want the debug print routines to direct their
          output to the UniCore On-Chip-Debugger channel using CP #1.
 
-config DEBUG_OCD_BREAKPOINT
-       bool "Breakpoint support via On-Chip-Debugger"
-       depends on DEBUG_OCD
-
-config DEBUG_UART
-       int "Kernel low-level debugging messages via serial port"
-       depends on DEBUG_LL
-       range 0 1
-       default "0"
-       help
-         Choice for UART for kernel low-level using PKUnity UARTS,
-         should be between zero and one. The port must have been
-         initialised by the boot-loader before use.
-
 endmenu
index b0954a2d23cfaf5b4db0bbe1b6e95493d75ebc03..950a9afa38f8632239df166ac21ffe094229217e 100644 (file)
@@ -10,8 +10,8 @@
 # Copyright (C) 2001~2010 GUAN Xue-tao
 #
 
-EXTRA_CFLAGS   := -fpic -fno-builtin
-EXTRA_AFLAGS   := -Wa,-march=all
+ccflags-y      := -fpic -fno-builtin
+asflags-y      := -Wa,-march=all
 
 OBJS           := misc.o
 
index 1628a63289946218c12cebed99246c87087e8a18..401f597bc38cfcdf102ff6188f8bd3c27f46dde5 100644 (file)
 #ifndef __UNICORE_BITOPS_H__
 #define __UNICORE_BITOPS_H__
 
-#define find_next_bit          __uc32_find_next_bit
-#define find_next_zero_bit     __uc32_find_next_zero_bit
-
-#define find_first_bit         __uc32_find_first_bit
-#define find_first_zero_bit    __uc32_find_first_zero_bit
-
 #define _ASM_GENERIC_BITOPS_FLS_H_
 #define _ASM_GENERIC_BITOPS___FLS_H_
 #define _ASM_GENERIC_BITOPS_FFS_H_
@@ -44,4 +38,10 @@ static inline int fls(int x)
 
 #include <asm-generic/bitops.h>
 
+/* following definitions: to avoid using codes in lib/find_*.c */
+#define find_next_bit          find_next_bit
+#define find_next_zero_bit     find_next_zero_bit
+#define find_first_bit         find_first_bit
+#define find_first_zero_bit    find_first_zero_bit
+
 #endif /* __UNICORE_BITOPS_H__ */
index e11cb07865782c81b82e4dd90d1977b8f4495245..f0d780a51f9b5dec74a5310fe0f1fd2c4fdc7b28 100644 (file)
@@ -53,7 +53,6 @@ struct thread_struct {
 #define start_thread(regs, pc, sp)                                     \
 ({                                                                     \
        unsigned long *stack = (unsigned long *)sp;                     \
-       set_fs(USER_DS);                                                \
        memset(regs->uregs, 0, sizeof(regs->uregs));                    \
        regs->UCreg_asr = USER_MODE;                                    \
        regs->UCreg_pc = pc & ~1;       /* pc */                        \
index a8970809428a65985873e42ffd417782c0f47ae9..d98bd812cae1ea17efcb314a1cccee9639636b37 100644 (file)
@@ -24,8 +24,8 @@
 
 #include "ksyms.h"
 
-EXPORT_SYMBOL(__uc32_find_next_zero_bit);
-EXPORT_SYMBOL(__uc32_find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_bit);
 
 EXPORT_SYMBOL(__backtrace);
 
index c360ce905d8b7bcb0d9b84b796089987c5cf967b..c77746247d3698856f26e27531c7454382178a6e 100644 (file)
@@ -17,7 +17,7 @@
  * Purpose  : Find a 'zero' bit
  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  */
-__uc32_find_first_zero_bit:
+ENTRY(find_first_zero_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -29,13 +29,14 @@ __uc32_find_first_zero_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_zero_bit)
 
 /*
  * Purpose  : Find next 'zero' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_zero_bit)
+ENTRY(find_next_zero_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -47,14 +48,14 @@ ENTRY(__uc32_find_next_zero_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_zero_bit)
+ENDPROC(find_next_zero_bit)
 
 /*
  * Purpose  : Find a 'one' bit
  * Prototype: int find_first_bit
  *             (const unsigned long *addr, unsigned int maxbit);
  */
-__uc32_find_first_bit:
+ENTRY(find_first_bit)
                cxor.a  r1, #0
                beq     3f
                mov     r2, #0
@@ -66,13 +67,14 @@ __uc32_find_first_bit:
                bub     1b
 3:             mov     r0, r1                  @ no free bits
                mov     pc, lr
+ENDPROC(find_first_bit)
 
 /*
  * Purpose  : Find next 'one' bit
  * Prototype: int find_next_zero_bit
  *             (void *addr, unsigned int maxbit, int offset)
  */
-ENTRY(__uc32_find_next_bit)
+ENTRY(find_next_bit)
                cxor.a  r1, #0
                beq     3b
                and.a   ip, r2, #7
@@ -83,7 +85,7 @@ ENTRY(__uc32_find_next_bit)
                or      r2, r2, #7              @ if zero, then no bits here
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
-ENDPROC(__uc32_find_next_bit)
+ENDPROC(find_next_bit)
 
 /*
  * One or more bits in the LSB of r3 are assumed to be set.
index 2d3e7112d2a3cbce8d778770e35754ac5a34e753..3b379cddbc641cced14c4472a4d7838852a47935 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/memblock.h>
 #include <linux/sort.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <asm/sections.h>
 #include <asm/setup.h>
index 77f7a384c0b5128831205165cbd51874a893d23d..efb42949cc09349e37246baa07f018648186386f 100644 (file)
@@ -194,9 +194,6 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
 config NEED_PER_CPU_PAGE_FIRST_CHUNK
        def_bool y
 
-config HAVE_CPUMASK_OF_CPU_MAP
-       def_bool X86_64_SMP
-
 config ARCH_HIBERNATION_POSSIBLE
        def_bool y
 
@@ -393,7 +390,7 @@ config X86_INTEL_CE
          This option compiles in support for the CE4100 SOC for settop
          boxes and media devices.
 
-config X86_INTEL_MID
+config X86_WANT_INTEL_MID
        bool "Intel MID platform support"
        depends on X86_32
        depends on X86_EXTENDED_PLATFORM
@@ -402,7 +399,10 @@ config X86_INTEL_MID
          systems which do not have the PCI legacy interfaces (Moorestown,
          Medfield). If you are building for a PC class system say N here.
 
-if X86_INTEL_MID
+if X86_WANT_INTEL_MID
+
+config X86_INTEL_MID
+       bool
 
 config X86_MRST
        bool "Moorestown MID platform"
@@ -414,6 +414,7 @@ config X86_MRST
        select SPI
        select INTEL_SCU_IPC
        select X86_PLATFORM_DEVICES
+       select X86_INTEL_MID
        ---help---
          Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
          Internet Device(MID) platform. Moorestown consists of two chips:
index b0b6950cc8c8850d68366b869ca39e4250827013..8efcf42a9d7e318b4cddb93a820cd01d1bd01f4e 100644 (file)
@@ -3,6 +3,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <crypto/aes.h>
 #include <asm/aes.h>
 
index feee8ff1d05ea4cc87e4c5be965b08d00e89731f..545d0ce5981839583d1ed6f185d6df64a9c13c1b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/hardirq.h>
 #include <linux/types.h>
 #include <linux/crypto.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <crypto/algapi.h>
 #include <crypto/aes.h>
index 9b7273cb21937e8a884a08b45b3024af1bf3cfbc..1a6c09af048fbd587613c750502677d7cbb1c052 100644 (file)
@@ -49,6 +49,7 @@ extern unsigned int apic_verbosity;
 extern int local_apic_timer_c2_ok;
 
 extern int disable_apic;
+extern unsigned int lapic_timer_frequency;
 
 #ifdef CONFIG_SMP
 extern void __inquire_remote_apic(int apicid);
index 908b96957d88adf11694f6e83652b47d06d3b8f0..c9547033e38e8fee78964ffda671d9e3402a4455 100644 (file)
  */
 #define E820_RESERVED_KERN        128
 
+/*
+ * Address ranges that need to be mapped by the kernel direct
+ * mapping. This is used to make sure regions such as
+ * EFI_RUNTIME_SERVICES_DATA are directly mapped. See setup_arch().
+ */
+#define E820_RESERVED_EFI         129
+
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 struct e820entry {
@@ -115,6 +122,7 @@ static inline void early_memtest(unsigned long start, unsigned long end)
 }
 #endif
 
+extern unsigned long e820_end_pfn(unsigned long limit_pfn, unsigned type);
 extern unsigned long e820_end_of_ram_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
 extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
index 7093e4a6a0bc6dd5644b2b14cbef9ef5f4085eef..b8d8bfcd44a95f48b15537b555636bbbb32c57b9 100644 (file)
@@ -33,8 +33,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)      \
        efi_call_virt(f, a1, a2, a3, a4, a5, a6)
 
-#define efi_ioremap(addr, size, type)          ioremap_cache(addr, size)
-
 #else /* !CONFIG_X86_32 */
 
 extern u64 efi_call0(void *fp);
@@ -84,9 +82,6 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
        efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
                  (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
 
-extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
-                                u32 type);
-
 #endif /* CONFIG_X86_32 */
 
 extern int add_efi_memmap;
index 4420993acc4734c962922d58ee63e0b700cf330e..925b605eb5c601fa9a6f6c24cf41e596b92d86f8 100644 (file)
@@ -3,11 +3,15 @@
 
 #include <linux/notifier.h>
 
-#define IPCMSG_VRTC    0xFA     /* Set vRTC device */
-
-/* Command id associated with message IPCMSG_VRTC */
-#define IPC_CMD_VRTC_SETTIME      1 /* Set time */
-#define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
+#define IPCMSG_WARM_RESET      0xF0
+#define IPCMSG_COLD_RESET      0xF1
+#define IPCMSG_SOFT_RESET      0xF2
+#define IPCMSG_COLD_BOOT       0xF3
+
+#define IPCMSG_VRTC            0xFA     /* Set vRTC device */
+       /* Command id associated with message IPCMSG_VRTC */
+       #define IPC_CMD_VRTC_SETTIME      1 /* Set time */
+       #define IPC_CMD_VRTC_SETALARM     2 /* Set alarm */
 
 /* Read single register */
 int intel_scu_ipc_ioread8(u16 addr, u8 *data);
index 72a8b52e7dfd0de3fa4271284fdd4a76da7fb31b..a01e7ec7d2377aaede271b6ad4ddd546ef5238a5 100644 (file)
@@ -17,7 +17,7 @@
 #define NMI_REASON_CLEAR_IOCHK 0x08
 #define NMI_REASON_CLEAR_MASK  0x0f
 
-static inline unsigned char get_nmi_reason(void)
+static inline unsigned char default_get_nmi_reason(void)
 {
        return inb(NMI_REASON_PORT);
 }
index c9321f34e55b3fa2cdb9fd4afeaa332dac345add..0e8ae57d3656c4576498b545826a5880214fe9e5 100644 (file)
@@ -201,7 +201,10 @@ int mce_notify_irq(void);
 void mce_notify_process(void);
 
 DECLARE_PER_CPU(struct mce, injectm);
-extern struct file_operations mce_chrdev_ops;
+
+extern void register_mce_write_callback(ssize_t (*)(struct file *filp,
+                                   const char __user *ubuf,
+                                   size_t usize, loff_t *off));
 
 /*
  * Exception handler
index 719f00b28ff5358caf87d736ed5b4100dafdce9e..93f79094c2243211eede22db91acdf33098a059a 100644 (file)
@@ -31,11 +31,20 @@ enum mrst_cpu_type {
 };
 
 extern enum mrst_cpu_type __mrst_cpu_chip;
+
+#ifdef CONFIG_X86_INTEL_MID
+
 static inline enum mrst_cpu_type mrst_identify_cpu(void)
 {
        return __mrst_cpu_chip;
 }
 
+#else /* !CONFIG_X86_INTEL_MID */
+
+#define mrst_identify_cpu()    (0)
+
+#endif /* !CONFIG_X86_INTEL_MID */
+
 enum mrst_timer_options {
        MRST_TIMER_DEFAULT,
        MRST_TIMER_APBT_ONLY,
@@ -44,6 +53,13 @@ enum mrst_timer_options {
 
 extern enum mrst_timer_options mrst_timer_options;
 
+/*
+ * Penwell uses spread spectrum clock, so the freq number is not exactly
+ * the same as reported by MSR based on SDM.
+ */
+#define PENWELL_FSB_FREQ_83SKU         83200
+#define PENWELL_FSB_FREQ_100SKU        99840
+
 #define SFI_MTMR_MAX_NUM 8
 #define SFI_MRTC_MAX   8
 
index 084ef95274cd78ceb51b1ea7a208a7a5e486199a..95203d40ffdde69d014c986453905280b49ee9e5 100644 (file)
@@ -169,7 +169,14 @@ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high)
        return native_write_msr_safe(msr, low, high);
 }
 
-/* rdmsr with exception handling */
+/*
+ * rdmsr with exception handling.
+ *
+ * Please note that the exception handling works only after we've
+ * switched to the "smart" #GP handler in trap_init() which knows about
+ * exception tables - using this macro earlier than that causes machine
+ * hangs on boxes which do not implement the @msr in the first argument.
+ */
 #define rdmsr_safe(msr, p1, p2)                                        \
 ({                                                             \
        int __err;                                              \
index c2ff2a1d845e402249e44a70e41459805c3faaa8..2d2f01ce6dcbf1a9c8b72ebef77a159e1b3a5b1a 100644 (file)
@@ -401,6 +401,7 @@ extern unsigned long arch_align_stack(unsigned long sp);
 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 
 void default_idle(void);
+bool set_pm_idle_to_default(void);
 
 void stop_this_cpu(void *dummy);
 
index fa7b9176b76cb33820034403fd8f4a50dc49709c..431793e5d4846f23bf5947f933fdaf9f5ae1987a 100644 (file)
@@ -32,6 +32,22 @@ extern int no_timer_check;
  *  (mathieu.desnoyers@polymtl.ca)
  *
  *                     -johnstul@us.ibm.com "math is hard, lets go shopping!"
+ *
+ * In:
+ *
+ * ns = cycles * cyc2ns_scale / SC
+ *
+ * Although we may still have enough bits to store the value of ns,
+ * in some cases, we may not have enough bits to store cycles * cyc2ns_scale,
+ * leading to an incorrect result.
+ *
+ * To avoid this, we can decompose 'cycles' into quotient and remainder
+ * of division by SC.  Then,
+ *
+ * ns = (quot * SC + rem) * cyc2ns_scale / SC
+ *    = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC
+ *
+ *                     - sqazi@google.com
  */
 
 DECLARE_PER_CPU(unsigned long, cyc2ns);
@@ -41,9 +57,14 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset);
 
 static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
 {
+       unsigned long long quot;
+       unsigned long long rem;
        int cpu = smp_processor_id();
        unsigned long long ns = per_cpu(cyc2ns_offset, cpu);
-       ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR;
+       quot = (cyc >> CYC2NS_SCALE_FACTOR);
+       rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1);
+       ns += quot * per_cpu(cyc2ns, cpu) +
+               ((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR);
        return ns;
 }
 
index 10474fb1185df7e30f52101cea4e358a18e39458..cf1d73643f60723dc514b52e66969ed46a9c01a4 100644 (file)
@@ -57,6 +57,7 @@
 
 #define UV1_HUB_PART_NUMBER    0x88a5
 #define UV2_HUB_PART_NUMBER    0x8eb8
+#define UV2_HUB_PART_NUMBER_X  0x1111
 
 /* Compat: if this #define is present, UV headers support UV2 */
 #define UV2_HUB_IS_SUPPORTED   1
index d3d859035af9e1968d0ad9d4a39000331c27c8f1..1971e652d24be5fc0674633c1edb3717645306e7 100644 (file)
@@ -152,6 +152,7 @@ struct x86_cpuinit_ops {
 /**
  * struct x86_platform_ops - platform specific runtime functions
  * @calibrate_tsc:             calibrate TSC
+ * @wallclock_init:            init the wallclock device
  * @get_wallclock:             get time from HW clock like RTC etc.
  * @set_wallclock:             set time back to HW clock
  * @is_untracked_pat_range     exclude from PAT logic
@@ -160,11 +161,13 @@ struct x86_cpuinit_ops {
  */
 struct x86_platform_ops {
        unsigned long (*calibrate_tsc)(void);
+       void (*wallclock_init)(void);
        unsigned long (*get_wallclock)(void);
        int (*set_wallclock)(unsigned long nowtime);
        void (*iommu_shutdown)(void);
        bool (*is_untracked_pat_range)(u64 start, u64 end);
        void (*nmi_init)(void);
+       unsigned char (*get_nmi_reason)(void);
        int (*i8042_detect)(void);
 };
 
diff --git a/arch/x86/include/asm/xen/grant_table.h b/arch/x86/include/asm/xen/grant_table.h
deleted file mode 100644 (file)
index fdbbb45..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _ASM_X86_XEN_GRANT_TABLE_H
-#define _ASM_X86_XEN_GRANT_TABLE_H
-
-#define xen_alloc_vm_area(size)        alloc_vm_area(size)
-#define xen_free_vm_area(area) free_vm_area(area)
-
-#endif /* _ASM_X86_XEN_GRANT_TABLE_H */
index 417777de5a40b9e039a039b0cd429927e37fca49..5728852fb90f932cebef5078727a386cdd63224c 100644 (file)
@@ -47,6 +47,7 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/physdev.h>
+#include <xen/interface/platform.h>
 
 /*
  * The hypercall asms have to meet several constraints:
@@ -300,6 +301,13 @@ HYPERVISOR_set_timer_op(u64 timeout)
        return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
 }
 
+static inline int
+HYPERVISOR_dom0_op(struct xen_platform_op *platform_op)
+{
+       platform_op->interface_version = XENPF_INTERFACE_VERSION;
+       return _hypercall1(int, dom0_op, platform_op);
+}
+
 static inline int
 HYPERVISOR_set_debugreg(int reg, unsigned long value)
 {
index 5d4922ad4b9b1460830c2e332adfa4e58494c3fa..a1f2db5f1170810013e7add2f40f43129ce6f04a 100644 (file)
@@ -55,6 +55,7 @@ DEFINE_GUEST_HANDLE(char);
 DEFINE_GUEST_HANDLE(int);
 DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
+DEFINE_GUEST_HANDLE(uint64_t);
 #endif
 
 #ifndef HYPERVISOR_VIRT_START
index c63822816249e8c41fa47643d3204bde8a758a42..1f84794f0759327c387d602cddccb3d479188f92 100644 (file)
@@ -738,5 +738,5 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n)
 
        atomic_set(&stop_machine_first, 1);
        wrote_text = 0;
-       __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+       __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
 }
index a2fd72e0ab35bbff6703836f82540a0f71588e85..f98d84caf94cfdc43cedda4cb411ebea5213e4b7 100644 (file)
@@ -186,7 +186,7 @@ static struct resource lapic_resource = {
        .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
 };
 
-static unsigned int calibration_result;
+unsigned int lapic_timer_frequency = 0;
 
 static void apic_pm_activate(void);
 
@@ -454,7 +454,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
        case CLOCK_EVT_MODE_ONESHOT:
-               __setup_APIC_LVTT(calibration_result,
+               __setup_APIC_LVTT(lapic_timer_frequency,
                                  mode != CLOCK_EVT_MODE_PERIODIC, 1);
                break;
        case CLOCK_EVT_MODE_UNUSED:
@@ -638,6 +638,25 @@ static int __init calibrate_APIC_clock(void)
        long delta, deltatsc;
        int pm_referenced = 0;
 
+       /**
+        * check if lapic timer has already been calibrated by platform
+        * specific routine, such as tsc calibration code. if so, we just fill
+        * in the clockevent structure and return.
+        */
+
+       if (lapic_timer_frequency) {
+               apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
+                               lapic_timer_frequency);
+               lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
+                                       TICK_NSEC, lapic_clockevent.shift);
+               lapic_clockevent.max_delta_ns =
+                       clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
+               lapic_clockevent.min_delta_ns =
+                       clockevent_delta2ns(0xF, &lapic_clockevent);
+               lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
+               return 0;
+       }
+
        local_irq_disable();
 
        /* Replace the global interrupt handler */
@@ -679,12 +698,12 @@ static int __init calibrate_APIC_clock(void)
        lapic_clockevent.min_delta_ns =
                clockevent_delta2ns(0xF, &lapic_clockevent);
 
-       calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
+       lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
 
        apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
        apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
        apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
-                   calibration_result);
+                   lapic_timer_frequency);
 
        if (cpu_has_tsc) {
                apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
@@ -695,13 +714,13 @@ static int __init calibrate_APIC_clock(void)
 
        apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
                    "%u.%04u MHz.\n",
-                   calibration_result / (1000000 / HZ),
-                   calibration_result % (1000000 / HZ));
+                   lapic_timer_frequency / (1000000 / HZ),
+                   lapic_timer_frequency % (1000000 / HZ));
 
        /*
         * Do a sanity check on the APIC calibration result
         */
-       if (calibration_result < (1000000 / HZ)) {
+       if (lapic_timer_frequency < (1000000 / HZ)) {
                local_irq_enable();
                pr_warning("APIC frequency too slow, disabling apic timer\n");
                return -1;
index 3c31fa98af6dcb23a9298fae4c0ea29495167d0f..6d939d7847e293901538cfe32ae1b95d1d82551a 100644 (file)
@@ -193,10 +193,8 @@ int __init arch_early_irq_init(void)
        struct irq_cfg *cfg;
        int count, node, i;
 
-       if (!legacy_pic->nr_legacy_irqs) {
-               nr_irqs_gsi = 0;
+       if (!legacy_pic->nr_legacy_irqs)
                io_apic_irqs = ~0UL;
-       }
 
        for (i = 0; i < nr_ioapics; i++) {
                ioapics[i].saved_registers =
@@ -1696,6 +1694,7 @@ __apicdebuginit(void) print_IO_APICs(void)
        int ioapic_idx;
        struct irq_cfg *cfg;
        unsigned int irq;
+       struct irq_chip *chip;
 
        printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
        for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
@@ -1716,6 +1715,10 @@ __apicdebuginit(void) print_IO_APICs(void)
        for_each_active_irq(irq) {
                struct irq_pin_list *entry;
 
+               chip = irq_get_chip(irq);
+               if (chip != &ioapic_chip)
+                       continue;
+
                cfg = irq_get_chip_data(irq);
                if (!cfg)
                        continue;
index 62ae3001ae02c4348d640dc01f67fd055718deb0..9d59bbacd4e3cb7a76474a59e2965c739140d475 100644 (file)
@@ -93,6 +93,8 @@ static int __init early_get_pnodeid(void)
 
        if (node_id.s.part_number == UV2_HUB_PART_NUMBER)
                uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1;
+       if (node_id.s.part_number == UV2_HUB_PART_NUMBER_X)
+               uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1;
 
        uv_hub_info->hub_revision = uv_min_hub_revision_id;
        pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1);
index 46ae4f65fc7f915e9da6b0442a131f813a60fe2c..0bab2b18bb2099c4290f046bb210035b05083869 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/elf.h>
@@ -441,8 +442,6 @@ static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
 
 static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 {
-       u32 dummy;
-
        early_init_amd_mc(c);
 
        /*
@@ -472,12 +471,12 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
        }
 #endif
-
-       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
+       u32 dummy;
+
 #ifdef CONFIG_SMP
        unsigned long long value;
 
@@ -656,6 +655,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                        checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
                }
        }
+
+       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 }
 
 #ifdef CONFIG_X86_32
index 83930deec3c6e2628cfd1ba2da5cecf4528d4232..507ea58688e251c12d9f33313cf5493edab3d499 100644 (file)
@@ -28,6 +28,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/cper.h>
index 6199232161cffa181d6cf80605adb38dfbb51a61..319882ef848d3cd43c0a4dcfa41ea14cd09502ab 100644 (file)
@@ -208,7 +208,7 @@ static int inject_init(void)
        if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
                return -ENOMEM;
        printk(KERN_INFO "Machine check injector initialized\n");
-       mce_chrdev_ops.write = mce_write;
+       register_mce_write_callback(mce_write);
        register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
                                "mce_notify");
        return 0;
index 864830e1dd655839dec78d5b45ed2e27442305c8..2af127d4c3d1dc2ebdab3e0e2ff95d2d07595a46 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/debugfs.h>
 #include <linux/irq_work.h>
+#include <linux/export.h>
 
 #include <asm/processor.h>
 #include <asm/mce.h>
@@ -1633,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
        }
 }
 
-/* Modified in mce-inject.c, so not static or const */
-struct file_operations mce_chrdev_ops = {
+static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf,
+                           size_t usize, loff_t *off);
+
+void register_mce_write_callback(ssize_t (*fn)(struct file *filp,
+                            const char __user *ubuf,
+                            size_t usize, loff_t *off))
+{
+       mce_write = fn;
+}
+EXPORT_SYMBOL_GPL(register_mce_write_callback);
+
+ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
+                        size_t usize, loff_t *off)
+{
+       if (mce_write)
+               return mce_write(filp, ubuf, usize, off);
+       else
+               return -EINVAL;
+}
+
+static const struct file_operations mce_chrdev_ops = {
        .open                   = mce_chrdev_open,
        .release                = mce_chrdev_release,
        .read                   = mce_chrdev_read,
+       .write                  = mce_chrdev_write,
        .poll                   = mce_chrdev_poll,
        .unlocked_ioctl         = mce_chrdev_ioctl,
        .llseek                 = no_llseek,
 };
-EXPORT_SYMBOL_GPL(mce_chrdev_ops);
 
 static struct miscdevice mce_chrdev_device = {
        MISC_MCELOG_MINOR,
index 27c625178bf11dd8a8e7f3bab162ed611515059d..787e06c84ea6a8cf6e097e15c4b13c2db87dbb7a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/percpu.h>
+#include <linux/export.h>
 #include <linux/sysdev.h>
 #include <linux/types.h>
 #include <linux/init.h>
index a71efcdbb0925ffe7c2f97d58d0625e4179662fc..97b26356e9ee8b022b45ae1adc5ef7628a5e2539 100644 (file)
@@ -547,6 +547,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 
                if (tmp != mask_lo) {
                        printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
+                       add_taint(TAINT_FIRMWARE_WORKAROUND);
                        mask_lo = tmp;
                }
        }
@@ -693,6 +694,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock)
 
        /* Disable MTRRs, and set the default type to uncached */
        mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
+       wbinvd();
 }
 
 static void post_set(void) __releases(set_atomicity_lock)
index 640891014b2ae3dccdef498db11f05a0942145e5..2bda212a0010ca561e8f34a9d56c2502b47ff70b 100644 (file)
@@ -312,12 +312,8 @@ int x86_setup_perfctr(struct perf_event *event)
                        return -EOPNOTSUPP;
        }
 
-       /*
-        * Do not allow config1 (extended registers) to propagate,
-        * there's no sane user-space generalization yet:
-        */
        if (attr->type == PERF_TYPE_RAW)
-               return 0;
+               return x86_pmu_extra_regs(event->attr.config, event);
 
        if (attr->type == PERF_TYPE_HW_CACHE)
                return set_ext_hw_attr(hwc, event);
@@ -588,7 +584,7 @@ done:
                                x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]);
                }
        }
-       return num ? -ENOSPC : 0;
+       return num ? -EINVAL : 0;
 }
 
 /*
@@ -607,7 +603,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
 
        if (is_x86_event(leader)) {
                if (n >= max_count)
-                       return -ENOSPC;
+                       return -EINVAL;
                cpuc->event_list[n] = leader;
                n++;
        }
@@ -620,7 +616,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
                        continue;
 
                if (n >= max_count)
-                       return -ENOSPC;
+                       return -EINVAL;
 
                cpuc->event_list[n] = event;
                n++;
@@ -1316,7 +1312,7 @@ static int validate_event(struct perf_event *event)
        c = x86_pmu.get_event_constraints(fake_cpuc, event);
 
        if (!c || !c->weight)
-               ret = -ENOSPC;
+               ret = -EINVAL;
 
        if (x86_pmu.put_event_constraints)
                x86_pmu.put_event_constraints(fake_cpuc, event);
@@ -1341,7 +1337,7 @@ static int validate_group(struct perf_event *event)
 {
        struct perf_event *leader = event->group_leader;
        struct cpu_hw_events *fake_cpuc;
-       int ret = -ENOSPC, n;
+       int ret = -EINVAL, n;
 
        fake_cpuc = allocate_fake_cpuc();
        if (IS_ERR(fake_cpuc))
index ab6343d21825d7d9328fae81fd6faef3bf092a13..3b8a2d30d14e8ebeb2c58406212fbbd3c79ba935 100644 (file)
@@ -199,8 +199,7 @@ static int force_ibs_eilvt_setup(void)
                goto out;
        }
 
-       pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
-       pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
+       pr_info("IBS: LVT offset %d assigned\n", offset);
 
        return 0;
 out:
@@ -265,19 +264,23 @@ perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *h
 static __init int amd_ibs_init(void)
 {
        u32 caps;
-       int ret;
+       int ret = -EINVAL;
 
        caps = __get_ibs_caps();
        if (!caps)
                return -ENODEV; /* ibs not supported by the cpu */
 
-       if (!ibs_eilvt_valid()) {
-               ret = force_ibs_eilvt_setup();
-               if (ret) {
-                       pr_err("Failed to setup IBS, %d\n", ret);
-                       return ret;
-               }
-       }
+       /*
+        * Force LVT offset assignment for family 10h: The offsets are
+        * not assigned by the BIOS for this family, so the OS is
+        * responsible for doing it. If the OS assignment fails, fall
+        * back to BIOS settings and try to setup this.
+        */
+       if (boot_cpu_data.x86 == 0x10)
+               force_ibs_eilvt_setup();
+
+       if (!ibs_eilvt_valid())
+               goto out;
 
        get_online_cpus();
        ibs_caps = caps;
@@ -287,7 +290,11 @@ static __init int amd_ibs_init(void)
        smp_call_function(setup_APIC_ibs, NULL, 1);
        put_online_cpus();
 
-       return perf_event_ibs_init();
+       ret = perf_event_ibs_init();
+out:
+       if (ret)
+               pr_err("Failed to setup IBS, %d\n", ret);
+       return ret;
 }
 
 /* Since we need the pci subsystem to init ibs we can't do this earlier: */
index e09ca20e86eeaeba463b6e42b8bcf1c7a0adb78b..8d601b18bf9f43688f2a6c5cb90994e00a4fa8d8 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <asm/hardirq.h>
 #include <asm/apic.h>
@@ -1544,6 +1545,13 @@ static void intel_clovertown_quirks(void)
        x86_pmu.pebs_constraints = NULL;
 }
 
+static void intel_sandybridge_quirks(void)
+{
+       printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
+       x86_pmu.pebs = 0;
+       x86_pmu.pebs_constraints = NULL;
+}
+
 __init int intel_pmu_init(void)
 {
        union cpuid10_edx edx;
@@ -1693,6 +1701,7 @@ __init int intel_pmu_init(void)
                break;
 
        case 42: /* SandyBridge */
+               x86_pmu.quirks = intel_sandybridge_quirks;
        case 45: /* SandyBridge, "Romely-EP" */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
index c0d238f49db843cbd98bea7a7bc68b700fc40d7f..73da6b64f5b788ccbb83eef3317c32161b755fca 100644 (file)
@@ -493,6 +493,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
        unsigned long from = cpuc->lbr_entries[0].from;
        unsigned long old_to, to = cpuc->lbr_entries[0].to;
        unsigned long ip = regs->ip;
+       int is_64bit = 0;
 
        /*
         * We don't need to fixup if the PEBS assist is fault like
@@ -544,7 +545,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
                } else
                        kaddr = (void *)to;
 
-               kernel_insn_init(&insn, kaddr);
+#ifdef CONFIG_X86_64
+               is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
+#endif
+               insn_init(&insn, kaddr, is_64bit);
                insn_get_length(&insn);
                to += insn.length;
        } while (to < ip);
index 492bf1358a7c388a9e252e8f031d6c6122e540d8..ef484d9d0a251b0128a164486096ce43c4ea8f4c 100644 (file)
@@ -1268,7 +1268,7 @@ reserve:
        }
 
 done:
-       return num ? -ENOSPC : 0;
+       return num ? -EINVAL : 0;
 }
 
 static __initconst const struct x86_pmu p4_pmu = {
index a621f3427685ab272d636e1b9ff06b9b0be8a01b..52821799a702c8c4f22719865bc90d82490294c0 100644 (file)
@@ -2,6 +2,7 @@
  * Architecture specific OF callbacks.
  */
 #include <linux/bootmem.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
index 3e2ef842531649de082d64298c6cb1044446c1bf..65ffd110a81bc95491fb13ae7c87cd7be1738f93 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/crash_dump.h>
+#include <linux/export.h>
 #include <linux/bootmem.h>
 #include <linux/pfn.h>
 #include <linux/suspend.h>
@@ -134,6 +135,7 @@ static void __init e820_print_type(u32 type)
                printk(KERN_CONT "(usable)");
                break;
        case E820_RESERVED:
+       case E820_RESERVED_EFI:
                printk(KERN_CONT "(reserved)");
                break;
        case E820_ACPI:
@@ -782,7 +784,7 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
 /*
  * Find the highest page frame number we have available
  */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
 {
        int i;
        unsigned long last_pfn = 0;
index 4aecc54236a947941397f2e5d407221fd395ebd4..1bb0bf4d92cd8edf9d639ea5aabd08bc7efad892 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <linux/sysdev.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -1048,6 +1049,14 @@ int hpet_rtc_timer_init(void)
 }
 EXPORT_SYMBOL_GPL(hpet_rtc_timer_init);
 
+static void hpet_disable_rtc_channel(void)
+{
+       unsigned long cfg;
+       cfg = hpet_readl(HPET_T1_CFG);
+       cfg &= ~HPET_TN_ENABLE;
+       hpet_writel(cfg, HPET_T1_CFG);
+}
+
 /*
  * The functions below are called from rtc driver.
  * Return 0 if HPET is not being used.
@@ -1059,6 +1068,9 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
                return 0;
 
        hpet_rtc_flags &= ~bit_mask;
+       if (unlikely(!hpet_rtc_flags))
+               hpet_disable_rtc_channel();
+
        return 1;
 }
 EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit);
@@ -1124,15 +1136,11 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq);
 
 static void hpet_rtc_timer_reinit(void)
 {
-       unsigned int cfg, delta;
+       unsigned int delta;
        int lost_ints = -1;
 
-       if (unlikely(!hpet_rtc_flags)) {
-               cfg = hpet_readl(HPET_T1_CFG);
-               cfg &= ~HPET_TN_ENABLE;
-               hpet_writel(cfg, HPET_T1_CFG);
-               return;
-       }
+       if (unlikely(!hpet_rtc_flags))
+               hpet_disable_rtc_channel();
 
        if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit)
                delta = hpet_default_delta;
index 6c0802eb2f7f7efdc79c9a51d160ac92c70e43c2..429e0c92924eede7d925c92836ac25505de86007 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/smp.h>
 #include <linux/ftrace.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include <asm/apic.h>
 #include <asm/io_apic.h>
index acf8fbf8fbda1960de6cbd18eaf47a0a049eed8b..69bca468c47a8ffc22ea5811cb3bdf63caf0f44b 100644 (file)
@@ -38,6 +38,9 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        u64 curbase = (u64)task_stack_page(current);
 
+       if (user_mode_vm(regs))
+               return;
+
        WARN_ONCE(regs->sp >= curbase &&
                  regs->sp <= curbase + THREAD_SIZE &&
                  regs->sp <  curbase + sizeof(struct thread_info) +
index cacdd46d184d4c0253540db3d3a2f9ed96047253..ea9d5f2f13efec411a79a0b43f003b29c06654d3 100644 (file)
@@ -24,8 +24,9 @@ union jump_code_union {
        } __attribute__((packed));
 };
 
-void arch_jump_label_transform(struct jump_entry *entry,
-                              enum jump_label_type type)
+static void __jump_label_transform(struct jump_entry *entry,
+                                  enum jump_label_type type,
+                                  void *(*poker)(void *, const void *, size_t))
 {
        union jump_code_union code;
 
@@ -35,17 +36,24 @@ void arch_jump_label_transform(struct jump_entry *entry,
                                (entry->code + JUMP_LABEL_NOP_SIZE);
        } else
                memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
+
+       (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+                              enum jump_label_type type)
+{
        get_online_cpus();
        mutex_lock(&text_mutex);
-       text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
+       __jump_label_transform(entry, type, text_poke_smp);
        mutex_unlock(&text_mutex);
        put_online_cpus();
 }
 
-void __init_or_module arch_jump_label_text_poke_early(jump_label_t addr)
+void arch_jump_label_transform_static(struct jump_entry *entry,
+                                     enum jump_label_type type)
 {
-       text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5],
-                       JUMP_LABEL_NOP_SIZE);
+       __jump_label_transform(entry, type, text_poke_early);
 }
 
 #endif
index c1a0188e29aef61d22706c8d0f2b99f843cf8fc7..44842d756b29fa9b2705fb8c57189fe5d28b5732 100644 (file)
@@ -74,9 +74,10 @@ static cycle_t kvm_clock_read(void)
        struct pvclock_vcpu_time_info *src;
        cycle_t ret;
 
-       src = &get_cpu_var(hv_clock);
+       preempt_disable_notrace();
+       src = &__get_cpu_var(hv_clock);
        ret = pvclock_clocksource_read(src);
-       put_cpu_var(hv_clock);
+       preempt_enable_notrace();
        return ret;
 }
 
index f2d2a664e7975acace35742dc7bf3fe3446c2aeb..9d46f5e43b51f0dd2b02ad0575c1e90470df862a 100644 (file)
@@ -256,7 +256,7 @@ static int __init microcode_dev_init(void)
        return 0;
 }
 
-static void microcode_dev_exit(void)
+static void __exit microcode_dev_exit(void)
 {
        misc_deregister(&microcode_dev);
 }
@@ -519,10 +519,8 @@ static int __init microcode_init(void)
 
        microcode_pdev = platform_device_register_simple("microcode", -1,
                                                         NULL, 0);
-       if (IS_ERR(microcode_pdev)) {
-               microcode_dev_exit();
+       if (IS_ERR(microcode_pdev))
                return PTR_ERR(microcode_pdev);
-       }
 
        get_online_cpus();
        mutex_lock(&microcode_mutex);
@@ -532,14 +530,12 @@ static int __init microcode_init(void)
        mutex_unlock(&microcode_mutex);
        put_online_cpus();
 
-       if (error) {
-               platform_device_unregister(microcode_pdev);
-               return error;
-       }
+       if (error)
+               goto out_pdev;
 
        error = microcode_dev_init();
        if (error)
-               return error;
+               goto out_sysdev_driver;
 
        register_syscore_ops(&mc_syscore_ops);
        register_hotcpu_notifier(&mc_cpu_notifier);
@@ -548,6 +544,20 @@ static int __init microcode_init(void)
                " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n");
 
        return 0;
+
+out_sysdev_driver:
+       get_online_cpus();
+       mutex_lock(&microcode_mutex);
+
+       sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
+
+       mutex_unlock(&microcode_mutex);
+       put_online_cpus();
+
+out_pdev:
+       platform_device_unregister(microcode_pdev);
+       return error;
+
 }
 module_init(microcode_init);
 
index 9103b89c145a534215824a9b2a7d80aa9e112527..0741b062a3048a6e2b1b5bd0eb4edbbf3d5bb9cf 100644 (file)
@@ -95,8 +95,8 @@ static void __init MP_bus_info(struct mpc_bus *m)
        }
 #endif
 
+       set_bit(m->busid, mp_bus_not_pci);
        if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) {
-               set_bit(m->busid, mp_bus_not_pci);
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
                mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
 #endif
index 7ec5bd140b87903a565a02a115188afdef27eb3f..e88f37b58dddeeaecfb8951649db799986b7e247 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/hardirq.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <linux/mca.h>
 
@@ -28,6 +29,7 @@
 #include <asm/traps.h>
 #include <asm/mach_traps.h>
 #include <asm/nmi.h>
+#include <asm/x86_init.h>
 
 #define NMI_MAX_NAMELEN        16
 struct nmiaction {
@@ -347,7 +349,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
 
        /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
        raw_spin_lock(&nmi_reason_lock);
-       reason = get_nmi_reason();
+       reason = x86_platform.get_nmi_reason();
 
        if (reason & NMI_REASON_MASK) {
                if (reason & NMI_REASON_SERR)
index 622872054fbefa96ee43e45cd029940b72b0a8e5..80dc793b3f6331747cd29ea5d0a1303e515f07db 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-debug.h>
 #include <linux/dmar.h>
+#include <linux/export.h>
 #include <linux/bootmem.h>
 #include <linux/gfp.h>
 #include <linux/pci.h>
index 63228035f9d7417c758960ae69b844756fda3ee0..34e06e84ce317991a52568208b265ec6c6f5d7d4 100644 (file)
@@ -10,9 +10,9 @@
 #include <linux/dmi.h>
 #include <linux/pfn.h>
 #include <linux/pci.h>
-#include <asm/pci-direct.h>
-
+#include <linux/export.h>
 
+#include <asm/pci-direct.h>
 #include <asm/e820.h>
 #include <asm/mmzone.h>
 #include <asm/setup.h>
index b9b3b1a51643931a0405a1c0f9cc5b62eec43b1f..ee5d4fbd53b4bac72d19e3aa3000e77467f0c25e 100644 (file)
@@ -403,6 +403,14 @@ void default_idle(void)
 EXPORT_SYMBOL(default_idle);
 #endif
 
+bool set_pm_idle_to_default(void)
+{
+       bool ret = !!pm_idle;
+
+       pm_idle = default_idle;
+
+       return ret;
+}
 void stop_this_cpu(void *dummy)
 {
        local_irq_disable();
index b78643d0f9a53d8b2050a14f7e8185b540ed8595..03920a15a632289605c6f0ba0b563d64065214a7 100644 (file)
@@ -553,4 +553,17 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC,
                        quirk_amd_nb_node);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_LINK,
                        quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F0,
+                       quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F1,
+                       quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F2,
+                       quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3,
+                       quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4,
+                       quirk_amd_nb_node);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F5,
+                       quirk_amd_nb_node);
+
 #endif
index e334be1182b9f0b3666464f8ff9f13b22d3ef1dc..37a458b521a6020598b69305c782a0f28bd75b27 100644 (file)
@@ -124,7 +124,7 @@ __setup("reboot=", reboot_setup);
  */
 
 /*
- * Some machines require the "reboot=b"  commandline option,
+ * Some machines require the "reboot=b" or "reboot=k"  commandline options,
  * this quirk makes that automatic.
  */
 static int __init set_bios_reboot(const struct dmi_system_id *d)
@@ -136,6 +136,15 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
        return 0;
 }
 
+static int __init set_kbd_reboot(const struct dmi_system_id *d)
+{
+       if (reboot_type != BOOT_KBD) {
+               reboot_type = BOOT_KBD;
+               printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident);
+       }
+       return 0;
+}
+
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
        {       /* Handle problems with rebooting on Dell E520's */
                .callback = set_bios_reboot,
@@ -295,7 +304,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                },
        },
        { /* Handle reboot issue on Acer Aspire one */
-               .callback = set_bios_reboot,
+               .callback = set_kbd_reboot,
                .ident = "Acer Aspire One A110",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -443,6 +452,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"),
                },
        },
+       {       /* Handle problems with rebooting on the OptiPlex 990. */
+               .callback = set_pci_reboot,
+               .ident = "Dell OptiPlex 990",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
+               },
+       },
        { }
 };
 
index ccdbc16b89413913fed82ae908088be8315c7a39..af6db6ec5b2a20db3d13861bdb97b878f8371f1e 100644 (file)
@@ -5,12 +5,14 @@
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
 #include <linux/bcd.h>
+#include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
 #include <asm/time.h>
+#include <asm/mrst.h>
 
 #ifdef CONFIG_X86_32
 /*
@@ -241,6 +243,10 @@ static __init int add_rtc_cmos(void)
        if (of_have_populated_dt())
                return 0;
 
+       /* Intel MID platforms don't have ioport rtc */
+       if (mrst_identify_cpu())
+               return -ENODEV;
+
        platform_device_register(&rtc_device);
        dev_info(&rtc_device.dev,
                 "registered platform RTC device (no PNP device found)\n");
index afaf38447ef5fc42c53e78168492fa9eb89a032b..9a9e40fb091ccbf0c79885dbbfd7d2e64b125d45 100644 (file)
@@ -691,6 +691,8 @@ early_param("reservelow", parse_reservelow);
 
 void __init setup_arch(char **cmdline_p)
 {
+       unsigned long end_pfn;
+
 #ifdef CONFIG_X86_32
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        visws_early_detect();
@@ -932,7 +934,24 @@ void __init setup_arch(char **cmdline_p)
        init_gbpages();
 
        /* max_pfn_mapped is updated here */
-       max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
+       end_pfn = max_low_pfn;
+
+#ifdef CONFIG_X86_64
+       /*
+        * There may be regions after the last E820_RAM region that we
+        * want to include in the kernel direct mapping, such as
+        * EFI_RUNTIME_SERVICES_DATA.
+        */
+       if (efi_enabled) {
+               unsigned long efi_end;
+
+               efi_end = e820_end_pfn(MAXMEM>>PAGE_SHIFT, E820_RESERVED_EFI);
+               if (efi_end > max_low_pfn)
+                       end_pfn = efi_end;
+       }
+#endif
+
+       max_low_pfn_mapped = init_memory_mapping(0, end_pfn << PAGE_SHIFT);
        max_pfn_mapped = max_low_pfn_mapped;
 
 #ifdef CONFIG_X86_64
@@ -1045,6 +1064,8 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.timers.wallclock_init();
 
+       x86_platform.wallclock_init();
+
        mcheck_init();
 
        arch_init_ideal_nops();
index 013e7eba83bbd400fa099df067e71fbddc44b34d..16204dc1548427d8895b6ce7da1436d81ecfe431 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
 #include <linux/cache.h>
index e07a2fc876b93e36a91ee551e47c4ef3568811cd..e2410e27f97ef94d7b87d8338b61f5b7bb87611e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/dma_remapping.h>
 #include <linux/init_task.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/init.h>
index 5a64d057be57a1e109d8e7ec612feda88c4bbade..dd5fbf4101fc393a3edad3bb3a569a1ed63269fa 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/i8253.h>
 #include <linux/time.h>
+#include <linux/export.h>
 #include <linux/mca.h>
 
 #include <asm/vsyscall.h>
index 8927486a464967a45c50779c71d874c5f257353b..76ee97709a00e88837192ac1a3deb5f84302ae8f 100644 (file)
@@ -26,6 +26,7 @@
  * Send feedback to <colpatch@us.ibm.com>
  */
 #include <linux/nodemask.h>
+#include <linux/export.h>
 #include <linux/mmzone.h>
 #include <linux/init.h>
 #include <linux/smp.h>
index b56c65de384d7f5f2a442dc1eaa24cc18d348645..e4d4a22e8b9430661d28aaa9650fc2f79af6c44b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/seqlock.h>
 #include <linux/jiffies.h>
 #include <linux/sysctl.h>
+#include <linux/topology.h>
 #include <linux/clocksource.h>
 #include <linux/getcpu.h>
 #include <linux/cpu.h>
index 6f164bd5e14d167d417b2f86e5fc8580047ed371..c1d6cd549397ad54dbcb32526c9170e1f590a759 100644 (file)
 #include <asm/pat.h>
 #include <asm/tsc.h>
 #include <asm/iommu.h>
+#include <asm/mach_traps.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 void __init x86_init_pgd_noop(pgd_t *unused) { }
 int __init iommu_init_noop(void) { return 0; }
 void iommu_shutdown_noop(void) { }
+void wallclock_init_noop(void) { }
 
 /*
  * The platform setup functions are preset with the default functions
@@ -97,11 +99,13 @@ static int default_i8042_detect(void) { return 1; };
 
 struct x86_platform_ops x86_platform = {
        .calibrate_tsc                  = native_calibrate_tsc,
+       .wallclock_init                 = wallclock_init_noop,
        .get_wallclock                  = mach_get_cmos_time,
        .set_wallclock                  = mach_set_rtc_mmss,
        .iommu_shutdown                 = iommu_shutdown_noop,
        .is_untracked_pat_range         = is_ISA_range,
        .nmi_init                       = default_nmi_init,
+       .get_nmi_reason                 = default_get_nmi_reason,
        .i8042_detect                   = default_i8042_detect
 };
 
index a0d6bd9ad442f1746bfa66eaabe86641470b7d0f..579a0b51696ac560b1768ae445bb8f2084172f8c 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/mce.h>
 #include <asm/i387.h>
 #include <asm/xcr.h>
+#include <asm/perf_event.h>
 
 #include "trace.h"
 
@@ -118,7 +119,7 @@ module_param(ple_gap, int, S_IRUGO);
 static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
 module_param(ple_window, int, S_IRUGO);
 
-#define NR_AUTOLOAD_MSRS 1
+#define NR_AUTOLOAD_MSRS 8
 #define VMCS02_POOL_SIZE 1
 
 struct vmcs {
@@ -622,6 +623,7 @@ static unsigned long *vmx_msr_bitmap_legacy;
 static unsigned long *vmx_msr_bitmap_longmode;
 
 static bool cpu_has_load_ia32_efer;
+static bool cpu_has_load_perf_global_ctrl;
 
 static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);
 static DEFINE_SPINLOCK(vmx_vpid_lock);
@@ -1191,15 +1193,34 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
        vmcs_write32(EXCEPTION_BITMAP, eb);
 }
 
+static void clear_atomic_switch_msr_special(unsigned long entry,
+               unsigned long exit)
+{
+       vmcs_clear_bits(VM_ENTRY_CONTROLS, entry);
+       vmcs_clear_bits(VM_EXIT_CONTROLS, exit);
+}
+
 static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
 {
        unsigned i;
        struct msr_autoload *m = &vmx->msr_autoload;
 
-       if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
-               vmcs_clear_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
-               vmcs_clear_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
-               return;
+       switch (msr) {
+       case MSR_EFER:
+               if (cpu_has_load_ia32_efer) {
+                       clear_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                                       VM_EXIT_LOAD_IA32_EFER);
+                       return;
+               }
+               break;
+       case MSR_CORE_PERF_GLOBAL_CTRL:
+               if (cpu_has_load_perf_global_ctrl) {
+                       clear_atomic_switch_msr_special(
+                                       VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
+                       return;
+               }
+               break;
        }
 
        for (i = 0; i < m->nr; ++i)
@@ -1215,25 +1236,55 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)
        vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
 }
 
+static void add_atomic_switch_msr_special(unsigned long entry,
+               unsigned long exit, unsigned long guest_val_vmcs,
+               unsigned long host_val_vmcs, u64 guest_val, u64 host_val)
+{
+       vmcs_write64(guest_val_vmcs, guest_val);
+       vmcs_write64(host_val_vmcs, host_val);
+       vmcs_set_bits(VM_ENTRY_CONTROLS, entry);
+       vmcs_set_bits(VM_EXIT_CONTROLS, exit);
+}
+
 static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,
                                  u64 guest_val, u64 host_val)
 {
        unsigned i;
        struct msr_autoload *m = &vmx->msr_autoload;
 
-       if (msr == MSR_EFER && cpu_has_load_ia32_efer) {
-               vmcs_write64(GUEST_IA32_EFER, guest_val);
-               vmcs_write64(HOST_IA32_EFER, host_val);
-               vmcs_set_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER);
-               vmcs_set_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER);
-               return;
+       switch (msr) {
+       case MSR_EFER:
+               if (cpu_has_load_ia32_efer) {
+                       add_atomic_switch_msr_special(VM_ENTRY_LOAD_IA32_EFER,
+                                       VM_EXIT_LOAD_IA32_EFER,
+                                       GUEST_IA32_EFER,
+                                       HOST_IA32_EFER,
+                                       guest_val, host_val);
+                       return;
+               }
+               break;
+       case MSR_CORE_PERF_GLOBAL_CTRL:
+               if (cpu_has_load_perf_global_ctrl) {
+                       add_atomic_switch_msr_special(
+                                       VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL,
+                                       GUEST_IA32_PERF_GLOBAL_CTRL,
+                                       HOST_IA32_PERF_GLOBAL_CTRL,
+                                       guest_val, host_val);
+                       return;
+               }
+               break;
        }
 
        for (i = 0; i < m->nr; ++i)
                if (m->guest[i].index == msr)
                        break;
 
-       if (i == m->nr) {
+       if (i == NR_AUTOLOAD_MSRS) {
+               printk_once(KERN_WARNING"Not enough mst switch entries. "
+                               "Can't add msr %x\n", msr);
+               return;
+       } else if (i == m->nr) {
                ++m->nr;
                vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, m->nr);
                vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, m->nr);
@@ -2455,6 +2506,42 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
                                   VM_EXIT_LOAD_IA32_EFER);
 
+       cpu_has_load_perf_global_ctrl =
+               allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS,
+                               VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
+               && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS,
+                                  VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL);
+
+       /*
+        * Some cpus support VM_ENTRY_(LOAD|SAVE)_IA32_PERF_GLOBAL_CTRL
+        * but due to arrata below it can't be used. Workaround is to use
+        * msr load mechanism to switch IA32_PERF_GLOBAL_CTRL.
+        *
+        * VM Exit May Incorrectly Clear IA32_PERF_GLOBAL_CTRL [34:32]
+        *
+        * AAK155             (model 26)
+        * AAP115             (model 30)
+        * AAT100             (model 37)
+        * BC86,AAY89,BD102   (model 44)
+        * BA97               (model 46)
+        *
+        */
+       if (cpu_has_load_perf_global_ctrl && boot_cpu_data.x86 == 0x6) {
+               switch (boot_cpu_data.x86_model) {
+               case 26:
+               case 30:
+               case 37:
+               case 44:
+               case 46:
+                       cpu_has_load_perf_global_ctrl = false;
+                       printk_once(KERN_WARNING"kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
+                                       "does not work properly. Using workaround\n");
+                       break;
+               default:
+                       break;
+               }
+       }
+
        return 0;
 }
 
@@ -5968,6 +6055,24 @@ static void vmx_cancel_injection(struct kvm_vcpu *vcpu)
        vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
 }
 
+static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
+{
+       int i, nr_msrs;
+       struct perf_guest_switch_msr *msrs;
+
+       msrs = perf_guest_get_msrs(&nr_msrs);
+
+       if (!msrs)
+               return;
+
+       for (i = 0; i < nr_msrs; i++)
+               if (msrs[i].host == msrs[i].guest)
+                       clear_atomic_switch_msr(vmx, msrs[i].msr);
+               else
+                       add_atomic_switch_msr(vmx, msrs[i].msr, msrs[i].guest,
+                                       msrs[i].host);
+}
+
 #ifdef CONFIG_X86_64
 #define R "r"
 #define Q "q"
@@ -6017,6 +6122,8 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
        if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
                vmx_set_interrupt_shadow(vcpu, 0);
 
+       atomic_switch_perf_msrs(vmx);
+
        vmx->__launched = vmx->loaded_vmcs->launched;
        asm(
                /* Store host registers */
index f63da5ef217c40deb6af93e0924246fc68f94008..cf4603ba866f7a10549ee7acdaf6fb2866e464ba 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/lguest_launcher.h>
 #include <linux/virtio_console.h>
 #include <linux/pm.h>
+#include <linux/export.h>
 #include <asm/apic.h>
 #include <asm/lguest.h>
 #include <asm/paravirt.h>
index ea305856151cefc62fccd7f216519bc9d5f2945c..dd74e46828c0fc243740b61a18c2dea654fafb5e 100644 (file)
@@ -201,6 +201,8 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr,
        do {
                VM_BUG_ON(compound_head(page) != head);
                pages[*nr] = page;
+               if (PageTail(page))
+                       get_huge_page_tail(page);
                (*nr)++;
                page++;
                refs++;
index b49962662101a0cf7361f0035e1b017333efc22a..f4f29b19fac5f2cc7c46023ef86c02a66b137e8e 100644 (file)
@@ -45,6 +45,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
        vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
        BUG_ON(!pte_none(*(kmap_pte-idx)));
        set_pte(kmap_pte-idx, mk_pte(page, prot));
+       arch_flush_lazy_mmu_mode();
 
        return (void *)vaddr;
 }
@@ -88,6 +89,7 @@ void __kunmap_atomic(void *kvaddr)
                 */
                kpte_clear_flush(kmap_pte-idx, vaddr);
                kmap_atomic_idx_pop();
+               arch_flush_lazy_mmu_mode();
        }
 #ifdef CONFIG_DEBUG_HIGHMEM
        else {
index cdfe4c54decac05e4943a00e27803f78898b6419..f148cf65267836d66e1fa666d612dca5669950c3 100644 (file)
@@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops);
 extern void op_nmi_exit(void);
 extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth);
 
+static int nmi_timer;
 
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
@@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 #ifdef CONFIG_X86_LOCAL_APIC
        ret = op_nmi_init(ops);
 #endif
+       nmi_timer = (ret != 0);
 #ifdef CONFIG_X86_IO_APIC
-       if (ret < 0)
+       if (nmi_timer)
                ret = op_nmi_timer_init(ops);
 #endif
        ops->backtrace = x86_backtrace;
@@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 void oprofile_arch_exit(void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-       op_nmi_exit();
+       if (!nmi_timer)
+               op_nmi_exit();
 #endif
 }
index 494f2e7ea2b430c86eb9db48d8560c8aae23f508..794b092d01aeb389ec9db257b00c03176066bd06 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
index c89266be6048ec0794d85047eabf7714096cee5d..2c2aeabc2609bdd90fd78d1287d5648016a198d0 100644 (file)
@@ -2,6 +2,7 @@
  * legacy.c - traditional, old school PCI bus probing
  */
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <asm/pci_x86.h>
 
index 28071bb31db7bc1512242589dd10ad5184c976dc..4c61b52191eb293bcaef2cac2380c6114cdaefcf 100644 (file)
@@ -109,7 +109,7 @@ static __init void sdv_serial_fixup(void)
 }
 
 #else
-static inline void sdv_serial_fixup(void);
+static inline void sdv_serial_fixup(void) {};
 #endif
 
 static void __init sdv_arch_setup(void)
index 3ae4128013e6063c5f63523342c9a8a284d35603..c9718a16be158bfa994e774b1b1ad2dd079c68cb 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/spinlock.h>
@@ -322,10 +323,13 @@ static void __init do_add_efi_memmap(void)
                case EFI_UNUSABLE_MEMORY:
                        e820_type = E820_UNUSABLE;
                        break;
+               case EFI_RUNTIME_SERVICES_DATA:
+                       e820_type = E820_RESERVED_EFI;
+                       break;
                default:
                        /*
                         * EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE
-                        * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
+                        * EFI_MEMORY_MAPPED_IO
                         * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
                         */
                        e820_type = E820_RESERVED;
@@ -670,10 +674,21 @@ void __init efi_enter_virtual_mode(void)
                end_pfn = PFN_UP(end);
                if (end_pfn <= max_low_pfn_mapped
                    || (end_pfn > (1UL << (32 - PAGE_SHIFT))
-                       && end_pfn <= max_pfn_mapped))
+                       && end_pfn <= max_pfn_mapped)) {
                        va = __va(md->phys_addr);
-               else
-                       va = efi_ioremap(md->phys_addr, size, md->type);
+
+                       if (!(md->attribute & EFI_MEMORY_WB)) {
+                               addr = (u64) (unsigned long)va;
+                               npages = md->num_pages;
+                               memrange_efi_to_native(&addr, &npages);
+                               set_memory_uc(addr, npages);
+                       }
+               } else {
+                       if (!(md->attribute & EFI_MEMORY_WB))
+                               va = ioremap_nocache(md->phys_addr, size);
+                       else
+                               va = ioremap_cache(md->phys_addr, size);
+               }
 
                md->virt_addr = (u64) (unsigned long) va;
 
@@ -683,13 +698,6 @@ void __init efi_enter_virtual_mode(void)
                        continue;
                }
 
-               if (!(md->attribute & EFI_MEMORY_WB)) {
-                       addr = md->virt_addr;
-                       npages = md->num_pages;
-                       memrange_efi_to_native(&addr, &npages);
-                       set_memory_uc(addr, npages);
-               }
-
                systab = (u64) (unsigned long) efi_phys.systab;
                if (md->phys_addr <= systab && systab < end) {
                        systab += md->virt_addr - md->phys_addr;
index 5cab48ee61a4a6e61e522117d97bbfdabaa95a6d..e36bf714cb7727352c237d6bffa0d838d2c1c08e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/efi.h>
 
 #include <asm/io.h>
+#include <asm/desc.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
index ac3aa54e26546ba5cb4121eba0c58ca00f06ea82..312250c6b2de3078bc47562c6b3034e53e74e4f3 100644 (file)
@@ -80,20 +80,3 @@ void __init efi_call_phys_epilog(void)
        local_irq_restore(efi_flags);
        early_code_mapping_set_exec(0);
 }
-
-void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
-                                u32 type)
-{
-       unsigned long last_map_pfn;
-
-       if (type == EFI_MEMORY_MAPPED_IO)
-               return ioremap(phys_addr, size);
-
-       last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size);
-       if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) {
-               unsigned long top = last_map_pfn << PAGE_SHIFT;
-               efi_ioremap(top, size - (top - phys_addr), type);
-       }
-
-       return (void __iomem *)__va(phys_addr);
-}
index 6ed7afdaf4afa5e194ea75a43c08e84d20c5d915..ad4ec1cb097ecfae17e4a99aed37cf985b03cb78 100644 (file)
@@ -76,6 +76,20 @@ struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
 EXPORT_SYMBOL_GPL(sfi_mrtc_array);
 int sfi_mrtc_num;
 
+static void mrst_power_off(void)
+{
+       if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT)
+               intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 1);
+}
+
+static void mrst_reboot(void)
+{
+       if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT)
+               intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
+       else
+               intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
+}
+
 /* parse all the mtimer info to a static mtimer array */
 static int __init sfi_parse_mtmr(struct sfi_table_header *table)
 {
@@ -187,11 +201,34 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
 static unsigned long __init mrst_calibrate_tsc(void)
 {
        unsigned long flags, fast_calibrate;
-
-       local_irq_save(flags);
-       fast_calibrate = apbt_quick_calibrate();
-       local_irq_restore(flags);
-
+       if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) {
+               u32 lo, hi, ratio, fsb;
+
+               rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+               pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
+               ratio = (hi >> 8) & 0x1f;
+               pr_debug("ratio is %d\n", ratio);
+               if (!ratio) {
+                       pr_err("read a zero ratio, should be incorrect!\n");
+                       pr_err("force tsc ratio to 16 ...\n");
+                       ratio = 16;
+               }
+               rdmsr(MSR_FSB_FREQ, lo, hi);
+               if ((lo & 0x7) == 0x7)
+                       fsb = PENWELL_FSB_FREQ_83SKU;
+               else
+                       fsb = PENWELL_FSB_FREQ_100SKU;
+               fast_calibrate = ratio * fsb;
+               pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
+               lapic_timer_frequency = fsb * 1000 / HZ;
+               /* mark tsc clocksource as reliable */
+               set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
+       } else {
+               local_irq_save(flags);
+               fast_calibrate = apbt_quick_calibrate();
+               local_irq_restore(flags);
+       }
+       
        if (fast_calibrate)
                return fast_calibrate;
 
@@ -242,15 +279,15 @@ static int mrst_i8042_detect(void)
        return 0;
 }
 
-/* Reboot and power off are handled by the SCU on a MID device */
-static void mrst_power_off(void)
-{
-       intel_scu_ipc_simple_command(0xf1, 1);
-}
-
-static void mrst_reboot(void)
+/*
+ * Moorestown does not have external NMI source nor port 0x61 to report
+ * NMI status. The possible NMI sources are from pmu as a result of NMI
+ * watchdog or lock debug. Reading io port 0x61 results in 0xff which
+ * misled NMI handler.
+ */
+static unsigned char mrst_get_nmi_reason(void)
 {
-       intel_scu_ipc_simple_command(0xf1, 0);
+       return 0;
 }
 
 /*
@@ -274,6 +311,8 @@ void __init x86_mrst_early_setup(void)
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
        x86_init.timers.wallclock_init = mrst_rtc_init;
+       x86_platform.get_nmi_reason = mrst_get_nmi_reason;
+
        x86_init.pci.init = pci_mrst_init;
        x86_init.pci.fixup_irqs = x86_init_noop;
 
@@ -448,6 +487,46 @@ static void __init *max7315_platform_data(void *info)
        return max7315;
 }
 
+static void *tca6416_platform_data(void *info)
+{
+       static struct pca953x_platform_data tca6416;
+       struct i2c_board_info *i2c_info = info;
+       int gpio_base, intr;
+       char base_pin_name[SFI_NAME_LEN + 1];
+       char intr_pin_name[SFI_NAME_LEN + 1];
+
+       strcpy(i2c_info->type, "tca6416");
+       strcpy(base_pin_name, "tca6416_base");
+       strcpy(intr_pin_name, "tca6416_int");
+
+       gpio_base = get_gpio_by_name(base_pin_name);
+       intr = get_gpio_by_name(intr_pin_name);
+
+       if (gpio_base == -1)
+               return NULL;
+       tca6416.gpio_base = gpio_base;
+       if (intr != -1) {
+               i2c_info->irq = intr + MRST_IRQ_OFFSET;
+               tca6416.irq_base = gpio_base + MRST_IRQ_OFFSET;
+       } else {
+               i2c_info->irq = -1;
+               tca6416.irq_base = -1;
+       }
+       return &tca6416;
+}
+
+static void *mpu3050_platform_data(void *info)
+{
+       struct i2c_board_info *i2c_info = info;
+       int intr = get_gpio_by_name("mpu3050_int");
+
+       if (intr == -1)
+               return NULL;
+
+       i2c_info->irq = intr + MRST_IRQ_OFFSET;
+       return NULL;
+}
+
 static void __init *emc1403_platform_data(void *info)
 {
        static short intr2nd_pdata;
@@ -608,13 +687,17 @@ static void *msic_ocd_platform_data(void *info)
 }
 
 static const struct devs_id __initconst device_ids[] = {
+       {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data},
        {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data},
+       {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data},
        {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data},
        {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data},
        {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data},
+       {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data},
        {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data},
        {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data},
        {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data},
+       {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data},
 
        /* MSIC subdevices */
        {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data},
index 9281da7d91bd193c221e1f7ba7fc422ff3880dcd..c0ac06da57ac39a4c6d6b687962f6b878005997c 100644 (file)
@@ -70,7 +70,7 @@ static struct mrst_device mrst_devs[] = {
 /* 24 */ { 0x4110, 0 },                        /* Lincroft */
 };
 
-/* n.b. We ignore PCI-id 0x815 in LSS9 b/c MeeGo has no driver for it */
+/* n.b. We ignore PCI-id 0x815 in LSS9 b/c Linux has no driver for it */
 static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0};
 static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803,
                                        0x0804, 0x0805, 0x080f, 0};
index 6d5dbcdd444ac1c2c054f9673c10bec04eb08327..225bd0f0f675395643c47859e61e0e5b6354ecb1 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/sfi.h>
 #include <linux/platform_device.h>
@@ -75,8 +76,8 @@ unsigned long vrtc_get_time(void)
 
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       /* vRTC YEAR reg contains the offset to 1960 */
-       year += 1960;
+       /* vRTC YEAR reg contains the offset to 1972 */
+       year += 1972;
 
        printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d "
                "mon: %d year: %d\n", sec, min, hour, mday, mon, year);
index 6f3855a5a2f783dce23282d5a1fa08bf03d9e4b4..0ce8616c88aef0e297487604d72fef168b3dacec 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/cs5535.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 #include <linux/pm.h>
 #include <linux/mfd/core.h>
 #include <linux/suspend.h>
index 8bc57baaa9ad506d1dc486322f137fae0d858384..766612137a62d55c6b328f1b3c30807d298a50ac 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/efi.h>
+#include <linux/export.h>
 #include <asm/efi.h>
 #include <linux/io.h>
 #include <asm/uv/bios.h>
index 87bb35e34ef175d0a8b3beedd5c4d76010c9169d..f10c0afa1cb4ceb6fdd34cd0f5e2a352f192cad5 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/suspend.h>
+#include <linux/export.h>
 #include <linux/smp.h>
 
 #include <asm/pgtable.h>
index 21bebe63df6660d08e0bd50ac6b8cb2486b76355..1d97bd84b6fbcfe684b559cf271f7fe72d75f92b 100644 (file)
@@ -57,9 +57,6 @@ config ARCH_HAS_SC_SIGNALS
 config ARCH_REUSE_HOST_VSYSCALL_AREA
        def_bool !64BIT
 
-config SMP_BROKEN
-       def_bool 64BIT
-
 config GENERIC_HWEIGHT
        def_bool y
 
index 118c143a9cb49ca03ced909f1a0744902889d701..2c32df6fe23167a6ca3955fdac07444f6f2fbc34 100644 (file)
@@ -11,7 +11,7 @@
 #endif
 
 #define KSTK_EIP(tsk) KSTK_REG(tsk, HOST_IP)
-#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_IP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_SP)
 #define KSTK_EBP(tsk) KSTK_REG(tsk, HOST_BP)
 
 #define ARCH_IS_STACKGROW(address) \
index 69527688f7940eebc63735a41f3431bdcbf280d6..c5ffb6ac870773d53e15857dc50749ab661ffc1d 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/fb.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 
 int fb_is_primary_device(struct fb_info *info)
 {
index da8afd576a6b7d161e3e81f2997912a73fec3d31..1f928659c338e6e5cfcf6386446f087f41f1e22f 100644 (file)
@@ -1356,7 +1356,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
        int cpu = (long)hcpu;
        switch (action) {
        case CPU_UP_PREPARE:
-               per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
+               xen_vcpu_setup(cpu);
                if (xen_have_vector_callback)
                        xen_init_lock_cpu(cpu);
                break;
@@ -1386,7 +1386,6 @@ static void __init xen_hvm_guest_init(void)
        xen_hvm_smp_init();
        register_cpu_notifier(&xen_hvm_cpu_notifier);
        xen_unplug_emulated_devices();
-       have_vcpu_info_placement = 0;
        x86_init.irqs.intr_init = xen_init_IRQ;
        xen_hvm_init_time_ops();
        xen_hvm_init_mmu_ops();
index 49ba9b5224d1a71da3b5d3dc139ca726f41bcd5e..5a40d24ba3316b85b42e5ef5d00280b89a2033b9 100644 (file)
@@ -71,7 +71,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
 
        if (shared == NULL) {
                struct vm_struct *area =
-                       xen_alloc_vm_area(PAGE_SIZE * max_nr_gframes);
+                       alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
                BUG_ON(area == NULL);
                shared = area->addr;
                *__shared = shared;
index 38d0af4fefec19f52d5e724c8f08102d391dc2e6..1093f80c162d24e5e455d760a5b77e1b16f800c5 100644 (file)
@@ -410,6 +410,6 @@ void __init xen_arch_setup(void)
 #endif
        disable_cpuidle();
        boot_option_idle_override = IDLE_HALT;
-
+       WARN_ON(set_pm_idle_to_default());
        fiddle_vdso();
 }
index 163b4679556e300615095cc995fa0eac6ea7cf45..0296a95225017912cec06b9794683e62b20a5382 100644 (file)
@@ -201,8 +201,22 @@ static unsigned long xen_get_wallclock(void)
 
 static int xen_set_wallclock(unsigned long now)
 {
+       struct xen_platform_op op;
+       int rc;
+
        /* do nothing for domU */
-       return -1;
+       if (!xen_initial_domain())
+               return -1;
+
+       op.cmd = XENPF_settime;
+       op.u.settime.secs = now;
+       op.u.settime.nsecs = 0;
+       op.u.settime.system_time = xen_clocksource_read();
+
+       rc = HYPERVISOR_dom0_op(&op);
+       WARN(rc != 0, "XENPF_settime failed: now=%ld\n", now);
+
+       return rc;
 }
 
 static struct clocksource xen_clocksource __read_mostly = {
index 8f630cec906e83f35b85df1a7437997dab9aae3d..27886935804966b8246c3495898cdaec1088b9f6 100644 (file)
@@ -1645,11 +1645,12 @@ static void blkiocg_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
        struct io_context *ioc;
 
-       task_lock(tsk);
-       ioc = tsk->io_context;
-       if (ioc)
-               ioc->cgroup_changed = 1;
-       task_unlock(tsk);
+       /* we don't lose anything even if ioc allocation fails */
+       ioc = get_task_io_context(tsk, GFP_ATOMIC, NUMA_NO_NODE);
+       if (ioc) {
+               ioc_cgroup_changed(ioc);
+               put_io_context(ioc, NULL);
+       }
 }
 
 void blkio_policy_register(struct blkio_policy_type *blkiop)
index f43c8a5840ae488131dbf395d5eaf96e2fea876d..8fbdac7010bb425fb025f156a1fe4210e58428b9 100644 (file)
@@ -39,6 +39,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap);
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
 EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
 
+DEFINE_IDA(blk_queue_ida);
+
 /*
  * For the allocated request tables
  */
@@ -358,7 +360,8 @@ EXPORT_SYMBOL(blk_put_queue);
 void blk_drain_queue(struct request_queue *q, bool drain_all)
 {
        while (true) {
-               int nr_rqs;
+               bool drain = false;
+               int i;
 
                spin_lock_irq(q->queue_lock);
 
@@ -368,14 +371,25 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)
 
                __blk_run_queue(q);
 
-               if (drain_all)
-                       nr_rqs = q->rq.count[0] + q->rq.count[1];
-               else
-                       nr_rqs = q->rq.elvpriv;
+               drain |= q->rq.elvpriv;
+
+               /*
+                * Unfortunately, requests are queued at and tracked from
+                * multiple places and there's no single counter which can
+                * be drained.  Check all the queues and counters.
+                */
+               if (drain_all) {
+                       drain |= !list_empty(&q->queue_head);
+                       for (i = 0; i < 2; i++) {
+                               drain |= q->rq.count[i];
+                               drain |= q->in_flight[i];
+                               drain |= !list_empty(&q->flush_queue[i]);
+                       }
+               }
 
                spin_unlock_irq(q->queue_lock);
 
-               if (!nr_rqs)
+               if (!drain)
                        break;
                msleep(10);
        }
@@ -462,6 +476,10 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        if (!q)
                return NULL;
 
+       q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL);
+       if (q->id < 0)
+               goto fail_q;
+
        q->backing_dev_info.ra_pages =
                        (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
        q->backing_dev_info.state = 0;
@@ -469,20 +487,17 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        q->backing_dev_info.name = "block";
 
        err = bdi_init(&q->backing_dev_info);
-       if (err) {
-               kmem_cache_free(blk_requestq_cachep, q);
-               return NULL;
-       }
+       if (err)
+               goto fail_id;
 
-       if (blk_throtl_init(q)) {
-               kmem_cache_free(blk_requestq_cachep, q);
-               return NULL;
-       }
+       if (blk_throtl_init(q))
+               goto fail_id;
 
        setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
                    laptop_mode_timer_fn, (unsigned long) q);
        setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
        INIT_LIST_HEAD(&q->timeout_list);
+       INIT_LIST_HEAD(&q->icq_list);
        INIT_LIST_HEAD(&q->flush_queue[0]);
        INIT_LIST_HEAD(&q->flush_queue[1]);
        INIT_LIST_HEAD(&q->flush_data_in_flight);
@@ -500,6 +515,12 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        q->queue_lock = &q->__queue_lock;
 
        return q;
+
+fail_id:
+       ida_simple_remove(&blk_queue_ida, q->id);
+fail_q:
+       kmem_cache_free(blk_requestq_cachep, q);
+       return NULL;
 }
 EXPORT_SYMBOL(blk_alloc_queue_node);
 
@@ -606,26 +627,31 @@ blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
 }
 EXPORT_SYMBOL(blk_init_allocated_queue_node);
 
-int blk_get_queue(struct request_queue *q)
+bool blk_get_queue(struct request_queue *q)
 {
-       if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
-               kobject_get(&q->kobj);
-               return 0;
+       if (likely(!blk_queue_dead(q))) {
+               __blk_get_queue(q);
+               return true;
        }
 
-       return 1;
+       return false;
 }
 EXPORT_SYMBOL(blk_get_queue);
 
 static inline void blk_free_request(struct request_queue *q, struct request *rq)
 {
-       if (rq->cmd_flags & REQ_ELVPRIV)
+       if (rq->cmd_flags & REQ_ELVPRIV) {
                elv_put_request(q, rq);
+               if (rq->elv.icq)
+                       put_io_context(rq->elv.icq->ioc, q);
+       }
+
        mempool_free(rq, q->rq.rq_pool);
 }
 
 static struct request *
-blk_alloc_request(struct request_queue *q, unsigned int flags, gfp_t gfp_mask)
+blk_alloc_request(struct request_queue *q, struct io_cq *icq,
+                 unsigned int flags, gfp_t gfp_mask)
 {
        struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
 
@@ -636,10 +662,15 @@ blk_alloc_request(struct request_queue *q, unsigned int flags, gfp_t gfp_mask)
 
        rq->cmd_flags = flags | REQ_ALLOCED;
 
-       if ((flags & REQ_ELVPRIV) &&
-           unlikely(elv_set_request(q, rq, gfp_mask))) {
-               mempool_free(rq, q->rq.rq_pool);
-               return NULL;
+       if (flags & REQ_ELVPRIV) {
+               rq->elv.icq = icq;
+               if (unlikely(elv_set_request(q, rq, gfp_mask))) {
+                       mempool_free(rq, q->rq.rq_pool);
+                       return NULL;
+               }
+               /* @rq->elv.icq holds on to io_context until @rq is freed */
+               if (icq)
+                       get_io_context(icq->ioc);
        }
 
        return rq;
@@ -751,11 +782,17 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
 {
        struct request *rq = NULL;
        struct request_list *rl = &q->rq;
-       struct io_context *ioc = NULL;
+       struct elevator_type *et;
+       struct io_context *ioc;
+       struct io_cq *icq = NULL;
        const bool is_sync = rw_is_sync(rw_flags) != 0;
+       bool retried = false;
        int may_queue;
+retry:
+       et = q->elevator->type;
+       ioc = current->io_context;
 
-       if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
+       if (unlikely(blk_queue_dead(q)))
                return NULL;
 
        may_queue = elv_may_queue(q, rw_flags);
@@ -764,7 +801,20 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
 
        if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
                if (rl->count[is_sync]+1 >= q->nr_requests) {
-                       ioc = current_io_context(GFP_ATOMIC, q->node);
+                       /*
+                        * We want ioc to record batching state.  If it's
+                        * not already there, creating a new one requires
+                        * dropping queue_lock, which in turn requires
+                        * retesting conditions to avoid queue hang.
+                        */
+                       if (!ioc && !retried) {
+                               spin_unlock_irq(q->queue_lock);
+                               create_io_context(current, gfp_mask, q->node);
+                               spin_lock_irq(q->queue_lock);
+                               retried = true;
+                               goto retry;
+                       }
+
                        /*
                         * The queue will fill after this allocation, so set
                         * it as full, and mark this process as "batching".
@@ -800,17 +850,36 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
        rl->count[is_sync]++;
        rl->starved[is_sync] = 0;
 
+       /*
+        * Decide whether the new request will be managed by elevator.  If
+        * so, mark @rw_flags and increment elvpriv.  Non-zero elvpriv will
+        * prevent the current elevator from being destroyed until the new
+        * request is freed.  This guarantees icq's won't be destroyed and
+        * makes creating new ones safe.
+        *
+        * Also, lookup icq while holding queue_lock.  If it doesn't exist,
+        * it will be created after releasing queue_lock.
+        */
        if (blk_rq_should_init_elevator(bio) &&
            !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags)) {
                rw_flags |= REQ_ELVPRIV;
                rl->elvpriv++;
+               if (et->icq_cache && ioc)
+                       icq = ioc_lookup_icq(ioc, q);
        }
 
        if (blk_queue_io_stat(q))
                rw_flags |= REQ_IO_STAT;
        spin_unlock_irq(q->queue_lock);
 
-       rq = blk_alloc_request(q, rw_flags, gfp_mask);
+       /* create icq if missing */
+       if (unlikely(et->icq_cache && !icq))
+               icq = ioc_create_icq(q, gfp_mask);
+
+       /* rqs are guaranteed to have icq on elv_set_request() if requested */
+       if (likely(!et->icq_cache || icq))
+               rq = blk_alloc_request(q, icq, rw_flags, gfp_mask);
+
        if (unlikely(!rq)) {
                /*
                 * Allocation failed presumably due to memory. Undo anything
@@ -872,10 +941,9 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
        rq = get_request(q, rw_flags, bio, GFP_NOIO);
        while (!rq) {
                DEFINE_WAIT(wait);
-               struct io_context *ioc;
                struct request_list *rl = &q->rq;
 
-               if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
+               if (unlikely(blk_queue_dead(q)))
                        return NULL;
 
                prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
@@ -892,8 +960,8 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
                 * up to a big batch of them for a small period time.
                 * See ioc_batching, ioc_set_batching
                 */
-               ioc = current_io_context(GFP_NOIO, q->node);
-               ioc_set_batching(q, ioc);
+               create_io_context(current, GFP_NOIO, q->node);
+               ioc_set_batching(q, current->io_context);
 
                spin_lock_irq(q->queue_lock);
                finish_wait(&rl->wait[is_sync], &wait);
@@ -1010,54 +1078,6 @@ static void add_acct_request(struct request_queue *q, struct request *rq,
        __elv_add_request(q, rq, where);
 }
 
-/**
- * blk_insert_request - insert a special request into a request queue
- * @q:         request queue where request should be inserted
- * @rq:                request to be inserted
- * @at_head:   insert request at head or tail of queue
- * @data:      private data
- *
- * Description:
- *    Many block devices need to execute commands asynchronously, so they don't
- *    block the whole kernel from preemption during request execution.  This is
- *    accomplished normally by inserting aritficial requests tagged as
- *    REQ_TYPE_SPECIAL in to the corresponding request queue, and letting them
- *    be scheduled for actual execution by the request queue.
- *
- *    We have the option of inserting the head or the tail of the queue.
- *    Typically we use the tail for new ioctls and so forth.  We use the head
- *    of the queue for things like a QUEUE_FULL message from a device, or a
- *    host that is unable to accept a particular command.
- */
-void blk_insert_request(struct request_queue *q, struct request *rq,
-                       int at_head, void *data)
-{
-       int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
-       unsigned long flags;
-
-       /*
-        * tell I/O scheduler that this isn't a regular read/write (ie it
-        * must not attempt merges on this) and that it acts as a soft
-        * barrier
-        */
-       rq->cmd_type = REQ_TYPE_SPECIAL;
-
-       rq->special = data;
-
-       spin_lock_irqsave(q->queue_lock, flags);
-
-       /*
-        * If command is tagged, release the tag
-        */
-       if (blk_rq_tagged(rq))
-               blk_queue_end_tag(q, rq);
-
-       add_acct_request(q, rq, where);
-       __blk_run_queue(q);
-       spin_unlock_irqrestore(q->queue_lock, flags);
-}
-EXPORT_SYMBOL(blk_insert_request);
-
 static void part_round_stats_single(int cpu, struct hd_struct *part,
                                    unsigned long now)
 {
@@ -1379,15 +1399,19 @@ get_rq:
                 */
                if (list_empty(&plug->list))
                        trace_block_plug(q);
-               else if (!plug->should_sort) {
-                       struct request *__rq;
+               else {
+                       if (!plug->should_sort) {
+                               struct request *__rq;
 
-                       __rq = list_entry_rq(plug->list.prev);
-                       if (__rq->q != q)
-                               plug->should_sort = 1;
+                               __rq = list_entry_rq(plug->list.prev);
+                               if (__rq->q != q)
+                                       plug->should_sort = 1;
+                       }
+                       if (request_count >= BLK_MAX_REQUEST_COUNT) {
+                               blk_flush_plug_list(plug, false);
+                               trace_block_plug(q);
+                       }
                }
-               if (request_count >= BLK_MAX_REQUEST_COUNT)
-                       blk_flush_plug_list(plug, false);
                list_add_tail(&req->queuelist, &plug->list);
                drive_stat_acct(req, 1);
        } else {
@@ -1763,6 +1787,10 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
                return -EIO;
 
        spin_lock_irqsave(q->queue_lock, flags);
+       if (unlikely(blk_queue_dead(q))) {
+               spin_unlock_irqrestore(q->queue_lock, flags);
+               return -ENODEV;
+       }
 
        /*
         * Submitting request must be dequeued before calling this function
@@ -2736,6 +2764,14 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth,
 {
        trace_block_unplug(q, depth, !from_schedule);
 
+       /*
+        * Don't mess with dead queue.
+        */
+       if (unlikely(blk_queue_dead(q))) {
+               spin_unlock(q->queue_lock);
+               return;
+       }
+
        /*
         * If we are punting this to kblockd, then we can safely drop
         * the queue_lock before waking kblockd (which needs to take
@@ -2812,6 +2848,15 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
                        depth = 0;
                        spin_lock(q->queue_lock);
                }
+
+               /*
+                * Short-circuit if @q is dead
+                */
+               if (unlikely(blk_queue_dead(q))) {
+                       __blk_end_request_all(rq, -ENODEV);
+                       continue;
+               }
+
                /*
                 * rq is already accounted, so use raw insert
                 */
index a1ebceb332f963ee366aa7ebed60d69c4e1c11cb..fb2cbd551621d3f23be57210534ed98417d01489 100644 (file)
@@ -50,7 +50,11 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 {
        int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
 
-       if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
+       WARN_ON(irqs_disabled());
+       spin_lock_irq(q->queue_lock);
+
+       if (unlikely(blk_queue_dead(q))) {
+               spin_unlock_irq(q->queue_lock);
                rq->errors = -ENXIO;
                if (rq->end_io)
                        rq->end_io(rq, rq->errors);
@@ -59,8 +63,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 
        rq->rq_disk = bd_disk;
        rq->end_io = done;
-       WARN_ON(irqs_disabled());
-       spin_lock_irq(q->queue_lock);
        __elv_add_request(q, rq, where);
        __blk_run_queue(q);
        /* the queue is stopped so it won't be run */
index 129b9e209a3b46dcf06ab36c0629e632e9b75035..da2a818c3a922037026988fffd8ab7c9ad3f9008 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mempool.h>
 #include <linux/bio.h>
 #include <linux/scatterlist.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include "blk.h"
index 6f9bbd978653e631f4fdd5cb36eee160d6045031..33fae7df16a016d7ccbb0ccb6b3f78e47d9f0765 100644 (file)
  */
 static struct kmem_cache *iocontext_cachep;
 
-static void cfq_dtor(struct io_context *ioc)
+/**
+ * get_io_context - increment reference count to io_context
+ * @ioc: io_context to get
+ *
+ * Increment reference count to @ioc.
+ */
+void get_io_context(struct io_context *ioc)
+{
+       BUG_ON(atomic_long_read(&ioc->refcount) <= 0);
+       atomic_long_inc(&ioc->refcount);
+}
+EXPORT_SYMBOL(get_io_context);
+
+/*
+ * Releasing ioc may nest into another put_io_context() leading to nested
+ * fast path release.  As the ioc's can't be the same, this is okay but
+ * makes lockdep whine.  Keep track of nesting and use it as subclass.
+ */
+#ifdef CONFIG_LOCKDEP
+#define ioc_release_depth(q)           ((q) ? (q)->ioc_release_depth : 0)
+#define ioc_release_depth_inc(q)       (q)->ioc_release_depth++
+#define ioc_release_depth_dec(q)       (q)->ioc_release_depth--
+#else
+#define ioc_release_depth(q)           0
+#define ioc_release_depth_inc(q)       do { } while (0)
+#define ioc_release_depth_dec(q)       do { } while (0)
+#endif
+
+static void icq_free_icq_rcu(struct rcu_head *head)
+{
+       struct io_cq *icq = container_of(head, struct io_cq, __rcu_head);
+
+       kmem_cache_free(icq->__rcu_icq_cache, icq);
+}
+
+/*
+ * Exit and free an icq.  Called with both ioc and q locked.
+ */
+static void ioc_exit_icq(struct io_cq *icq)
 {
-       if (!hlist_empty(&ioc->cic_list)) {
-               struct cfq_io_context *cic;
+       struct io_context *ioc = icq->ioc;
+       struct request_queue *q = icq->q;
+       struct elevator_type *et = q->elevator->type;
+
+       lockdep_assert_held(&ioc->lock);
+       lockdep_assert_held(q->queue_lock);
+
+       radix_tree_delete(&ioc->icq_tree, icq->q->id);
+       hlist_del_init(&icq->ioc_node);
+       list_del_init(&icq->q_node);
+
+       /*
+        * Both setting lookup hint to and clearing it from @icq are done
+        * under queue_lock.  If it's not pointing to @icq now, it never
+        * will.  Hint assignment itself can race safely.
+        */
+       if (rcu_dereference_raw(ioc->icq_hint) == icq)
+               rcu_assign_pointer(ioc->icq_hint, NULL);
 
-               cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
-                                                               cic_list);
-               cic->dtor(ioc);
+       if (et->ops.elevator_exit_icq_fn) {
+               ioc_release_depth_inc(q);
+               et->ops.elevator_exit_icq_fn(icq);
+               ioc_release_depth_dec(q);
        }
+
+       /*
+        * @icq->q might have gone away by the time RCU callback runs
+        * making it impossible to determine icq_cache.  Record it in @icq.
+        */
+       icq->__rcu_icq_cache = et->icq_cache;
+       call_rcu(&icq->__rcu_head, icq_free_icq_rcu);
 }
 
 /*
- * IO Context helper functions. put_io_context() returns 1 if there are no
- * more users of this io context, 0 otherwise.
+ * Slow path for ioc release in put_io_context().  Performs double-lock
+ * dancing to unlink all icq's and then frees ioc.
  */
-int put_io_context(struct io_context *ioc)
+static void ioc_release_fn(struct work_struct *work)
 {
-       if (ioc == NULL)
-               return 1;
+       struct io_context *ioc = container_of(work, struct io_context,
+                                             release_work);
+       struct request_queue *last_q = NULL;
 
-       BUG_ON(atomic_long_read(&ioc->refcount) == 0);
+       spin_lock_irq(&ioc->lock);
 
-       if (atomic_long_dec_and_test(&ioc->refcount)) {
-               rcu_read_lock();
-               cfq_dtor(ioc);
-               rcu_read_unlock();
+       while (!hlist_empty(&ioc->icq_list)) {
+               struct io_cq *icq = hlist_entry(ioc->icq_list.first,
+                                               struct io_cq, ioc_node);
+               struct request_queue *this_q = icq->q;
 
-               kmem_cache_free(iocontext_cachep, ioc);
-               return 1;
+               if (this_q != last_q) {
+                       /*
+                        * Need to switch to @this_q.  Once we release
+                        * @ioc->lock, it can go away along with @cic.
+                        * Hold on to it.
+                        */
+                       __blk_get_queue(this_q);
+
+                       /*
+                        * blk_put_queue() might sleep thanks to kobject
+                        * idiocy.  Always release both locks, put and
+                        * restart.
+                        */
+                       if (last_q) {
+                               spin_unlock(last_q->queue_lock);
+                               spin_unlock_irq(&ioc->lock);
+                               blk_put_queue(last_q);
+                       } else {
+                               spin_unlock_irq(&ioc->lock);
+                       }
+
+                       last_q = this_q;
+                       spin_lock_irq(this_q->queue_lock);
+                       spin_lock(&ioc->lock);
+                       continue;
+               }
+               ioc_exit_icq(icq);
        }
-       return 0;
+
+       if (last_q) {
+               spin_unlock(last_q->queue_lock);
+               spin_unlock_irq(&ioc->lock);
+               blk_put_queue(last_q);
+       } else {
+               spin_unlock_irq(&ioc->lock);
+       }
+
+       kmem_cache_free(iocontext_cachep, ioc);
 }
-EXPORT_SYMBOL(put_io_context);
 
-static void cfq_exit(struct io_context *ioc)
+/**
+ * put_io_context - put a reference of io_context
+ * @ioc: io_context to put
+ * @locked_q: request_queue the caller is holding queue_lock of (hint)
+ *
+ * Decrement reference count of @ioc and release it if the count reaches
+ * zero.  If the caller is holding queue_lock of a queue, it can indicate
+ * that with @locked_q.  This is an optimization hint and the caller is
+ * allowed to pass in %NULL even when it's holding a queue_lock.
+ */
+void put_io_context(struct io_context *ioc, struct request_queue *locked_q)
 {
-       rcu_read_lock();
+       struct request_queue *last_q = locked_q;
+       unsigned long flags;
+
+       if (ioc == NULL)
+               return;
+
+       BUG_ON(atomic_long_read(&ioc->refcount) <= 0);
+       if (locked_q)
+               lockdep_assert_held(locked_q->queue_lock);
+
+       if (!atomic_long_dec_and_test(&ioc->refcount))
+               return;
+
+       /*
+        * Destroy @ioc.  This is a bit messy because icq's are chained
+        * from both ioc and queue, and ioc->lock nests inside queue_lock.
+        * The inner ioc->lock should be held to walk our icq_list and then
+        * for each icq the outer matching queue_lock should be grabbed.
+        * ie. We need to do reverse-order double lock dancing.
+        *
+        * Another twist is that we are often called with one of the
+        * matching queue_locks held as indicated by @locked_q, which
+        * prevents performing double-lock dance for other queues.
+        *
+        * So, we do it in two stages.  The fast path uses the queue_lock
+        * the caller is holding and, if other queues need to be accessed,
+        * uses trylock to avoid introducing locking dependency.  This can
+        * handle most cases, especially if @ioc was performing IO on only
+        * single device.
+        *
+        * If trylock doesn't cut it, we defer to @ioc->release_work which
+        * can do all the double-locking dancing.
+        */
+       spin_lock_irqsave_nested(&ioc->lock, flags,
+                                ioc_release_depth(locked_q));
+
+       while (!hlist_empty(&ioc->icq_list)) {
+               struct io_cq *icq = hlist_entry(ioc->icq_list.first,
+                                               struct io_cq, ioc_node);
+               struct request_queue *this_q = icq->q;
 
-       if (!hlist_empty(&ioc->cic_list)) {
-               struct cfq_io_context *cic;
+               if (this_q != last_q) {
+                       if (last_q && last_q != locked_q)
+                               spin_unlock(last_q->queue_lock);
+                       last_q = NULL;
 
-               cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
-                                                               cic_list);
-               cic->exit(ioc);
+                       if (!spin_trylock(this_q->queue_lock))
+                               break;
+                       last_q = this_q;
+                       continue;
+               }
+               ioc_exit_icq(icq);
        }
-       rcu_read_unlock();
+
+       if (last_q && last_q != locked_q)
+               spin_unlock(last_q->queue_lock);
+
+       spin_unlock_irqrestore(&ioc->lock, flags);
+
+       /* if no icq is left, we're done; otherwise, kick release_work */
+       if (hlist_empty(&ioc->icq_list))
+               kmem_cache_free(iocontext_cachep, ioc);
+       else
+               schedule_work(&ioc->release_work);
 }
+EXPORT_SYMBOL(put_io_context);
 
 /* Called by the exiting task */
 void exit_io_context(struct task_struct *task)
 {
        struct io_context *ioc;
 
+       /* PF_EXITING prevents new io_context from being attached to @task */
+       WARN_ON_ONCE(!(current->flags & PF_EXITING));
+
        task_lock(task);
        ioc = task->io_context;
        task->io_context = NULL;
        task_unlock(task);
 
-       if (atomic_dec_and_test(&ioc->nr_tasks))
-               cfq_exit(ioc);
+       atomic_dec(&ioc->nr_tasks);
+       put_io_context(ioc, NULL);
+}
+
+/**
+ * ioc_clear_queue - break any ioc association with the specified queue
+ * @q: request_queue being cleared
+ *
+ * Walk @q->icq_list and exit all io_cq's.  Must be called with @q locked.
+ */
+void ioc_clear_queue(struct request_queue *q)
+{
+       lockdep_assert_held(q->queue_lock);
 
-       put_io_context(ioc);
+       while (!list_empty(&q->icq_list)) {
+               struct io_cq *icq = list_entry(q->icq_list.next,
+                                              struct io_cq, q_node);
+               struct io_context *ioc = icq->ioc;
+
+               spin_lock(&ioc->lock);
+               ioc_exit_icq(icq);
+               spin_unlock(&ioc->lock);
+       }
 }
 
-struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
+void create_io_context_slowpath(struct task_struct *task, gfp_t gfp_flags,
+                               int node)
 {
        struct io_context *ioc;
 
-       ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node);
-       if (ioc) {
-               atomic_long_set(&ioc->refcount, 1);
-               atomic_set(&ioc->nr_tasks, 1);
-               spin_lock_init(&ioc->lock);
-               ioc->ioprio_changed = 0;
-               ioc->ioprio = 0;
-               ioc->last_waited = 0; /* doesn't matter... */
-               ioc->nr_batch_requests = 0; /* because this is 0 */
-               INIT_RADIX_TREE(&ioc->radix_root, GFP_ATOMIC | __GFP_HIGH);
-               INIT_HLIST_HEAD(&ioc->cic_list);
-               ioc->ioc_data = NULL;
-#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
-               ioc->cgroup_changed = 0;
-#endif
-       }
+       ioc = kmem_cache_alloc_node(iocontext_cachep, gfp_flags | __GFP_ZERO,
+                                   node);
+       if (unlikely(!ioc))
+               return;
 
-       return ioc;
+       /* initialize */
+       atomic_long_set(&ioc->refcount, 1);
+       atomic_set(&ioc->nr_tasks, 1);
+       spin_lock_init(&ioc->lock);
+       INIT_RADIX_TREE(&ioc->icq_tree, GFP_ATOMIC | __GFP_HIGH);
+       INIT_HLIST_HEAD(&ioc->icq_list);
+       INIT_WORK(&ioc->release_work, ioc_release_fn);
+
+       /*
+        * Try to install.  ioc shouldn't be installed if someone else
+        * already did or @task, which isn't %current, is exiting.  Note
+        * that we need to allow ioc creation on exiting %current as exit
+        * path may issue IOs from e.g. exit_files().  The exit path is
+        * responsible for not issuing IO after exit_io_context().
+        */
+       task_lock(task);
+       if (!task->io_context &&
+           (task == current || !(task->flags & PF_EXITING)))
+               task->io_context = ioc;
+       else
+               kmem_cache_free(iocontext_cachep, ioc);
+       task_unlock(task);
 }
 
-/*
- * If the current task has no IO context then create one and initialise it.
- * Otherwise, return its existing IO context.
+/**
+ * get_task_io_context - get io_context of a task
+ * @task: task of interest
+ * @gfp_flags: allocation flags, used if allocation is necessary
+ * @node: allocation node, used if allocation is necessary
  *
- * This returned IO context doesn't have a specifically elevated refcount,
- * but since the current task itself holds a reference, the context can be
- * used in general code, so long as it stays within `current` context.
+ * Return io_context of @task.  If it doesn't exist, it is created with
+ * @gfp_flags and @node.  The returned io_context has its reference count
+ * incremented.
+ *
+ * This function always goes through task_lock() and it's better to use
+ * %current->io_context + get_io_context() for %current.
  */
-struct io_context *current_io_context(gfp_t gfp_flags, int node)
+struct io_context *get_task_io_context(struct task_struct *task,
+                                      gfp_t gfp_flags, int node)
 {
-       struct task_struct *tsk = current;
-       struct io_context *ret;
-
-       ret = tsk->io_context;
-       if (likely(ret))
-               return ret;
-
-       ret = alloc_io_context(gfp_flags, node);
-       if (ret) {
-               /* make sure set_task_ioprio() sees the settings above */
-               smp_wmb();
-               tsk->io_context = ret;
-       }
+       struct io_context *ioc;
 
-       return ret;
+       might_sleep_if(gfp_flags & __GFP_WAIT);
+
+       do {
+               task_lock(task);
+               ioc = task->io_context;
+               if (likely(ioc)) {
+                       get_io_context(ioc);
+                       task_unlock(task);
+                       return ioc;
+               }
+               task_unlock(task);
+       } while (create_io_context(task, gfp_flags, node));
+
+       return NULL;
 }
+EXPORT_SYMBOL(get_task_io_context);
 
-/*
- * If the current task has no IO context then create one and initialise it.
- * If it does have a context, take a ref on it.
+/**
+ * ioc_lookup_icq - lookup io_cq from ioc
+ * @ioc: the associated io_context
+ * @q: the associated request_queue
  *
- * This is always called in the context of the task which submitted the I/O.
+ * Look up io_cq associated with @ioc - @q pair from @ioc.  Must be called
+ * with @q->queue_lock held.
  */
-struct io_context *get_io_context(gfp_t gfp_flags, int node)
+struct io_cq *ioc_lookup_icq(struct io_context *ioc, struct request_queue *q)
 {
-       struct io_context *ioc = NULL;
+       struct io_cq *icq;
+
+       lockdep_assert_held(q->queue_lock);
 
        /*
-        * Check for unlikely race with exiting task. ioc ref count is
-        * zero when ioc is being detached.
+        * icq's are indexed from @ioc using radix tree and hint pointer,
+        * both of which are protected with RCU.  All removals are done
+        * holding both q and ioc locks, and we're holding q lock - if we
+        * find a icq which points to us, it's guaranteed to be valid.
         */
-       do {
-               ioc = current_io_context(gfp_flags, node);
-               if (unlikely(!ioc))
-                       break;
-       } while (!atomic_long_inc_not_zero(&ioc->refcount));
+       rcu_read_lock();
+       icq = rcu_dereference(ioc->icq_hint);
+       if (icq && icq->q == q)
+               goto out;
 
-       return ioc;
+       icq = radix_tree_lookup(&ioc->icq_tree, q->id);
+       if (icq && icq->q == q)
+               rcu_assign_pointer(ioc->icq_hint, icq); /* allowed to race */
+       else
+               icq = NULL;
+out:
+       rcu_read_unlock();
+       return icq;
 }
-EXPORT_SYMBOL(get_io_context);
+EXPORT_SYMBOL(ioc_lookup_icq);
+
+/**
+ * ioc_create_icq - create and link io_cq
+ * @q: request_queue of interest
+ * @gfp_mask: allocation mask
+ *
+ * Make sure io_cq linking %current->io_context and @q exists.  If either
+ * io_context and/or icq don't exist, they will be created using @gfp_mask.
+ *
+ * The caller is responsible for ensuring @ioc won't go away and @q is
+ * alive and will stay alive until this function returns.
+ */
+struct io_cq *ioc_create_icq(struct request_queue *q, gfp_t gfp_mask)
+{
+       struct elevator_type *et = q->elevator->type;
+       struct io_context *ioc;
+       struct io_cq *icq;
+
+       /* allocate stuff */
+       ioc = create_io_context(current, gfp_mask, q->node);
+       if (!ioc)
+               return NULL;
+
+       icq = kmem_cache_alloc_node(et->icq_cache, gfp_mask | __GFP_ZERO,
+                                   q->node);
+       if (!icq)
+               return NULL;
+
+       if (radix_tree_preload(gfp_mask) < 0) {
+               kmem_cache_free(et->icq_cache, icq);
+               return NULL;
+       }
+
+       icq->ioc = ioc;
+       icq->q = q;
+       INIT_LIST_HEAD(&icq->q_node);
+       INIT_HLIST_NODE(&icq->ioc_node);
+
+       /* lock both q and ioc and try to link @icq */
+       spin_lock_irq(q->queue_lock);
+       spin_lock(&ioc->lock);
+
+       if (likely(!radix_tree_insert(&ioc->icq_tree, q->id, icq))) {
+               hlist_add_head(&icq->ioc_node, &ioc->icq_list);
+               list_add(&icq->q_node, &q->icq_list);
+               if (et->ops.elevator_init_icq_fn)
+                       et->ops.elevator_init_icq_fn(icq);
+       } else {
+               kmem_cache_free(et->icq_cache, icq);
+               icq = ioc_lookup_icq(ioc, q);
+               if (!icq)
+                       printk(KERN_ERR "cfq: icq link failed!\n");
+       }
+
+       spin_unlock(&ioc->lock);
+       spin_unlock_irq(q->queue_lock);
+       radix_tree_preload_end();
+       return icq;
+}
+
+void ioc_set_changed(struct io_context *ioc, int which)
+{
+       struct io_cq *icq;
+       struct hlist_node *n;
+
+       hlist_for_each_entry(icq, n, &ioc->icq_list, ioc_node)
+               set_bit(which, &icq->changed);
+}
+
+/**
+ * ioc_ioprio_changed - notify ioprio change
+ * @ioc: io_context of interest
+ * @ioprio: new ioprio
+ *
+ * @ioc's ioprio has changed to @ioprio.  Set %ICQ_IOPRIO_CHANGED for all
+ * icq's.  iosched is responsible for checking the bit and applying it on
+ * request issue path.
+ */
+void ioc_ioprio_changed(struct io_context *ioc, int ioprio)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->lock, flags);
+       ioc->ioprio = ioprio;
+       ioc_set_changed(ioc, ICQ_IOPRIO_CHANGED);
+       spin_unlock_irqrestore(&ioc->lock, flags);
+}
+
+/**
+ * ioc_cgroup_changed - notify cgroup change
+ * @ioc: io_context of interest
+ *
+ * @ioc's cgroup has changed.  Set %ICQ_CGROUP_CHANGED for all icq's.
+ * iosched is responsible for checking the bit and applying it on request
+ * issue path.
+ */
+void ioc_cgroup_changed(struct io_context *ioc)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ioc->lock, flags);
+       ioc_set_changed(ioc, ICQ_CGROUP_CHANGED);
+       spin_unlock_irqrestore(&ioc->lock, flags);
+}
+EXPORT_SYMBOL(ioc_cgroup_changed);
 
 static int __init blk_ioc_init(void)
 {
index e663ac2d8e68f70ff17ce274f3cebec16c1dd18c..164cd0059706214e53c01b780b353fca98d9b829 100644 (file)
@@ -204,10 +204,11 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
                if (!iov[i].iov_len)
                        return -EINVAL;
 
-               if (uaddr & queue_dma_alignment(q)) {
+               /*
+                * Keep going so we check length of all segments
+                */
+               if (uaddr & queue_dma_alignment(q))
                        unaligned = 1;
-                       break;
-               }
        }
 
        if (unaligned || (q->dma_pad_mask & len) || map_data)
index e7f9f657f10563216be47d8e30ff93acbf4fa312..cf150011d808bc71fee8ff894387de0581235f56 100644 (file)
@@ -425,7 +425,7 @@ queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
        if (!entry->show)
                return -EIO;
        mutex_lock(&q->sysfs_lock);
-       if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
+       if (blk_queue_dead(q)) {
                mutex_unlock(&q->sysfs_lock);
                return -ENOENT;
        }
@@ -447,7 +447,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
 
        q = container_of(kobj, struct request_queue, kobj);
        mutex_lock(&q->sysfs_lock);
-       if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
+       if (blk_queue_dead(q)) {
                mutex_unlock(&q->sysfs_lock);
                return -ENOENT;
        }
@@ -479,8 +479,12 @@ static void blk_release_queue(struct kobject *kobj)
 
        blk_sync_queue(q);
 
-       if (q->elevator)
+       if (q->elevator) {
+               spin_lock_irq(q->queue_lock);
+               ioc_clear_queue(q);
+               spin_unlock_irq(q->queue_lock);
                elevator_exit(q->elevator);
+       }
 
        blk_throtl_exit(q);
 
@@ -494,6 +498,8 @@ static void blk_release_queue(struct kobject *kobj)
        blk_trace_shutdown(q);
 
        bdi_destroy(&q->backing_dev_info);
+
+       ida_simple_remove(&blk_queue_ida, q->id);
        kmem_cache_free(blk_requestq_cachep, q);
 }
 
index 4553245d93175bc34ddd83966e640161ca81e89f..5eed6a76721d1d78e8105f4bbde30e41f20a66cd 100644 (file)
@@ -310,7 +310,7 @@ static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
        struct request_queue *q = td->queue;
 
        /* no throttling for dead queue */
-       if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
+       if (unlikely(blk_queue_dead(q)))
                return NULL;
 
        rcu_read_lock();
@@ -335,7 +335,7 @@ static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
        spin_lock_irq(q->queue_lock);
 
        /* Make sure @q is still alive */
-       if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
+       if (unlikely(blk_queue_dead(q))) {
                kfree(tg);
                return NULL;
        }
index 3f6551b3c92d7fa14edc1b1d85c1ef500561e789..7efd772336de998be8c53b01a1805ae63069de62 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef BLK_INTERNAL_H
 #define BLK_INTERNAL_H
 
+#include <linux/idr.h>
+
 /* Amount of time in which a process may batch requests */
 #define BLK_BATCH_TIME (HZ/50UL)
 
@@ -9,6 +11,12 @@
 
 extern struct kmem_cache *blk_requestq_cachep;
 extern struct kobj_type blk_queue_ktype;
+extern struct ida blk_queue_ida;
+
+static inline void __blk_get_queue(struct request_queue *q)
+{
+       kobject_get(&q->kobj);
+}
 
 void init_request_from_bio(struct request *req, struct bio *bio);
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
@@ -85,8 +93,8 @@ static inline struct request *__elv_next_request(struct request_queue *q)
                        q->flush_queue_delayed = 1;
                        return NULL;
                }
-               if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) ||
-                   !q->elevator->ops->elevator_dispatch_fn(q, 0))
+               if (unlikely(blk_queue_dead(q)) ||
+                   !q->elevator->type->ops.elevator_dispatch_fn(q, 0))
                        return NULL;
        }
 }
@@ -95,16 +103,16 @@ static inline void elv_activate_rq(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_activate_req_fn)
-               e->ops->elevator_activate_req_fn(q, rq);
+       if (e->type->ops.elevator_activate_req_fn)
+               e->type->ops.elevator_activate_req_fn(q, rq);
 }
 
 static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_deactivate_req_fn)
-               e->ops->elevator_deactivate_req_fn(q, rq);
+       if (e->type->ops.elevator_deactivate_req_fn)
+               e->type->ops.elevator_deactivate_req_fn(q, rq);
 }
 
 #ifdef CONFIG_FAIL_IO_TIMEOUT
@@ -119,8 +127,6 @@ static inline int blk_should_fake_timeout(struct request_queue *q)
 }
 #endif
 
-struct io_context *current_io_context(gfp_t gfp_flags, int node);
-
 int ll_back_merge_fn(struct request_queue *q, struct request *req,
                     struct bio *bio);
 int ll_front_merge_fn(struct request_queue *q, struct request *req, 
@@ -189,6 +195,42 @@ static inline int blk_do_io_stat(struct request *rq)
                (rq->cmd_flags & REQ_DISCARD));
 }
 
+/*
+ * Internal io_context interface
+ */
+void get_io_context(struct io_context *ioc);
+struct io_cq *ioc_lookup_icq(struct io_context *ioc, struct request_queue *q);
+struct io_cq *ioc_create_icq(struct request_queue *q, gfp_t gfp_mask);
+void ioc_clear_queue(struct request_queue *q);
+
+void create_io_context_slowpath(struct task_struct *task, gfp_t gfp_mask,
+                               int node);
+
+/**
+ * create_io_context - try to create task->io_context
+ * @task: target task
+ * @gfp_mask: allocation mask
+ * @node: allocation node
+ *
+ * If @task->io_context is %NULL, allocate a new io_context and install it.
+ * Returns the current @task->io_context which may be %NULL if allocation
+ * failed.
+ *
+ * Note that this function can't be called with IRQ disabled because
+ * task_lock which protects @task->io_context is IRQ-unsafe.
+ */
+static inline struct io_context *create_io_context(struct task_struct *task,
+                                                  gfp_t gfp_mask, int node)
+{
+       WARN_ON_ONCE(irqs_disabled());
+       if (unlikely(!task->io_context))
+               create_io_context_slowpath(task, gfp_mask, node);
+       return task->io_context;
+}
+
+/*
+ * Internal throttling interface
+ */
 #ifdef CONFIG_BLK_DEV_THROTTLING
 extern bool blk_throtl_bio(struct request_queue *q, struct bio *bio);
 extern void blk_throtl_drain(struct request_queue *q);
index 6690e6e41037ec305e7b5cd606f96c59fb29fe17..7ad49c88f6b197a04c66e05aab9facacd2781af4 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/delay.h>
 #include <linux/scatterlist.h>
 #include <linux/bsg-lib.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <scsi/scsi_cmnd.h>
 
 /**
index 702f1316bb8fec6d68fcb7e0fc262c960530fc29..167d586cece6e110ae7a0f39bc475c95643f7dd4 100644 (file)
@@ -769,12 +769,10 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
                                         struct file *file)
 {
        struct bsg_device *bd;
-       int ret;
 #ifdef BSG_DEBUG
        unsigned char buf[32];
 #endif
-       ret = blk_get_queue(rq);
-       if (ret)
+       if (!blk_get_queue(rq))
                return ERR_PTR(-ENXIO);
 
        bd = bsg_alloc_device();
index 16ace89613bc6e4ce343cdd2f1da85218b7dc5e7..163263ddd3814e3f087eb1a7e1461242fabbd702 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/rbtree.h>
 #include <linux/ioprio.h>
 #include <linux/blktrace_api.h>
+#include "blk.h"
 #include "cfq.h"
 
 /*
@@ -53,20 +54,11 @@ static const int cfq_hist_divisor = 4;
 #define CFQQ_SECT_THR_NONROT   (sector_t)(2 * 32)
 #define CFQQ_SEEKY(cfqq)       (hweight32(cfqq->seek_history) > 32/8)
 
-#define RQ_CIC(rq)             \
-       ((struct cfq_io_context *) (rq)->elevator_private[0])
-#define RQ_CFQQ(rq)            (struct cfq_queue *) ((rq)->elevator_private[1])
-#define RQ_CFQG(rq)            (struct cfq_group *) ((rq)->elevator_private[2])
+#define RQ_CIC(rq)             icq_to_cic((rq)->elv.icq)
+#define RQ_CFQQ(rq)            (struct cfq_queue *) ((rq)->elv.priv[0])
+#define RQ_CFQG(rq)            (struct cfq_group *) ((rq)->elv.priv[1])
 
 static struct kmem_cache *cfq_pool;
-static struct kmem_cache *cfq_ioc_pool;
-
-static DEFINE_PER_CPU(unsigned long, cfq_ioc_count);
-static struct completion *ioc_gone;
-static DEFINE_SPINLOCK(ioc_gone_lock);
-
-static DEFINE_SPINLOCK(cic_index_lock);
-static DEFINE_IDA(cic_index_ida);
 
 #define CFQ_PRIO_LISTS         IOPRIO_BE_NR
 #define cfq_class_idle(cfqq)   ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
@@ -75,6 +67,14 @@ static DEFINE_IDA(cic_index_ida);
 #define sample_valid(samples)  ((samples) > 80)
 #define rb_entry_cfqg(node)    rb_entry((node), struct cfq_group, rb_node)
 
+struct cfq_ttime {
+       unsigned long last_end_request;
+
+       unsigned long ttime_total;
+       unsigned long ttime_samples;
+       unsigned long ttime_mean;
+};
+
 /*
  * Most of our rbtree usage is for sorting with min extraction, so
  * if we cache the leftmost node we don't have to walk down the tree
@@ -216,6 +216,12 @@ struct cfq_group {
        struct cfq_ttime ttime;
 };
 
+struct cfq_io_cq {
+       struct io_cq            icq;            /* must be the first member */
+       struct cfq_queue        *cfqq[2];
+       struct cfq_ttime        ttime;
+};
+
 /*
  * Per block device queue structure
  */
@@ -267,7 +273,7 @@ struct cfq_data {
        struct work_struct unplug_work;
 
        struct cfq_queue *active_queue;
-       struct cfq_io_context *active_cic;
+       struct cfq_io_cq *active_cic;
 
        /*
         * async queue for each priority case
@@ -290,9 +296,6 @@ struct cfq_data {
        unsigned int cfq_group_idle;
        unsigned int cfq_latency;
 
-       unsigned int cic_index;
-       struct list_head cic_list;
-
        /*
         * Fallback dummy cfqq for extreme OOM conditions
         */
@@ -464,37 +467,35 @@ static inline int cfqg_busy_async_queues(struct cfq_data *cfqd,
 static void cfq_dispatch_insert(struct request_queue *, struct request *);
 static struct cfq_queue *cfq_get_queue(struct cfq_data *, bool,
                                       struct io_context *, gfp_t);
-static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
-                                               struct io_context *);
 
-static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
-                                           bool is_sync)
+static inline struct cfq_io_cq *icq_to_cic(struct io_cq *icq)
 {
-       return cic->cfqq[is_sync];
+       /* cic->icq is the first member, %NULL will convert to %NULL */
+       return container_of(icq, struct cfq_io_cq, icq);
 }
 
-static inline void cic_set_cfqq(struct cfq_io_context *cic,
-                               struct cfq_queue *cfqq, bool is_sync)
+static inline struct cfq_io_cq *cfq_cic_lookup(struct cfq_data *cfqd,
+                                              struct io_context *ioc)
 {
-       cic->cfqq[is_sync] = cfqq;
+       if (ioc)
+               return icq_to_cic(ioc_lookup_icq(ioc, cfqd->queue));
+       return NULL;
 }
 
-#define CIC_DEAD_KEY   1ul
-#define CIC_DEAD_INDEX_SHIFT   1
-
-static inline void *cfqd_dead_key(struct cfq_data *cfqd)
+static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_cq *cic, bool is_sync)
 {
-       return (void *)(cfqd->cic_index << CIC_DEAD_INDEX_SHIFT | CIC_DEAD_KEY);
+       return cic->cfqq[is_sync];
 }
 
-static inline struct cfq_data *cic_to_cfqd(struct cfq_io_context *cic)
+static inline void cic_set_cfqq(struct cfq_io_cq *cic, struct cfq_queue *cfqq,
+                               bool is_sync)
 {
-       struct cfq_data *cfqd = cic->key;
-
-       if (unlikely((unsigned long) cfqd & CIC_DEAD_KEY))
-               return NULL;
+       cic->cfqq[is_sync] = cfqq;
+}
 
-       return cfqd;
+static inline struct cfq_data *cic_to_cfqd(struct cfq_io_cq *cic)
+{
+       return cic->icq.q->elevator->elevator_data;
 }
 
 /*
@@ -1561,7 +1562,7 @@ static struct request *
 cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
 {
        struct task_struct *tsk = current;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic;
        struct cfq_queue *cfqq;
 
        cic = cfq_cic_lookup(cfqd, tsk->io_context);
@@ -1655,6 +1656,8 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
                    struct request *next)
 {
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
+       struct cfq_data *cfqd = q->elevator->elevator_data;
+
        /*
         * reposition in fifo if next is older than rq
         */
@@ -1669,13 +1672,23 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
        cfq_remove_request(next);
        cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg,
                                        rq_data_dir(next), rq_is_sync(next));
+
+       cfqq = RQ_CFQQ(next);
+       /*
+        * all requests of this queue are merged to other queues, delete it
+        * from the service tree. If it's the active_queue,
+        * cfq_dispatch_requests() will choose to expire it or do idle
+        */
+       if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list) &&
+           cfqq != cfqd->active_queue)
+               cfq_del_cfqq_rr(cfqd, cfqq);
 }
 
 static int cfq_allow_merge(struct request_queue *q, struct request *rq,
                           struct bio *bio)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic;
        struct cfq_queue *cfqq;
 
        /*
@@ -1685,12 +1698,19 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
                return false;
 
        /*
-        * Lookup the cfqq that this bio will be queued with. Allow
-        * merge only if rq is queued there.
+        * Lookup the cfqq that this bio will be queued with and allow
+        * merge only if rq is queued there.  This function can be called
+        * from plug merge without queue_lock.  In such cases, ioc of @rq
+        * and %current are guaranteed to be equal.  Avoid lookup which
+        * requires queue_lock by using @rq's cic.
         */
-       cic = cfq_cic_lookup(cfqd, current->io_context);
-       if (!cic)
-               return false;
+       if (current->io_context == RQ_CIC(rq)->icq.ioc) {
+               cic = RQ_CIC(rq);
+       } else {
+               cic = cfq_cic_lookup(cfqd, current->io_context);
+               if (!cic)
+                       return false;
+       }
 
        cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
        return cfqq == RQ_CFQQ(rq);
@@ -1774,7 +1794,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
                cfqd->active_queue = NULL;
 
        if (cfqd->active_cic) {
-               put_io_context(cfqd->active_cic->ioc);
+               put_io_context(cfqd->active_cic->icq.ioc, cfqd->queue);
                cfqd->active_cic = NULL;
        }
 }
@@ -1994,7 +2014,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 {
        struct cfq_queue *cfqq = cfqd->active_queue;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic;
        unsigned long sl, group_idle = 0;
 
        /*
@@ -2029,7 +2049,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
         * task has exited, don't wait
         */
        cic = cfqd->active_cic;
-       if (!cic || !atomic_read(&cic->ioc->nr_tasks))
+       if (!cic || !atomic_read(&cic->icq.ioc->nr_tasks))
                return;
 
        /*
@@ -2580,9 +2600,9 @@ static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
        cfq_dispatch_insert(cfqd->queue, rq);
 
        if (!cfqd->active_cic) {
-               struct cfq_io_context *cic = RQ_CIC(rq);
+               struct cfq_io_cq *cic = RQ_CIC(rq);
 
-               atomic_long_inc(&cic->ioc->refcount);
+               atomic_long_inc(&cic->icq.ioc->refcount);
                cfqd->active_cic = cic;
        }
 
@@ -2665,84 +2685,6 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
        cfq_put_cfqg(cfqg);
 }
 
-/*
- * Call func for each cic attached to this ioc.
- */
-static void
-call_for_each_cic(struct io_context *ioc,
-                 void (*func)(struct io_context *, struct cfq_io_context *))
-{
-       struct cfq_io_context *cic;
-       struct hlist_node *n;
-
-       rcu_read_lock();
-
-       hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
-               func(ioc, cic);
-
-       rcu_read_unlock();
-}
-
-static void cfq_cic_free_rcu(struct rcu_head *head)
-{
-       struct cfq_io_context *cic;
-
-       cic = container_of(head, struct cfq_io_context, rcu_head);
-
-       kmem_cache_free(cfq_ioc_pool, cic);
-       elv_ioc_count_dec(cfq_ioc_count);
-
-       if (ioc_gone) {
-               /*
-                * CFQ scheduler is exiting, grab exit lock and check
-                * the pending io context count. If it hits zero,
-                * complete ioc_gone and set it back to NULL
-                */
-               spin_lock(&ioc_gone_lock);
-               if (ioc_gone && !elv_ioc_count_read(cfq_ioc_count)) {
-                       complete(ioc_gone);
-                       ioc_gone = NULL;
-               }
-               spin_unlock(&ioc_gone_lock);
-       }
-}
-
-static void cfq_cic_free(struct cfq_io_context *cic)
-{
-       call_rcu(&cic->rcu_head, cfq_cic_free_rcu);
-}
-
-static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
-{
-       unsigned long flags;
-       unsigned long dead_key = (unsigned long) cic->key;
-
-       BUG_ON(!(dead_key & CIC_DEAD_KEY));
-
-       spin_lock_irqsave(&ioc->lock, flags);
-       radix_tree_delete(&ioc->radix_root, dead_key >> CIC_DEAD_INDEX_SHIFT);
-       hlist_del_rcu(&cic->cic_list);
-       spin_unlock_irqrestore(&ioc->lock, flags);
-
-       cfq_cic_free(cic);
-}
-
-/*
- * Must be called with rcu_read_lock() held or preemption otherwise disabled.
- * Only two callers of this - ->dtor() which is called with the rcu_read_lock(),
- * and ->trim() which is called with the task lock held
- */
-static void cfq_free_io_context(struct io_context *ioc)
-{
-       /*
-        * ioc->refcount is zero here, or we are called from elv_unregister(),
-        * so no more cic's are allowed to be linked into this ioc.  So it
-        * should be ok to iterate over the known list, we will see all cic's
-        * since no new ones are added.
-        */
-       call_for_each_cic(ioc, cic_free_func);
-}
-
 static void cfq_put_cooperator(struct cfq_queue *cfqq)
 {
        struct cfq_queue *__cfqq, *next;
@@ -2776,27 +2718,17 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
        cfq_put_queue(cfqq);
 }
 
-static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
-                                        struct cfq_io_context *cic)
+static void cfq_init_icq(struct io_cq *icq)
 {
-       struct io_context *ioc = cic->ioc;
+       struct cfq_io_cq *cic = icq_to_cic(icq);
 
-       list_del_init(&cic->queue_list);
-
-       /*
-        * Make sure dead mark is seen for dead queues
-        */
-       smp_wmb();
-       cic->key = cfqd_dead_key(cfqd);
+       cic->ttime.last_end_request = jiffies;
+}
 
-       rcu_read_lock();
-       if (rcu_dereference(ioc->ioc_data) == cic) {
-               rcu_read_unlock();
-               spin_lock(&ioc->lock);
-               rcu_assign_pointer(ioc->ioc_data, NULL);
-               spin_unlock(&ioc->lock);
-       } else
-               rcu_read_unlock();
+static void cfq_exit_icq(struct io_cq *icq)
+{
+       struct cfq_io_cq *cic = icq_to_cic(icq);
+       struct cfq_data *cfqd = cic_to_cfqd(cic);
 
        if (cic->cfqq[BLK_RW_ASYNC]) {
                cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
@@ -2809,57 +2741,6 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
        }
 }
 
-static void cfq_exit_single_io_context(struct io_context *ioc,
-                                      struct cfq_io_context *cic)
-{
-       struct cfq_data *cfqd = cic_to_cfqd(cic);
-
-       if (cfqd) {
-               struct request_queue *q = cfqd->queue;
-               unsigned long flags;
-
-               spin_lock_irqsave(q->queue_lock, flags);
-
-               /*
-                * Ensure we get a fresh copy of the ->key to prevent
-                * race between exiting task and queue
-                */
-               smp_read_barrier_depends();
-               if (cic->key == cfqd)
-                       __cfq_exit_single_io_context(cfqd, cic);
-
-               spin_unlock_irqrestore(q->queue_lock, flags);
-       }
-}
-
-/*
- * The process that ioc belongs to has exited, we need to clean up
- * and put the internal structures we have that belongs to that process.
- */
-static void cfq_exit_io_context(struct io_context *ioc)
-{
-       call_for_each_cic(ioc, cfq_exit_single_io_context);
-}
-
-static struct cfq_io_context *
-cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
-{
-       struct cfq_io_context *cic;
-
-       cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask | __GFP_ZERO,
-                                                       cfqd->queue->node);
-       if (cic) {
-               cic->ttime.last_end_request = jiffies;
-               INIT_LIST_HEAD(&cic->queue_list);
-               INIT_HLIST_NODE(&cic->cic_list);
-               cic->dtor = cfq_free_io_context;
-               cic->exit = cfq_exit_io_context;
-               elv_ioc_count_inc(cfq_ioc_count);
-       }
-
-       return cic;
-}
-
 static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
 {
        struct task_struct *tsk = current;
@@ -2902,21 +2783,18 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc)
        cfq_clear_cfqq_prio_changed(cfqq);
 }
 
-static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
+static void changed_ioprio(struct cfq_io_cq *cic)
 {
        struct cfq_data *cfqd = cic_to_cfqd(cic);
        struct cfq_queue *cfqq;
-       unsigned long flags;
 
        if (unlikely(!cfqd))
                return;
 
-       spin_lock_irqsave(cfqd->queue->queue_lock, flags);
-
        cfqq = cic->cfqq[BLK_RW_ASYNC];
        if (cfqq) {
                struct cfq_queue *new_cfqq;
-               new_cfqq = cfq_get_queue(cfqd, BLK_RW_ASYNC, cic->ioc,
+               new_cfqq = cfq_get_queue(cfqd, BLK_RW_ASYNC, cic->icq.ioc,
                                                GFP_ATOMIC);
                if (new_cfqq) {
                        cic->cfqq[BLK_RW_ASYNC] = new_cfqq;
@@ -2927,14 +2805,6 @@ static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
        cfqq = cic->cfqq[BLK_RW_SYNC];
        if (cfqq)
                cfq_mark_cfqq_prio_changed(cfqq);
-
-       spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
-}
-
-static void cfq_ioc_set_ioprio(struct io_context *ioc)
-{
-       call_for_each_cic(ioc, changed_ioprio);
-       ioc->ioprio_changed = 0;
 }
 
 static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
@@ -2958,11 +2828,10 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 }
 
 #ifdef CONFIG_CFQ_GROUP_IOSCHED
-static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic)
+static void changed_cgroup(struct cfq_io_cq *cic)
 {
        struct cfq_queue *sync_cfqq = cic_to_cfqq(cic, 1);
        struct cfq_data *cfqd = cic_to_cfqd(cic);
-       unsigned long flags;
        struct request_queue *q;
 
        if (unlikely(!cfqd))
@@ -2970,8 +2839,6 @@ static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic)
 
        q = cfqd->queue;
 
-       spin_lock_irqsave(q->queue_lock, flags);
-
        if (sync_cfqq) {
                /*
                 * Drop reference to sync queue. A new sync queue will be
@@ -2981,14 +2848,6 @@ static void changed_cgroup(struct io_context *ioc, struct cfq_io_context *cic)
                cic_set_cfqq(cic, NULL, 1);
                cfq_put_queue(sync_cfqq);
        }
-
-       spin_unlock_irqrestore(q->queue_lock, flags);
-}
-
-static void cfq_ioc_set_cgroup(struct io_context *ioc)
-{
-       call_for_each_cic(ioc, changed_cgroup);
-       ioc->cgroup_changed = 0;
 }
 #endif  /* CONFIG_CFQ_GROUP_IOSCHED */
 
@@ -2997,7 +2856,7 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync,
                     struct io_context *ioc, gfp_t gfp_mask)
 {
        struct cfq_queue *cfqq, *new_cfqq = NULL;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic;
        struct cfq_group *cfqg;
 
 retry:
@@ -3088,153 +2947,6 @@ cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
        return cfqq;
 }
 
-/*
- * We drop cfq io contexts lazily, so we may find a dead one.
- */
-static void
-cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
-                 struct cfq_io_context *cic)
-{
-       unsigned long flags;
-
-       WARN_ON(!list_empty(&cic->queue_list));
-       BUG_ON(cic->key != cfqd_dead_key(cfqd));
-
-       spin_lock_irqsave(&ioc->lock, flags);
-
-       BUG_ON(rcu_dereference_check(ioc->ioc_data,
-               lockdep_is_held(&ioc->lock)) == cic);
-
-       radix_tree_delete(&ioc->radix_root, cfqd->cic_index);
-       hlist_del_rcu(&cic->cic_list);
-       spin_unlock_irqrestore(&ioc->lock, flags);
-
-       cfq_cic_free(cic);
-}
-
-static struct cfq_io_context *
-cfq_cic_lookup(struct cfq_data *cfqd, struct io_context *ioc)
-{
-       struct cfq_io_context *cic;
-       unsigned long flags;
-
-       if (unlikely(!ioc))
-               return NULL;
-
-       rcu_read_lock();
-
-       /*
-        * we maintain a last-hit cache, to avoid browsing over the tree
-        */
-       cic = rcu_dereference(ioc->ioc_data);
-       if (cic && cic->key == cfqd) {
-               rcu_read_unlock();
-               return cic;
-       }
-
-       do {
-               cic = radix_tree_lookup(&ioc->radix_root, cfqd->cic_index);
-               rcu_read_unlock();
-               if (!cic)
-                       break;
-               if (unlikely(cic->key != cfqd)) {
-                       cfq_drop_dead_cic(cfqd, ioc, cic);
-                       rcu_read_lock();
-                       continue;
-               }
-
-               spin_lock_irqsave(&ioc->lock, flags);
-               rcu_assign_pointer(ioc->ioc_data, cic);
-               spin_unlock_irqrestore(&ioc->lock, flags);
-               break;
-       } while (1);
-
-       return cic;
-}
-
-/*
- * Add cic into ioc, using cfqd as the search key. This enables us to lookup
- * the process specific cfq io context when entered from the block layer.
- * Also adds the cic to a per-cfqd list, used when this queue is removed.
- */
-static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
-                       struct cfq_io_context *cic, gfp_t gfp_mask)
-{
-       unsigned long flags;
-       int ret;
-
-       ret = radix_tree_preload(gfp_mask);
-       if (!ret) {
-               cic->ioc = ioc;
-               cic->key = cfqd;
-
-               spin_lock_irqsave(&ioc->lock, flags);
-               ret = radix_tree_insert(&ioc->radix_root,
-                                               cfqd->cic_index, cic);
-               if (!ret)
-                       hlist_add_head_rcu(&cic->cic_list, &ioc->cic_list);
-               spin_unlock_irqrestore(&ioc->lock, flags);
-
-               radix_tree_preload_end();
-
-               if (!ret) {
-                       spin_lock_irqsave(cfqd->queue->queue_lock, flags);
-                       list_add(&cic->queue_list, &cfqd->cic_list);
-                       spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
-               }
-       }
-
-       if (ret)
-               printk(KERN_ERR "cfq: cic link failed!\n");
-
-       return ret;
-}
-
-/*
- * Setup general io context and cfq io context. There can be several cfq
- * io contexts per general io context, if this process is doing io to more
- * than one device managed by cfq.
- */
-static struct cfq_io_context *
-cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
-{
-       struct io_context *ioc = NULL;
-       struct cfq_io_context *cic;
-
-       might_sleep_if(gfp_mask & __GFP_WAIT);
-
-       ioc = get_io_context(gfp_mask, cfqd->queue->node);
-       if (!ioc)
-               return NULL;
-
-       cic = cfq_cic_lookup(cfqd, ioc);
-       if (cic)
-               goto out;
-
-       cic = cfq_alloc_io_context(cfqd, gfp_mask);
-       if (cic == NULL)
-               goto err;
-
-       if (cfq_cic_link(cfqd, ioc, cic, gfp_mask))
-               goto err_free;
-
-out:
-       smp_read_barrier_depends();
-       if (unlikely(ioc->ioprio_changed))
-               cfq_ioc_set_ioprio(ioc);
-
-#ifdef CONFIG_CFQ_GROUP_IOSCHED
-       if (unlikely(ioc->cgroup_changed))
-               cfq_ioc_set_cgroup(ioc);
-#endif
-       return cic;
-err_free:
-       cfq_cic_free(cic);
-err:
-       put_io_context(ioc);
-       return NULL;
-}
-
 static void
 __cfq_update_io_thinktime(struct cfq_ttime *ttime, unsigned long slice_idle)
 {
@@ -3248,7 +2960,7 @@ __cfq_update_io_thinktime(struct cfq_ttime *ttime, unsigned long slice_idle)
 
 static void
 cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-       struct cfq_io_context *cic)
+                       struct cfq_io_cq *cic)
 {
        if (cfq_cfqq_sync(cfqq)) {
                __cfq_update_io_thinktime(&cic->ttime, cfqd->cfq_slice_idle);
@@ -3286,7 +2998,7 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
  */
 static void
 cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                      struct cfq_io_context *cic)
+                      struct cfq_io_cq *cic)
 {
        int old_idle, enable_idle;
 
@@ -3303,8 +3015,9 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 
        if (cfqq->next_rq && (cfqq->next_rq->cmd_flags & REQ_NOIDLE))
                enable_idle = 0;
-       else if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
-           (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
+       else if (!atomic_read(&cic->icq.ioc->nr_tasks) ||
+                !cfqd->cfq_slice_idle ||
+                (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
                enable_idle = 0;
        else if (sample_valid(cic->ttime.ttime_samples)) {
                if (cic->ttime.ttime_mean > cfqd->cfq_slice_idle)
@@ -3436,7 +3149,7 @@ static void
 cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
                struct request *rq)
 {
-       struct cfq_io_context *cic = RQ_CIC(rq);
+       struct cfq_io_cq *cic = RQ_CIC(rq);
 
        cfqd->rq_queued++;
        if (rq->cmd_flags & REQ_PRIO)
@@ -3489,7 +3202,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
        struct cfq_queue *cfqq = RQ_CFQQ(rq);
 
        cfq_log_cfqq(cfqd, cfqq, "insert_request");
-       cfq_init_prio_data(cfqq, RQ_CIC(rq)->ioc);
+       cfq_init_prio_data(cfqq, RQ_CIC(rq)->icq.ioc);
 
        rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
        list_add_tail(&rq->queuelist, &cfqq->fifo);
@@ -3539,7 +3252,7 @@ static void cfq_update_hw_tag(struct cfq_data *cfqd)
 
 static bool cfq_should_wait_busy(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
-       struct cfq_io_context *cic = cfqd->active_cic;
+       struct cfq_io_cq *cic = cfqd->active_cic;
 
        /* If the queue already has requests, don't wait */
        if (!RB_EMPTY_ROOT(&cfqq->sort_list))
@@ -3676,7 +3389,7 @@ static int cfq_may_queue(struct request_queue *q, int rw)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct task_struct *tsk = current;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic;
        struct cfq_queue *cfqq;
 
        /*
@@ -3691,7 +3404,7 @@ static int cfq_may_queue(struct request_queue *q, int rw)
 
        cfqq = cic_to_cfqq(cic, rw_is_sync(rw));
        if (cfqq) {
-               cfq_init_prio_data(cfqq, cic->ioc);
+               cfq_init_prio_data(cfqq, cic->icq.ioc);
 
                return __cfq_may_queue(cfqq);
        }
@@ -3712,21 +3425,17 @@ static void cfq_put_request(struct request *rq)
                BUG_ON(!cfqq->allocated[rw]);
                cfqq->allocated[rw]--;
 
-               put_io_context(RQ_CIC(rq)->ioc);
-
-               rq->elevator_private[0] = NULL;
-               rq->elevator_private[1] = NULL;
-
                /* Put down rq reference on cfqg */
                cfq_put_cfqg(RQ_CFQG(rq));
-               rq->elevator_private[2] = NULL;
+               rq->elv.priv[0] = NULL;
+               rq->elv.priv[1] = NULL;
 
                cfq_put_queue(cfqq);
        }
 }
 
 static struct cfq_queue *
-cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_context *cic,
+cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_cq *cic,
                struct cfq_queue *cfqq)
 {
        cfq_log_cfqq(cfqd, cfqq, "merging with queue %p", cfqq->new_cfqq);
@@ -3741,7 +3450,7 @@ cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_context *cic,
  * was the last process referring to said cfqq.
  */
 static struct cfq_queue *
-split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq)
+split_cfqq(struct cfq_io_cq *cic, struct cfq_queue *cfqq)
 {
        if (cfqq_process_refs(cfqq) == 1) {
                cfqq->pid = current->pid;
@@ -3764,25 +3473,29 @@ static int
 cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
 {
        struct cfq_data *cfqd = q->elevator->elevator_data;
-       struct cfq_io_context *cic;
+       struct cfq_io_cq *cic = icq_to_cic(rq->elv.icq);
        const int rw = rq_data_dir(rq);
        const bool is_sync = rq_is_sync(rq);
        struct cfq_queue *cfqq;
-       unsigned long flags;
 
        might_sleep_if(gfp_mask & __GFP_WAIT);
 
-       cic = cfq_get_io_context(cfqd, gfp_mask);
-
-       spin_lock_irqsave(q->queue_lock, flags);
+       spin_lock_irq(q->queue_lock);
 
-       if (!cic)
-               goto queue_fail;
+       /* handle changed notifications */
+       if (unlikely(cic->icq.changed)) {
+               if (test_and_clear_bit(ICQ_IOPRIO_CHANGED, &cic->icq.changed))
+                       changed_ioprio(cic);
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+               if (test_and_clear_bit(ICQ_CGROUP_CHANGED, &cic->icq.changed))
+                       changed_cgroup(cic);
+#endif
+       }
 
 new_queue:
        cfqq = cic_to_cfqq(cic, is_sync);
        if (!cfqq || cfqq == &cfqd->oom_cfqq) {
-               cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask);
+               cfqq = cfq_get_queue(cfqd, is_sync, cic->icq.ioc, gfp_mask);
                cic_set_cfqq(cic, cfqq, is_sync);
        } else {
                /*
@@ -3808,17 +3521,10 @@ new_queue:
        cfqq->allocated[rw]++;
 
        cfqq->ref++;
-       rq->elevator_private[0] = cic;
-       rq->elevator_private[1] = cfqq;
-       rq->elevator_private[2] = cfq_ref_get_cfqg(cfqq->cfqg);
-       spin_unlock_irqrestore(q->queue_lock, flags);
+       rq->elv.priv[0] = cfqq;
+       rq->elv.priv[1] = cfq_ref_get_cfqg(cfqq->cfqg);
+       spin_unlock_irq(q->queue_lock);
        return 0;
-
-queue_fail:
-       cfq_schedule_dispatch(cfqd);
-       spin_unlock_irqrestore(q->queue_lock, flags);
-       cfq_log(cfqd, "set_request fail");
-       return 1;
 }
 
 static void cfq_kick_queue(struct work_struct *work)
@@ -3922,14 +3628,6 @@ static void cfq_exit_queue(struct elevator_queue *e)
        if (cfqd->active_queue)
                __cfq_slice_expired(cfqd, cfqd->active_queue, 0);
 
-       while (!list_empty(&cfqd->cic_list)) {
-               struct cfq_io_context *cic = list_entry(cfqd->cic_list.next,
-                                                       struct cfq_io_context,
-                                                       queue_list);
-
-               __cfq_exit_single_io_context(cfqd, cic);
-       }
-
        cfq_put_async_queues(cfqd);
        cfq_release_cfq_groups(cfqd);
 
@@ -3944,10 +3642,6 @@ static void cfq_exit_queue(struct elevator_queue *e)
 
        cfq_shutdown_timer_wq(cfqd);
 
-       spin_lock(&cic_index_lock);
-       ida_remove(&cic_index_ida, cfqd->cic_index);
-       spin_unlock(&cic_index_lock);
-
        /*
         * Wait for cfqg->blkg->key accessors to exit their grace periods.
         * Do this wait only if there are other unlinked groups out
@@ -3969,24 +3663,6 @@ static void cfq_exit_queue(struct elevator_queue *e)
        kfree(cfqd);
 }
 
-static int cfq_alloc_cic_index(void)
-{
-       int index, error;
-
-       do {
-               if (!ida_pre_get(&cic_index_ida, GFP_KERNEL))
-                       return -ENOMEM;
-
-               spin_lock(&cic_index_lock);
-               error = ida_get_new(&cic_index_ida, &index);
-               spin_unlock(&cic_index_lock);
-               if (error && error != -EAGAIN)
-                       return error;
-       } while (error);
-
-       return index;
-}
-
 static void *cfq_init_queue(struct request_queue *q)
 {
        struct cfq_data *cfqd;
@@ -3994,23 +3670,9 @@ static void *cfq_init_queue(struct request_queue *q)
        struct cfq_group *cfqg;
        struct cfq_rb_root *st;
 
-       i = cfq_alloc_cic_index();
-       if (i < 0)
-               return NULL;
-
        cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
-       if (!cfqd) {
-               spin_lock(&cic_index_lock);
-               ida_remove(&cic_index_ida, i);
-               spin_unlock(&cic_index_lock);
+       if (!cfqd)
                return NULL;
-       }
-
-       /*
-        * Don't need take queue_lock in the routine, since we are
-        * initializing the ioscheduler, and nobody is using cfqd
-        */
-       cfqd->cic_index = i;
 
        /* Init root service tree */
        cfqd->grp_service_tree = CFQ_RB_ROOT;
@@ -4067,8 +3729,6 @@ static void *cfq_init_queue(struct request_queue *q)
        cfqd->oom_cfqq.ref++;
        cfq_link_cfqq_cfqg(&cfqd->oom_cfqq, &cfqd->root_group);
 
-       INIT_LIST_HEAD(&cfqd->cic_list);
-
        cfqd->queue = q;
 
        init_timer(&cfqd->idle_slice_timer);
@@ -4097,34 +3757,6 @@ static void *cfq_init_queue(struct request_queue *q)
        return cfqd;
 }
 
-static void cfq_slab_kill(void)
-{
-       /*
-        * Caller already ensured that pending RCU callbacks are completed,
-        * so we should have no busy allocations at this point.
-        */
-       if (cfq_pool)
-               kmem_cache_destroy(cfq_pool);
-       if (cfq_ioc_pool)
-               kmem_cache_destroy(cfq_ioc_pool);
-}
-
-static int __init cfq_slab_setup(void)
-{
-       cfq_pool = KMEM_CACHE(cfq_queue, 0);
-       if (!cfq_pool)
-               goto fail;
-
-       cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
-       if (!cfq_ioc_pool)
-               goto fail;
-
-       return 0;
-fail:
-       cfq_slab_kill();
-       return -ENOMEM;
-}
-
 /*
  * sysfs parts below -->
  */
@@ -4230,15 +3862,18 @@ static struct elevator_type iosched_cfq = {
                .elevator_completed_req_fn =    cfq_completed_request,
                .elevator_former_req_fn =       elv_rb_former_request,
                .elevator_latter_req_fn =       elv_rb_latter_request,
+               .elevator_init_icq_fn =         cfq_init_icq,
+               .elevator_exit_icq_fn =         cfq_exit_icq,
                .elevator_set_req_fn =          cfq_set_request,
                .elevator_put_req_fn =          cfq_put_request,
                .elevator_may_queue_fn =        cfq_may_queue,
                .elevator_init_fn =             cfq_init_queue,
                .elevator_exit_fn =             cfq_exit_queue,
-               .trim =                         cfq_free_io_context,
        },
+       .icq_size       =       sizeof(struct cfq_io_cq),
+       .icq_align      =       __alignof__(struct cfq_io_cq),
        .elevator_attrs =       cfq_attrs,
-       .elevator_name        "cfq",
+       .elevator_name  =       "cfq",
        .elevator_owner =       THIS_MODULE,
 };
 
@@ -4256,6 +3891,8 @@ static struct blkio_policy_type blkio_policy_cfq;
 
 static int __init cfq_init(void)
 {
+       int ret;
+
        /*
         * could be 0 on HZ < 1000 setups
         */
@@ -4270,10 +3907,16 @@ static int __init cfq_init(void)
 #else
                cfq_group_idle = 0;
 #endif
-       if (cfq_slab_setup())
+       cfq_pool = KMEM_CACHE(cfq_queue, 0);
+       if (!cfq_pool)
                return -ENOMEM;
 
-       elv_register(&iosched_cfq);
+       ret = elv_register(&iosched_cfq);
+       if (ret) {
+               kmem_cache_destroy(cfq_pool);
+               return ret;
+       }
+
        blkio_policy_register(&blkio_policy_cfq);
 
        return 0;
@@ -4281,21 +3924,9 @@ static int __init cfq_init(void)
 
 static void __exit cfq_exit(void)
 {
-       DECLARE_COMPLETION_ONSTACK(all_gone);
        blkio_policy_unregister(&blkio_policy_cfq);
        elv_unregister(&iosched_cfq);
-       ioc_gone = &all_gone;
-       /* ioc_gone's update must be visible before reading ioc_count */
-       smp_wmb();
-
-       /*
-        * this also protects us from entering cfq_slab_kill() with
-        * pending RCU callbacks
-        */
-       if (elv_ioc_count_read(cfq_ioc_count))
-               wait_for_completion(&all_gone);
-       ida_destroy(&cic_index_ida);
-       cfq_slab_kill();
+       kmem_cache_destroy(cfq_pool);
 }
 
 module_init(cfq_init);
index c644137d9cd643b0e3b80750333dc42e92d1e964..7bf12d793fcdee25eb1ba178a59203b72d60ec2e 100644 (file)
@@ -448,9 +448,7 @@ static struct elevator_type iosched_deadline = {
 
 static int __init deadline_init(void)
 {
-       elv_register(&iosched_deadline);
-
-       return 0;
+       return elv_register(&iosched_deadline);
 }
 
 static void __exit deadline_exit(void)
index 66343d6917d0cc64bbeccb7f55572237b8f78aba..99838f460b44d5c399505071b3d9105218e30c68 100644 (file)
@@ -61,8 +61,8 @@ static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
        struct request_queue *q = rq->q;
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_allow_merge_fn)
-               return e->ops->elevator_allow_merge_fn(q, rq, bio);
+       if (e->type->ops.elevator_allow_merge_fn)
+               return e->type->ops.elevator_allow_merge_fn(q, rq, bio);
 
        return 1;
 }
@@ -168,17 +168,13 @@ static struct elevator_type *elevator_get(const char *name)
        return e;
 }
 
-static void *elevator_init_queue(struct request_queue *q,
-                                struct elevator_queue *eq)
+static int elevator_init_queue(struct request_queue *q,
+                              struct elevator_queue *eq)
 {
-       return eq->ops->elevator_init_fn(q);
-}
-
-static void elevator_attach(struct request_queue *q, struct elevator_queue *eq,
-                          void *data)
-{
-       q->elevator = eq;
-       eq->elevator_data = data;
+       eq->elevator_data = eq->type->ops.elevator_init_fn(q);
+       if (eq->elevator_data)
+               return 0;
+       return -ENOMEM;
 }
 
 static char chosen_elevator[ELV_NAME_MAX];
@@ -207,8 +203,7 @@ static struct elevator_queue *elevator_alloc(struct request_queue *q,
        if (unlikely(!eq))
                goto err;
 
-       eq->ops = &e->ops;
-       eq->elevator_type = e;
+       eq->type = e;
        kobject_init(&eq->kobj, &elv_ktype);
        mutex_init(&eq->sysfs_lock);
 
@@ -232,7 +227,7 @@ static void elevator_release(struct kobject *kobj)
        struct elevator_queue *e;
 
        e = container_of(kobj, struct elevator_queue, kobj);
-       elevator_put(e->elevator_type);
+       elevator_put(e->type);
        kfree(e->hash);
        kfree(e);
 }
@@ -241,7 +236,7 @@ int elevator_init(struct request_queue *q, char *name)
 {
        struct elevator_type *e = NULL;
        struct elevator_queue *eq;
-       void *data;
+       int err;
 
        if (unlikely(q->elevator))
                return 0;
@@ -278,13 +273,13 @@ int elevator_init(struct request_queue *q, char *name)
        if (!eq)
                return -ENOMEM;
 
-       data = elevator_init_queue(q, eq);
-       if (!data) {
+       err = elevator_init_queue(q, eq);
+       if (err) {
                kobject_put(&eq->kobj);
-               return -ENOMEM;
+               return err;
        }
 
-       elevator_attach(q, eq, data);
+       q->elevator = eq;
        return 0;
 }
 EXPORT_SYMBOL(elevator_init);
@@ -292,9 +287,8 @@ EXPORT_SYMBOL(elevator_init);
 void elevator_exit(struct elevator_queue *e)
 {
        mutex_lock(&e->sysfs_lock);
-       if (e->ops->elevator_exit_fn)
-               e->ops->elevator_exit_fn(e);
-       e->ops = NULL;
+       if (e->type->ops.elevator_exit_fn)
+               e->type->ops.elevator_exit_fn(e);
        mutex_unlock(&e->sysfs_lock);
 
        kobject_put(&e->kobj);
@@ -504,8 +498,8 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
                return ELEVATOR_BACK_MERGE;
        }
 
-       if (e->ops->elevator_merge_fn)
-               return e->ops->elevator_merge_fn(q, req, bio);
+       if (e->type->ops.elevator_merge_fn)
+               return e->type->ops.elevator_merge_fn(q, req, bio);
 
        return ELEVATOR_NO_MERGE;
 }
@@ -521,6 +515,7 @@ static bool elv_attempt_insert_merge(struct request_queue *q,
                                     struct request *rq)
 {
        struct request *__rq;
+       bool ret;
 
        if (blk_queue_nomerges(q))
                return false;
@@ -534,22 +529,29 @@ static bool elv_attempt_insert_merge(struct request_queue *q,
        if (blk_queue_noxmerges(q))
                return false;
 
+       ret = false;
        /*
         * See if our hash lookup can find a potential backmerge.
         */
-       __rq = elv_rqhash_find(q, blk_rq_pos(rq));
-       if (__rq && blk_attempt_req_merge(q, __rq, rq))
-               return true;
+       while (1) {
+               __rq = elv_rqhash_find(q, blk_rq_pos(rq));
+               if (!__rq || !blk_attempt_req_merge(q, __rq, rq))
+                       break;
 
-       return false;
+               /* The merged request could be merged with others, try again */
+               ret = true;
+               rq = __rq;
+       }
+
+       return ret;
 }
 
 void elv_merged_request(struct request_queue *q, struct request *rq, int type)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_merged_fn)
-               e->ops->elevator_merged_fn(q, rq, type);
+       if (e->type->ops.elevator_merged_fn)
+               e->type->ops.elevator_merged_fn(q, rq, type);
 
        if (type == ELEVATOR_BACK_MERGE)
                elv_rqhash_reposition(q, rq);
@@ -563,8 +565,8 @@ void elv_merge_requests(struct request_queue *q, struct request *rq,
        struct elevator_queue *e = q->elevator;
        const int next_sorted = next->cmd_flags & REQ_SORTED;
 
-       if (next_sorted && e->ops->elevator_merge_req_fn)
-               e->ops->elevator_merge_req_fn(q, rq, next);
+       if (next_sorted && e->type->ops.elevator_merge_req_fn)
+               e->type->ops.elevator_merge_req_fn(q, rq, next);
 
        elv_rqhash_reposition(q, rq);
 
@@ -581,8 +583,8 @@ void elv_bio_merged(struct request_queue *q, struct request *rq,
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_bio_merged_fn)
-               e->ops->elevator_bio_merged_fn(q, rq, bio);
+       if (e->type->ops.elevator_bio_merged_fn)
+               e->type->ops.elevator_bio_merged_fn(q, rq, bio);
 }
 
 void elv_requeue_request(struct request_queue *q, struct request *rq)
@@ -608,12 +610,12 @@ void elv_drain_elevator(struct request_queue *q)
 
        lockdep_assert_held(q->queue_lock);
 
-       while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+       while (q->elevator->type->ops.elevator_dispatch_fn(q, 1))
                ;
        if (q->nr_sorted && printed++ < 10) {
                printk(KERN_ERR "%s: forced dispatching is broken "
                       "(nr_sorted=%u), please report this\n",
-                      q->elevator->elevator_type->elevator_name, q->nr_sorted);
+                      q->elevator->type->elevator_name, q->nr_sorted);
        }
 }
 
@@ -702,7 +704,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
                 * rq cannot be accessed after calling
                 * elevator_add_req_fn.
                 */
-               q->elevator->ops->elevator_add_req_fn(q, rq);
+               q->elevator->type->ops.elevator_add_req_fn(q, rq);
                break;
 
        case ELEVATOR_INSERT_FLUSH:
@@ -731,8 +733,8 @@ struct request *elv_latter_request(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_latter_req_fn)
-               return e->ops->elevator_latter_req_fn(q, rq);
+       if (e->type->ops.elevator_latter_req_fn)
+               return e->type->ops.elevator_latter_req_fn(q, rq);
        return NULL;
 }
 
@@ -740,8 +742,8 @@ struct request *elv_former_request(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_former_req_fn)
-               return e->ops->elevator_former_req_fn(q, rq);
+       if (e->type->ops.elevator_former_req_fn)
+               return e->type->ops.elevator_former_req_fn(q, rq);
        return NULL;
 }
 
@@ -749,10 +751,8 @@ int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_set_req_fn)
-               return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
-
-       rq->elevator_private[0] = NULL;
+       if (e->type->ops.elevator_set_req_fn)
+               return e->type->ops.elevator_set_req_fn(q, rq, gfp_mask);
        return 0;
 }
 
@@ -760,16 +760,16 @@ void elv_put_request(struct request_queue *q, struct request *rq)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_put_req_fn)
-               e->ops->elevator_put_req_fn(rq);
+       if (e->type->ops.elevator_put_req_fn)
+               e->type->ops.elevator_put_req_fn(rq);
 }
 
 int elv_may_queue(struct request_queue *q, int rw)
 {
        struct elevator_queue *e = q->elevator;
 
-       if (e->ops->elevator_may_queue_fn)
-               return e->ops->elevator_may_queue_fn(q, rw);
+       if (e->type->ops.elevator_may_queue_fn)
+               return e->type->ops.elevator_may_queue_fn(q, rw);
 
        return ELV_MQUEUE_MAY;
 }
@@ -804,8 +804,8 @@ void elv_completed_request(struct request_queue *q, struct request *rq)
        if (blk_account_rq(rq)) {
                q->in_flight[rq_is_sync(rq)]--;
                if ((rq->cmd_flags & REQ_SORTED) &&
-                   e->ops->elevator_completed_req_fn)
-                       e->ops->elevator_completed_req_fn(q, rq);
+                   e->type->ops.elevator_completed_req_fn)
+                       e->type->ops.elevator_completed_req_fn(q, rq);
        }
 }
 
@@ -823,7 +823,7 @@ elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
        e = container_of(kobj, struct elevator_queue, kobj);
        mutex_lock(&e->sysfs_lock);
-       error = e->ops ? entry->show(e, page) : -ENOENT;
+       error = e->type ? entry->show(e, page) : -ENOENT;
        mutex_unlock(&e->sysfs_lock);
        return error;
 }
@@ -841,7 +841,7 @@ elv_attr_store(struct kobject *kobj, struct attribute *attr,
 
        e = container_of(kobj, struct elevator_queue, kobj);
        mutex_lock(&e->sysfs_lock);
-       error = e->ops ? entry->store(e, page, length) : -ENOENT;
+       error = e->type ? entry->store(e, page, length) : -ENOENT;
        mutex_unlock(&e->sysfs_lock);
        return error;
 }
@@ -856,14 +856,13 @@ static struct kobj_type elv_ktype = {
        .release        = elevator_release,
 };
 
-int elv_register_queue(struct request_queue *q)
+int __elv_register_queue(struct request_queue *q, struct elevator_queue *e)
 {
-       struct elevator_queue *e = q->elevator;
        int error;
 
        error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
        if (!error) {
-               struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
+               struct elv_fs_entry *attr = e->type->elevator_attrs;
                if (attr) {
                        while (attr->attr.name) {
                                if (sysfs_create_file(&e->kobj, &attr->attr))
@@ -876,31 +875,55 @@ int elv_register_queue(struct request_queue *q)
        }
        return error;
 }
-EXPORT_SYMBOL(elv_register_queue);
 
-static void __elv_unregister_queue(struct elevator_queue *e)
+int elv_register_queue(struct request_queue *q)
 {
-       kobject_uevent(&e->kobj, KOBJ_REMOVE);
-       kobject_del(&e->kobj);
-       e->registered = 0;
+       return __elv_register_queue(q, q->elevator);
 }
+EXPORT_SYMBOL(elv_register_queue);
 
 void elv_unregister_queue(struct request_queue *q)
 {
-       if (q)
-               __elv_unregister_queue(q->elevator);
+       if (q) {
+               struct elevator_queue *e = q->elevator;
+
+               kobject_uevent(&e->kobj, KOBJ_REMOVE);
+               kobject_del(&e->kobj);
+               e->registered = 0;
+       }
 }
 EXPORT_SYMBOL(elv_unregister_queue);
 
-void elv_register(struct elevator_type *e)
+int elv_register(struct elevator_type *e)
 {
        char *def = "";
 
+       /* create icq_cache if requested */
+       if (e->icq_size) {
+               if (WARN_ON(e->icq_size < sizeof(struct io_cq)) ||
+                   WARN_ON(e->icq_align < __alignof__(struct io_cq)))
+                       return -EINVAL;
+
+               snprintf(e->icq_cache_name, sizeof(e->icq_cache_name),
+                        "%s_io_cq", e->elevator_name);
+               e->icq_cache = kmem_cache_create(e->icq_cache_name, e->icq_size,
+                                                e->icq_align, 0, NULL);
+               if (!e->icq_cache)
+                       return -ENOMEM;
+       }
+
+       /* register, don't allow duplicate names */
        spin_lock(&elv_list_lock);
-       BUG_ON(elevator_find(e->elevator_name));
+       if (elevator_find(e->elevator_name)) {
+               spin_unlock(&elv_list_lock);
+               if (e->icq_cache)
+                       kmem_cache_destroy(e->icq_cache);
+               return -EBUSY;
+       }
        list_add_tail(&e->list, &elv_list);
        spin_unlock(&elv_list_lock);
 
+       /* print pretty message */
        if (!strcmp(e->elevator_name, chosen_elevator) ||
                        (!*chosen_elevator &&
                         !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
@@ -908,30 +931,26 @@ void elv_register(struct elevator_type *e)
 
        printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
                                                                def);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(elv_register);
 
 void elv_unregister(struct elevator_type *e)
 {
-       struct task_struct *g, *p;
+       /* unregister */
+       spin_lock(&elv_list_lock);
+       list_del_init(&e->list);
+       spin_unlock(&elv_list_lock);
 
        /*
-        * Iterate every thread in the process to remove the io contexts.
+        * Destroy icq_cache if it exists.  icq's are RCU managed.  Make
+        * sure all RCU operations are complete before proceeding.
         */
-       if (e->ops.trim) {
-               read_lock(&tasklist_lock);
-               do_each_thread(g, p) {
-                       task_lock(p);
-                       if (p->io_context)
-                               e->ops.trim(p->io_context);
-                       task_unlock(p);
-               } while_each_thread(g, p);
-               read_unlock(&tasklist_lock);
+       if (e->icq_cache) {
+               rcu_barrier();
+               kmem_cache_destroy(e->icq_cache);
+               e->icq_cache = NULL;
        }
-
-       spin_lock(&elv_list_lock);
-       list_del_init(&e->list);
-       spin_unlock(&elv_list_lock);
 }
 EXPORT_SYMBOL_GPL(elv_unregister);
 
@@ -944,54 +963,41 @@ EXPORT_SYMBOL_GPL(elv_unregister);
 static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
 {
        struct elevator_queue *old_elevator, *e;
-       void *data;
        int err;
 
-       /*
-        * Allocate new elevator
-        */
+       /* allocate new elevator */
        e = elevator_alloc(q, new_e);
        if (!e)
                return -ENOMEM;
 
-       data = elevator_init_queue(q, e);
-       if (!data) {
+       err = elevator_init_queue(q, e);
+       if (err) {
                kobject_put(&e->kobj);
-               return -ENOMEM;
+               return err;
        }
 
-       /*
-        * Turn on BYPASS and drain all requests w/ elevator private data
-        */
+       /* turn on BYPASS and drain all requests w/ elevator private data */
        elv_quiesce_start(q);
 
-       /*
-        * Remember old elevator.
-        */
-       old_elevator = q->elevator;
-
-       /*
-        * attach and start new elevator
-        */
-       spin_lock_irq(q->queue_lock);
-       elevator_attach(q, e, data);
-       spin_unlock_irq(q->queue_lock);
-
-       if (old_elevator->registered) {
-               __elv_unregister_queue(old_elevator);
-
-               err = elv_register_queue(q);
+       /* unregister old queue, register new one and kill old elevator */
+       if (q->elevator->registered) {
+               elv_unregister_queue(q);
+               err = __elv_register_queue(q, e);
                if (err)
                        goto fail_register;
        }
 
-       /*
-        * finally exit old elevator and turn off BYPASS.
-        */
+       /* done, clear io_cq's, switch elevators and turn off BYPASS */
+       spin_lock_irq(q->queue_lock);
+       ioc_clear_queue(q);
+       old_elevator = q->elevator;
+       q->elevator = e;
+       spin_unlock_irq(q->queue_lock);
+
        elevator_exit(old_elevator);
        elv_quiesce_end(q);
 
-       blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
+       blk_add_trace_msg(q, "elv switch: %s", e->type->elevator_name);
 
        return 0;
 
@@ -1001,7 +1007,6 @@ fail_register:
         * one again (along with re-adding the sysfs dir)
         */
        elevator_exit(e);
-       q->elevator = old_elevator;
        elv_register_queue(q);
        elv_quiesce_end(q);
 
@@ -1026,7 +1031,7 @@ int elevator_change(struct request_queue *q, const char *name)
                return -EINVAL;
        }
 
-       if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
+       if (!strcmp(elevator_name, q->elevator->type->elevator_name)) {
                elevator_put(e);
                return 0;
        }
@@ -1061,7 +1066,7 @@ ssize_t elv_iosched_show(struct request_queue *q, char *name)
        if (!q->elevator || !blk_queue_stackable(q))
                return sprintf(name, "none\n");
 
-       elv = e->elevator_type;
+       elv = e->type;
 
        spin_lock(&elv_list_lock);
        list_for_each_entry(__e, &elv_list, list) {
index 9253839714ff95b4acc6da413bd87f610ddce44c..c958169d24f04c338624e842622955453f62b5ae 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mutex.h>
 #include <linux/idr.h>
 #include <linux/log2.h>
-#include <linux/ctype.h>
 
 #include "blk.h"
 
@@ -616,7 +615,7 @@ void add_disk(struct gendisk *disk)
         * Take an extra ref on queue which will be put on disk_release()
         * so that it sticks around as long as @disk is there.
         */
-       WARN_ON_ONCE(blk_get_queue(disk->queue));
+       WARN_ON_ONCE(!blk_get_queue(disk->queue));
 
        retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
                                   "bdi");
@@ -916,74 +915,6 @@ static int __init genhd_device_init(void)
 
 subsys_initcall(genhd_device_init);
 
-static ssize_t alias_show(struct device *dev,
-                              struct device_attribute *attr, char *buf)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-       ssize_t ret = 0;
-
-       if (disk->alias)
-               ret = snprintf(buf, ALIAS_LEN, "%s\n", disk->alias);
-       return ret;
-}
-
-static ssize_t alias_store(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
-{
-       struct gendisk *disk = dev_to_disk(dev);
-       char *alias;
-       char *envp[] = { NULL, NULL };
-       unsigned char c;
-       int i;
-       ssize_t ret = count;
-
-       if (!count)
-               return -EINVAL;
-
-       if (count >= ALIAS_LEN) {
-               printk(KERN_ERR "alias: alias is too long\n");
-               return -EINVAL;
-       }
-
-       /* Validation check */
-       for (i = 0; i < count; i++) {
-               c = buf[i];
-               if (i == count - 1 && c == '\n')
-                       break;
-               if (!isalnum(c) && c != '_' && c != '-') {
-                       printk(KERN_ERR "alias: invalid alias\n");
-                       return -EINVAL;
-               }
-       }
-
-       if (disk->alias) {
-               printk(KERN_INFO "alias: %s is already assigned (%s)\n",
-                      disk->disk_name, disk->alias);
-               return -EINVAL;
-       }
-
-       alias = kasprintf(GFP_KERNEL, "%s", buf);
-       if (!alias)
-               return -ENOMEM;
-
-       if (alias[count - 1] == '\n')
-               alias[count - 1] = '\0';
-
-       envp[0] = kasprintf(GFP_KERNEL, "ALIAS=%s", alias);
-       if (!envp[0]) {
-               kfree(alias);
-               return -ENOMEM;
-       }
-
-       disk->alias = alias;
-       printk(KERN_INFO "alias: assigned %s to %s\n", alias, disk->disk_name);
-
-       kobject_uevent_env(&dev->kobj, KOBJ_ADD, envp);
-
-       kfree(envp[0]);
-       return ret;
-}
-
 static ssize_t disk_range_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
 {
@@ -1043,7 +974,6 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
        return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
 }
 
-static DEVICE_ATTR(alias, S_IRUGO|S_IWUSR, alias_show, alias_store);
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
 static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
 static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
@@ -1066,7 +996,6 @@ static struct device_attribute dev_attr_fail_timeout =
 #endif
 
 static struct attribute *disk_attrs[] = {
-       &dev_attr_alias.attr,
        &dev_attr_range.attr,
        &dev_attr_ext_range.attr,
        &dev_attr_removable.attr,
index 5c74efc019034af5ca519b747e5388258ebe83dd..ca939fc1030f29489f8a5f2c5a142c4e6a6f2264 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/capability.h>
 #include <linux/blkdev.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>
index 06389e9ef96d552836a1509ddf86745d82c09762..413a0b1d788c745df932745a65adb36ec119afaa 100644 (file)
@@ -94,9 +94,7 @@ static struct elevator_type elevator_noop = {
 
 static int __init noop_init(void)
 {
-       elv_register(&elevator_noop);
-
-       return 0;
+       return elv_register(&elevator_noop);
 }
 
 static void __exit noop_exit(void)
index a816f24f2d527993aea1fb724680857e77a06ff2..a0f768c1d9aa75fdb94a70dba711e175d8f66c9f 100644 (file)
@@ -383,6 +383,7 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_blkcipher rblkcipher;
@@ -404,6 +405,12 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
@@ -457,6 +464,7 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_blkcipher rblkcipher;
@@ -478,6 +486,12 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index 701556ffaaef0e6ca21256b52a8b594904852f9e..04add3dca6fe44dfc242e89a36741c56786327fa 100644 (file)
@@ -111,6 +111,7 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_aead raead;
@@ -132,6 +133,12 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
@@ -190,6 +197,7 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_aead raead;
@@ -210,6 +218,12 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 
 static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
index a3e6ef99394a9e78c7408ea4db65caa652004a1d..ac93c99cfae85abbc7fa433d94ef3fe80437cbb0 100644 (file)
@@ -399,6 +399,7 @@ static unsigned int crypto_ahash_extsize(struct crypto_alg *alg)
        return sizeof(struct crypto_shash *);
 }
 
+#ifdef CONFIG_NET
 static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_hash rhash;
@@ -416,6 +417,12 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index 518c22bd9562ee20cb040c63d7f9eb6a62b4d5c0..0d5a90ca6501e5a7febeb18a7aca46aad5cd78fd 100644 (file)
@@ -25,6 +25,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/highmem.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/async_tx.h>
index fdd8257d35d9d8133098f3592f5e3d1c2fd09261..91d5d385899ee06c507cee1aa496330405d6276b 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/raid/pq.h>
 #include <linux/async_tx.h>
index ce038d861eb9d2706e4474e725b5c6f4eadc4a00..a9f08a6a582ebccce298f718d0bbf5db8b1e1a7a 100644 (file)
@@ -22,6 +22,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/raid/pq.h>
 #include <linux/async_tx.h>
index 7f2c00a452053a2aeba0365b873f9ed27b3a5063..842120979374c9cfc0fd6810e577a3720d2c45ff 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 #include <linux/rculist.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/async_tx.h>
 
index bc28337fded2fdb2ae1b2725ae22464898bdb051..154cc84381c23d07374a4a411bd4f4a7146606f5 100644 (file)
@@ -25,6 +25,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/raid/xor.h>
index c88ff9e3fd30ec0c07c00b3e59917f6b36031363..aa2b0270ed16d007861c27dfdb54fb54e8a0e19b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/random.h>
+#include <linux/module.h>
 
 #undef pr
 #define pr(fmt, args...) pr_info("raid6test: " fmt, ##args)
index 2572d26001364b6206b300ecbc42ca18dfca9182..1e61d1a888b2b76f1b1e2fc8ac67e7741b221f45 100644 (file)
@@ -494,6 +494,7 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
                return crypto_init_blkcipher_ops_async(tfm);
 }
 
+#ifdef CONFIG_NET
 static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_blkcipher rblkcipher;
@@ -515,6 +516,12 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index 2abca780312d74246c60d7fcc9f6e9bf71f421c0..0605a2bbba75e17e67e59f602f1d12c453404031 100644 (file)
@@ -44,9 +44,6 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact)
 
        down_read(&crypto_alg_sem);
 
-       if (list_empty(&crypto_alg_list))
-               return NULL;
-
        list_for_each_entry(q, &crypto_alg_list, cra_list) {
                int match = 0;
 
index b980ee1af459f531f80475f4b7f888613060d22f..adad92a44ba2b763ced8c84eac837f5b5e2004d4 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include <crypto/algapi.h>
 #include <crypto/crypto_wq.h>
 
index 7fca1f59a4f5253baff7a13db7d1fcab9cc9371e..0477a6a01d58258eb07441561cb99640a2c3bd00 100644 (file)
@@ -23,6 +23,7 @@
 #include <crypto/internal/hash.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <asm/byteorder.h>
index fefda78a6a2aa925d29e776dc87a956a605a2ab2..2e458e5482d0c5708cbab83dddaad11215c28a0e 100644 (file)
@@ -48,6 +48,7 @@ static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm)
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_comp rpcomp;
@@ -62,6 +63,12 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index 3808697814d720aed2f9f5639791376586782be6..4a0a7aad2204fd4b31afea660452fa0ece9fb457 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/atomic.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
+#include <linux/module.h>      /* for module_name() */
 #include <linux/rwsem.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
index feb7de00f437380fc8e95a3bf21398c9b4b1ce23..64f864fa8043740f50bc186e58a2ee37d8a1499a 100644 (file)
@@ -60,6 +60,7 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
        return 0;
 }
 
+#ifdef CONFIG_NET
 static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_rng rrng;
@@ -76,6 +77,12 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index ea8a9c6e21e371170606863ecb5f8cc7a5030ea8..9100912716ae948fa57da13b9030a248f0460942 100644 (file)
@@ -524,6 +524,7 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg)
        return alg->cra_ctxsize;
 }
 
+#ifdef CONFIG_NET
 static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_hash rhash;
@@ -541,6 +542,12 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
 nla_put_failure:
        return -EMSGSIZE;
 }
+#else
+static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+       return -ENOSYS;
+}
+#endif
 
 static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
        __attribute__ ((unused));
index f35ff8a3926e2689deb66f6db541a79b1a6703f3..4243905ba135196b5285b5fbdc249f831c193df8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/crypto.h>
+#include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <asm/byteorder.h>
 #include <crypto/scatterwalk.h>
index bb7b67fba3495ccafbb2bc3a714b1dae6bae47a8..a5fbdf3738cfd4fa8f0938f53ceabd8fb4d9e2ea 100644 (file)
@@ -22,6 +22,7 @@
 #include <crypto/internal/hash.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
                           0x02020202, 0x02020202, 0x02020202, 0x02020202,
index e1141402dbed1868e4e473e21fe0bf09b8521daf..f4f523bf59390108e5095a303038da3ce872f345 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index c57b5c707a777647199012484e3bff977aff180b..20516e599476c6b59cbb100d7dfdd01357ef0273 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
index 52aaff3df562b94ffbd73206ae0cf363001e42bd..f06a3ee356ba72048b8a2fac77faeaf0324ec5e0 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acevents.h"
index 00cd95692a91df8af9535bdba3032fce17f0309a..aee887e3ca5c6ca57ac76de607e622b581f60e03 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index 55accb7018bb24776f32541fddfe7cf7498383f8..cc70f3fdcdd1a0f1d4222f6f7e6a84ca9ff7ebf5 100644 (file)
@@ -269,16 +269,17 @@ acpi_status acpi_hw_clear_acpi_status(void)
 
        status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
                                        ACPI_BITMASK_ALL_FIXED_STATUS);
-       if (ACPI_FAILURE(status)) {
-               goto unlock_and_exit;
-       }
+
+       acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
+
+       if (ACPI_FAILURE(status))
+               goto exit;
 
        /* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
        status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
 
-      unlock_and_exit:
-       acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
+exit:
        return_ACPI_STATUS(status);
 }
 
index 2ac28bbe8827822f975755b3b7dd7cabab0882a3..d52da307365006f36a067a3f033cad82fd93ff42 100644 (file)
@@ -46,6 +46,7 @@
 #include "accommon.h"
 #include "actables.h"
 #include <linux/tboot.h>
+#include <linux/module.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
index 9c8eb71a12fb41f8a09e9ac4e48a1b95daa68452..50d21c40b5c1bdd9767aeee49851cd754f0c917b 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 
index f75f81ad15c962a20c0cbc1afa7ba035e9ccca8c..c2793a82f120cae892508419c41a61569e63327e 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index c53f0040e49016b041b364c8366ca8568d953a08..e7f016d1b226edcd295f5a60adc73a0632d8b3ac 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index 3fd4526f3dba0f4de2d35f76c9c3c435ea64d1e4..83bf930243034608eeda0b5467883c1782c7c3c8 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index db7660f8b869a14789a8ae0e8d103fc6635c992f..57e6d825ed8411c8d0bd16c1de6208686a920244 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index 2ff657a28f26d3f8132c4e362b635bd198a3a1e9..fe86b37b16ce657bd719b68c656ce252581a0452 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acresrc.h"
index 4b7085dfc683bdef506be4fa62d0f29ae8af0465..e7d13f5d3f2da0f77d7b04a71e1118cb2793f7cd 100644 (file)
@@ -42,6 +42,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index a9bcd816dc298f7fbc1be186080915ade6410766..a1f8d7509e664f256bb03153319699915fc0bfef 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 
index 97cb36f85ce9d4e98f8e5576df9a4d70a049aeb6..8b087e2d64f4d9e331be57092e3c36395b58db8c 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index 833a38a9c90524c9b099b14d7d40761b660c1b75..ffba0a39c3e8598d1aeceecd1a007ddf974213cd 100644 (file)
@@ -43,6 +43,7 @@
 
 #define DEFINE_ACPI_GLOBALS
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 
index 98ad125e14ffc15fe2914eb249202d459bb342c4..420ebfe08c7218b091e1050217524547b15284aa 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acevents.h"
index 916ae097c43c9ef99b4d44c41939d0c0d4d6301c..8d0245ec431525bbd62a030d82e1eea2bfcdb9bd 100644 (file)
@@ -41,6 +41,7 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
+#include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
index 127408069ca7fa745953fd5a8e164cd74779c680..631b9477b99c02f827103aa00a8d3a83c380d359 100644 (file)
@@ -932,7 +932,8 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
 static int erst_open_pstore(struct pstore_info *psi);
 static int erst_close_pstore(struct pstore_info *psi);
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
-                          struct timespec *time, struct pstore_info *psi);
+                          struct timespec *time, char **buf,
+                          struct pstore_info *psi);
 static int erst_writer(enum pstore_type_id type, u64 *id, unsigned int part,
                       size_t size, struct pstore_info *psi);
 static int erst_clearer(enum pstore_type_id type, u64 id,
@@ -986,17 +987,23 @@ static int erst_close_pstore(struct pstore_info *psi)
 }
 
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
-                          struct timespec *time, struct pstore_info *psi)
+                          struct timespec *time, char **buf,
+                          struct pstore_info *psi)
 {
        int rc;
        ssize_t len = 0;
        u64 record_id;
-       struct cper_pstore_record *rcd = (struct cper_pstore_record *)
-                                       (erst_info.buf - sizeof(*rcd));
+       struct cper_pstore_record *rcd;
+       size_t rcd_len = sizeof(*rcd) + erst_info.bufsize;
 
        if (erst_disable)
                return -ENODEV;
 
+       rcd = kmalloc(rcd_len, GFP_KERNEL);
+       if (!rcd) {
+               rc = -ENOMEM;
+               goto out;
+       }
 skip:
        rc = erst_get_record_id_next(&reader_pos, &record_id);
        if (rc)
@@ -1004,22 +1011,27 @@ skip:
 
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               rc = -1;
+               rc = -EINVAL;
                goto out;
        }
 
-       len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
-                       erst_info.bufsize);
+       len = erst_read(record_id, &rcd->hdr, rcd_len);
        /* The record may be cleared by others, try read next record */
        if (len == -ENOENT)
                goto skip;
-       else if (len < 0) {
-               rc = -1;
+       else if (len < sizeof(*rcd)) {
+               rc = -EIO;
                goto out;
        }
        if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
                goto skip;
 
+       *buf = kmalloc(len, GFP_KERNEL);
+       if (*buf == NULL) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       memcpy(*buf, rcd->data, len - sizeof(*rcd));
        *id = record_id;
        if (uuid_le_cmp(rcd->sec_hdr.section_type,
                        CPER_SECTION_TYPE_DMESG) == 0)
@@ -1037,6 +1049,7 @@ skip:
        time->tv_nsec = 0;
 
 out:
+       kfree(rcd);
        return (rc < 0) ? rc : (len - sizeof(*rcd));
 }
 
index 7489b89c300fc3b0ab2f0a55c2bc09ead5e2c738..cfc0cc10af39f4e948d98a0d9de9d3e988a44fd1 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/io.h>
@@ -76,7 +76,7 @@ static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
 {
        struct acpi_iomap *map;
 
-       map = __acpi_find_iomap(paddr, size);
+       map = __acpi_find_iomap(paddr, size/8);
        if (map)
                return map->vaddr + (paddr - map->paddr);
        else
index af308d03f49235a6da0b30791e6857c824e8e32f..cb9629638def78fdd1432dc06102c2a5f5097a24 100644 (file)
@@ -28,7 +28,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
index 437ddbf0c49abbd521dde72eae7011c5e4d3672f..9ecec98bc76e9aa030c3c5c0c060ba283e1dcf64 100644 (file)
@@ -911,10 +911,7 @@ void __init acpi_early_init(void)
        }
 #endif
 
-       status =
-           acpi_enable_subsystem(~
-                                 (ACPI_NO_HARDWARE_INIT |
-                                  ACPI_NO_ACPI_ENABLE));
+       status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
                goto error0;
@@ -935,8 +932,7 @@ static int __init acpi_bus_init(void)
 
        acpi_os_initialize1();
 
-       status =
-           acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
+       status = acpi_enable_subsystem(ACPI_NO_ACPI_ENABLE);
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR PREFIX
                       "Unable to start the ACPI Interpreter\n");
index 182a9fc363553d5ef7372ad253fe06b449c0da96..b55d6a20dc0eda9a78419f29bb8eb229cc157930 100644 (file)
@@ -2,6 +2,7 @@
  * debugfs.c - ACPI debugfs interface to userspace.
  */
 
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
 #include <acpi/acpi_drivers.h>
index 22f918bacd35b0186af2328ec68d19b0567b08b9..6c47ae9793a7bf6a5e7c809b22c8d3e2d0d8d6db 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/debugfs.h>
+#include <linux/module.h>
 #include "internal.h"
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
index 85d908993809d39147ecdc4c9c4bc2203bf28d0e..1442737cedec784874fed04a74f251d543b1a61e 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/poll.h>
index 7c47ed55e528be27ea167bfaa5a6872b9b609bb1..29a4a5c8ee009da357b55f652c7bcb8f01a270b6 100644 (file)
@@ -6,6 +6,7 @@
  *
  * This file is released under the GPLv2.
  */
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/device.h>
index f5f986991b52f8a5a5faae4f3446105e1d2fe2bf..251c7b6273a9e83b21757aaa4c9c7cf3189a6e98 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/bcd.h>
 #include <asm/uaccess.h>
index 02d2a4c9084df510c7f6929d08a7082f1ecba5d8..3a0428e8435c0fcb0221540ded7f20d731d764ae 100644 (file)
@@ -7,6 +7,7 @@
  *     Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
  *     - Added _PDC for platforms with Intel CPUs
  */
+#include <linux/export.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
 
index a4e0f1ba6040c7f398f08f8816090ec5524ea629..9d7bc9f6b6cc662d52f7ba1802c0d2a7f524a7d1 100644 (file)
@@ -426,7 +426,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
 
        if (action == CPU_ONLINE && pr) {
                acpi_processor_ppc_has_changed(pr, 0);
-               acpi_processor_cst_has_changed(pr);
+               acpi_processor_hotplug(pr);
                acpi_processor_reevaluate_tstate(pr, action);
                acpi_processor_tstate_has_changed(pr);
        }
@@ -503,8 +503,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
        acpi_processor_get_throttling_info(pr);
        acpi_processor_get_limit_info(pr);
 
-
-       if (cpuidle_get_driver() == &acpi_idle_driver)
+       if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
                acpi_processor_power_init(pr, device);
 
        pr->cdev = thermal_cooling_device_register("Processor", device,
@@ -800,17 +799,9 @@ static int __init acpi_processor_init(void)
 
        memset(&errata, 0, sizeof(errata));
 
-       if (!cpuidle_register_driver(&acpi_idle_driver)) {
-               printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
-                       acpi_idle_driver.name);
-       } else {
-               printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n",
-                       cpuidle_get_driver()->name);
-       }
-
        result = acpi_bus_register_driver(&acpi_processor_driver);
        if (result < 0)
-               goto out_cpuidle;
+               return result;
 
        acpi_processor_install_hotplug_notify();
 
@@ -821,11 +812,6 @@ static int __init acpi_processor_init(void)
        acpi_processor_throttling_init();
 
        return 0;
-
-out_cpuidle:
-       cpuidle_unregister_driver(&acpi_idle_driver);
-
-       return result;
 }
 
 static void __exit acpi_processor_exit(void)
index 9b88f9828d8ca2ce98dc69be2606ffcc069d323e..0e8e2de2ed3e3a6b18ab07d07713a529295f31aa 100644 (file)
@@ -224,7 +224,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
 /*
  * Suspend / resume control
  */
-static int acpi_idle_suspend;
 static u32 saved_bm_rld;
 
 static void acpi_idle_bm_rld_save(void)
@@ -243,21 +242,13 @@ static void acpi_idle_bm_rld_restore(void)
 
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
 {
-       if (acpi_idle_suspend == 1)
-               return 0;
-
        acpi_idle_bm_rld_save();
-       acpi_idle_suspend = 1;
        return 0;
 }
 
 int acpi_processor_resume(struct acpi_device * device)
 {
-       if (acpi_idle_suspend == 0)
-               return 0;
-
        acpi_idle_bm_rld_restore();
-       acpi_idle_suspend = 0;
        return 0;
 }
 
@@ -741,66 +732,65 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
 /**
  * acpi_idle_enter_c1 - enters an ACPI C1 state-type
  * @dev: the target CPU
- * @state: the state data
+ * @drv: cpuidle driver containing cpuidle state info
+ * @index: index of target state
  *
  * This is equivalent to the HALT instruction.
  */
 static int acpi_idle_enter_c1(struct cpuidle_device *dev,
-                             struct cpuidle_state *state)
+               struct cpuidle_driver *drv, int index)
 {
        ktime_t  kt1, kt2;
        s64 idle_time;
        struct acpi_processor *pr;
-       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
 
        pr = __this_cpu_read(processors);
+       dev->last_residency = 0;
 
        if (unlikely(!pr))
-               return 0;
+               return -EINVAL;
 
        local_irq_disable();
 
-       /* Do not access any ACPI IO ports in suspend path */
-       if (acpi_idle_suspend) {
-               local_irq_enable();
-               cpu_relax();
-               return 0;
-       }
-
        lapic_timer_state_broadcast(pr, cx, 1);
        kt1 = ktime_get_real();
        acpi_idle_do_entry(cx);
        kt2 = ktime_get_real();
        idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
+       /* Update device last_residency*/
+       dev->last_residency = (int)idle_time;
+
        local_irq_enable();
        cx->usage++;
        lapic_timer_state_broadcast(pr, cx, 0);
 
-       return idle_time;
+       return index;
 }
 
 /**
  * acpi_idle_enter_simple - enters an ACPI state without BM handling
  * @dev: the target CPU
- * @state: the state data
+ * @drv: cpuidle driver with cpuidle state information
+ * @index: the index of suggested state
  */
 static int acpi_idle_enter_simple(struct cpuidle_device *dev,
-                                 struct cpuidle_state *state)
+               struct cpuidle_driver *drv, int index)
 {
        struct acpi_processor *pr;
-       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
        ktime_t  kt1, kt2;
        s64 idle_time_ns;
        s64 idle_time;
 
        pr = __this_cpu_read(processors);
+       dev->last_residency = 0;
 
        if (unlikely(!pr))
-               return 0;
-
-       if (acpi_idle_suspend)
-               return(acpi_idle_enter_c1(dev, state));
+               return -EINVAL;
 
        local_irq_disable();
 
@@ -815,7 +805,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                if (unlikely(need_resched())) {
                        current_thread_info()->status |= TS_POLLING;
                        local_irq_enable();
-                       return 0;
+                       return -EINVAL;
                }
        }
 
@@ -837,6 +827,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
        idle_time = idle_time_ns;
        do_div(idle_time, NSEC_PER_USEC);
 
+       /* Update device last_residency*/
+       dev->last_residency = (int)idle_time;
+
        /* Tell the scheduler how much we idled: */
        sched_clock_idle_wakeup_event(idle_time_ns);
 
@@ -848,7 +841,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 
        lapic_timer_state_broadcast(pr, cx, 0);
        cx->time += idle_time;
-       return idle_time;
+       return index;
 }
 
 static int c3_cpu_count;
@@ -857,37 +850,37 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
 /**
  * acpi_idle_enter_bm - enters C3 with proper BM handling
  * @dev: the target CPU
- * @state: the state data
+ * @drv: cpuidle driver containing state data
+ * @index: the index of suggested state
  *
  * If BM is detected, the deepest non-C3 idle state is entered instead.
  */
 static int acpi_idle_enter_bm(struct cpuidle_device *dev,
-                             struct cpuidle_state *state)
+               struct cpuidle_driver *drv, int index)
 {
        struct acpi_processor *pr;
-       struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
+       struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
        ktime_t  kt1, kt2;
        s64 idle_time_ns;
        s64 idle_time;
 
 
        pr = __this_cpu_read(processors);
+       dev->last_residency = 0;
 
        if (unlikely(!pr))
-               return 0;
-
-       if (acpi_idle_suspend)
-               return(acpi_idle_enter_c1(dev, state));
+               return -EINVAL;
 
        if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
-               if (dev->safe_state) {
-                       dev->last_state = dev->safe_state;
-                       return dev->safe_state->enter(dev, dev->safe_state);
+               if (drv->safe_state_index >= 0) {
+                       return drv->states[drv->safe_state_index].enter(dev,
+                                               drv, drv->safe_state_index);
                } else {
                        local_irq_disable();
                        acpi_safe_halt();
                        local_irq_enable();
-                       return 0;
+                       return -EINVAL;
                }
        }
 
@@ -904,7 +897,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
                if (unlikely(need_resched())) {
                        current_thread_info()->status |= TS_POLLING;
                        local_irq_enable();
-                       return 0;
+                       return -EINVAL;
                }
        }
 
@@ -954,6 +947,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        idle_time = idle_time_ns;
        do_div(idle_time, NSEC_PER_USEC);
 
+       /* Update device last_residency*/
+       dev->last_residency = (int)idle_time;
+
        /* Tell the scheduler how much we idled: */
        sched_clock_idle_wakeup_event(idle_time_ns);
 
@@ -965,7 +961,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 
        lapic_timer_state_broadcast(pr, cx, 0);
        cx->time += idle_time;
-       return idle_time;
+       return index;
 }
 
 struct cpuidle_driver acpi_idle_driver = {
@@ -974,14 +970,16 @@ struct cpuidle_driver acpi_idle_driver = {
 };
 
 /**
- * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
+ * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE
+ * device i.e. per-cpu data
+ *
  * @pr: the ACPI processor
  */
-static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
+static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
 {
        int i, count = CPUIDLE_DRIVER_STATE_START;
        struct acpi_processor_cx *cx;
-       struct cpuidle_state *state;
+       struct cpuidle_state_usage *state_usage;
        struct cpuidle_device *dev = &pr->power.dev;
 
        if (!pr->flags.power_setup_done)
@@ -992,9 +990,62 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
        }
 
        dev->cpu = pr->id;
+
+       if (max_cstate == 0)
+               max_cstate = 1;
+
+       for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
+               cx = &pr->power.states[i];
+               state_usage = &dev->states_usage[count];
+
+               if (!cx->valid)
+                       continue;
+
+#ifdef CONFIG_HOTPLUG_CPU
+               if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+                   !pr->flags.has_cst &&
+                   !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
+                       continue;
+#endif
+
+               cpuidle_set_statedata(state_usage, cx);
+
+               count++;
+               if (count == CPUIDLE_STATE_MAX)
+                       break;
+       }
+
+       dev->state_count = count;
+
+       if (!count)
+               return -EINVAL;
+
+       return 0;
+}
+
+/**
+ * acpi_processor_setup_cpuidle states- prepares and configures cpuidle
+ * global state data i.e. idle routines
+ *
+ * @pr: the ACPI processor
+ */
+static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
+{
+       int i, count = CPUIDLE_DRIVER_STATE_START;
+       struct acpi_processor_cx *cx;
+       struct cpuidle_state *state;
+       struct cpuidle_driver *drv = &acpi_idle_driver;
+
+       if (!pr->flags.power_setup_done)
+               return -EINVAL;
+
+       if (pr->flags.power == 0)
+               return -EINVAL;
+
+       drv->safe_state_index = -1;
        for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
-               dev->states[i].name[0] = '\0';
-               dev->states[i].desc[0] = '\0';
+               drv->states[i].name[0] = '\0';
+               drv->states[i].desc[0] = '\0';
        }
 
        if (max_cstate == 0)
@@ -1002,7 +1053,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
 
        for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
                cx = &pr->power.states[i];
-               state = &dev->states[count];
 
                if (!cx->valid)
                        continue;
@@ -1013,8 +1063,8 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
                        continue;
 #endif
-               cpuidle_set_statedata(state, cx);
 
+               state = &drv->states[count];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
                strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
                state->exit_latency = cx->latency;
@@ -1027,13 +1077,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                                state->flags |= CPUIDLE_FLAG_TIME_VALID;
 
                        state->enter = acpi_idle_enter_c1;
-                       dev->safe_state = state;
+                       drv->safe_state_index = count;
                        break;
 
                        case ACPI_STATE_C2:
                        state->flags |= CPUIDLE_FLAG_TIME_VALID;
                        state->enter = acpi_idle_enter_simple;
-                       dev->safe_state = state;
+                       drv->safe_state_index = count;
                        break;
 
                        case ACPI_STATE_C3:
@@ -1049,7 +1099,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                        break;
        }
 
-       dev->state_count = count;
+       drv->state_count = count;
 
        if (!count)
                return -EINVAL;
@@ -1057,7 +1107,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
        return 0;
 }
 
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+int acpi_processor_hotplug(struct acpi_processor *pr)
 {
        int ret = 0;
 
@@ -1078,7 +1128,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
        cpuidle_disable_device(&pr->power.dev);
        acpi_processor_get_power_info(pr);
        if (pr->flags.power) {
-               acpi_processor_setup_cpuidle(pr);
+               acpi_processor_setup_cpuidle_cx(pr);
                ret = cpuidle_enable_device(&pr->power.dev);
        }
        cpuidle_resume_and_unlock();
@@ -1086,10 +1136,72 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
        return ret;
 }
 
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+       int cpu;
+       struct acpi_processor *_pr;
+
+       if (disabled_by_idle_boot_param())
+               return 0;
+
+       if (!pr)
+               return -EINVAL;
+
+       if (nocst)
+               return -ENODEV;
+
+       if (!pr->flags.power_setup_done)
+               return -ENODEV;
+
+       /*
+        * FIXME:  Design the ACPI notification to make it once per
+        * system instead of once per-cpu.  This condition is a hack
+        * to make the code that updates C-States be called once.
+        */
+
+       if (smp_processor_id() == 0 &&
+                       cpuidle_get_driver() == &acpi_idle_driver) {
+
+               cpuidle_pause_and_lock();
+               /* Protect against cpu-hotplug */
+               get_online_cpus();
+
+               /* Disable all cpuidle devices */
+               for_each_online_cpu(cpu) {
+                       _pr = per_cpu(processors, cpu);
+                       if (!_pr || !_pr->flags.power_setup_done)
+                               continue;
+                       cpuidle_disable_device(&_pr->power.dev);
+               }
+
+               /* Populate Updated C-state information */
+               acpi_processor_setup_cpuidle_states(pr);
+
+               /* Enable all cpuidle devices */
+               for_each_online_cpu(cpu) {
+                       _pr = per_cpu(processors, cpu);
+                       if (!_pr || !_pr->flags.power_setup_done)
+                               continue;
+                       acpi_processor_get_power_info(_pr);
+                       if (_pr->flags.power) {
+                               acpi_processor_setup_cpuidle_cx(_pr);
+                               cpuidle_enable_device(&_pr->power.dev);
+                       }
+               }
+               put_online_cpus();
+               cpuidle_resume_and_unlock();
+       }
+
+       return 0;
+}
+
+static int acpi_processor_registered;
+
 int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device)
 {
        acpi_status status = 0;
+       int retval;
        static int first_run;
 
        if (disabled_by_idle_boot_param())
@@ -1126,9 +1238,26 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
         * platforms that only support C1.
         */
        if (pr->flags.power) {
-               acpi_processor_setup_cpuidle(pr);
-               if (cpuidle_register_device(&pr->power.dev))
-                       return -EIO;
+               /* Register acpi_idle_driver if not already registered */
+               if (!acpi_processor_registered) {
+                       acpi_processor_setup_cpuidle_states(pr);
+                       retval = cpuidle_register_driver(&acpi_idle_driver);
+                       if (retval)
+                               return retval;
+                       printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
+                                       acpi_idle_driver.name);
+               }
+               /* Register per-cpu cpuidle_device. Cpuidle driver
+                * must already be registered before registering device
+                */
+               acpi_processor_setup_cpuidle_cx(pr);
+               retval = cpuidle_register_device(&pr->power.dev);
+               if (retval) {
+                       if (acpi_processor_registered == 0)
+                               cpuidle_unregister_driver(&acpi_idle_driver);
+                       return retval;
+               }
+               acpi_processor_registered++;
        }
        return 0;
 }
@@ -1139,8 +1268,13 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
        if (disabled_by_idle_boot_param())
                return 0;
 
-       cpuidle_unregister_device(&pr->power.dev);
-       pr->flags.power_setup_done = 0;
+       if (pr->flags.power) {
+               cpuidle_unregister_device(&pr->power.dev);
+               acpi_processor_registered--;
+               if (acpi_processor_registered == 0)
+                       cpuidle_unregister_driver(&acpi_idle_driver);
+       }
 
+       pr->flags.power_setup_done = 0;
        return 0;
 }
index f8be23b6c12919f5d31a4cce63908b920f8f3c4b..f8d2a472795c588b8eee51cfa1319fa98a6e132d 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include "sbshc.h"
 
index 449c556274c052cf4c9fd221c577b7735bcdca0f..8ab80bafe3f1604f3e05e7287ed5fe4f9ed1e6fb 100644 (file)
@@ -1062,13 +1062,12 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id)
        if (!id)
                return;
 
-       id->id = kmalloc(strlen(dev_id) + 1, GFP_KERNEL);
+       id->id = kstrdup(dev_id, GFP_KERNEL);
        if (!id->id) {
                kfree(id);
                return;
        }
 
-       strcpy(id->id, dev_id);
        list_add_tail(&id->list, &device->pnp.ids);
 }
 
index 0e46faef1d301a298bb8e233a4d4893090831504..6d9a3ab58db2608c3101cea8cf7ccefa54439d66 100644 (file)
@@ -398,6 +398,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        },
        {
        .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VPCEB17FX",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
        .ident = "Sony Vaio VGN-SR11M",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
index c538d0ef10ff648de4140eb54f6f7c8c3c7bc88f..9f66181c814e78e2fc40c88ba743b5aa062e50e9 100644 (file)
@@ -706,11 +706,23 @@ static void __exit interrupt_stats_exit(void)
        return;
 }
 
+static ssize_t
+acpi_show_profile(struct device *dev, struct device_attribute *attr,
+                 char *buf)
+{
+       return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile);
+}
+
+static const struct device_attribute pm_profile_attr =
+       __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL);
+
 int __init acpi_sysfs_init(void)
 {
        int result;
 
        result = acpi_tables_sysfs_init();
-
+       if (result)
+               return result;
+       result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
        return result;
 }
index 5af3479714f6dbd81268ef482603865258c4ee71..f3f0fe7e255a23ef679f718324cbf9e2f16e3f31 100644 (file)
@@ -33,6 +33,7 @@
  *
  */
 
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/pci.h>
index fb7b90b059226c7235c9c5a719fda26aeb6ba981..cf26222a93c5ddc7a88092ab9c7fcdf262a45ae1 100644 (file)
@@ -390,6 +390,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        /* Promise */
        { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },   /* PDC42819 */
 
+       /* Asmedia */
+       { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },   /* ASM1061 */
+
        /* Generic, PCI class code for AHCI */
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
index 004f2ce3dc737a01ddc9adab97958e1cd88d4b7c..43b875810d1b7b91c98386fb6f3a5c58be79fdb9 100644 (file)
@@ -65,9 +65,9 @@ static struct scsi_host_template ahci_platform_sht = {
 static int __init ahci_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct ahci_platform_data *pdata = dev->platform_data;
+       struct ahci_platform_data *pdata = dev_get_platdata(dev);
        const struct platform_device_id *id = platform_get_device_id(pdev);
-       struct ata_port_info pi = ahci_port_info[id->driver_data];
+       struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
        const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ahci_host_priv *hpriv;
        struct ata_host *host;
@@ -191,7 +191,7 @@ err0:
 static int __devexit ahci_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct ahci_platform_data *pdata = dev->platform_data;
+       struct ahci_platform_data *pdata = dev_get_platdata(dev);
        struct ata_host *host = dev_get_drvdata(dev);
 
        ata_host_detach(host);
index c021186736e9328cdc8c5de33ea1349177613ef9..a9b282038000c921eca51f7484866d890dec5d54 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -2882,7 +2883,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
            sata_scr_read(link, SCR_STATUS, &sstatus))
                rc = -ERESTART;
 
-       if (rc == -ERESTART || try >= max_tries) {
+       if (try >= max_tries) {
                /*
                 * Thaw host port even if reset failed, so that the port
                 * can be retried on the next phy event.  This risks
@@ -2908,6 +2909,16 @@ int ata_eh_reset(struct ata_link *link, int classify,
                ata_eh_acquire(ap);
        }
 
+       /*
+        * While disks spinup behind PMP, some controllers fail sending SRST.
+        * They need to be reset - as well as the PMP - before retrying.
+        */
+       if (rc == -ERESTART) {
+               if (ata_is_host_link(link))
+                       ata_eh_thaw_port(ap);
+               goto out;
+       }
+
        if (try == max_tries - 1) {
                sata_down_spd_limit(link, 0);
                if (slave)
index 3eb2b816eb2a573a875baaf6bbcb5a82caabf5ee..21b80c555c607768912953c1f355bf25615c8a22 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/libata.h>
 #include <linux/slab.h>
 #include "libata.h"
@@ -388,12 +389,9 @@ static void sata_pmp_quirks(struct ata_port *ap)
                        /* link reports offline after LPM */
                        link->flags |= ATA_LFLAG_NO_LPM;
 
-                       /* Class code report is unreliable and SRST
-                        * times out under certain configurations.
-                        */
+                       /* Class code report is unreliable. */
                        if (link->pmp < 5)
-                               link->flags |= ATA_LFLAG_NO_SRST |
-                                              ATA_LFLAG_ASSUME_ATA;
+                               link->flags |= ATA_LFLAG_ASSUME_ATA;
 
                        /* port 5 is for SEMB device and it doesn't like SRST */
                        if (link->pmp == 5)
index 19ba77032ac27ed94d0ca54aa23ccb5e2e8eb3fa..2a5412e7e9c11c85d23c12959ad503f9f2e182aa 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
@@ -1216,6 +1217,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
 
 /**
  *     __ata_change_queue_depth - helper for ata_scsi_change_queue_depth
+ *     @ap: ATA port to which the device change the queue depth
+ *     @sdev: SCSI device to configure queue depth for
+ *     @queue_depth: new queue depth
+ *     @reason: calling context
  *
  *     libsas and libata have different approaches for associating a sdev to
  *     its ata_port.
index 239bfa67d0321eef0e3e6198fbfb606cdf05ddf9..4cadfa28f940450ee2f5a890af44e34ad583e921 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kernel.h>
 #include <linux/gfp.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <linux/libata.h>
 #include <linux/highmem.h>
 
@@ -2532,10 +2533,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,
        if (rc)
                goto out;
 
+#ifdef CONFIG_ATA_BMDMA
        if (bmdma)
                /* prepare and activate BMDMA host */
                rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        else
+#endif
                /* prepare and activate SFF host */
                rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
        if (rc)
@@ -2543,10 +2546,12 @@ static int ata_pci_init_one(struct pci_dev *pdev,
        host->private_data = host_priv;
        host->flags |= hflags;
 
+#ifdef CONFIG_ATA_BMDMA
        if (bmdma) {
                pci_set_master(pdev);
                rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
        } else
+#endif
                rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
 out:
        if (rc == 0)
index a72ab0dde4e52332104003fd63806d85f271c037..2a472c5bb7db7015d76118434a8d50e7795a07d1 100644 (file)
@@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev)
        }
 
        ret = of_irq_to_resource(dn, 0, &irq_res);
-       if (ret == NO_IRQ)
+       if (!ret)
                irq_res.start = irq_res.end = 0;
        else
                irq_res.flags = 0;
index 447d9c05fb5a927a3d5b2c513fe4b8a70c36f625..95ec435f0eb425049a9a447a49aaea430df6f949 100644 (file)
@@ -104,7 +104,7 @@ static const struct ata_port_info sis_port_info = {
 };
 
 MODULE_AUTHOR("Uwe Koziolek");
-MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
+MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
index a34dca0ad041713af58df661856195baaaf7ca63..21c1b96c34c6da46264cadfd8d38d7cb88571ba4 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/notifier.h>
 
 /**
  * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure.
index 82c865452c7080d180ec6a453ab1efb3e988dac3..919daa7cd5b1db3443c65863cc07c20c830f680b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kallsyms.h>
 #include <linux/mutex.h>
 #include <linux/async.h>
+#include <linux/pm_runtime.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -1743,6 +1744,10 @@ void device_shutdown(void)
                list_del_init(&dev->kobj.entry);
                spin_unlock(&devices_kset->list_lock);
 
+               /* Don't allow any more runtime suspends */
+               pm_runtime_get_noresume(dev);
+               pm_runtime_barrier(dev);
+
                if (dev->bus && dev->bus->shutdown) {
                        dev_dbg(dev, "shutdown\n");
                        dev->bus->shutdown(dev);
index f369e2795985a66d0e00c399464bef711acbf697..bb0025c510b3860e1f84b434c03a4d34a1d64851 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 
 struct dma_coherent_mem {
index 763d59c1eb65d0e329a727b1f58953e6ab2bca9b..6f3676f1559f173b7767a2bdda577df2292ef461 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 
 /*
index 6428cba3aadddf51081926671143504e5a9247e8..4f8b741f461526b4c3034cf4690216a03538f2a5 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kobject.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include "base.h"
 
 struct kobject *hypervisor_kobj;
index 793f796c4da3e1cd20143e1266d41246f2289b73..5693ecee9a4052a339b9eca105ff3704fffe29b4 100644 (file)
@@ -127,12 +127,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       nid, K(node_page_state(nid, NR_WRITEBACK)),
                       nid, K(node_page_state(nid, NR_FILE_PAGES)),
                       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
-                      nid, K(node_page_state(nid, NR_ANON_PAGES)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+                      nid, K(node_page_state(nid, NR_ANON_PAGES)
                        + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
-                       HPAGE_PMD_NR
+                       HPAGE_PMD_NR),
+#else
+                      nid, K(node_page_state(nid, NR_ANON_PAGES)),
 #endif
-                      ),
                       nid, K(node_page_state(nid, NR_SHMEM)),
                       nid, node_page_state(nid, NR_KERNEL_STACK) *
                                THREAD_SIZE / 1024,
@@ -143,13 +144,14 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
                                node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
                       nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
-                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
                        , nid,
                        K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
-                       HPAGE_PMD_NR)
+                       HPAGE_PMD_NR));
+#else
+                      nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));
 #endif
-                      );
        n += hugetlb_report_node_meminfo(nid, buf + n);
        return n;
 }
index 5f0f85d5c5765558a25fa7ec165be968e5fbcabf..428e55e012dcd06f91ade3154c941aab6f1d5bb5 100644 (file)
@@ -229,7 +229,8 @@ int pm_clk_suspend(struct device *dev)
 
        list_for_each_entry_reverse(ce, &psd->clock_list, node) {
                if (ce->status < PCE_STATUS_ERROR) {
-                       clk_disable(ce->clk);
+                       if (ce->status == PCE_STATUS_ENABLED)
+                               clk_disable(ce->clk);
                        ce->status = PCE_STATUS_ACQUIRED;
                }
        }
index 29820c3961823bdc6dbfe5d6061f1100d4c21161..4af7c1cbf909b61d576bc0900df85983d2eedf9d 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/pm_clock.h>
 
index 9508df71274bf5489de904aa53f5a3afc9eeeb6f..265a0ee3b49eac0ae9a179e158c2f612d3eedba8 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/export.h>
 
 #ifdef CONFIG_PM_RUNTIME
 /**
index 59f8ab23548689768a45baa6d68c11c97ca75b50..c3d2dfcf438dd1735fcf401be9f8185440e9a1a9 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/device.h>
 #include <linux/kallsyms.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
@@ -919,7 +920,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
  End:
        if (!error) {
                dev->power.is_suspended = true;
-               if (dev->power.wakeup_path && dev->parent)
+               if (dev->power.wakeup_path
+                   && dev->parent && !dev->parent->power.ignore_children)
                        dev->parent->power.wakeup_path = true;
        }
 
index 434a6c01167521007e14f11ad0d7f2accdb8cf7b..95706fa24c73559ecd04aacf8c0a6296616c452f 100644 (file)
@@ -669,7 +669,7 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev)
        struct device_opp *dev_opp = find_device_opp(dev);
 
        if (IS_ERR(dev_opp))
-               return ERR_PTR(PTR_ERR(dev_opp)); /* matching type */
+               return ERR_CAST(dev_opp); /* matching type */
 
        return &dev_opp->head;
 }
index 91e061417382fc26a8baa387172537e944a5a0eb..86de6c50fc4181f796c5d0e3d20e796380f112b0 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 
 
 static DEFINE_MUTEX(dev_pm_qos_mtx);
@@ -211,11 +212,9 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
        if (!dev || !req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_add_request() called for already "
-                       "added request\n");
+       if (WARN(dev_pm_qos_request_active(req),
+                "%s() called for already added request\n", __func__))
                return -EINVAL;
-       }
 
        req->dev = dev;
 
@@ -270,11 +269,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (!dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_update_request() called for "
-                       "unknown object\n");
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
                return -EINVAL;
-       }
 
        mutex_lock(&dev_pm_qos_mtx);
 
@@ -311,11 +308,9 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
-       if (!dev_pm_qos_request_active(req)) {
-               WARN(1, KERN_ERR "dev_pm_qos_remove_request() called for "
-                       "unknown object\n");
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
                return -EINVAL;
-       }
 
        mutex_lock(&dev_pm_qos_mtx);
 
index 6bb3aafa85ede9efe75d41abba500211fc9b262b..8c78443bca8f743caa1638f70f46a528d92f19e0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/export.h>
 #include <linux/pm_runtime.h>
 #include <trace/events/rpm.h>
 #include "power.h"
@@ -29,13 +30,10 @@ static int rpm_suspend(struct device *dev, int rpmflags);
 void update_pm_runtime_accounting(struct device *dev)
 {
        unsigned long now = jiffies;
-       int delta;
+       unsigned long delta;
 
        delta = now - dev->power.accounting_timestamp;
 
-       if (delta < 0)
-               delta = 0;
-
        dev->power.accounting_timestamp = now;
 
        if (dev->power.disable_depth > 0)
@@ -296,6 +294,9 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
  * the callback was running then carry it out, otherwise send an idle
  * notification for its parent (if the suspend succeeded and both
  * ignore_children of parent->power and irq_safe of dev->power are not set).
+ * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
+ * flag is set and the next autosuspend-delay expiration time is in the
+ * future, schedule another autosuspend attempt.
  *
  * This function must be called under dev->power.lock with interrupts disabled.
  */
@@ -416,10 +417,21 @@ static int rpm_suspend(struct device *dev, int rpmflags)
        if (retval) {
                __update_runtime_status(dev, RPM_ACTIVE);
                dev->power.deferred_resume = false;
-               if (retval == -EAGAIN || retval == -EBUSY)
+               if (retval == -EAGAIN || retval == -EBUSY) {
                        dev->power.runtime_error = 0;
-               else
+
+                       /*
+                        * If the callback routine failed an autosuspend, and
+                        * if the last_busy time has been updated so that there
+                        * is a new autosuspend expiration time, automatically
+                        * reschedule another autosuspend.
+                        */
+                       if ((rpmflags & RPM_AUTO) &&
+                           pm_runtime_autosuspend_expiration(dev) != 0)
+                               goto repeat;
+               } else {
                        pm_runtime_cancel_pending(dev);
+               }
                wake_up_all(&dev->power.wait_queue);
                goto out;
        }
index 17b7934f31cb00c014688d6d0e197886687c3730..adf41be0ea664b7debc52b0ec49c5282a4fb46d5 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/pm_runtime.h>
 #include <linux/atomic.h>
 #include <linux/jiffies.h>
index af10abecb99be81fb98de22bfd7fa8decb404595..d94a1f5121cf2292b5032ced369b0d6308faee72 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/resume-trace.h>
+#include <linux/export.h>
 #include <linux/rtc.h>
 
 #include <asm/rtc.h>
index 14ee07e9cc431a3882497b689daea2fe75ce3e94..caf995fb774b4ceef6ad03809ac7a2f1b5a5e9e5 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/capability.h>
+#include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
index afcfef838263e3cf9ec1067ce3b92625d4c3056a..666f6f5011dc85339287f9b982f991e22081626b 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <trace/events/regmap.h>
 #include <linux/bsearch.h>
 #include <linux/sort.h>
index 84997efdb23d699de42e5c8beadd1724795a1968..f6c453c3816e79e285cd65de6332e9d63ca59aa5 100644 (file)
@@ -27,6 +27,7 @@
  * transport class is framed entirely in terms of generic devices to
  * allow it to be used by any physical HBA in the system.
  */
+#include <linux/export.h>
 #include <linux/attribute_container.h>
 #include <linux/transport_class.h>
 
index 189a97b51be909be5fa5543b91141264dc35b0b1..893f6e0c759fa75f0831ad6fa157567ab31a71a1 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
 bool bcma_core_is_enabled(struct bcma_device *core)
index 47cce9d696306f28f8f6d9221e73b0f863df7f7e..e9f1b3fd252c2302cca16e196be08fd0740beed5 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
index 2968d809d49f8357cae15ef644cdd5a81cbe0a5a..800163c8c2e7a046a4aa1219e6d7c876be0be19b 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
 static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
index 81f3d0a4b856cb96b78c5492e779f1042c2788c5..4fde6254f04e236a71ea6f755df4e106aef0f495 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
 /**************************************************
index ac4bc626c14969888f00b643a8e53e6f5b31b191..1b51d8b7ac8024698bc9b053322a2b82ddbe47ab 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/bcma/bcma.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 
 static void bcma_host_pci_switch_core(struct bcma_device *core)
 {
index 8c09c3e547cd1d305050d9885a6641c9b33dcd01..70c84b95109860205a7ec1d216ef8df58f34ba30 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/module.h>
 #include <linux/bcma/bcma.h>
 #include <linux/slab.h>
 
index 167ba0af47f54b527e3b231f7aaf92b96c37cf00..321de7b6c44228e5b7c5cfc0a410be19a54759fe 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/genhd.h>
 #include <linux/netdevice.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 #include "aoe.h"
 
 static DEFINE_MUTEX(aoeblk_mutex);
index 146296ca4965a8e44123928d2406820b949a1488..5f8e39c43ae53f8a5264dd600ad64cd759485467 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/skbuff.h>
+#include <linux/export.h>
 #include "aoe.h"
 
 enum {
index 486f94ef24d499bfe0d17eb379fe5043a94f36a5..8004ac30a7a8634bc7f963be8db2c6c1eac61ce4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -4319,6 +4320,10 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
                dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
                return -ENODEV;
        }
+
+       pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
+                               PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
+
        err = pci_enable_device(h->pdev);
        if (err) {
                dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n");
@@ -5158,6 +5163,7 @@ reinit_after_soft_reset:
        h->cciss_max_sectors = 8192;
 
        rebuild_lun_table(h, 1, 0);
+       cciss_engage_scsi(h);
        h->busy_initializing = 0;
        return 1;
 
index 951a4e33b92b788b208d6320636b77422bf9474f..e820b68d2f6cd4d74382b85b5e020069294f00f3 100644 (file)
@@ -1720,5 +1720,6 @@ static int  cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
 /* If no tape support, then these become defined out of existence */
 
 #define cciss_scsi_setup(cntl_num)
+#define cciss_engage_scsi(h)
 
 #endif /* CONFIG_CISS_SCSI_TAPE */
index 3d806820280e3bc4aaa5e81d6bea411f6597e400..68b205a9338f631adbd98df74836b98aa95d27ac 100644 (file)
@@ -161,17 +161,19 @@ static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
        &xor_funcs
 };
 
-static loff_t get_loop_size(struct loop_device *lo, struct file *file)
+static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)
 {
-       loff_t size, offset, loopsize;
+       loff_t size, loopsize;
 
        /* Compute loopsize in bytes */
        size = i_size_read(file->f_mapping->host);
-       offset = lo->lo_offset;
        loopsize = size - offset;
-       if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
-               loopsize = lo->lo_sizelimit;
+       /* offset is beyond i_size, wierd but possible */
+       if (loopsize < 0)
+               return 0;
 
+       if (sizelimit > 0 && sizelimit < loopsize)
+               loopsize = sizelimit;
        /*
         * Unfortunately, if we want to do I/O on the device,
         * the number of 512-byte sectors has to fit into a sector_t.
@@ -179,17 +181,25 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file)
        return loopsize >> 9;
 }
 
+static loff_t get_loop_size(struct loop_device *lo, struct file *file)
+{
+       return get_size(lo->lo_offset, lo->lo_sizelimit, file);
+}
+
 static int
-figure_loop_size(struct loop_device *lo)
+figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
 {
-       loff_t size = get_loop_size(lo, lo->lo_backing_file);
+       loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);
        sector_t x = (sector_t)size;
 
        if (unlikely((loff_t)x != size))
                return -EFBIG;
-
+       if (lo->lo_offset != offset)
+               lo->lo_offset = offset;
+       if (lo->lo_sizelimit != sizelimit)
+               lo->lo_sizelimit = sizelimit;
        set_capacity(lo->lo_disk, x);
-       return 0;                                       
+       return 0;
 }
 
 static inline int
@@ -372,7 +382,8 @@ do_lo_receive(struct loop_device *lo,
 
        if (retval < 0)
                return retval;
-
+       if (retval != bvec->bv_len)
+               return -EIO;
        return 0;
 }
 
@@ -1058,9 +1069,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
 
        if (lo->lo_offset != info->lo_offset ||
            lo->lo_sizelimit != info->lo_sizelimit) {
-               lo->lo_offset = info->lo_offset;
-               lo->lo_sizelimit = info->lo_sizelimit;
-               if (figure_loop_size(lo))
+               if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
                        return -EFBIG;
        }
        loop_config_discard(lo);
@@ -1246,7 +1255,7 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
        err = -ENXIO;
        if (unlikely(lo->lo_state != Lo_bound))
                goto out;
-       err = figure_loop_size(lo);
+       err = figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
        if (unlikely(err))
                goto out;
        sec = get_capacity(lo->lo_disk);
@@ -1284,13 +1293,19 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
                        goto out_unlocked;
                break;
        case LOOP_SET_STATUS:
-               err = loop_set_status_old(lo, (struct loop_info __user *) arg);
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+                       err = loop_set_status_old(lo,
+                                       (struct loop_info __user *)arg);
                break;
        case LOOP_GET_STATUS:
                err = loop_get_status_old(lo, (struct loop_info __user *) arg);
                break;
        case LOOP_SET_STATUS64:
-               err = loop_set_status64(lo, (struct loop_info64 __user *) arg);
+               err = -EPERM;
+               if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+                       err = loop_set_status64(lo,
+                                       (struct loop_info64 __user *) arg);
                break;
        case LOOP_GET_STATUS64:
                err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
index 6b9a2000d56affdd7788ff26581ae587f3937f96..a79fb4f7ff622632809c2b93f47df93fb7561ccb 100644 (file)
@@ -630,6 +630,7 @@ static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t
                if (dev->status & 0x10)
                        return -ETIME;
 
+       memset(&hdr, 0, sizeof(hdr));
        hdr.magic = PG_MAGIC;
        hdr.dlen = dev->dlen;
        copy = 0;
index 8e1ce2e2916a72cdeff49a8fa46f2179d04691dd..da0abc1838c196680bd093f0664924140ae4834f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ata.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
index 7fad7af87eb205dbf82805336d73fc37d797cfcb..f58cdcfb305f2c497f408ac427e80fd1c536e648 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
index b70f0fca9a42e724e3911d62cd64729a2f20ce4b..e7472f567c9de7bb640bf1cc5b56e51b7cf88471 100644 (file)
@@ -619,8 +619,10 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx)
               host->state == HST_DEV_SCAN);
        spin_unlock_irq(&host->lock);
 
-       DPRINTK("blk_insert_request, tag == %u\n", idx);
-       blk_insert_request(host->oob_q, crq->rq, 1, crq);
+       DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx);
+       crq->rq->cmd_type = REQ_TYPE_SPECIAL;
+       crq->rq->special = crq;
+       blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL);
 
        return 0;
 
@@ -658,8 +660,10 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
        BUG_ON(rc < 0);
        crq->msg_bucket = (u32) rc;
 
-       DPRINTK("blk_insert_request, tag == %u\n", idx);
-       blk_insert_request(host->oob_q, crq->rq, 1, crq);
+       DPRINTK("blk_execute_rq_nowait, tag == %u\n", idx);
+       crq->rq->cmd_type = REQ_TYPE_SPECIAL;
+       crq->rq->special = crq;
+       blk_execute_rq_nowait(host->oob_q, NULL, crq->rq, true, NULL);
 
        return 0;
 }
index e7a5750a93d945657f0aa1e63175ad66369aeaa6..4d0b70adf5f73356bb79fafc06927b5f33207a64 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
+#include <linux/module.h>
 #include <linux/virtio.h>
 #include <linux/virtio_blk.h>
 #include <linux/scatterlist.h>
index 15ec4db194d1bb793e4409dfed54563e4b71b080..0088bf60f3689db6a704c1856c4f94a682d7db44 100644 (file)
@@ -39,9 +39,6 @@
 #include <linux/list.h>
 #include <linux/delay.h>
 #include <linux/freezer.h>
-#include <linux/loop.h>
-#include <linux/falloc.h>
-#include <linux/fs.h>
 
 #include <xen/events.h>
 #include <xen/page.h>
@@ -362,7 +359,7 @@ static int xen_blkbk_map(struct blkif_request *req,
 {
        struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        int i;
-       int nseg = req->nr_segments;
+       int nseg = req->u.rw.nr_segments;
        int ret = 0;
 
        /*
@@ -416,30 +413,25 @@ static int xen_blkbk_map(struct blkif_request *req,
        return ret;
 }
 
-static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req)
+static int dispatch_discard_io(struct xen_blkif *blkif,
+                               struct blkif_request *req)
 {
        int err = 0;
        int status = BLKIF_RSP_OKAY;
        struct block_device *bdev = blkif->vbd.bdev;
 
-       if (blkif->blk_backend_type == BLKIF_BACKEND_PHY)
-               /* just forward the discard request */
+       blkif->st_ds_req++;
+
+       xen_blkif_get(blkif);
+       if (blkif->blk_backend_type == BLKIF_BACKEND_PHY ||
+           blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
+               unsigned long secure = (blkif->vbd.discard_secure &&
+                       (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
+                       BLKDEV_DISCARD_SECURE : 0;
                err = blkdev_issue_discard(bdev,
                                req->u.discard.sector_number,
                                req->u.discard.nr_sectors,
-                               GFP_KERNEL, 0);
-       else if (blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
-               /* punch a hole in the backing file */
-               struct loop_device *lo = bdev->bd_disk->private_data;
-               struct file *file = lo->lo_backing_file;
-
-               if (file->f_op->fallocate)
-                       err = file->f_op->fallocate(file,
-                               FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE,
-                               req->u.discard.sector_number << 9,
-                               req->u.discard.nr_sectors << 9);
-               else
-                       err = -EOPNOTSUPP;
+                               GFP_KERNEL, secure);
        } else
                err = -EOPNOTSUPP;
 
@@ -449,7 +441,9 @@ static void xen_blk_discard(struct xen_blkif *blkif, struct blkif_request *req)
        } else if (err)
                status = BLKIF_RSP_ERROR;
 
-       make_response(blkif, req->id, req->operation, status);
+       make_response(blkif, req->u.discard.id, req->operation, status);
+       xen_blkif_put(blkif);
+       return err;
 }
 
 static void xen_blk_drain_io(struct xen_blkif *blkif)
@@ -573,8 +567,11 @@ __do_block_io_op(struct xen_blkif *blkif)
 
                /* Apply all sanity checks to /private copy/ of request. */
                barrier();
-
-               if (dispatch_rw_block_io(blkif, &req, pending_req))
+               if (unlikely(req.operation == BLKIF_OP_DISCARD)) {
+                       free_req(pending_req);
+                       if (dispatch_discard_io(blkif, &req))
+                               break;
+               } else if (dispatch_rw_block_io(blkif, &req, pending_req))
                        break;
 
                /* Yield point for this unbounded loop. */
@@ -633,10 +630,6 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                blkif->st_f_req++;
                operation = WRITE_FLUSH;
                break;
-       case BLKIF_OP_DISCARD:
-               blkif->st_ds_req++;
-               operation = REQ_DISCARD;
-               break;
        default:
                operation = 0; /* make gcc happy */
                goto fail_response;
@@ -644,9 +637,9 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
        }
 
        /* Check that the number of segments is sane. */
-       nseg = req->nr_segments;
-       if (unlikely(nseg == 0 && operation != WRITE_FLUSH &&
-                               operation != REQ_DISCARD) ||
+       nseg = req->u.rw.nr_segments;
+
+       if (unlikely(nseg == 0 && operation != WRITE_FLUSH) ||
            unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
                pr_debug(DRV_PFX "Bad number of segments in request (%d)\n",
                         nseg);
@@ -654,12 +647,12 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                goto fail_response;
        }
 
-       preq.dev           = req->handle;
+       preq.dev           = req->u.rw.handle;
        preq.sector_number = req->u.rw.sector_number;
        preq.nr_sects      = 0;
 
        pending_req->blkif     = blkif;
-       pending_req->id        = req->id;
+       pending_req->id        = req->u.rw.id;
        pending_req->operation = req->operation;
        pending_req->status    = BLKIF_RSP_OKAY;
        pending_req->nr_pages  = nseg;
@@ -707,7 +700,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
         * the hypercall to unmap the grants - that is all done in
         * xen_blkbk_unmap.
         */
-       if (operation != REQ_DISCARD && xen_blkbk_map(req, pending_req, seg))
+       if (xen_blkbk_map(req, pending_req, seg))
                goto fail_flush;
 
        /*
@@ -739,23 +732,16 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
        /* This will be hit if the operation was a flush or discard. */
        if (!bio) {
-               BUG_ON(operation != WRITE_FLUSH && operation != REQ_DISCARD);
+               BUG_ON(operation != WRITE_FLUSH);
 
-               if (operation == WRITE_FLUSH) {
-                       bio = bio_alloc(GFP_KERNEL, 0);
-                       if (unlikely(bio == NULL))
-                               goto fail_put_bio;
+               bio = bio_alloc(GFP_KERNEL, 0);
+               if (unlikely(bio == NULL))
+                       goto fail_put_bio;
 
-                       biolist[nbio++] = bio;
-                       bio->bi_bdev    = preq.bdev;
-                       bio->bi_private = pending_req;
-                       bio->bi_end_io  = end_block_io_op;
-               } else if (operation == REQ_DISCARD) {
-                       xen_blk_discard(blkif, req);
-                       xen_blkif_put(blkif);
-                       free_req(pending_req);
-                       return 0;
-               }
+               biolist[nbio++] = bio;
+               bio->bi_bdev    = preq.bdev;
+               bio->bi_private = pending_req;
+               bio->bi_end_io  = end_block_io_op;
        }
 
        /*
@@ -784,7 +770,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
        xen_blkbk_unmap(pending_req);
  fail_response:
        /* Haven't submitted any bio's yet. */
-       make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
+       make_response(blkif, req->u.rw.id, req->operation, BLKIF_RSP_ERROR);
        free_req(pending_req);
        msleep(1); /* back off a bit */
        return -EIO;
index de09f525d6c174509af3a1e25ce6609fbb2ef1fc..d0ee7edc9be8ad1819a91a491eb907f18d545fbf 100644 (file)
@@ -60,58 +60,66 @@ struct blkif_common_response {
        char dummy;
 };
 
-/* i386 protocol version */
-#pragma pack(push, 4)
-
 struct blkif_x86_32_request_rw {
+       uint8_t        nr_segments;  /* number of segments                   */
+       blkif_vdev_t   handle;       /* only for read/write requests         */
+       uint64_t       id;           /* private guest value, echoed in resp  */
        blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
        struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
+} __attribute__((__packed__));
 
 struct blkif_x86_32_request_discard {
+       uint8_t        flag;         /* BLKIF_DISCARD_SECURE or zero         */
+       blkif_vdev_t   _pad1;        /* was "handle" for read/write requests */
+       uint64_t       id;           /* private guest value, echoed in resp  */
        blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-       uint64_t nr_sectors;
-};
+       uint64_t       nr_sectors;
+} __attribute__((__packed__));
 
 struct blkif_x86_32_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
-       uint8_t        nr_segments;  /* number of segments                   */
-       blkif_vdev_t   handle;       /* only for read/write requests         */
-       uint64_t       id;           /* private guest value, echoed in resp  */
        union {
                struct blkif_x86_32_request_rw rw;
                struct blkif_x86_32_request_discard discard;
        } u;
-};
+} __attribute__((__packed__));
+
+/* i386 protocol version */
+#pragma pack(push, 4)
 struct blkif_x86_32_response {
        uint64_t        id;              /* copied from request */
        uint8_t         operation;       /* copied from request */
        int16_t         status;          /* BLKIF_RSP_???       */
 };
 #pragma pack(pop)
-
 /* x86_64 protocol version */
 
 struct blkif_x86_64_request_rw {
+       uint8_t        nr_segments;  /* number of segments                   */
+       blkif_vdev_t   handle;       /* only for read/write requests         */
+       uint32_t       _pad1;        /* offsetof(blkif_reqest..,u.rw.id)==8  */
+       uint64_t       id;
        blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
        struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
+} __attribute__((__packed__));
 
 struct blkif_x86_64_request_discard {
+       uint8_t        flag;         /* BLKIF_DISCARD_SECURE or zero         */
+       blkif_vdev_t   _pad1;        /* was "handle" for read/write requests */
+        uint32_t       _pad2;        /* offsetof(blkif_..,u.discard.id)==8   */
+       uint64_t       id;
        blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-       uint64_t nr_sectors;
-};
+       uint64_t       nr_sectors;
+} __attribute__((__packed__));
 
 struct blkif_x86_64_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
-       uint8_t        nr_segments;  /* number of segments                   */
-       blkif_vdev_t   handle;       /* only for read/write requests         */
-       uint64_t       __attribute__((__aligned__(8))) id;
        union {
                struct blkif_x86_64_request_rw rw;
                struct blkif_x86_64_request_discard discard;
        } u;
-};
+} __attribute__((__packed__));
+
 struct blkif_x86_64_response {
        uint64_t       __attribute__((__aligned__(8))) id;
        uint8_t         operation;       /* copied from request */
@@ -156,6 +164,7 @@ struct xen_vbd {
        /* Cached size parameter. */
        sector_t                size;
        bool                    flush_support;
+       bool                    discard_secure;
 };
 
 struct backend_info;
@@ -170,7 +179,7 @@ struct xen_blkif {
        enum blkif_protocol     blk_protocol;
        enum blkif_backend_type blk_backend_type;
        union blkif_back_rings  blk_rings;
-       struct vm_struct        *blk_ring_area;
+       void                    *blk_ring;
        /* The VBD attached to this interface. */
        struct xen_vbd          vbd;
        /* Back pointer to the backend_info. */
@@ -198,9 +207,6 @@ struct xen_blkif {
        int                     st_wr_sect;
 
        wait_queue_head_t       waiting_to_free;
-
-       grant_handle_t          shmem_handle;
-       grant_ref_t             shmem_ref;
 };
 
 
@@ -240,22 +246,23 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
        dst->operation = src->operation;
-       dst->nr_segments = src->nr_segments;
-       dst->handle = src->handle;
-       dst->id = src->id;
        switch (src->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
        case BLKIF_OP_FLUSH_DISKCACHE:
+               dst->u.rw.nr_segments = src->u.rw.nr_segments;
+               dst->u.rw.handle = src->u.rw.handle;
+               dst->u.rw.id = src->u.rw.id;
                dst->u.rw.sector_number = src->u.rw.sector_number;
                barrier();
-               if (n > dst->nr_segments)
-                       n = dst->nr_segments;
+               if (n > dst->u.rw.nr_segments)
+                       n = dst->u.rw.nr_segments;
                for (i = 0; i < n; i++)
                        dst->u.rw.seg[i] = src->u.rw.seg[i];
                break;
        case BLKIF_OP_DISCARD:
+               dst->u.discard.flag = src->u.discard.flag;
                dst->u.discard.sector_number = src->u.discard.sector_number;
                dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
                break;
@@ -269,22 +276,23 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
 {
        int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
        dst->operation = src->operation;
-       dst->nr_segments = src->nr_segments;
-       dst->handle = src->handle;
-       dst->id = src->id;
        switch (src->operation) {
        case BLKIF_OP_READ:
        case BLKIF_OP_WRITE:
        case BLKIF_OP_WRITE_BARRIER:
        case BLKIF_OP_FLUSH_DISKCACHE:
+               dst->u.rw.nr_segments = src->u.rw.nr_segments;
+               dst->u.rw.handle = src->u.rw.handle;
+               dst->u.rw.id = src->u.rw.id;
                dst->u.rw.sector_number = src->u.rw.sector_number;
                barrier();
-               if (n > dst->nr_segments)
-                       n = dst->nr_segments;
+               if (n > dst->u.rw.nr_segments)
+                       n = dst->u.rw.nr_segments;
                for (i = 0; i < n; i++)
                        dst->u.rw.seg[i] = src->u.rw.seg[i];
                break;
        case BLKIF_OP_DISCARD:
+               dst->u.discard.flag = src->u.discard.flag;
                dst->u.discard.sector_number = src->u.discard.sector_number;
                dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
                break;
index 2c008afe63d9dbb5499712f9abd3333904a35a3c..187fd2c1a15d077cd8cf1c8f88877b3307f8a661 100644 (file)
@@ -122,38 +122,6 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
        return blkif;
 }
 
-static int map_frontend_page(struct xen_blkif *blkif, unsigned long shared_page)
-{
-       struct gnttab_map_grant_ref op;
-
-       gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-                         GNTMAP_host_map, shared_page, blkif->domid);
-
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
-
-       if (op.status) {
-               DPRINTK("Grant table operation failure !\n");
-               return op.status;
-       }
-
-       blkif->shmem_ref = shared_page;
-       blkif->shmem_handle = op.handle;
-
-       return 0;
-}
-
-static void unmap_frontend_page(struct xen_blkif *blkif)
-{
-       struct gnttab_unmap_grant_ref op;
-
-       gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-                           GNTMAP_host_map, blkif->shmem_handle);
-
-       if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
-               BUG();
-}
-
 static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page,
                         unsigned int evtchn)
 {
@@ -163,35 +131,29 @@ static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page,
        if (blkif->irq)
                return 0;
 
-       blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE);
-       if (!blkif->blk_ring_area)
-               return -ENOMEM;
-
-       err = map_frontend_page(blkif, shared_page);
-       if (err) {
-               free_vm_area(blkif->blk_ring_area);
+       err = xenbus_map_ring_valloc(blkif->be->dev, shared_page, &blkif->blk_ring);
+       if (err < 0)
                return err;
-       }
 
        switch (blkif->blk_protocol) {
        case BLKIF_PROTOCOL_NATIVE:
        {
                struct blkif_sring *sring;
-               sring = (struct blkif_sring *)blkif->blk_ring_area->addr;
+               sring = (struct blkif_sring *)blkif->blk_ring;
                BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE);
                break;
        }
        case BLKIF_PROTOCOL_X86_32:
        {
                struct blkif_x86_32_sring *sring_x86_32;
-               sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring_area->addr;
+               sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring;
                BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE);
                break;
        }
        case BLKIF_PROTOCOL_X86_64:
        {
                struct blkif_x86_64_sring *sring_x86_64;
-               sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring_area->addr;
+               sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring;
                BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE);
                break;
        }
@@ -203,8 +165,7 @@ static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page,
                                                    xen_blkif_be_int, 0,
                                                    "blkif-backend", blkif);
        if (err < 0) {
-               unmap_frontend_page(blkif);
-               free_vm_area(blkif->blk_ring_area);
+               xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring);
                blkif->blk_rings.common.sring = NULL;
                return err;
        }
@@ -230,8 +191,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif)
        }
 
        if (blkif->blk_rings.common.sring) {
-               unmap_frontend_page(blkif);
-               free_vm_area(blkif->blk_ring_area);
+               xenbus_unmap_ring_vfree(blkif->be->dev, blkif->blk_ring);
                blkif->blk_rings.common.sring = NULL;
        }
 }
@@ -378,6 +338,9 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
        if (q && q->flush_flags)
                vbd->flush_support = true;
 
+       if (q && blk_queue_secdiscard(q))
+               vbd->discard_secure = true;
+
        DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
                handle, blkif->domid);
        return 0;
@@ -460,6 +423,15 @@ int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
                                state = 1;
                                blkif->blk_backend_type = BLKIF_BACKEND_PHY;
                        }
+                       /* Optional. */
+                       err = xenbus_printf(xbt, dev->nodename,
+                               "discard-secure", "%d",
+                               blkif->vbd.discard_secure);
+                       if (err) {
+                               xenbus_dev_fatal(dev, err,
+                                       "writting discard-secure");
+                               goto kfree;
+                       }
                }
        } else {
                err = PTR_ERR(type);
index 7b2ec5908413da7b989044828879afa173613b87..8cb0c27f2654c52f1a6cd8dbc61e87c46f0911af 100644 (file)
@@ -98,7 +98,8 @@ struct blkfront_info
        unsigned long shadow_free;
        unsigned int feature_flush;
        unsigned int flush_op;
-       unsigned int feature_discard;
+       unsigned int feature_discard:1;
+       unsigned int feature_secdiscard:1;
        unsigned int discard_granularity;
        unsigned int discard_alignment;
        int is_ready;
@@ -135,15 +136,15 @@ static int get_id_from_freelist(struct blkfront_info *info)
 {
        unsigned long free = info->shadow_free;
        BUG_ON(free >= BLK_RING_SIZE);
-       info->shadow_free = info->shadow[free].req.id;
-       info->shadow[free].req.id = 0x0fffffee; /* debug */
+       info->shadow_free = info->shadow[free].req.u.rw.id;
+       info->shadow[free].req.u.rw.id = 0x0fffffee; /* debug */
        return free;
 }
 
 static void add_id_to_freelist(struct blkfront_info *info,
                               unsigned long id)
 {
-       info->shadow[id].req.id  = info->shadow_free;
+       info->shadow[id].req.u.rw.id  = info->shadow_free;
        info->shadow[id].request = NULL;
        info->shadow_free = id;
 }
@@ -156,7 +157,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
        if (end > nr_minors) {
                unsigned long *bitmap, *old;
 
-               bitmap = kzalloc(BITS_TO_LONGS(end) * sizeof(*bitmap),
+               bitmap = kcalloc(BITS_TO_LONGS(end), sizeof(*bitmap),
                                 GFP_KERNEL);
                if (bitmap == NULL)
                        return -ENOMEM;
@@ -287,9 +288,9 @@ static int blkif_queue_request(struct request *req)
        id = get_id_from_freelist(info);
        info->shadow[id].request = req;
 
-       ring_req->id = id;
+       ring_req->u.rw.id = id;
        ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
-       ring_req->handle = info->handle;
+       ring_req->u.rw.handle = info->handle;
 
        ring_req->operation = rq_data_dir(req) ?
                BLKIF_OP_WRITE : BLKIF_OP_READ;
@@ -305,16 +306,21 @@ static int blkif_queue_request(struct request *req)
                ring_req->operation = info->flush_op;
        }
 
-       if (unlikely(req->cmd_flags & REQ_DISCARD)) {
+       if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) {
                /* id, sector_number and handle are set above. */
                ring_req->operation = BLKIF_OP_DISCARD;
-               ring_req->nr_segments = 0;
                ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
+               if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard)
+                       ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
+               else
+                       ring_req->u.discard.flag = 0;
        } else {
-               ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
-               BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+               ring_req->u.rw.nr_segments = blk_rq_map_sg(req->q, req,
+                                                          info->sg);
+               BUG_ON(ring_req->u.rw.nr_segments >
+                      BLKIF_MAX_SEGMENTS_PER_REQUEST);
 
-               for_each_sg(info->sg, sg, ring_req->nr_segments, i) {
+               for_each_sg(info->sg, sg, ring_req->u.rw.nr_segments, i) {
                        buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg)));
                        fsect = sg->offset >> 9;
                        lsect = fsect + (sg->length >> 9) - 1;
@@ -424,6 +430,8 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
                blk_queue_max_discard_sectors(rq, get_capacity(gd));
                rq->limits.discard_granularity = info->discard_granularity;
                rq->limits.discard_alignment = info->discard_alignment;
+               if (info->feature_secdiscard)
+                       queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, rq);
        }
 
        /* Hard sector size and max sectors impersonate the equiv. hardware. */
@@ -705,7 +713,9 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 static void blkif_completion(struct blk_shadow *s)
 {
        int i;
-       for (i = 0; i < s->req.nr_segments; i++)
+       /* Do not let BLKIF_OP_DISCARD as nr_segment is in the same place
+        * flag. */
+       for (i = 0; i < s->req.u.rw.nr_segments; i++)
                gnttab_end_foreign_access(s->req.u.rw.seg[i].gref, 0, 0UL);
 }
 
@@ -736,7 +746,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                id   = bret->id;
                req  = info->shadow[id].request;
 
-               blkif_completion(&info->shadow[id]);
+               if (bret->operation != BLKIF_OP_DISCARD)
+                       blkif_completion(&info->shadow[id]);
 
                add_id_to_freelist(info, id);
 
@@ -749,7 +760,9 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                                           info->gd->disk_name);
                                error = -EOPNOTSUPP;
                                info->feature_discard = 0;
+                               info->feature_secdiscard = 0;
                                queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
+                               queue_flag_clear(QUEUE_FLAG_SECDISCARD, rq);
                        }
                        __blk_end_request_all(req, error);
                        break;
@@ -763,7 +776,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
                                error = -EOPNOTSUPP;
                        }
                        if (unlikely(bret->status == BLKIF_RSP_ERROR &&
-                                    info->shadow[id].req.nr_segments == 0)) {
+                                    info->shadow[id].req.u.rw.nr_segments == 0)) {
                                printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n",
                                       info->flush_op == BLKIF_OP_WRITE_BARRIER ?
                                       "barrier" :  "flush disk cache",
@@ -984,8 +997,8 @@ static int blkfront_probe(struct xenbus_device *dev,
        INIT_WORK(&info->work, blkif_restart_queue);
 
        for (i = 0; i < BLK_RING_SIZE; i++)
-               info->shadow[i].req.id = i+1;
-       info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
+               info->shadow[i].req.u.rw.id = i+1;
+       info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
 
        /* Front end dir is a number, which is used as the id. */
        info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
@@ -1019,9 +1032,9 @@ static int blkif_recover(struct blkfront_info *info)
        /* Stage 2: Set up free list. */
        memset(&info->shadow, 0, sizeof(info->shadow));
        for (i = 0; i < BLK_RING_SIZE; i++)
-               info->shadow[i].req.id = i+1;
+               info->shadow[i].req.u.rw.id = i+1;
        info->shadow_free = info->ring.req_prod_pvt;
-       info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
+       info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
 
        /* Stage 3: Find pending requests and requeue them. */
        for (i = 0; i < BLK_RING_SIZE; i++) {
@@ -1034,17 +1047,19 @@ static int blkif_recover(struct blkfront_info *info)
                *req = copy[i].req;
 
                /* We get a new request id, and must reset the shadow state. */
-               req->id = get_id_from_freelist(info);
-               memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
+               req->u.rw.id = get_id_from_freelist(info);
+               memcpy(&info->shadow[req->u.rw.id], &copy[i], sizeof(copy[i]));
 
+               if (req->operation != BLKIF_OP_DISCARD) {
                /* Rewrite any grant references invalidated by susp/resume. */
-               for (j = 0; j < req->nr_segments; j++)
-                       gnttab_grant_foreign_access_ref(
-                               req->u.rw.seg[j].gref,
-                               info->xbdev->otherend_id,
-                               pfn_to_mfn(info->shadow[req->id].frame[j]),
-                               rq_data_dir(info->shadow[req->id].request));
-               info->shadow[req->id].req = *req;
+                       for (j = 0; j < req->u.rw.nr_segments; j++)
+                               gnttab_grant_foreign_access_ref(
+                                       req->u.rw.seg[j].gref,
+                                       info->xbdev->otherend_id,
+                                       pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]),
+                                       rq_data_dir(info->shadow[req->u.rw.id].request));
+               }
+               info->shadow[req->u.rw.id].req = *req;
 
                info->ring.req_prod_pvt++;
        }
@@ -1135,11 +1150,13 @@ static void blkfront_setup_discard(struct blkfront_info *info)
        char *type;
        unsigned int discard_granularity;
        unsigned int discard_alignment;
+       unsigned int discard_secure;
 
        type = xenbus_read(XBT_NIL, info->xbdev->otherend, "type", NULL);
        if (IS_ERR(type))
                return;
 
+       info->feature_secdiscard = 0;
        if (strncmp(type, "phy", 3) == 0) {
                err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
                        "discard-granularity", "%u", &discard_granularity,
@@ -1150,6 +1167,12 @@ static void blkfront_setup_discard(struct blkfront_info *info)
                        info->discard_granularity = discard_granularity;
                        info->discard_alignment = discard_alignment;
                }
+               err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+                           "discard-secure", "%d", &discard_secure,
+                           NULL);
+               if (!err)
+                       info->feature_secdiscard = discard_secure;
+
        } else if (strncmp(type, "file", 4) == 0)
                info->feature_discard = 1;
 
index db7cb8111fbe58a89f21ee6ccea50467356bd38a..106beb194f3c8d438e105dab8d12aaecb8716103 100644 (file)
@@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
 
        pipe = usb_sndctrlpipe(udev, 0);
 
-       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
        if (!send_buf) {
                BT_ERR("Can't allocate memory chunk for firmware");
                return -ENOMEM;
@@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
 
        count = firmware->size;
 
-       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
        if (!send_buf) {
                BT_ERR("Can't allocate memory chunk for firmware");
                return -ENOMEM;
index 8b1b643a519b330a8119ad5bde789ec105edfdfc..54952ab800b88b5e5ae34229f7602c71c11e45e1 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -65,6 +66,7 @@ struct bcm203x_data {
        unsigned long           state;
 
        struct work_struct      work;
+       atomic_t                shutdown;
 
        struct urb              *urb;
        unsigned char           *buffer;
@@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb)
 
                data->state = BCM203X_SELECT_MEMORY;
 
+               /* use workqueue to have a small delay */
                schedule_work(&data->work);
                break;
 
@@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work)
        struct bcm203x_data *data =
                container_of(work, struct bcm203x_data, work);
 
-       if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
+       if (atomic_read(&data->shutdown))
+               return;
+
+       if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
                BT_ERR("Can't submit URB");
 }
 
@@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
 
        usb_set_intfdata(intf, data);
 
+       /* use workqueue to have a small delay */
        schedule_work(&data->work);
 
        return 0;
@@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf)
 
        BT_DBG("intf %p", intf);
 
+       atomic_inc(&data->shutdown);
+       cancel_work_sync(&data->work);
+
        usb_kill_urb(data->urb);
 
        usb_set_intfdata(intf, NULL);
index 005919ab043c16bb4e699b4f58ee5a4fdbd94c6e..61b591470a90827280005b50b000907a7e7c2ac2 100644 (file)
@@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data,
 
        BT_INFO("BlueFRITZ! USB loading firmware");
 
+       buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
+       if (!buf) {
+               BT_ERR("Can't allocate memory chunk for firmware");
+               return -ENOMEM;
+       }
+
        pipe = usb_sndctrlpipe(data->udev, 0);
 
        if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
                                0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
                BT_ERR("Can't change to loading configuration");
+               kfree(buf);
                return -EBUSY;
        }
 
        data->udev->toggle[0] = data->udev->toggle[1] = 0;
 
-       buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-       if (!buf) {
-               BT_ERR("Can't allocate memory chunk for firmware");
-               return -ENOMEM;
-       }
-
        pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
 
        while (count) {
index 548d1d9e4ddad7328c2ac9d68ec7d17de949d15a..a88a78c86162fb15516fe5525a639f0769dec18d 100644 (file)
@@ -18,6 +18,8 @@
  * this warranty disclaimer.
  **/
 
+#include <linux/module.h>
+
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
index c827d737cceea91dd9ce4fd6bdf521824e7e834e..9ef48167e2cf8ba64c790d4846a2d297e84c6fd0 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/module.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index f9b726091ad0bba89464bad3a59f363318eba508..fe4ebc375b3dafd274da41c803cbb9ac37754146 100644 (file)
@@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = {
        /* Canyon CN-BTU1 with HID interfaces */
        { USB_DEVICE(0x0c10, 0x0000) },
 
+       /* Broadcom BCM20702A0 */
+       { USB_DEVICE(0x413c, 0x8197) },
+
        { }     /* Terminating entry */
 };
 
index 04d353f58d717ec7763d8aa853b434e644ea67af..b5f83b44a0cd18a42f32aa8b4398ea69b5b9ba2b 100644 (file)
@@ -29,6 +29,7 @@
 #include <net/bluetooth/hci.h>
 
 #include <linux/ti_wilink_st.h>
+#include <linux/module.h>
 
 /* Bluetooth Driver Version */
 #define VERSION               "1.0"
index 66cd0b8096ca426f9755f958797fb80560770f49..c92424ca1a55370dcdaa7798cb6eb1ae6fbdd90c 100644 (file)
@@ -1186,10 +1186,11 @@ static void gen6_cleanup(void)
 /* Certain Gen5 chipsets require require idling the GPU before
  * unmapping anything from the GTT when VT-d is enabled.
  */
-extern int intel_iommu_gfx_mapped;
 static inline int needs_idle_maps(void)
 {
+#ifdef CONFIG_INTEL_IOMMU
        const unsigned short gpu_devid = intel_private.pcidev->device;
+       extern int intel_iommu_gfx_mapped;
 
        /* Query intel_iommu to see if we need the workaround. Presumably that
         * was loaded first.
@@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void)
             gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
             intel_iommu_gfx_mapped)
                return 1;
-
+#endif
        return 0;
 }
 
@@ -1236,7 +1237,7 @@ static int i9xx_setup(void)
                intel_private.gtt_bus_addr = reg_addr + gtt_offset;
        }
 
-       if (needs_idle_maps());
+       if (needs_idle_maps())
                intel_private.base.do_idle_maps = 1;
 
        intel_i9xx_setup_flush();
index 75f1cbd61c174b36f1e637b59d203980e61c8cac..fd699ccecf5b83efb694734ef5a137c8d20a2217 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/virtio.h>
 #include <linux/virtio_rng.h>
+#include <linux/module.h>
 
 static struct virtqueue *vq;
 static unsigned int data_avail;
index 8fc04b4f311f72c802a1df13af7108e3082a1b3f..1451790337160fb8c9fd6a5af935dea6b236f4ca 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/bootmem.h>
 #include <linux/splice.h>
 #include <linux/pfn.h>
+#include <linux/export.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index d0c57c2e29094eb6caba946789295893d4befdbc..6abdde4da2b7834991a8e4e0b3feb52e0e054993 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
index 810aff9e750fde8e28a16d6a81866c72a6dc5aa2..7c7f42a1f880cc81af6dafd89b73810c7eca34aa 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/kmsg_dump.h>
 #include <linux/time.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
index 63e19ba56bbea5a12ee784f023bd13a758eaf611..6035ab8d5ef7e25e6eae89fbfdc53476f248de8b 100644 (file)
@@ -941,7 +941,7 @@ void get_random_bytes(void *buf, int nbytes)
                if (!arch_get_random_long(&v))
                        break;
                
-               memcpy(buf, &v, chunk);
+               memcpy(p, &v, chunk);
                p += chunk;
                nbytes -= chunk;
        }
index f22861511909e9f66c366642415368931704974c..eedd5474850c5008fe4ea957d73d5197a86dba14 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
+#include <linux/export.h>
 
 struct ttyprintk_port {
        struct tty_port port;
index 4ca181f1378b5b7c3a13de0efb6f47b31d28966d..8e3c46d67cb3d9f1f636ca0e38fb175e02a18cdb 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/virtio_console.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include "../tty/hvc/hvc_console.h"
 
 /*
index 32a77becc098534c2b0b77a585d48f4974538c65..ca09bc421ddbc25345cf3d6d9b0efe237941454c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct sh_cmt_priv {
        void __iomem *mapbase;
index 40630cb9823707423c84e2459b812165786c5a15..db8d5955bad47542f17c24c9186bc3c56be46403 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct sh_mtu2_priv {
        void __iomem *mapbase;
index 80813576861781194f235f52507480e1d44a92f7..079e96ad44e875b34861126a7446004109df1f74 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/clockchips.h>
 #include <linux/sh_timer.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct sh_tmu_priv {
        void __iomem *mapbase;
index faf7c521784874c0dbbce7a65b9b05d3ea379f2f..c5072a91e8489de1464ea2e1594c7faf7432f597 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/cpu.h>
 #include <linux/sysfs.h>
 #include <linux/cpufreq.h>
+#include <linux/module.h>
 #include <linux/jiffies.h>
 #include <linux/percpu.h>
 #include <linux/kobject.h>
index edaa987621ea31a5add7a48736dc1822fca572c0..f5002015d82ea277c4e3e946a03e209a15f3eb64 100644 (file)
@@ -109,7 +109,7 @@ static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)
 
 static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
 {
-       int res;
+       int i, res;
 
        BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
 
@@ -120,8 +120,8 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
                        freq_table[3].frequency = 1000000;
        }
        pr_info("db8500-cpufreq : Available frequencies:\n");
-       while (freq_table[i].frequency != CPUFREQ_TABLE_END)
-               pr_info("  %d Mhz\n", freq_table[i++].frequency/1000);
+       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
+               pr_info("  %d Mhz\n", freq_table[i].frequency/1000);
 
        /* get policy fields based on the table */
        res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
index b8d1d205e1effe1fb523114b4918624062802a5a..3475f65aeec692c4f7102492f028a3cf05e2d06c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 
 static struct clk *armclk;
 static struct regulator *vddarm;
index 0df0141100978d583c3a2bbeac17c4625429ab8a..06ce2680d00d4ff33582d04cc9cb67eabf0bc442 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/cpuidle.h>
 #include <linux/ktime.h>
 #include <linux/hrtimer.h>
+#include <linux/module.h>
 #include <trace/events/power.h>
 
 #include "cpuidle.h"
@@ -61,8 +62,9 @@ static int __cpuidle_register_device(struct cpuidle_device *dev);
 int cpuidle_idle_call(void)
 {
        struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
+       struct cpuidle_driver *drv = cpuidle_get_driver();
        struct cpuidle_state *target_state;
-       int next_state;
+       int next_state, entered_state;
 
        if (off)
                return -ENODEV;
@@ -83,45 +85,36 @@ int cpuidle_idle_call(void)
        hrtimer_peek_ahead_timers();
 #endif
 
-       /*
-        * Call the device's prepare function before calling the
-        * governor's select function.  ->prepare gives the device's
-        * cpuidle driver a chance to update any dynamic information
-        * of its cpuidle states for the current idle period, e.g.
-        * state availability, latencies, residencies, etc.
-        */
-       if (dev->prepare)
-               dev->prepare(dev);
-
        /* ask the governor for the next state */
-       next_state = cpuidle_curr_governor->select(dev);
+       next_state = cpuidle_curr_governor->select(drv, dev);
        if (need_resched()) {
                local_irq_enable();
                return 0;
        }
 
-       target_state = &dev->states[next_state];
-
-       /* enter the state and update stats */
-       dev->last_state = target_state;
+       target_state = &drv->states[next_state];
 
        trace_power_start(POWER_CSTATE, next_state, dev->cpu);
        trace_cpu_idle(next_state, dev->cpu);
 
-       dev->last_residency = target_state->enter(dev, target_state);
+       entered_state = target_state->enter(dev, drv, next_state);
 
        trace_power_end(dev->cpu);
        trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
 
-       if (dev->last_state)
-               target_state = dev->last_state;
-
-       target_state->time += (unsigned long long)dev->last_residency;
-       target_state->usage++;
+       if (entered_state >= 0) {
+               /* Update cpuidle counters */
+               /* This can be moved to within driver enter routine
+                * but that results in multiple copies of same code.
+                */
+               dev->states_usage[entered_state].time +=
+                               (unsigned long long)dev->last_residency;
+               dev->states_usage[entered_state].usage++;
+       }
 
        /* give the governor an opportunity to reflect on the outcome */
        if (cpuidle_curr_governor->reflect)
-               cpuidle_curr_governor->reflect(dev);
+               cpuidle_curr_governor->reflect(dev, entered_state);
 
        return 0;
 }
@@ -172,11 +165,11 @@ void cpuidle_resume_and_unlock(void)
 EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
 
 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
-static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
+static int poll_idle(struct cpuidle_device *dev,
+               struct cpuidle_driver *drv, int index)
 {
        ktime_t t1, t2;
        s64 diff;
-       int ret;
 
        t1 = ktime_get();
        local_irq_enable();
@@ -188,15 +181,14 @@ static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st)
        if (diff > INT_MAX)
                diff = INT_MAX;
 
-       ret = (int) diff;
-       return ret;
+       dev->last_residency = (int) diff;
+
+       return index;
 }
 
-static void poll_idle_init(struct cpuidle_device *dev)
+static void poll_idle_init(struct cpuidle_driver *drv)
 {
-       struct cpuidle_state *state = &dev->states[0];
-
-       cpuidle_set_statedata(state, NULL);
+       struct cpuidle_state *state = &drv->states[0];
 
        snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
        snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
@@ -207,7 +199,7 @@ static void poll_idle_init(struct cpuidle_device *dev)
        state->enter = poll_idle;
 }
 #else
-static void poll_idle_init(struct cpuidle_device *dev) {}
+static void poll_idle_init(struct cpuidle_driver *drv) {}
 #endif /* CONFIG_ARCH_HAS_CPU_RELAX */
 
 /**
@@ -234,21 +226,20 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
                        return ret;
        }
 
-       poll_idle_init(dev);
+       poll_idle_init(cpuidle_get_driver());
 
        if ((ret = cpuidle_add_state_sysfs(dev)))
                return ret;
 
        if (cpuidle_curr_governor->enable &&
-           (ret = cpuidle_curr_governor->enable(dev)))
+           (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev)))
                goto fail_sysfs;
 
        for (i = 0; i < dev->state_count; i++) {
-               dev->states[i].usage = 0;
-               dev->states[i].time = 0;
+               dev->states_usage[i].usage = 0;
+               dev->states_usage[i].time = 0;
        }
        dev->last_residency = 0;
-       dev->last_state = NULL;
 
        smp_wmb();
 
@@ -282,7 +273,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev)
        dev->enabled = 0;
 
        if (cpuidle_curr_governor->disable)
-               cpuidle_curr_governor->disable(dev);
+               cpuidle_curr_governor->disable(cpuidle_get_driver(), dev);
 
        cpuidle_remove_state_sysfs(dev);
        enabled_devices--;
@@ -310,26 +301,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
 
        init_completion(&dev->kobj_unregister);
 
-       /*
-        * cpuidle driver should set the dev->power_specified bit
-        * before registering the device if the driver provides
-        * power_usage numbers.
-        *
-        * For those devices whose ->power_specified is not set,
-        * we fill in power_usage with decreasing values as the
-        * cpuidle code has an implicit assumption that state Cn
-        * uses less power than C(n-1).
-        *
-        * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
-        * an power value of -1.  So we use -2, -3, etc, for other
-        * c-states.
-        */
-       if (!dev->power_specified) {
-               int i;
-               for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++)
-                       dev->states[i].power_usage = -1 - i;
-       }
-
        per_cpu(cpuidle_devices, dev->cpu) = dev;
        list_add(&dev->device_list, &cpuidle_detected_devices);
        if ((ret = cpuidle_add_sysfs(sys_dev))) {
index 3f7e3cedd133b4ef66965351efb34351374b4af8..284d7af5a9c827ab227293fafd52cd27db442864 100644 (file)
 static struct cpuidle_driver *cpuidle_curr_driver;
 DEFINE_SPINLOCK(cpuidle_driver_lock);
 
+static void __cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+       int i;
+       /*
+        * cpuidle driver should set the drv->power_specified bit
+        * before registering if the driver provides
+        * power_usage numbers.
+        *
+        * If power_specified is not set,
+        * we fill in power_usage with decreasing values as the
+        * cpuidle code has an implicit assumption that state Cn
+        * uses less power than C(n-1).
+        *
+        * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
+        * an power value of -1.  So we use -2, -3, etc, for other
+        * c-states.
+        */
+       if (!drv->power_specified) {
+               for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++)
+                       drv->states[i].power_usage = -1 - i;
+       }
+}
+
+
 /**
  * cpuidle_register_driver - registers a driver
  * @drv: the driver
@@ -34,6 +58,7 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
                spin_unlock(&cpuidle_driver_lock);
                return -EBUSY;
        }
+       __cpuidle_register_driver(drv);
        cpuidle_curr_driver = drv;
        spin_unlock(&cpuidle_driver_lock);
 
index f62fde21e9626edc19e2374a1fb8850b922e9410..b6a09ea859b135c31e6dcffbad0e7a3d2ad66eee 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/cpuidle.h>
 #include <linux/pm_qos.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/jiffies.h>
 
 #include <asm/io.h>
@@ -60,9 +60,11 @@ static inline void ladder_do_selection(struct ladder_device *ldev,
 
 /**
  * ladder_select_state - selects the next state to enter
+ * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int ladder_select_state(struct cpuidle_device *dev)
+static int ladder_select_state(struct cpuidle_driver *drv,
+                               struct cpuidle_device *dev)
 {
        struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
        struct ladder_device_state *last_state;
@@ -77,15 +79,17 @@ static int ladder_select_state(struct cpuidle_device *dev)
 
        last_state = &ldev->states[last_idx];
 
-       if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
-               last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency;
+       if (drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) {
+               last_residency = cpuidle_get_last_residency(dev) - \
+                                        drv->states[last_idx].exit_latency;
+       }
        else
                last_residency = last_state->threshold.promotion_time + 1;
 
        /* consider promotion */
-       if (last_idx < dev->state_count - 1 &&
+       if (last_idx < drv->state_count - 1 &&
            last_residency > last_state->threshold.promotion_time &&
-           dev->states[last_idx + 1].exit_latency <= latency_req) {
+           drv->states[last_idx + 1].exit_latency <= latency_req) {
                last_state->stats.promotion_count++;
                last_state->stats.demotion_count = 0;
                if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
@@ -96,11 +100,11 @@ static int ladder_select_state(struct cpuidle_device *dev)
 
        /* consider demotion */
        if (last_idx > CPUIDLE_DRIVER_STATE_START &&
-           dev->states[last_idx].exit_latency > latency_req) {
+           drv->states[last_idx].exit_latency > latency_req) {
                int i;
 
                for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
-                       if (dev->states[i].exit_latency <= latency_req)
+                       if (drv->states[i].exit_latency <= latency_req)
                                break;
                }
                ladder_do_selection(ldev, last_idx, i);
@@ -123,9 +127,11 @@ static int ladder_select_state(struct cpuidle_device *dev)
 
 /**
  * ladder_enable_device - setup for the governor
+ * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int ladder_enable_device(struct cpuidle_device *dev)
+static int ladder_enable_device(struct cpuidle_driver *drv,
+                               struct cpuidle_device *dev)
 {
        int i;
        struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
@@ -134,8 +140,8 @@ static int ladder_enable_device(struct cpuidle_device *dev)
 
        ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
 
-       for (i = 0; i < dev->state_count; i++) {
-               state = &dev->states[i];
+       for (i = 0; i < drv->state_count; i++) {
+               state = &drv->states[i];
                lstate = &ldev->states[i];
 
                lstate->stats.promotion_count = 0;
@@ -144,7 +150,7 @@ static int ladder_enable_device(struct cpuidle_device *dev)
                lstate->threshold.promotion_count = PROMOTION_COUNT;
                lstate->threshold.demotion_count = DEMOTION_COUNT;
 
-               if (i < dev->state_count - 1)
+               if (i < drv->state_count - 1)
                        lstate->threshold.promotion_time = state->exit_latency;
                if (i > 0)
                        lstate->threshold.demotion_time = state->exit_latency;
@@ -153,11 +159,24 @@ static int ladder_enable_device(struct cpuidle_device *dev)
        return 0;
 }
 
+/**
+ * ladder_reflect - update the correct last_state_idx
+ * @dev: the CPU
+ * @index: the index of actual state entered
+ */
+static void ladder_reflect(struct cpuidle_device *dev, int index)
+{
+       struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
+       if (index > 0)
+               ldev->last_state_idx = index;
+}
+
 static struct cpuidle_governor ladder_governor = {
        .name =         "ladder",
        .rating =       10,
        .enable =       ladder_enable_device,
        .select =       ladder_select_state,
+       .reflect =      ladder_reflect,
        .owner =        THIS_MODULE,
 };
 
index 3600f1955e4806dee41e61bef256697c6052832b..ad0952601ae2d2e322f6d5a81e42cc58545cc40e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/tick.h>
 #include <linux/sched.h>
 #include <linux/math64.h>
+#include <linux/module.h>
 
 #define BUCKETS 12
 #define INTERVALS 8
@@ -182,7 +183,7 @@ static inline int performance_multiplier(void)
 
 static DEFINE_PER_CPU(struct menu_device, menu_devices);
 
-static void menu_update(struct cpuidle_device *dev);
+static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
 
 /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
 static u64 div_round64(u64 dividend, u32 divisor)
@@ -228,9 +229,10 @@ static void detect_repeating_patterns(struct menu_device *data)
 
 /**
  * menu_select - selects the next idle state to enter
+ * @drv: cpuidle driver containing state data
  * @dev: the CPU
  */
-static int menu_select(struct cpuidle_device *dev)
+static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 {
        struct menu_device *data = &__get_cpu_var(menu_devices);
        int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
@@ -240,7 +242,7 @@ static int menu_select(struct cpuidle_device *dev)
        struct timespec t;
 
        if (data->needs_update) {
-               menu_update(dev);
+               menu_update(drv, dev);
                data->needs_update = 0;
        }
 
@@ -285,11 +287,9 @@ static int menu_select(struct cpuidle_device *dev)
         * Find the idle state with the lowest power while satisfying
         * our constraints.
         */
-       for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) {
-               struct cpuidle_state *s = &dev->states[i];
+       for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
+               struct cpuidle_state *s = &drv->states[i];
 
-               if (s->flags & CPUIDLE_FLAG_IGNORE)
-                       continue;
                if (s->target_residency > data->predicted_us)
                        continue;
                if (s->exit_latency > latency_req)
@@ -310,26 +310,30 @@ static int menu_select(struct cpuidle_device *dev)
 /**
  * menu_reflect - records that data structures need update
  * @dev: the CPU
+ * @index: the index of actual entered state
  *
  * NOTE: it's important to be fast here because this operation will add to
  *       the overall exit latency.
  */
-static void menu_reflect(struct cpuidle_device *dev)
+static void menu_reflect(struct cpuidle_device *dev, int index)
 {
        struct menu_device *data = &__get_cpu_var(menu_devices);
-       data->needs_update = 1;
+       data->last_state_idx = index;
+       if (index >= 0)
+               data->needs_update = 1;
 }
 
 /**
  * menu_update - attempts to guess what happened after entry
+ * @drv: cpuidle driver containing state data
  * @dev: the CPU
  */
-static void menu_update(struct cpuidle_device *dev)
+static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 {
        struct menu_device *data = &__get_cpu_var(menu_devices);
        int last_idx = data->last_state_idx;
        unsigned int last_idle_us = cpuidle_get_last_residency(dev);
-       struct cpuidle_state *target = &dev->states[last_idx];
+       struct cpuidle_state *target = &drv->states[last_idx];
        unsigned int measured_us;
        u64 new_factor;
 
@@ -383,9 +387,11 @@ static void menu_update(struct cpuidle_device *dev)
 
 /**
  * menu_enable_device - scans a CPU's states and does setup
+ * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int menu_enable_device(struct cpuidle_device *dev)
+static int menu_enable_device(struct cpuidle_driver *drv,
+                               struct cpuidle_device *dev)
 {
        struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
 
index be7917ec40c9f111270ca889ebdba3a25c61fb38..1e756e160dca0ff3d8d9fe25d74a57cdfff2be16 100644 (file)
@@ -216,7 +216,8 @@ static struct kobj_type ktype_cpuidle = {
 
 struct cpuidle_state_attr {
        struct attribute attr;
-       ssize_t (*show)(struct cpuidle_state *, char *);
+       ssize_t (*show)(struct cpuidle_state *, \
+                                       struct cpuidle_state_usage *, char *);
        ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
 };
 
@@ -224,19 +225,22 @@ struct cpuidle_state_attr {
 static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
 
 #define define_show_state_function(_name) \
-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, \
+                        struct cpuidle_state_usage *state_usage, char *buf) \
 { \
        return sprintf(buf, "%u\n", state->_name);\
 }
 
 #define define_show_state_ull_function(_name) \
-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, \
+                       struct cpuidle_state_usage *state_usage, char *buf) \
 { \
-       return sprintf(buf, "%llu\n", state->_name);\
+       return sprintf(buf, "%llu\n", state_usage->_name);\
 }
 
 #define define_show_state_str_function(_name) \
-static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, \
+                       struct cpuidle_state_usage *state_usage, char *buf) \
 { \
        if (state->_name[0] == '\0')\
                return sprintf(buf, "<null>\n");\
@@ -269,16 +273,18 @@ static struct attribute *cpuidle_state_default_attrs[] = {
 
 #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
 #define kobj_to_state(k) (kobj_to_state_obj(k)->state)
+#define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
 #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
 static ssize_t cpuidle_state_show(struct kobject * kobj,
        struct attribute * attr ,char * buf)
 {
        int ret = -EIO;
        struct cpuidle_state *state = kobj_to_state(kobj);
+       struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
        struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
 
        if (cattr->show)
-               ret = cattr->show(state, buf);
+               ret = cattr->show(state, state_usage, buf);
 
        return ret;
 }
@@ -316,13 +322,15 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device)
 {
        int i, ret = -ENOMEM;
        struct cpuidle_state_kobj *kobj;
+       struct cpuidle_driver *drv = cpuidle_get_driver();
 
        /* state statistics */
        for (i = 0; i < device->state_count; i++) {
                kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
                if (!kobj)
                        goto error_state;
-               kobj->state = &device->states[i];
+               kobj->state = &drv->states[i];
+               kobj->state_usage = &device->states_usage[i];
                init_completion(&kobj->kobj_unregister);
 
                ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj,
index 3cf303ee3fe3449efd185a8567252a36759d5bca..dcd8babae9eb36fe864bae433558e5e1b4c77d83 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <crypto/internal/hash.h>
 #include <crypto/sha.h>
 
@@ -342,11 +343,13 @@ static void mv_process_hash_current(int first_block)
                else
                        op.config |= CFG_MID_FRAG;
 
-               writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
-               writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
-               writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
-               writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
-               writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
+               if (first_block) {
+                       writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
+                       writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
+                       writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
+                       writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
+                       writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
+               }
        }
 
        memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config));
index 25ec0bb05198f1587fb8687d057941c5f09c09d6..bc6f5faa1e9ee692242a58c88b76932da114f15b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/dca.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DCA_VERSION "1.12.1"
 
index 5e8f335e6f6ef36145da8ec7461ba15c04f6344c..591b6597c00a68eee807559bb1237727a2f2e14a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/err.h>
 #include <linux/dca.h>
 #include <linux/gfp.h>
+#include <linux/export.h>
 
 static struct class *dca_class;
 static struct idr dca_idr;
index 643b055ed3cdc619d07166e8eaa84b2f849252df..8f0491037080df38856b76ec73db77cf18d3320f 100644 (file)
@@ -1,36 +1,29 @@
-config ARCH_HAS_DEVFREQ
-       bool
-       depends on ARCH_HAS_OPP
-       help
-         Denotes that the architecture supports DEVFREQ. If the architecture
-         supports multiple OPP entries per device and the frequency of the
-         devices with OPPs may be altered dynamically, the architecture
-         supports DEVFREQ.
-
 menuconfig PM_DEVFREQ
        bool "Generic Dynamic Voltage and Frequency Scaling (DVFS) support"
-       depends on PM_OPP && ARCH_HAS_DEVFREQ
        help
-         With OPP support, a device may have a list of frequencies and
-         voltages available. DEVFREQ, a generic DVFS framework can be
-         registered for a device with OPP support in order to let the
-         governor provided to DEVFREQ choose an operating frequency
-         based on the OPP's list and the policy given with DEVFREQ.
+         A device may have a list of frequencies and voltages available.
+         devfreq, a generic DVFS framework can be registered for a device
+         in order to let the governor provided to devfreq choose an
+         operating frequency based on the device driver's policy.
 
-         Each device may have its own governor and policy. DEVFREQ can
+         Each device may have its own governor and policy. Devfreq can
          reevaluate the device state periodically and/or based on the
-         OPP list changes (each frequency/voltage pair in OPP may be
-         disabled or enabled).
+         notification to "nb", a notifier block, of devfreq.
 
-         Like some CPUs with CPUFREQ, a device may have multiple clocks.
+         Like some CPUs with CPUfreq, a device may have multiple clocks.
          However, because the clock frequencies of a single device are
-         determined by the single device's state, an instance of DEVFREQ
+         determined by the single device's state, an instance of devfreq
          is attached to a single device and returns a "representative"
-         clock frequency from the OPP of the device, which is also attached
-         to a device by 1-to-1. The device registering DEVFREQ takes the
-         responsiblity to "interpret" the frequency listed in OPP and
+         clock frequency of the device, which is also attached
+         to a device by 1-to-1. The device registering devfreq takes the
+         responsiblity to "interpret" the representative frequency and
          to set its every clock accordingly with the "target" callback
-         given to DEVFREQ.
+         given to devfreq.
+
+         When OPP is used with the devfreq device, it is recommended to
+         register devfreq's nb to the OPP's notifier head.  If OPP is
+         used with the devfreq device, you may use OPP helper
+         functions defined in devfreq.h.
 
 if PM_DEVFREQ
 
index 5d15b812377bc9ad23420e6d41bd7ea62dc62e2f..59d24e9cb8c512a949a24803c5bf11a143fc649d 100644 (file)
@@ -15,7 +15,9 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/opp.h>
 #include <linux/devfreq.h>
 #include <linux/workqueue.h>
@@ -416,10 +418,14 @@ out:
  */
 int devfreq_remove_device(struct devfreq *devfreq)
 {
+       bool central_polling;
+
        if (!devfreq)
                return -EINVAL;
 
-       if (!devfreq->governor->no_central_polling) {
+       central_polling = !devfreq->governor->no_central_polling;
+
+       if (central_polling) {
                mutex_lock(&devfreq_list_lock);
                while (wait_remove_device == devfreq) {
                        mutex_unlock(&devfreq_list_lock);
@@ -431,7 +437,7 @@ int devfreq_remove_device(struct devfreq *devfreq)
        mutex_lock(&devfreq->lock);
        _remove_devfreq(devfreq, false); /* it unlocks devfreq->lock */
 
-       if (!devfreq->governor->no_central_polling)
+       if (central_polling)
                mutex_unlock(&devfreq_list_lock);
 
        return 0;
index d746899f36e143278a8bca4bf660058ae81e74cd..4be55f9bb6c19c6b6165a6de82eea9b2d977c18d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/dmaengine.h>
+#include <linux/module.h>
 
 #include <asm/irq.h>
 #include <mach/dma-v1.h>
index eab1fe71259ee46afd95a954419e12afade56c79..f993955a640c376342498d3336668348ecd78884 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/dmaengine.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/module.h>
 
 #include <asm/irq.h>
 #include <mach/sdma.h>
index 9e96c43a846a6316f2f73f91ad45195e1fafe807..19a0c64d45d3643a99e7b8972c8c3f3a16fc6e5f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/intel_mid_dma.h>
+#include <linux/module.h>
 
 #define MAX_CHAN       4 /*max ch across controllers*/
 #include "intel_mid_dma_regs.h"
index ddc2a1331822ad0c976931c614d0f9665d846f72..0e5ef33f90a17ad75bebaa889a7ae7a46d75248c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <mach/ipu.h>
 
index 467e4dcb20a012cadfcc10bc616b25dbe11d373a..13259cad0ceb61df6a593af758ebf1aec4ec877b 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/dmaengine.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
index a687a0d169624f9f22c82fe3047c83e143ce953d..a774c0ddaf5b06f05e19ddacccf0423a824f1423 100644 (file)
@@ -90,6 +90,7 @@ enum apimask_bits {
        ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H |
                           APIMASK_ECC_UE_L | APIMASK_ECC_CE_L),
 };
+#define APIMASK_ADI(n)         CPC925_BIT(((n)+1))
 
 /************************************************************
  *     Processor Interface Exception Register (APIEXCP)
@@ -581,16 +582,73 @@ static void cpc925_mc_check(struct mem_ctl_info *mci)
 }
 
 /******************** CPU err device********************************/
+static u32 cpc925_cpu_mask_disabled(void)
+{
+       struct device_node *cpus;
+       struct device_node *cpunode = NULL;
+       static u32 mask = 0;
+
+       /* use cached value if available */
+       if (mask != 0)
+               return mask;
+
+       mask = APIMASK_ADI0 | APIMASK_ADI1;
+
+       cpus = of_find_node_by_path("/cpus");
+       if (cpus == NULL) {
+               cpc925_printk(KERN_DEBUG, "No /cpus node !\n");
+               return 0;
+       }
+
+       while ((cpunode = of_get_next_child(cpus, cpunode)) != NULL) {
+               const u32 *reg = of_get_property(cpunode, "reg", NULL);
+
+               if (strcmp(cpunode->type, "cpu")) {
+                       cpc925_printk(KERN_ERR, "Not a cpu node in /cpus: %s\n", cpunode->name);
+                       continue;
+               }
+
+               if (reg == NULL || *reg > 2) {
+                       cpc925_printk(KERN_ERR, "Bad reg value at %s\n", cpunode->full_name);
+                       continue;
+               }
+
+               mask &= ~APIMASK_ADI(*reg);
+       }
+
+       if (mask != (APIMASK_ADI0 | APIMASK_ADI1)) {
+               /* We assume that each CPU sits on it's own PI and that
+                * for present CPUs the reg property equals to the PI
+                * interface id */
+               cpc925_printk(KERN_WARNING,
+                               "Assuming PI id is equal to CPU MPIC id!\n");
+       }
+
+       of_node_put(cpunode);
+       of_node_put(cpus);
+
+       return mask;
+}
+
 /* Enable CPU Errors detection */
 static void cpc925_cpu_init(struct cpc925_dev_info *dev_info)
 {
        u32 apimask;
+       u32 cpumask;
 
        apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
-       if ((apimask & CPU_MASK_ENABLE) == 0) {
-               apimask |= CPU_MASK_ENABLE;
-               __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET);
+
+       cpumask = cpc925_cpu_mask_disabled();
+       if (apimask & cpumask) {
+               cpc925_printk(KERN_WARNING, "CPU(s) not present, "
+                               "but enabled in APIMASK, disabling\n");
+               apimask &= ~cpumask;
        }
+
+       if ((apimask & CPU_MASK_ENABLE) == 0)
+               apimask |= CPU_MASK_ENABLE;
+
+       __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET);
 }
 
 /* Disable CPU Errors detection */
@@ -622,6 +680,9 @@ static void cpc925_cpu_check(struct edac_device_ctl_info *edac_dev)
        if ((apiexcp & CPU_EXCP_DETECTED) == 0)
                return;
 
+       if ((apiexcp & ~cpc925_cpu_mask_disabled()) == 0)
+               return;
+
        apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
        cpc925_printk(KERN_INFO, "Processor Interface Fault\n"
                                 "Processor Interface register dump:\n");
index a4987e03f59e8b26416cc4d9b1559f0d0ea16c06..73c3e26a0bceb61803feced841fdcc6b7029500c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kobject.h>
 #include <linux/sysdev.h>
 #include <linux/edac.h>
+#include <linux/module.h>
 #include <asm/mce.h>
 
 #include "mce_amd.h"
index 8af8e864a9cffbc13c91c625a837e11bb8de24fe..73464a62adf74ae1483a16ad71847c03fc03169f 100644 (file)
@@ -1128,7 +1128,7 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
        { .compatible = "fsl,p1020-memory-controller", },
        { .compatible = "fsl,p1021-memory-controller", },
        { .compatible = "fsl,p2020-memory-controller", },
-       { .compatible = "fsl,p4080-memory-controller", },
+       { .compatible = "fsl,qoriq-memory-controller", },
        {},
 };
 MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
index 0de7d8770891e5421a52f7a8732b66e09dd13423..38400963e245f93b74beb056f7e5fa10f2209680 100644 (file)
@@ -205,7 +205,7 @@ static struct platform_driver ppc4xx_edac_driver = {
        .remove                 = ppc4xx_edac_remove,
        .driver = {
                .owner = THIS_MODULE,
-               .name = PPC4XX_EDAC_MODULE_NAME
+               .name = PPC4XX_EDAC_MODULE_NAME,
                .of_match_table = ppc4xx_edac_match,
        },
 };
index 57c3973093ad13ab49355f6af6e9c38f05a5bcae..0f90e007187515d92df0db3f1bca6550b9c09293 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include <asm/byteorder.h>
 
index bcb1126e3d00b2357a0c5748edbd8b1b470c0423..153980be4ee64462f12a97563c0143fc59b3eb82 100644 (file)
@@ -585,14 +585,12 @@ int dmi_name_in_serial(const char *str)
 }
 
 /**
- *     dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ *     dmi_name_in_vendors - Check if string is in the DMI system or board vendor name
  *     @str:   Case sensitive Name
  */
 int dmi_name_in_vendors(const char *str)
 {
-       static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
-                               DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
-                               DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+       static int fields[] = { DMI_SYS_VENDOR, DMI_BOARD_VENDOR, DMI_NONE };
        int i;
        for (i = 0; fields[i] != DMI_NONE; i++) {
                int f = fields[i];
index f1b7f659d3c988d74d1453533ff75bd078c04ba9..e22957665808799a8d8459acea84c7aebbae396d 100644 (file)
@@ -151,7 +151,8 @@ edd_show_host_bus(struct edd_device *edev, char *buf)
                p += scnprintf(p, left, "\tbase_address: %x\n",
                             info->params.interface_path.isa.base_address);
        } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||
-                  !strncmp(info->params.host_bus_type, "PCI", 3)) {
+                  !strncmp(info->params.host_bus_type, "PCI", 3) ||
+                  !strncmp(info->params.host_bus_type, "XPRS", 4)) {
                p += scnprintf(p, left,
                             "\t%02x:%02x.%d  channel: %u\n",
                             info->params.interface_path.pci.bus,
@@ -159,7 +160,6 @@ edd_show_host_bus(struct edd_device *edev, char *buf)
                             info->params.interface_path.pci.function,
                             info->params.interface_path.pci.channel);
        } else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||
-                  !strncmp(info->params.host_bus_type, "XPRS", 4) ||
                   !strncmp(info->params.host_bus_type, "HTPT", 4)) {
                p += scnprintf(p, left,
                             "\tTBD: %llx\n",
@@ -668,7 +668,7 @@ edd_get_pci_dev(struct edd_device *edev)
 {
        struct edd_info *info = edd_dev_get_info(edev);
 
-       if (edd_dev_is_type(edev, "PCI")) {
+       if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) {
                return pci_get_bus_and_slot(info->params.interface_path.pci.bus,
                                     PCI_DEVFN(info->params.interface_path.pci.slot,
                                               info->params.interface_path.pci.
index 8370f72d87ff5ed955789973845629f406f6734e..b0a81173a268175f71606e1aad2ab6067b67f698 100644 (file)
@@ -457,7 +457,8 @@ static int efi_pstore_close(struct pstore_info *psi)
 }
 
 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
-                              struct timespec *timespec, struct pstore_info *psi)
+                              struct timespec *timespec,
+                              char **buf, struct pstore_info *psi)
 {
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        struct efivars *efivars = psi->data;
@@ -478,7 +479,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
                                timespec->tv_nsec = 0;
                                get_var_data_locked(efivars, &efivars->walk_entry->var);
                                size = efivars->walk_entry->var.DataSize;
-                               memcpy(psi->buf, efivars->walk_entry->var.Data, size);
+                               *buf = kmalloc(size, GFP_KERNEL);
+                               if (*buf == NULL)
+                                       return -ENOMEM;
+                               memcpy(*buf, efivars->walk_entry->var.Data,
+                                      size);
                                efivars->walk_entry = list_entry(efivars->walk_entry->list.next,
                                                   struct efivar_entry, list);
                                return size;
@@ -576,7 +581,8 @@ static int efi_pstore_close(struct pstore_info *psi)
 }
 
 static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
-                              struct timespec *time, struct pstore_info *psi)
+                              struct timespec *timespec,
+                              char **buf, struct pstore_info *psi)
 {
        return -1;
 }
index aa83de9db1b91ce380ed86ca9e6f4a421491095a..c4e7c59d1c6379f0cc13f020c966807f9ea6c9f7 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kdebug.h>
 #include <linux/reboot.h>
 #include <linux/efi.h>
+#include <linux/module.h>
 
 #define GSMI_SHUTDOWN_CLEAN    0       /* Clean Shutdown */
 /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
index f10fc521951b17491348f0cd0fbb1f3013e31eae..1eedb6f7fdabe46efa082039818bef6f31fe1591 100644 (file)
 #include <linux/module.h>
 #include <linux/sigma.h>
 
-/* Return: 0==OK, <0==error, =1 ==no more actions */
+static size_t sigma_action_size(struct sigma_action *sa)
+{
+       size_t payload = 0;
+
+       switch (sa->instr) {
+       case SIGMA_ACTION_WRITEXBYTES:
+       case SIGMA_ACTION_WRITESINGLE:
+       case SIGMA_ACTION_WRITESAFELOAD:
+               payload = sigma_action_len(sa);
+               break;
+       default:
+               break;
+       }
+
+       payload = ALIGN(payload, 2);
+
+       return payload + sizeof(struct sigma_action);
+}
+
+/*
+ * Returns a negative error value in case of an error, 0 if processing of
+ * the firmware should be stopped after this action, 1 otherwise.
+ */
 static int
-process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
+process_sigma_action(struct i2c_client *client, struct sigma_action *sa)
 {
-       struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos);
        size_t len = sigma_action_len(sa);
-       int ret = 0;
+       int ret;
 
        pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
                sa->instr, sa->addr, len);
@@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
        case SIGMA_ACTION_WRITEXBYTES:
        case SIGMA_ACTION_WRITESINGLE:
        case SIGMA_ACTION_WRITESAFELOAD:
-               if (ssfw->fw->size < ssfw->pos + len)
-                       return -EINVAL;
                ret = i2c_master_send(client, (void *)&sa->addr, len);
                if (ret < 0)
                        return -EINVAL;
                break;
-
        case SIGMA_ACTION_DELAY:
-               ret = 0;
                udelay(len);
                len = 0;
                break;
-
        case SIGMA_ACTION_END:
-               return 1;
-
+               return 0;
        default:
                return -EINVAL;
        }
 
-       /* when arrive here ret=0 or sent data */
-       ssfw->pos += sigma_action_size(sa, len);
-       return ssfw->pos == ssfw->fw->size;
+       return 1;
 }
 
 static int
 process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
 {
-       pr_debug("%s: processing %p\n", __func__, ssfw);
+       struct sigma_action *sa;
+       size_t size;
+       int ret;
+
+       while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
+               sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
+
+               size = sigma_action_size(sa);
+               ssfw->pos += size;
+               if (ssfw->pos > ssfw->fw->size || size == 0)
+                       break;
+
+               ret = process_sigma_action(client, sa);
 
-       while (1) {
-               int ret = process_sigma_action(client, ssfw);
                pr_debug("%s: action returned %i\n", __func__, ret);
-               if (ret == 1)
-                       return 0;
-               else if (ret)
+
+               if (ret <= 0)
                        return ret;
        }
+
+       if (ssfw->pos != ssfw->fw->size)
+               return -EINVAL;
+
+       return 0;
 }
 
 int process_sigma_firmware(struct i2c_client *client, const char *name)
@@ -89,16 +116,24 @@ int process_sigma_firmware(struct i2c_client *client, const char *name)
 
        /* then verify the header */
        ret = -EINVAL;
-       if (fw->size < sizeof(*ssfw_head))
+
+       /*
+        * Reject too small or unreasonable large files. The upper limit has been
+        * chosen a bit arbitrarily, but it should be enough for all practical
+        * purposes and having the limit makes it easier to avoid integer
+        * overflows later in the loading process.
+        */
+       if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000)
                goto done;
 
        ssfw_head = (void *)fw->data;
        if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
                goto done;
 
-       crc = crc32(0, fw->data, fw->size);
+       crc = crc32(0, fw->data + sizeof(*ssfw_head),
+                       fw->size - sizeof(*ssfw_head));
        pr_debug("%s: crc=%x\n", __func__, crc);
-       if (crc != ssfw_head->crc)
+       if (crc != le32_to_cpu(ssfw_head->crc))
                goto done;
 
        ssfw.pos = sizeof(*ssfw_head);
index 8b3c745b1b051f7924fc3a95c113dd840a60ec4a..8482a23887dc4e8a64f12783fad08c658d8b1ddb 100644 (file)
@@ -95,14 +95,18 @@ config GPIO_EP93XX
        depends on ARCH_EP93XX
        select GPIO_GENERIC
 
-config GPIO_EXYNOS4
-       def_bool y
-       depends on CPU_EXYNOS4210
-
 config GPIO_MPC5200
        def_bool y
        depends on PPC_MPC52xx
 
+config GPIO_MPC8XXX
+       bool "MPC512x/MPC8xxx GPIO support"
+       depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
+                  FSL_SOC_BOOKE || PPC_86xx
+       help
+         Say Y here if you're going to use hardware that connects to the
+         MPC512x/831x/834x/837x/8572/8610 GPIOs.
+
 config GPIO_MSM_V1
        tristate "Qualcomm MSM GPIO v1"
        depends on GPIOLIB && ARCH_MSM
@@ -131,18 +135,6 @@ config GPIO_MXS
        select GPIO_GENERIC
        select GENERIC_IRQ_CHIP
 
-config GPIO_PLAT_SAMSUNG
-       def_bool y
-       depends on SAMSUNG_GPIOLIB_4BIT
-
-config GPIO_S5PC100
-       def_bool y
-       depends on CPU_S5PC100
-
-config GPIO_S5PV210
-       def_bool y
-       depends on CPU_S5PV210
-
 config GPIO_PL061
        bool "PrimeCell PL061 GPIO support"
        depends on ARM_AMBA
index 19c5d27b6d2e916216594bca14e7243983634bf1..4e018d6a763996127cd370a6a3908273024f37a8 100644 (file)
@@ -16,10 +16,9 @@ obj-$(CONFIG_GPIO_CS5535)    += gpio-cs5535.o
 obj-$(CONFIG_GPIO_DA9052)      += gpio-da9052.o
 obj-$(CONFIG_ARCH_DAVINCI)     += gpio-davinci.o
 obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
-obj-$(CONFIG_GPIO_EXYNOS4)     += gpio-exynos4.o
 obj-$(CONFIG_GPIO_IT8761E)     += gpio-it8761e.o
 obj-$(CONFIG_GPIO_JANZ_TTL)    += gpio-janz-ttl.o
-obj-$(CONFIG_MACH_KS8695)      += gpio-ks8695.o
+obj-$(CONFIG_ARCH_KS8695)      += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)    += gpio-langwell.o
 obj-$(CONFIG_ARCH_LPC32XX)     += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_MAX730X)     += gpio-max730x.o
@@ -30,6 +29,7 @@ obj-$(CONFIG_GPIO_MC33880)    += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MCP23S08)    += gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)      += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MPC5200)     += gpio-mpc5200.o
+obj-$(CONFIG_GPIO_MPC8XXX)     += gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSM_V1)      += gpio-msm-v1.o
 obj-$(CONFIG_GPIO_MSM_V2)      += gpio-msm-v2.o
 obj-$(CONFIG_GPIO_MXC)         += gpio-mxc.o
@@ -42,10 +42,7 @@ obj-$(CONFIG_GPIO_PCH)               += gpio-pch.o
 obj-$(CONFIG_GPIO_PL061)       += gpio-pl061.o
 obj-$(CONFIG_PLAT_PXA)         += gpio-pxa.o
 obj-$(CONFIG_GPIO_RDC321X)     += gpio-rdc321x.o
-
-obj-$(CONFIG_GPIO_PLAT_SAMSUNG)        += gpio-plat-samsung.o
-obj-$(CONFIG_GPIO_S5PC100)     += gpio-s5pc100.o
-obj-$(CONFIG_GPIO_S5PV210)     += gpio-s5pv210.o
+obj-$(CONFIG_PLAT_SAMSUNG)     += gpio-samsung.o
 obj-$(CONFIG_ARCH_SA1100)      += gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)         += gpio-sch.o
 obj-$(CONFIG_GPIO_STMPE)       += gpio-stmpe.o
index ff525c0958ddba130a1a58a6d4ac8c9830469edf..a31ad6f5d9106f370167f518f719f4cf2d26323a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/spi/74x164.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct gen_74x164_chip {
        struct spi_device       *spi;
index 7aafbb4373396661dc1afc15b4606c11c77bb20c..1c0fc3756cb103c89c616ed6d3258b3c21864926 100644 (file)
@@ -15,6 +15,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c
deleted file mode 100644 (file)
index d24b337..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * EXYNOS4 - GPIOlib support
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
-                               unsigned int off, s3c_gpio_pull_t pull)
-{
-       if (pull == S3C_GPIO_PULL_UP)
-               pull = 3;
-
-       return s3c_gpio_setpull_updown(chip, off, pull);
-}
-
-s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
-                                               unsigned int off)
-{
-       s3c_gpio_pull_t pull;
-
-       pull = s3c_gpio_getpull_updown(chip, off);
-       if (pull == 3)
-               pull = S3C_GPIO_PULL_UP;
-
-       return pull;
-}
-
-static struct s3c_gpio_cfg gpio_cfg = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_exynos4,
-       .get_pull       = s3c_gpio_getpull_exynos4,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_exynos4,
-       .get_pull       = s3c_gpio_getpull_exynos4,
-};
-
-/*
- * Following are the gpio banks in v310.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
-       {
-               .chip   = {
-                       .base   = EXYNOS4_GPA0(0),
-                       .ngpio  = EXYNOS4_GPIO_A0_NR,
-                       .label  = "GPA0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPA1(0),
-                       .ngpio  = EXYNOS4_GPIO_A1_NR,
-                       .label  = "GPA1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPB(0),
-                       .ngpio  = EXYNOS4_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPC0(0),
-                       .ngpio  = EXYNOS4_GPIO_C0_NR,
-                       .label  = "GPC0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPC1(0),
-                       .ngpio  = EXYNOS4_GPIO_C1_NR,
-                       .label  = "GPC1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPD0(0),
-                       .ngpio  = EXYNOS4_GPIO_D0_NR,
-                       .label  = "GPD0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPD1(0),
-                       .ngpio  = EXYNOS4_GPIO_D1_NR,
-                       .label  = "GPD1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPE0(0),
-                       .ngpio  = EXYNOS4_GPIO_E0_NR,
-                       .label  = "GPE0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPE1(0),
-                       .ngpio  = EXYNOS4_GPIO_E1_NR,
-                       .label  = "GPE1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPE2(0),
-                       .ngpio  = EXYNOS4_GPIO_E2_NR,
-                       .label  = "GPE2",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPE3(0),
-                       .ngpio  = EXYNOS4_GPIO_E3_NR,
-                       .label  = "GPE3",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPE4(0),
-                       .ngpio  = EXYNOS4_GPIO_E4_NR,
-                       .label  = "GPE4",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPF0(0),
-                       .ngpio  = EXYNOS4_GPIO_F0_NR,
-                       .label  = "GPF0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPF1(0),
-                       .ngpio  = EXYNOS4_GPIO_F1_NR,
-                       .label  = "GPF1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPF2(0),
-                       .ngpio  = EXYNOS4_GPIO_F2_NR,
-                       .label  = "GPF2",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPF3(0),
-                       .ngpio  = EXYNOS4_GPIO_F3_NR,
-                       .label  = "GPF3",
-               },
-       },
-};
-
-static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
-       {
-               .chip   = {
-                       .base   = EXYNOS4_GPJ0(0),
-                       .ngpio  = EXYNOS4_GPIO_J0_NR,
-                       .label  = "GPJ0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPJ1(0),
-                       .ngpio  = EXYNOS4_GPIO_J1_NR,
-                       .label  = "GPJ1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPK0(0),
-                       .ngpio  = EXYNOS4_GPIO_K0_NR,
-                       .label  = "GPK0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPK1(0),
-                       .ngpio  = EXYNOS4_GPIO_K1_NR,
-                       .label  = "GPK1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPK2(0),
-                       .ngpio  = EXYNOS4_GPIO_K2_NR,
-                       .label  = "GPK2",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPK3(0),
-                       .ngpio  = EXYNOS4_GPIO_K3_NR,
-                       .label  = "GPK3",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPL0(0),
-                       .ngpio  = EXYNOS4_GPIO_L0_NR,
-                       .label  = "GPL0",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPL1(0),
-                       .ngpio  = EXYNOS4_GPIO_L1_NR,
-                       .label  = "GPL1",
-               },
-       }, {
-               .chip   = {
-                       .base   = EXYNOS4_GPL2(0),
-                       .ngpio  = EXYNOS4_GPIO_L2_NR,
-                       .label  = "GPL2",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY0(0),
-                       .ngpio  = EXYNOS4_GPIO_Y0_NR,
-                       .label  = "GPY0",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY1(0),
-                       .ngpio  = EXYNOS4_GPIO_Y1_NR,
-                       .label  = "GPY1",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY2(0),
-                       .ngpio  = EXYNOS4_GPIO_Y2_NR,
-                       .label  = "GPY2",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY3(0),
-                       .ngpio  = EXYNOS4_GPIO_Y3_NR,
-                       .label  = "GPY3",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY4(0),
-                       .ngpio  = EXYNOS4_GPIO_Y4_NR,
-                       .label  = "GPY4",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY5(0),
-                       .ngpio  = EXYNOS4_GPIO_Y5_NR,
-                       .label  = "GPY5",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = EXYNOS4_GPY6(0),
-                       .ngpio  = EXYNOS4_GPIO_Y6_NR,
-                       .label  = "GPY6",
-               },
-       }, {
-               .base   = (S5P_VA_GPIO2 + 0xC00),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(0),
-               .chip   = {
-                       .base   = EXYNOS4_GPX0(0),
-                       .ngpio  = EXYNOS4_GPIO_X0_NR,
-                       .label  = "GPX0",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO2 + 0xC20),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(8),
-               .chip   = {
-                       .base   = EXYNOS4_GPX1(0),
-                       .ngpio  = EXYNOS4_GPIO_X1_NR,
-                       .label  = "GPX1",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO2 + 0xC40),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(16),
-               .chip   = {
-                       .base   = EXYNOS4_GPX2(0),
-                       .ngpio  = EXYNOS4_GPIO_X2_NR,
-                       .label  = "GPX2",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO2 + 0xC60),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(24),
-               .chip   = {
-                       .base   = EXYNOS4_GPX3(0),
-                       .ngpio  = EXYNOS4_GPIO_X3_NR,
-                       .label  = "GPX3",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       },
-};
-
-static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
-       {
-               .chip   = {
-                       .base   = EXYNOS4_GPZ(0),
-                       .ngpio  = EXYNOS4_GPIO_Z_NR,
-                       .label  = "GPZ",
-               },
-       },
-};
-
-static __init int exynos4_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chip;
-       int i;
-       int group = 0;
-       int nr_chips;
-
-       /* GPIO part 1 */
-
-       chip = exynos4_gpio_part1_4bit;
-       nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
-
-       for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL) {
-                       chip->config = &gpio_cfg;
-                       /* Assign the GPIO interrupt group */
-                       chip->group = group++;
-               }
-               if (chip->base == NULL)
-                       chip->base = S5P_VA_GPIO1 + (i) * 0x20;
-       }
-
-       samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
-
-       /* GPIO part 2 */
-
-       chip = exynos4_gpio_part2_4bit;
-       nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
-
-       for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL) {
-                       chip->config = &gpio_cfg;
-                       /* Assign the GPIO interrupt group */
-                       chip->group = group++;
-               }
-               if (chip->base == NULL)
-                       chip->base = S5P_VA_GPIO2 + (i) * 0x20;
-       }
-
-       samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
-
-       /* GPIO part 3 */
-
-       chip = exynos4_gpio_part3_4bit;
-       nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
-
-       for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL) {
-                       chip->config = &gpio_cfg;
-                       /* Assign the GPIO interrupt group */
-                       chip->group = group++;
-               }
-               if (chip->base == NULL)
-                       chip->base = S5P_VA_GPIO3 + (i) * 0x20;
-       }
-
-       samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
-       s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
-       s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
-
-       return 0;
-}
-core_initcall(exynos4_gpiolib_init);
index b3b4652e89ec1309eeb52df13537936203807378..2de57ce5feb6c65d7b02ca0a3d462d01a80a5116 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/spi/mc33880.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "mc33880"
 
index 1ef46e6c2a2a715e01c8e5f3ebfff3dfc67abe3a..c5d83a8a91c2a81710d8790eb208104ab5735ff2 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
index 3aa6beec8c1e71b1e08527b43c6dbbd9e3f8f037..ea8e73869250c24be2fd3e1fc35439fb3271f917 100644 (file)
@@ -14,6 +14,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
index 52d3ed208105adf8a40e7fbf64fb1618ac986100..2c7cef367fc0e85664231cedd0b0b91cc6ec1062 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/of_gpio.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
+#include <linux/module.h>
 
 #include <asm/gpio.h>
 #include <asm/mpc52xx.h>
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
new file mode 100644 (file)
index 0000000..ec3fcf0
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * GPIOs on MPC512x/8349/8572/8610 and compatible
+ *
+ * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+
+#define MPC8XXX_GPIO_PINS      32
+
+#define GPIO_DIR               0x00
+#define GPIO_ODR               0x04
+#define GPIO_DAT               0x08
+#define GPIO_IER               0x0c
+#define GPIO_IMR               0x10
+#define GPIO_ICR               0x14
+#define GPIO_ICR2              0x18
+
+struct mpc8xxx_gpio_chip {
+       struct of_mm_gpio_chip mm_gc;
+       spinlock_t lock;
+
+       /*
+        * shadowed data register to be able to clear/set output pins in
+        * open drain mode safely
+        */
+       u32 data;
+       struct irq_host *irq;
+       void *of_dev_id_data;
+};
+
+static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
+{
+       return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
+}
+
+static inline struct mpc8xxx_gpio_chip *
+to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
+{
+       return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
+}
+
+static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
+}
+
+/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
+ * defined as output cannot be determined by reading GPDAT register,
+ * so we use shadow data register instead. The status of input pins
+ * is determined by reading GPDAT register.
+ */
+static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+       u32 val;
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+
+       return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+}
+
+static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+
+       return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
+}
+
+static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       if (val)
+               mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
+       else
+               mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
+
+       out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+       return 0;
+}
+
+static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+       unsigned long flags;
+
+       mpc8xxx_gpio_set(gc, gpio, val);
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+       return 0;
+}
+
+static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
+               return irq_create_mapping(mpc8xxx_gc->irq, offset);
+       else
+               return -ENXIO;
+}
+
+static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned int mask;
+
+       mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
+       if (mask)
+               generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
+                                                    32 - ffs(mask)));
+       chip->irq_eoi(&desc->irq_data);
+}
+
+static void mpc8xxx_irq_unmask(struct irq_data *d)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_mask(struct irq_data *d)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_ack(struct irq_data *d)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+
+       out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+}
+
+static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       switch (flow_type) {
+       case IRQ_TYPE_EDGE_FALLING:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               setbits32(mm->regs + GPIO_ICR,
+                         mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       case IRQ_TYPE_EDGE_BOTH:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               clrbits32(mm->regs + GPIO_ICR,
+                         mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long gpio = irqd_to_hwirq(d);
+       void __iomem *reg;
+       unsigned int shift;
+       unsigned long flags;
+
+       if (gpio < 16) {
+               reg = mm->regs + GPIO_ICR;
+               shift = (15 - gpio) * 2;
+       } else {
+               reg = mm->regs + GPIO_ICR2;
+               shift = (15 - (gpio % 16)) * 2;
+       }
+
+       switch (flow_type) {
+       case IRQ_TYPE_EDGE_FALLING:
+       case IRQ_TYPE_LEVEL_LOW:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               clrsetbits_be32(reg, 3 << shift, 2 << shift);
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       case IRQ_TYPE_EDGE_RISING:
+       case IRQ_TYPE_LEVEL_HIGH:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               clrsetbits_be32(reg, 3 << shift, 1 << shift);
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       case IRQ_TYPE_EDGE_BOTH:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               clrbits32(reg, 3 << shift);
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct irq_chip mpc8xxx_irq_chip = {
+       .name           = "mpc8xxx-gpio",
+       .irq_unmask     = mpc8xxx_irq_unmask,
+       .irq_mask       = mpc8xxx_irq_mask,
+       .irq_ack        = mpc8xxx_irq_ack,
+       .irq_set_type   = mpc8xxx_irq_set_type,
+};
+
+static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+                               irq_hw_number_t hw)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
+
+       if (mpc8xxx_gc->of_dev_id_data)
+               mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
+
+       irq_set_chip_data(virq, h->host_data);
+       irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
+       irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+       return 0;
+}
+
+static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
+                                 const u32 *intspec, unsigned int intsize,
+                                 irq_hw_number_t *out_hwirq,
+                                 unsigned int *out_flags)
+
+{
+       /* interrupt sense values coming from the device tree equal either
+        * EDGE_FALLING or EDGE_BOTH
+        */
+       *out_hwirq = intspec[0];
+       *out_flags = intspec[1];
+
+       return 0;
+}
+
+static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+       .map    = mpc8xxx_gpio_irq_map,
+       .xlate  = mpc8xxx_gpio_irq_xlate,
+};
+
+static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
+       { .compatible = "fsl,mpc8349-gpio", },
+       { .compatible = "fsl,mpc8572-gpio", },
+       { .compatible = "fsl,mpc8610-gpio", },
+       { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+       { .compatible = "fsl,pq3-gpio",     },
+       { .compatible = "fsl,qoriq-gpio",   },
+       {}
+};
+
+static void __init mpc8xxx_add_controller(struct device_node *np)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc;
+       struct of_mm_gpio_chip *mm_gc;
+       struct gpio_chip *gc;
+       const struct of_device_id *id;
+       unsigned hwirq;
+       int ret;
+
+       mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
+       if (!mpc8xxx_gc) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       spin_lock_init(&mpc8xxx_gc->lock);
+
+       mm_gc = &mpc8xxx_gc->mm_gc;
+       gc = &mm_gc->gc;
+
+       mm_gc->save_regs = mpc8xxx_gpio_save_regs;
+       gc->ngpio = MPC8XXX_GPIO_PINS;
+       gc->direction_input = mpc8xxx_gpio_dir_in;
+       gc->direction_output = mpc8xxx_gpio_dir_out;
+       if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
+               gc->get = mpc8572_gpio_get;
+       else
+               gc->get = mpc8xxx_gpio_get;
+       gc->set = mpc8xxx_gpio_set;
+       gc->to_irq = mpc8xxx_gpio_to_irq;
+
+       ret = of_mm_gpiochip_add(np, mm_gc);
+       if (ret)
+               goto err;
+
+       hwirq = irq_of_parse_and_map(np, 0);
+       if (hwirq == NO_IRQ)
+               goto skip_irq;
+
+       mpc8xxx_gc->irq =
+               irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
+                              &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+       if (!mpc8xxx_gc->irq)
+               goto skip_irq;
+
+       id = of_match_node(mpc8xxx_gpio_ids, np);
+       if (id)
+               mpc8xxx_gc->of_dev_id_data = id->data;
+
+       mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
+
+       /* ack and mask all irqs */
+       out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
+       out_be32(mm_gc->regs + GPIO_IMR, 0);
+
+       irq_set_handler_data(hwirq, mpc8xxx_gc);
+       irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
+
+skip_irq:
+       return;
+
+err:
+       pr_err("%s: registration failed with status %d\n",
+              np->full_name, ret);
+       kfree(mpc8xxx_gc);
+
+       return;
+}
+
+static int __init mpc8xxx_add_gpiochips(void)
+{
+       struct device_node *np;
+
+       for_each_matching_node(np, mpc8xxx_gpio_ids)
+               mpc8xxx_add_controller(np);
+
+       return 0;
+}
+arch_initcall(mpc8xxx_add_gpiochips);
index b81c989921141fc2fc1f457d62ed23a2f1d3ad7d..e79147634573683a27b46953b0a90e2d995a5a5f 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/basic_mmio_gpio.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/module.h>
 #include <asm-generic/bug.h>
 #include <asm/mach/irq.h>
 
index 292b50481db921d8160f0b97111f51735d7e04b3..385c58e8405b7d4c5ebbd4eafbf92e637e034651 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/basic_mmio_gpio.h>
+#include <linux/module.h>
 #include <mach/mxs.h>
 
 #define MXS_SET                0x4
index 0e49d87f6c60c7b35df327dafd235a394cbb07e5..0b0562979171065bb3c454112c985cb74a633728 100644 (file)
@@ -148,13 +148,17 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
        return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0;
 }
 
-#define MOD_REG_BIT(reg, bit_mask, set)        \
-do {   \
-       int l = __raw_readl(base + reg); \
-       if (set) l |= bit_mask; \
-       else l &= ~bit_mask; \
-       __raw_writel(l, base + reg); \
-} while(0)
+static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
+{
+       int l = __raw_readl(base + reg);
+
+       if (set) 
+               l |= mask;
+       else
+               l &= ~mask;
+
+       __raw_writel(l, base + reg);
+}
 
 /**
  * _set_gpio_debounce - low level gpio debounce time
@@ -210,28 +214,28 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
        u32 gpio_bit = 1 << gpio;
 
        if (cpu_is_omap44xx()) {
-               MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
-                       trigger & IRQ_TYPE_LEVEL_LOW);
-               MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
-                       trigger & IRQ_TYPE_LEVEL_HIGH);
-               MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
-                       trigger & IRQ_TYPE_EDGE_RISING);
-               MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
-                       trigger & IRQ_TYPE_EDGE_FALLING);
+               _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit,
+                         trigger & IRQ_TYPE_LEVEL_LOW);
+               _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit,
+                         trigger & IRQ_TYPE_LEVEL_HIGH);
+               _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit,
+                         trigger & IRQ_TYPE_EDGE_RISING);
+               _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit,
+                         trigger & IRQ_TYPE_EDGE_FALLING);
        } else {
-               MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-                       trigger & IRQ_TYPE_LEVEL_LOW);
-               MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-                       trigger & IRQ_TYPE_LEVEL_HIGH);
-               MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-                       trigger & IRQ_TYPE_EDGE_RISING);
-               MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-                       trigger & IRQ_TYPE_EDGE_FALLING);
+               _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
+                         trigger & IRQ_TYPE_LEVEL_LOW);
+               _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
+                         trigger & IRQ_TYPE_LEVEL_HIGH);
+               _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
+                         trigger & IRQ_TYPE_EDGE_RISING);
+               _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
+                         trigger & IRQ_TYPE_EDGE_FALLING);
        }
        if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
                if (cpu_is_omap44xx()) {
-                       MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit,
-                               trigger != 0);
+                       _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit,
+                                 trigger != 0);
                } else {
                        /*
                         * GPIO wakeup request can only be generated on edge
@@ -1086,6 +1090,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
 
        gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
                                    handle_simple_irq);
+       if (!gc) {
+               dev_err(bank->dev, "Memory alloc failed for gc\n");
+               return;
+       }
+
        ct = gc->chip_types;
 
        /* NOTE: No ack required, reading IRQ status clears it. */
index 0550dcb85814026b9e759abd4c8a81d83b02f9cc..d3f3e8f5456129e7036fc3737181d37b40b8c642 100644 (file)
@@ -546,7 +546,7 @@ static void pca953x_irq_teardown(struct pca953x_chip *chip)
  * Translate OpenFirmware node properties into platform_data
  * WARNING: This is DEPRECATED and will be removed eventually!
  */
-void
+static void
 pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
        struct device_node *node;
@@ -574,7 +574,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
                *invert = *val;
 }
 #else
-void
+static void
 pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
 {
        *gpio_base = -1;
@@ -596,9 +596,6 @@ static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert)
 
        /* set platform specific polarity inversion */
        ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
-       if (ret)
-               goto out;
-       return 0;
 out:
        return ret;
 }
@@ -640,7 +637,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        struct pca953x_platform_data *pdata;
        struct pca953x_chip *chip;
        int irq_base=0, invert=0;
-       int ret = 0;
+       int ret;
 
        chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
        if (chip == NULL)
@@ -673,10 +670,10 @@ static int __devinit pca953x_probe(struct i2c_client *client,
        pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
 
        if (chip->chip_type == PCA953X_TYPE)
-               device_pca953x_init(chip, invert);
-       else if (chip->chip_type == PCA957X_TYPE)
-               device_pca957x_init(chip, invert);
+               ret = device_pca953x_init(chip, invert);
        else
+               ret = device_pca957x_init(chip, invert);
+       if (ret)
                goto out_failed;
 
        ret = pca953x_irq_setup(chip, id, irq_base);
index 7369fdda92b01703e9611fdb96164e75b1afe564..3e1f1ecd07bec0555b7d16a73049001839591e89 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pcf857x.h>
+#include <linux/module.h>
 
 
 static const struct i2c_device_id pcf857x_id[] = {
index 1e8a4a5388108b756e132203d11115401d7f58c8..a6008e123d04b74c410aa8cfcf8876eddc2ddbba 100644 (file)
@@ -14,6 +14,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/gpio.h>
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c
deleted file mode 100644 (file)
index ef67f19..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * SAMSUNG - GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-#ifndef DEBUG_GPIO
-#define gpio_dbg(x...) do { } while (0)
-#else
-#define gpio_dbg(x...) printk(KERN_DEBUG x)
-#endif
-
-/* The samsung_gpiolib_4bit routines are to control the gpio banks where
- * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
- * following example:
- *
- * base + 0x00: Control register, 4 bits per gpio
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *             bit n: data bit n
- *
- * Note, since the data register is one bit per gpio and is at base + 0x4
- * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
- * the output.
-*/
-
-static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
-                                     unsigned int offset)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-
-       con = __raw_readl(base + GPIOCON_OFF);
-       con &= ~(0xf << con_4bit_shift(offset));
-       __raw_writel(con, base + GPIOCON_OFF);
-
-       gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
-
-       return 0;
-}
-
-static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
-                                      unsigned int offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-       unsigned long dat;
-
-       con = __raw_readl(base + GPIOCON_OFF);
-       con &= ~(0xf << con_4bit_shift(offset));
-       con |= 0x1 << con_4bit_shift(offset);
-
-       dat = __raw_readl(base + GPIODAT_OFF);
-
-       if (value)
-               dat |= 1 << offset;
-       else
-               dat &= ~(1 << offset);
-
-       __raw_writel(dat, base + GPIODAT_OFF);
-       __raw_writel(con, base + GPIOCON_OFF);
-       __raw_writel(dat, base + GPIODAT_OFF);
-
-       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-       return 0;
-}
-
-/* The next set of routines are for the case where the GPIO configuration
- * registers are 4 bits per GPIO but there is more than one register (the
- * bank has more than 8 GPIOs.
- *
- * This case is the similar to the 4 bit case, but the registers are as
- * follows:
- *
- * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x08: Data register, 1 bit per gpio
- *             bit n: data bit n
- *
- * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
- * store the 'base + 0x4' address so that these routines see the data
- * register at ourchip->base + 0x04.
- */
-
-static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
-                                      unsigned int offset)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       void __iomem *regcon = base;
-       unsigned long con;
-
-       if (offset > 7)
-               offset -= 8;
-       else
-               regcon -= 4;
-
-       con = __raw_readl(regcon);
-       con &= ~(0xf << con_4bit_shift(offset));
-       __raw_writel(con, regcon);
-
-       gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
-
-       return 0;
-}
-
-static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
-                                       unsigned int offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       void __iomem *regcon = base;
-       unsigned long con;
-       unsigned long dat;
-       unsigned con_offset = offset;
-
-       if (con_offset > 7)
-               con_offset -= 8;
-       else
-               regcon -= 4;
-
-       con = __raw_readl(regcon);
-       con &= ~(0xf << con_4bit_shift(con_offset));
-       con |= 0x1 << con_4bit_shift(con_offset);
-
-       dat = __raw_readl(base + GPIODAT_OFF);
-
-       if (value)
-               dat |= 1 << offset;
-       else
-               dat &= ~(1 << offset);
-
-       __raw_writel(dat, base + GPIODAT_OFF);
-       __raw_writel(con, regcon);
-       __raw_writel(dat, base + GPIODAT_OFF);
-
-       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-       return 0;
-}
-
-void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
-{
-       chip->chip.direction_input = samsung_gpiolib_4bit_input;
-       chip->chip.direction_output = samsung_gpiolib_4bit_output;
-       chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
-{
-       chip->chip.direction_input = samsung_gpiolib_4bit2_input;
-       chip->chip.direction_output = samsung_gpiolib_4bit2_output;
-       chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-}
-
-void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
-                                          int nr_chips)
-{
-       for (; nr_chips > 0; nr_chips--, chip++) {
-               samsung_gpiolib_add_4bit(chip);
-               s3c_gpiolib_add(chip);
-       }
-}
-
-void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
-                                           int nr_chips)
-{
-       for (; nr_chips > 0; nr_chips--, chip++) {
-               samsung_gpiolib_add_4bit2(chip);
-               s3c_gpiolib_add(chip);
-       }
-}
-
-void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
-                                          int nr_chips)
-{
-       for (; nr_chips > 0; nr_chips--, chip++)
-               s3c_gpiolib_add(chip);
-}
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c
deleted file mode 100644 (file)
index 7f87b0c..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * S5PC100 - GPIOlib support
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- *  Copyright 2009 Samsung Electronics Co
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-/* S5PC100 GPIO bank summary:
- *
- * Bank        GPIOs   Style   INT Type
- * A0  8       4Bit    GPIO_INT0
- * A1  5       4Bit    GPIO_INT1
- * B   8       4Bit    GPIO_INT2
- * C   5       4Bit    GPIO_INT3
- * D   7       4Bit    GPIO_INT4
- * E0  8       4Bit    GPIO_INT5
- * E1  6       4Bit    GPIO_INT6
- * F0  8       4Bit    GPIO_INT7
- * F1  8       4Bit    GPIO_INT8
- * F2  8       4Bit    GPIO_INT9
- * F3  4       4Bit    GPIO_INT10
- * G0  8       4Bit    GPIO_INT11
- * G1  3       4Bit    GPIO_INT12
- * G2  7       4Bit    GPIO_INT13
- * G3  7       4Bit    GPIO_INT14
- * H0  8       4Bit    WKUP_INT
- * H1  8       4Bit    WKUP_INT
- * H2  8       4Bit    WKUP_INT
- * H3  8       4Bit    WKUP_INT
- * I   8       4Bit    GPIO_INT15
- * J0  8       4Bit    GPIO_INT16
- * J1  5       4Bit    GPIO_INT17
- * J2  8       4Bit    GPIO_INT18
- * J3  8       4Bit    GPIO_INT19
- * J4  4       4Bit    GPIO_INT20
- * K0  8       4Bit    None
- * K1  6       4Bit    None
- * K2  8       4Bit    None
- * K3  8       4Bit    None
- * L0  8       4Bit    None
- * L1  8       4Bit    None
- * L2  8       4Bit    None
- * L3  8       4Bit    None
- */
-
-static struct s3c_gpio_cfg gpio_cfg = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_eint = {
-       .cfg_eint       = 0xf,
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-/*
- * GPIO bank's base address given the index of the bank in the
- * list of all gpio banks.
- */
-#define S5PC100_BANK_BASE(bank_nr)     (S5P_VA_GPIO + ((bank_nr) * 0x20))
-
-/*
- * Following are the gpio banks in S5PC100.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
-       {
-               .chip   = {
-                       .base   = S5PC100_GPA0(0),
-                       .ngpio  = S5PC100_GPIO_A0_NR,
-                       .label  = "GPA0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPA1(0),
-                       .ngpio  = S5PC100_GPIO_A1_NR,
-                       .label  = "GPA1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPB(0),
-                       .ngpio  = S5PC100_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPC(0),
-                       .ngpio  = S5PC100_GPIO_C_NR,
-                       .label  = "GPC",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPD(0),
-                       .ngpio  = S5PC100_GPIO_D_NR,
-                       .label  = "GPD",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPE0(0),
-                       .ngpio  = S5PC100_GPIO_E0_NR,
-                       .label  = "GPE0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPE1(0),
-                       .ngpio  = S5PC100_GPIO_E1_NR,
-                       .label  = "GPE1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPF0(0),
-                       .ngpio  = S5PC100_GPIO_F0_NR,
-                       .label  = "GPF0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPF1(0),
-                       .ngpio  = S5PC100_GPIO_F1_NR,
-                       .label  = "GPF1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPF2(0),
-                       .ngpio  = S5PC100_GPIO_F2_NR,
-                       .label  = "GPF2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPF3(0),
-                       .ngpio  = S5PC100_GPIO_F3_NR,
-                       .label  = "GPF3",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPG0(0),
-                       .ngpio  = S5PC100_GPIO_G0_NR,
-                       .label  = "GPG0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPG1(0),
-                       .ngpio  = S5PC100_GPIO_G1_NR,
-                       .label  = "GPG1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPG2(0),
-                       .ngpio  = S5PC100_GPIO_G2_NR,
-                       .label  = "GPG2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPG3(0),
-                       .ngpio  = S5PC100_GPIO_G3_NR,
-                       .label  = "GPG3",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPI(0),
-                       .ngpio  = S5PC100_GPIO_I_NR,
-                       .label  = "GPI",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPJ0(0),
-                       .ngpio  = S5PC100_GPIO_J0_NR,
-                       .label  = "GPJ0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPJ1(0),
-                       .ngpio  = S5PC100_GPIO_J1_NR,
-                       .label  = "GPJ1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPJ2(0),
-                       .ngpio  = S5PC100_GPIO_J2_NR,
-                       .label  = "GPJ2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPJ3(0),
-                       .ngpio  = S5PC100_GPIO_J3_NR,
-                       .label  = "GPJ3",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PC100_GPJ4(0),
-                       .ngpio  = S5PC100_GPIO_J4_NR,
-                       .label  = "GPJ4",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK0(0),
-                       .ngpio  = S5PC100_GPIO_K0_NR,
-                       .label  = "GPK0",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK1(0),
-                       .ngpio  = S5PC100_GPIO_K1_NR,
-                       .label  = "GPK1",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK2(0),
-                       .ngpio  = S5PC100_GPIO_K2_NR,
-                       .label  = "GPK2",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK3(0),
-                       .ngpio  = S5PC100_GPIO_K3_NR,
-                       .label  = "GPK3",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL0(0),
-                       .ngpio  = S5PC100_GPIO_L0_NR,
-                       .label  = "GPL0",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL1(0),
-                       .ngpio  = S5PC100_GPIO_L1_NR,
-                       .label  = "GPL1",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL2(0),
-                       .ngpio  = S5PC100_GPIO_L2_NR,
-                       .label  = "GPL2",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL3(0),
-                       .ngpio  = S5PC100_GPIO_L3_NR,
-                       .label  = "GPL3",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL4(0),
-                       .ngpio  = S5PC100_GPIO_L4_NR,
-                       .label  = "GPL4",
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC00),
-               .config = &gpio_cfg_eint,
-               .irq_base = IRQ_EINT(0),
-               .chip   = {
-                       .base   = S5PC100_GPH0(0),
-                       .ngpio  = S5PC100_GPIO_H0_NR,
-                       .label  = "GPH0",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC20),
-               .config = &gpio_cfg_eint,
-               .irq_base = IRQ_EINT(8),
-               .chip   = {
-                       .base   = S5PC100_GPH1(0),
-                       .ngpio  = S5PC100_GPIO_H1_NR,
-                       .label  = "GPH1",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC40),
-               .config = &gpio_cfg_eint,
-               .irq_base = IRQ_EINT(16),
-               .chip   = {
-                       .base   = S5PC100_GPH2(0),
-                       .ngpio  = S5PC100_GPIO_H2_NR,
-                       .label  = "GPH2",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC60),
-               .config = &gpio_cfg_eint,
-               .irq_base = IRQ_EINT(24),
-               .chip   = {
-                       .base   = S5PC100_GPH3(0),
-                       .ngpio  = S5PC100_GPIO_H3_NR,
-                       .label  = "GPH3",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       },
-};
-
-static __init int s5pc100_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
-       int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
-       int gpioint_group = 0;
-       int i;
-
-       for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL) {
-                       chip->config = &gpio_cfg;
-                       chip->group = gpioint_group++;
-               }
-               if (chip->base == NULL)
-                       chip->base = S5PC100_BANK_BASE(i);
-       }
-
-       samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
-       s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-
-       return 0;
-}
-core_initcall(s5pc100_gpiolib_init);
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
deleted file mode 100644 (file)
index eb12f16..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * S5PV210 - GPIOlib support
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <mach/map.h>
-
-static struct s3c_gpio_cfg gpio_cfg = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-/* GPIO bank's base address given the index of the bank in the
- * list of all gpio banks.
- */
-#define S5PV210_BANK_BASE(bank_nr)     (S5P_VA_GPIO + ((bank_nr) * 0x20))
-
-/*
- * Following are the gpio banks in v210.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
-       {
-               .chip   = {
-                       .base   = S5PV210_GPA0(0),
-                       .ngpio  = S5PV210_GPIO_A0_NR,
-                       .label  = "GPA0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPA1(0),
-                       .ngpio  = S5PV210_GPIO_A1_NR,
-                       .label  = "GPA1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPB(0),
-                       .ngpio  = S5PV210_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPC0(0),
-                       .ngpio  = S5PV210_GPIO_C0_NR,
-                       .label  = "GPC0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPC1(0),
-                       .ngpio  = S5PV210_GPIO_C1_NR,
-                       .label  = "GPC1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPD0(0),
-                       .ngpio  = S5PV210_GPIO_D0_NR,
-                       .label  = "GPD0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPD1(0),
-                       .ngpio  = S5PV210_GPIO_D1_NR,
-                       .label  = "GPD1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPE0(0),
-                       .ngpio  = S5PV210_GPIO_E0_NR,
-                       .label  = "GPE0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPE1(0),
-                       .ngpio  = S5PV210_GPIO_E1_NR,
-                       .label  = "GPE1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPF0(0),
-                       .ngpio  = S5PV210_GPIO_F0_NR,
-                       .label  = "GPF0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPF1(0),
-                       .ngpio  = S5PV210_GPIO_F1_NR,
-                       .label  = "GPF1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPF2(0),
-                       .ngpio  = S5PV210_GPIO_F2_NR,
-                       .label  = "GPF2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPF3(0),
-                       .ngpio  = S5PV210_GPIO_F3_NR,
-                       .label  = "GPF3",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPG0(0),
-                       .ngpio  = S5PV210_GPIO_G0_NR,
-                       .label  = "GPG0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPG1(0),
-                       .ngpio  = S5PV210_GPIO_G1_NR,
-                       .label  = "GPG1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPG2(0),
-                       .ngpio  = S5PV210_GPIO_G2_NR,
-                       .label  = "GPG2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPG3(0),
-                       .ngpio  = S5PV210_GPIO_G3_NR,
-                       .label  = "GPG3",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_GPI(0),
-                       .ngpio  = S5PV210_GPIO_I_NR,
-                       .label  = "GPI",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPJ0(0),
-                       .ngpio  = S5PV210_GPIO_J0_NR,
-                       .label  = "GPJ0",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPJ1(0),
-                       .ngpio  = S5PV210_GPIO_J1_NR,
-                       .label  = "GPJ1",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPJ2(0),
-                       .ngpio  = S5PV210_GPIO_J2_NR,
-                       .label  = "GPJ2",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPJ3(0),
-                       .ngpio  = S5PV210_GPIO_J3_NR,
-                       .label  = "GPJ3",
-               },
-       }, {
-               .chip   = {
-                       .base   = S5PV210_GPJ4(0),
-                       .ngpio  = S5PV210_GPIO_J4_NR,
-                       .label  = "GPJ4",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_MP01(0),
-                       .ngpio  = S5PV210_GPIO_MP01_NR,
-                       .label  = "MP01",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_MP02(0),
-                       .ngpio  = S5PV210_GPIO_MP02_NR,
-                       .label  = "MP02",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_MP03(0),
-                       .ngpio  = S5PV210_GPIO_MP03_NR,
-                       .label  = "MP03",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_MP04(0),
-                       .ngpio  = S5PV210_GPIO_MP04_NR,
-                       .label  = "MP04",
-               },
-       }, {
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PV210_MP05(0),
-                       .ngpio  = S5PV210_GPIO_MP05_NR,
-                       .label  = "MP05",
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC00),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(0),
-               .chip   = {
-                       .base   = S5PV210_GPH0(0),
-                       .ngpio  = S5PV210_GPIO_H0_NR,
-                       .label  = "GPH0",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC20),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(8),
-               .chip   = {
-                       .base   = S5PV210_GPH1(0),
-                       .ngpio  = S5PV210_GPIO_H1_NR,
-                       .label  = "GPH1",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC40),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(16),
-               .chip   = {
-                       .base   = S5PV210_GPH2(0),
-                       .ngpio  = S5PV210_GPIO_H2_NR,
-                       .label  = "GPH2",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       }, {
-               .base   = (S5P_VA_GPIO + 0xC60),
-               .config = &gpio_cfg_noint,
-               .irq_base = IRQ_EINT(24),
-               .chip   = {
-                       .base   = S5PV210_GPH3(0),
-                       .ngpio  = S5PV210_GPIO_H3_NR,
-                       .label  = "GPH3",
-                       .to_irq = samsung_gpiolib_to_irq,
-               },
-       },
-};
-
-static __init int s5pv210_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
-       int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
-       int gpioint_group = 0;
-       int i = 0;
-
-       for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL) {
-                       chip->config = &gpio_cfg;
-                       chip->group = gpioint_group++;
-               }
-               if (chip->base == NULL)
-                       chip->base = S5PV210_BANK_BASE(i);
-       }
-
-       samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
-       s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-
-       return 0;
-}
-core_initcall(s5pv210_gpiolib_init);
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
new file mode 100644 (file)
index 0000000..8662518
--- /dev/null
@@ -0,0 +1,2712 @@
+/*
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * SAMSUNG - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/ioport.h>
+
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/gpio-fns.h>
+#include <plat/pm.h>
+
+#ifndef DEBUG_GPIO
+#define gpio_dbg(x...) do { } while (0)
+#else
+#define gpio_dbg(x...) printk(KERN_DEBUG x)
+#endif
+
+int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
+                               unsigned int off, samsung_gpio_pull_t pull)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup;
+
+       pup = __raw_readl(reg);
+       pup &= ~(3 << shift);
+       pup |= pull << shift;
+       __raw_writel(pup, reg);
+
+       return 0;
+}
+
+samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
+                                               unsigned int off)
+{
+       void __iomem *reg = chip->base + 0x08;
+       int shift = off * 2;
+       u32 pup = __raw_readl(reg);
+
+       pup >>= shift;
+       pup &= 0x3;
+
+       return (__force samsung_gpio_pull_t)pup;
+}
+
+int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
+                        unsigned int off, samsung_gpio_pull_t pull)
+{
+       switch (pull) {
+       case S3C_GPIO_PULL_NONE:
+               pull = 0x01;
+               break;
+       case S3C_GPIO_PULL_UP:
+               pull = 0x00;
+               break;
+       case S3C_GPIO_PULL_DOWN:
+               pull = 0x02;
+               break;
+       }
+       return samsung_gpio_setpull_updown(chip, off, pull);
+}
+
+samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
+                                        unsigned int off)
+{
+       samsung_gpio_pull_t pull;
+
+       pull = samsung_gpio_getpull_updown(chip, off);
+
+       switch (pull) {
+       case 0x00:
+               pull = S3C_GPIO_PULL_UP;
+               break;
+       case 0x01:
+       case 0x03:
+               pull = S3C_GPIO_PULL_NONE;
+               break;
+       case 0x02:
+               pull = S3C_GPIO_PULL_DOWN;
+               break;
+       }
+
+       return pull;
+}
+
+static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
+                                 unsigned int off, samsung_gpio_pull_t pull,
+                                 samsung_gpio_pull_t updown)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       if (pull == updown)
+               pup &= ~(1 << off);
+       else if (pull == S3C_GPIO_PULL_NONE)
+               pup |= (1 << off);
+       else
+               return -EINVAL;
+
+       __raw_writel(pup, reg);
+       return 0;
+}
+
+static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
+                                                 unsigned int off,
+                                                 samsung_gpio_pull_t updown)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup &= (1 << off);
+       return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
+                                            unsigned int off)
+{
+       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
+                            unsigned int off, samsung_gpio_pull_t pull)
+{
+       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
+}
+
+samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
+                                              unsigned int off)
+{
+       return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
+                              unsigned int off, samsung_gpio_pull_t pull)
+{
+       return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+
+static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
+                               unsigned int off, samsung_gpio_pull_t pull)
+{
+       if (pull == S3C_GPIO_PULL_UP)
+               pull = 3;
+
+       return samsung_gpio_setpull_updown(chip, off, pull);
+}
+
+static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip,
+                                               unsigned int off)
+{
+       samsung_gpio_pull_t pull;
+
+       pull = samsung_gpio_getpull_updown(chip, off);
+
+       if (pull == 3)
+               pull = S3C_GPIO_PULL_UP;
+
+       return pull;
+}
+
+/*
+ * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ *     00 = input
+ *     01 = output
+ *     1x = special function
+ */
+
+static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
+                                   unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off * 2;
+       u32 con;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               if (cfg > 3)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x3 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_2bit(). Will return a value whicg
+ * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+
+static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
+                                            unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off * 2;
+       con &= 3;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
+/*
+ * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ *     0000 = Input
+ *     0001 = Output
+ *     others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+ */
+
+static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
+                                   unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0xf << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to samsung_gpio_setcfg_4bit().
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ */
+
+static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
+                                        unsigned int off)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       con = __raw_readl(reg);
+       con >>= shift;
+       con &= 0xf;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/*
+ * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+ */
+
+static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
+                                    unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = off;
+       u32 con;
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+
+               /* Map output to 0, and SFN2 to 1 */
+               cfg -= 1;
+               if (cfg > 1)
+                       return -EINVAL;
+
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0x1 << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+
+/*
+ * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa samsung_gpio_getcfg_2bit
+ * @sa samsung_gpio_getcfg_4bit
+ */
+
+static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
+                                         unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off;
+       con &= 1;
+       con++;
+
+       return S3C_GPIO_SFN(con);
+}
+#endif
+
+#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
+static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
+                                    unsigned int off, unsigned int cfg)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift;
+       u32 con;
+
+       switch (off) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+       case 5:
+               shift = (off & 7) * 4;
+               reg -= 4;
+               break;
+       case 6:
+               shift = ((off + 1) & 7) * 4;
+               reg -= 4;
+       default:
+               shift = ((off + 1) & 7) * 4;
+               break;
+       }
+
+       if (samsung_gpio_is_cfg_special(cfg)) {
+               cfg &= 0xf;
+               cfg <<= shift;
+       }
+
+       con = __raw_readl(reg);
+       con &= ~(0xf << shift);
+       con |= cfg;
+       __raw_writel(con, reg);
+
+       return 0;
+}
+#endif
+
+static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
+                                          int nr_chips)
+{
+       for (; nr_chips > 0; nr_chips--, chipcfg++) {
+               if (!chipcfg->set_config)
+                       chipcfg->set_config = samsung_gpio_setcfg_4bit;
+               if (!chipcfg->get_config)
+                       chipcfg->get_config = samsung_gpio_getcfg_4bit;
+               if (!chipcfg->set_pull)
+                       chipcfg->set_pull = samsung_gpio_setpull_updown;
+               if (!chipcfg->get_pull)
+                       chipcfg->get_pull = samsung_gpio_getpull_updown;
+       }
+}
+
+struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
+       .set_config     = samsung_gpio_setcfg_2bit,
+       .get_config     = samsung_gpio_getcfg_2bit,
+};
+
+#ifdef CONFIG_PLAT_S3C24XX
+static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
+       .set_config     = s3c24xx_gpio_setcfg_abank,
+       .get_config     = s3c24xx_gpio_getcfg_abank,
+};
+#endif
+
+static struct samsung_gpio_cfg exynos4_gpio_cfg = {
+       .set_pull       = exynos4_gpio_setpull,
+       .get_pull       = exynos4_gpio_getpull,
+       .set_config     = samsung_gpio_setcfg_4bit,
+       .get_config     = samsung_gpio_getcfg_4bit,
+};
+
+#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
+static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
+       .cfg_eint       = 0x3,
+       .set_config     = s5p64x0_gpio_setcfg_rbank,
+       .get_config     = samsung_gpio_getcfg_4bit,
+       .set_pull       = samsung_gpio_setpull_updown,
+       .get_pull       = samsung_gpio_getpull_updown,
+};
+#endif
+
+static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
+       {
+               .cfg_eint       = 0x0,
+       }, {
+               .cfg_eint       = 0x3,
+       }, {
+               .cfg_eint       = 0x7,
+       }, {
+               .cfg_eint       = 0xF,
+       }, {
+               .cfg_eint       = 0x0,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       }, {
+               .cfg_eint       = 0x2,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       }, {
+               .cfg_eint       = 0x3,
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       }, {
+               .set_config     = samsung_gpio_setcfg_2bit,
+               .get_config     = samsung_gpio_getcfg_2bit,
+       }, {
+               .set_pull       = exynos4_gpio_setpull,
+               .get_pull       = exynos4_gpio_getpull,
+       }, {
+               .cfg_eint       = 0x3,
+               .set_pull       = exynos4_gpio_setpull,
+               .get_pull       = exynos4_gpio_getpull,
+       }
+};
+
+/*
+ * Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ *             gpio n: 2 bits starting at (2*n)
+ *             00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *             bit n: data bit n
+*/
+
+static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long con;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       con = __raw_readl(base + 0x00);
+       con &= ~(3 << (offset * 2));
+
+       __raw_writel(con, base + 0x00);
+
+       samsung_gpio_unlock(ourchip, flags);
+       return 0;
+}
+
+static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
+                                      unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+       unsigned long con;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       dat = __raw_readl(base + 0x04);
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+       __raw_writel(dat, base + 0x04);
+
+       con = __raw_readl(base + 0x00);
+       con &= ~(3 << (offset * 2));
+       con |= 1 << (offset * 2);
+
+       __raw_writel(con, base + 0x00);
+       __raw_writel(dat, base + 0x04);
+
+       samsung_gpio_unlock(ourchip, flags);
+       return 0;
+}
+
+/*
+ * The samsung_gpiolib_4bit routines are to control the gpio banks where
+ * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
+ * following example:
+ *
+ * base + 0x00: Control register, 4 bits per gpio
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ *             bit n: data bit n
+ *
+ * Note, since the data register is one bit per gpio and is at base + 0x4
+ * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
+ * state of the output.
+ */
+
+static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
+                                     unsigned int offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long con;
+
+       con = __raw_readl(base + GPIOCON_OFF);
+       con &= ~(0xf << con_4bit_shift(offset));
+       __raw_writel(con, base + GPIOCON_OFF);
+
+       gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+
+       return 0;
+}
+
+static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
+                                      unsigned int offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long con;
+       unsigned long dat;
+
+       con = __raw_readl(base + GPIOCON_OFF);
+       con &= ~(0xf << con_4bit_shift(offset));
+       con |= 0x1 << con_4bit_shift(offset);
+
+       dat = __raw_readl(base + GPIODAT_OFF);
+
+       if (value)
+               dat |= 1 << offset;
+       else
+               dat &= ~(1 << offset);
+
+       __raw_writel(dat, base + GPIODAT_OFF);
+       __raw_writel(con, base + GPIOCON_OFF);
+       __raw_writel(dat, base + GPIODAT_OFF);
+
+       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+       return 0;
+}
+
+/*
+ * The next set of routines are for the case where the GPIO configuration
+ * registers are 4 bits per GPIO but there is more than one register (the
+ * bank has more than 8 GPIOs.
+ *
+ * This case is the similar to the 4 bit case, but the registers are as
+ * follows:
+ *
+ * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
+ *             gpio n: 4 bits starting at (4*n)
+ *             0000 = input, 0001 = output, others mean special-function
+ * base + 0x08: Data register, 1 bit per gpio
+ *             bit n: data bit n
+ *
+ * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
+ * routines we store the 'base + 0x4' address so that these routines see
+ * the data register at ourchip->base + 0x04.
+ */
+
+static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
+                                      unsigned int offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+
+       if (offset > 7)
+               offset -= 8;
+       else
+               regcon -= 4;
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(offset));
+       __raw_writel(con, regcon);
+
+       gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+
+       return 0;
+}
+
+static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
+                                       unsigned int offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+       unsigned long dat;
+       unsigned con_offset = offset;
+
+       if (con_offset > 7)
+               con_offset -= 8;
+       else
+               regcon -= 4;
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(con_offset));
+       con |= 0x1 << con_4bit_shift(con_offset);
+
+       dat = __raw_readl(base + GPIODAT_OFF);
+
+       if (value)
+               dat |= 1 << offset;
+       else
+               dat &= ~(1 << offset);
+
+       __raw_writel(dat, base + GPIODAT_OFF);
+       __raw_writel(con, regcon);
+       __raw_writel(dat, base + GPIODAT_OFF);
+
+       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+
+       return 0;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+/* The next set of routines are for the case of s3c24xx bank a */
+
+static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
+{
+       return -EINVAL;
+}
+
+static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+       unsigned long con;
+
+       local_irq_save(flags);
+
+       con = __raw_readl(base + 0x00);
+       dat = __raw_readl(base + 0x04);
+
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+
+       __raw_writel(dat, base + 0x04);
+
+       con &= ~(1 << offset);
+
+       __raw_writel(con, base + 0x00);
+       __raw_writel(dat, base + 0x04);
+
+       local_irq_restore(flags);
+       return 0;
+}
+#endif
+
+/* The next set of routines are for the case of s5p64x0 bank r */
+
+static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
+                                      unsigned int offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+       unsigned long flags;
+
+       switch (offset) {
+       case 6:
+               offset += 1;
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+       case 5:
+               regcon -= 4;
+               break;
+       default:
+               offset -= 7;
+               break;
+       }
+
+       samsung_gpio_lock(ourchip, flags);
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(offset));
+       __raw_writel(con, regcon);
+
+       samsung_gpio_unlock(ourchip, flags);
+
+       return 0;
+}
+
+static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
+                                       unsigned int offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       void __iomem *regcon = base;
+       unsigned long con;
+       unsigned long dat;
+       unsigned long flags;
+       unsigned con_offset  = offset;
+
+       switch (con_offset) {
+       case 6:
+               con_offset += 1;
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+       case 5:
+               regcon -= 4;
+               break;
+       default:
+               con_offset -= 7;
+               break;
+       }
+
+       samsung_gpio_lock(ourchip, flags);
+
+       con = __raw_readl(regcon);
+       con &= ~(0xf << con_4bit_shift(con_offset));
+       con |= 0x1 << con_4bit_shift(con_offset);
+
+       dat = __raw_readl(base + GPIODAT_OFF);
+       if (value)
+               dat |= 1 << offset;
+       else
+               dat &= ~(1 << offset);
+
+       __raw_writel(con, regcon);
+       __raw_writel(dat, base + GPIODAT_OFF);
+
+       samsung_gpio_unlock(ourchip, flags);
+
+       return 0;
+}
+
+static void samsung_gpiolib_set(struct gpio_chip *chip,
+                               unsigned offset, int value)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       void __iomem *base = ourchip->base;
+       unsigned long flags;
+       unsigned long dat;
+
+       samsung_gpio_lock(ourchip, flags);
+
+       dat = __raw_readl(base + 0x04);
+       dat &= ~(1 << offset);
+       if (value)
+               dat |= 1 << offset;
+       __raw_writel(dat, base + 0x04);
+
+       samsung_gpio_unlock(ourchip, flags);
+}
+
+static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
+       unsigned long val;
+
+       val = __raw_readl(ourchip->base + 0x04);
+       val >>= offset;
+       val &= 1;
+
+       return val;
+}
+
+/*
+ * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own samsung_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
+{
+       unsigned int gpn;
+       int i;
+
+       gpn = chip->chip.base;
+       for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+               BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+               s3c_gpios[gpn] = chip;
+       }
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/*
+ * samsung_gpiolib_add() - add the Samsung gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+
+static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
+{
+       struct gpio_chip *gc = &chip->chip;
+       int ret;
+
+       BUG_ON(!chip->base);
+       BUG_ON(!gc->label);
+       BUG_ON(!gc->ngpio);
+
+       spin_lock_init(&chip->lock);
+
+       if (!gc->direction_input)
+               gc->direction_input = samsung_gpiolib_2bit_input;
+       if (!gc->direction_output)
+               gc->direction_output = samsung_gpiolib_2bit_output;
+       if (!gc->set)
+               gc->set = samsung_gpiolib_set;
+       if (!gc->get)
+               gc->get = samsung_gpiolib_get;
+
+#ifdef CONFIG_PM
+       if (chip->pm != NULL) {
+               if (!chip->pm->save || !chip->pm->resume)
+                       printk(KERN_ERR "gpio: %s has missing PM functions\n",
+                              gc->label);
+       } else
+               printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+#endif
+
+       /* gpiochip_add() prints own failure message on error. */
+       ret = gpiochip_add(gc);
+       if (ret >= 0)
+               s3c_gpiolib_track(chip);
+}
+
+static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
+                                            int nr_chips, void __iomem *base)
+{
+       int i;
+       struct gpio_chip *gc = &chip->chip;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               /* skip banks not present on SoC */
+               if (chip->chip.base >= S3C_GPIO_END)
+                       continue;
+
+               if (!chip->config)
+                       chip->config = &s3c24xx_gpiocfg_default;
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * 0x10);
+
+               if (!gc->direction_input)
+                       gc->direction_input = samsung_gpiolib_2bit_input;
+               if (!gc->direction_output)
+                       gc->direction_output = samsung_gpiolib_2bit_output;
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
+                                                 int nr_chips, void __iomem *base,
+                                                 unsigned int offset)
+{
+       int i;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_2bit_input;
+               chip->chip.direction_output = samsung_gpiolib_2bit_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[7];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * offset);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+/*
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+
+static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
+                                                 int nr_chips, void __iomem *base)
+{
+       int i;
+
+       for (i = 0 ; i < nr_chips; i++, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_4bit_input;
+               chip->chip.direction_output = samsung_gpiolib_4bit_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[2];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+               if ((base != NULL) && (chip->base == NULL))
+                       chip->base = base + ((i) * 0x20);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
+                                                  int nr_chips)
+{
+       for (; nr_chips > 0; nr_chips--, chip++) {
+               chip->chip.direction_input = samsung_gpiolib_4bit2_input;
+               chip->chip.direction_output = samsung_gpiolib_4bit2_output;
+
+               if (!chip->config)
+                       chip->config = &samsung_gpio_cfgs[2];
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
+                                            int nr_chips)
+{
+       for (; nr_chips > 0; nr_chips--, chip++) {
+               chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
+               chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
+
+               if (!chip->pm)
+                       chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
+
+               samsung_gpiolib_add(chip);
+       }
+}
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
+
+       return samsung_chip->irq_base + offset;
+}
+
+#ifdef CONFIG_PLAT_S3C24XX
+static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       if (offset < 4)
+               return IRQ_EINT0 + offset;
+
+       if (offset < 8)
+               return IRQ_EINT4 + offset - 4;
+
+       return -EINVAL;
+}
+#endif
+
+#ifdef CONFIG_PLAT_S3C64XX
+static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+       return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+       return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+#endif
+
+struct samsung_gpio_chip s3c24xx_gpios[] = {
+#ifdef CONFIG_PLAT_S3C24XX
+       {
+               .config = &s3c24xx_gpiocfg_banka,
+               .chip   = {
+                       .base                   = S3C2410_GPA(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOA",
+                       .ngpio                  = 24,
+                       .direction_input        = s3c24xx_gpiolib_banka_input,
+                       .direction_output       = s3c24xx_gpiolib_banka_output,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPB(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOB",
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPC(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOC",
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPD(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOD",
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPE(0),
+                       .label  = "GPIOE",
+                       .owner  = THIS_MODULE,
+                       .ngpio  = 16,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPF(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOF",
+                       .ngpio  = 8,
+                       .to_irq = s3c24xx_gpiolib_fbank_to_irq,
+               },
+       }, {
+               .irq_base = IRQ_EINT8,
+               .chip   = {
+                       .base   = S3C2410_GPG(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOG",
+                       .ngpio  = 16,
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C2410_GPH(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOH",
+                       .ngpio  = 11,
+               },
+       },
+               /* GPIOS for the S3C2443 and later devices. */
+       {
+               .base   = S3C2440_GPJCON,
+               .chip   = {
+                       .base   = S3C2410_GPJ(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOJ",
+                       .ngpio  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPKCON,
+               .chip   = {
+                       .base   = S3C2410_GPK(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOK",
+                       .ngpio  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPLCON,
+               .chip   = {
+                       .base   = S3C2410_GPL(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOL",
+                       .ngpio  = 15,
+               },
+       }, {
+               .base   = S3C2443_GPMCON,
+               .chip   = {
+                       .base   = S3C2410_GPM(0),
+                       .owner  = THIS_MODULE,
+                       .label  = "GPIOM",
+                       .ngpio  = 2,
+               },
+       },
+#endif
+};
+
+/*
+ * GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   SlpCon  ExtInt Group
+ * A   8       4Bit    Yes     1
+ * B   7       4Bit    Yes     1
+ * C   8       4Bit    Yes     2
+ * D   5       4Bit    Yes     3
+ * E   5       4Bit    Yes     None
+ * F   16      2Bit    Yes     4 [1]
+ * G   7       4Bit    Yes     5
+ * H   10      4Bit[2] Yes     6
+ * I   16      2Bit    Yes     None
+ * J   12      2Bit    Yes     None
+ * K   16      4Bit[2] No      None
+ * L   15      4Bit[2] No      None
+ * M   6       4Bit    No      IRQ_EINT
+ * N   16      2Bit    No      IRQ_EINT
+ * O   16      2Bit    Yes     7
+ * P   15      2Bit    Yes     8
+ * Q   9       2Bit    Yes     9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
+#ifdef CONFIG_PLAT_S3C64XX
+       {
+               .chip   = {
+                       .base   = S3C64XX_GPA(0),
+                       .ngpio  = S3C64XX_GPIO_A_NR,
+                       .label  = "GPA",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPB(0),
+                       .ngpio  = S3C64XX_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPC(0),
+                       .ngpio  = S3C64XX_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .chip   = {
+                       .base   = S3C64XX_GPD(0),
+                       .ngpio  = S3C64XX_GPIO_D_NR,
+                       .label  = "GPD",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[0],
+               .chip   = {
+                       .base   = S3C64XX_GPE(0),
+                       .ngpio  = S3C64XX_GPIO_E_NR,
+                       .label  = "GPE",
+               },
+       }, {
+               .base   = S3C64XX_GPG_BASE,
+               .chip   = {
+                       .base   = S3C64XX_GPG(0),
+                       .ngpio  = S3C64XX_GPIO_G_NR,
+                       .label  = "GPG",
+               },
+       }, {
+               .base   = S3C64XX_GPM_BASE,
+               .config = &samsung_gpio_cfgs[1],
+               .chip   = {
+                       .base   = S3C64XX_GPM(0),
+                       .ngpio  = S3C64XX_GPIO_M_NR,
+                       .label  = "GPM",
+                       .to_irq = s3c64xx_gpiolib_mbank_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
+#ifdef CONFIG_PLAT_S3C64XX
+       {
+               .base   = S3C64XX_GPH_BASE + 0x4,
+               .chip   = {
+                       .base   = S3C64XX_GPH(0),
+                       .ngpio  = S3C64XX_GPIO_H_NR,
+                       .label  = "GPH",
+               },
+       }, {
+               .base   = S3C64XX_GPK_BASE + 0x4,
+               .config = &samsung_gpio_cfgs[0],
+               .chip   = {
+                       .base   = S3C64XX_GPK(0),
+                       .ngpio  = S3C64XX_GPIO_K_NR,
+                       .label  = "GPK",
+               },
+       }, {
+               .base   = S3C64XX_GPL_BASE + 0x4,
+               .config = &samsung_gpio_cfgs[1],
+               .chip   = {
+                       .base   = S3C64XX_GPL(0),
+                       .ngpio  = S3C64XX_GPIO_L_NR,
+                       .label  = "GPL",
+                       .to_irq = s3c64xx_gpiolib_lbank_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
+#ifdef CONFIG_PLAT_S3C64XX
+       {
+               .base   = S3C64XX_GPF_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPF(0),
+                       .ngpio  = S3C64XX_GPIO_F_NR,
+                       .label  = "GPF",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[7],
+               .chip   = {
+                       .base   = S3C64XX_GPI(0),
+                       .ngpio  = S3C64XX_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[7],
+               .chip   = {
+                       .base   = S3C64XX_GPJ(0),
+                       .ngpio  = S3C64XX_GPIO_J_NR,
+                       .label  = "GPJ",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPO(0),
+                       .ngpio  = S3C64XX_GPIO_O_NR,
+                       .label  = "GPO",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPP(0),
+                       .ngpio  = S3C64XX_GPIO_P_NR,
+                       .label  = "GPP",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S3C64XX_GPQ(0),
+                       .ngpio  = S3C64XX_GPIO_Q_NR,
+                       .label  = "GPQ",
+               },
+       }, {
+               .base   = S3C64XX_GPN_BASE,
+               .irq_base = IRQ_EINT(0),
+               .config = &samsung_gpio_cfgs[5],
+               .chip   = {
+                       .base   = S3C64XX_GPN(0),
+                       .ngpio  = S3C64XX_GPIO_N_NR,
+                       .label  = "GPN",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+/*
+ * S5P6440 GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   SlpCon  ExtInt Group
+ * A   6       4Bit    Yes     1
+ * B   7       4Bit    Yes     1
+ * C   8       4Bit    Yes     2
+ * F   2       2Bit    Yes     4 [1]
+ * G   7       4Bit    Yes     5
+ * H   10      4Bit[2] Yes     6
+ * I   16      2Bit    Yes     None
+ * J   12      2Bit    Yes     None
+ * N   16      2Bit    No      IRQ_EINT
+ * P   8       2Bit    Yes     8
+ * R   15      4Bit[2] Yes     8
+ */
+
+static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
+#ifdef CONFIG_CPU_S5P6440
+       {
+               .chip   = {
+                       .base   = S5P6440_GPA(0),
+                       .ngpio  = S5P6440_GPIO_A_NR,
+                       .label  = "GPA",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5P6440_GPB(0),
+                       .ngpio  = S5P6440_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5P6440_GPC(0),
+                       .ngpio  = S5P6440_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .base   = S5P64X0_GPG_BASE,
+               .chip   = {
+                       .base   = S5P6440_GPG(0),
+                       .ngpio  = S5P6440_GPIO_G_NR,
+                       .label  = "GPG",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
+#ifdef CONFIG_CPU_S5P6440
+       {
+               .base   = S5P64X0_GPH_BASE + 0x4,
+               .chip   = {
+                       .base   = S5P6440_GPH(0),
+                       .ngpio  = S5P6440_GPIO_H_NR,
+                       .label  = "GPH",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
+#ifdef CONFIG_CPU_S5P6440
+       {
+               .base   = S5P64X0_GPR_BASE + 0x4,
+               .config = &s5p64x0_gpio_cfg_rbank,
+               .chip   = {
+                       .base   = S5P6440_GPR(0),
+                       .ngpio  = S5P6440_GPIO_R_NR,
+                       .label  = "GPR",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
+#ifdef CONFIG_CPU_S5P6440
+       {
+               .base   = S5P64X0_GPF_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S5P6440_GPF(0),
+                       .ngpio  = S5P6440_GPIO_F_NR,
+                       .label  = "GPF",
+               },
+       }, {
+               .base   = S5P64X0_GPI_BASE,
+               .config = &samsung_gpio_cfgs[4],
+               .chip   = {
+                       .base   = S5P6440_GPI(0),
+                       .ngpio  = S5P6440_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .base   = S5P64X0_GPJ_BASE,
+               .config = &samsung_gpio_cfgs[4],
+               .chip   = {
+                       .base   = S5P6440_GPJ(0),
+                       .ngpio  = S5P6440_GPIO_J_NR,
+                       .label  = "GPJ",
+               },
+       }, {
+               .base   = S5P64X0_GPN_BASE,
+               .config = &samsung_gpio_cfgs[5],
+               .chip   = {
+                       .base   = S5P6440_GPN(0),
+                       .ngpio  = S5P6440_GPIO_N_NR,
+                       .label  = "GPN",
+               },
+       }, {
+               .base   = S5P64X0_GPP_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S5P6440_GPP(0),
+                       .ngpio  = S5P6440_GPIO_P_NR,
+                       .label  = "GPP",
+               },
+       },
+#endif
+};
+
+/*
+ * S5P6450 GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   SlpCon  ExtInt Group
+ * A   6       4Bit    Yes     1
+ * B   7       4Bit    Yes     1
+ * C   8       4Bit    Yes     2
+ * D   8       4Bit    Yes     None
+ * F   2       2Bit    Yes     None
+ * G   14      4Bit[2] Yes     5
+ * H   10      4Bit[2] Yes     6
+ * I   16      2Bit    Yes     None
+ * J   12      2Bit    Yes     None
+ * K   5       4Bit    Yes     None
+ * N   16      2Bit    No      IRQ_EINT
+ * P   11      2Bit    Yes     8
+ * Q   14      2Bit    Yes     None
+ * R   15      4Bit[2] Yes     None
+ * S   8       2Bit    Yes     None
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
+#ifdef CONFIG_CPU_S5P6450
+       {
+               .chip   = {
+                       .base   = S5P6450_GPA(0),
+                       .ngpio  = S5P6450_GPIO_A_NR,
+                       .label  = "GPA",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5P6450_GPB(0),
+                       .ngpio  = S5P6450_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5P6450_GPC(0),
+                       .ngpio  = S5P6450_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5P6450_GPD(0),
+                       .ngpio  = S5P6450_GPIO_D_NR,
+                       .label  = "GPD",
+               },
+       }, {
+               .base   = S5P6450_GPK_BASE,
+               .chip   = {
+                       .base   = S5P6450_GPK(0),
+                       .ngpio  = S5P6450_GPIO_K_NR,
+                       .label  = "GPK",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
+#ifdef CONFIG_CPU_S5P6450
+       {
+               .base   = S5P64X0_GPG_BASE + 0x4,
+               .chip   = {
+                       .base   = S5P6450_GPG(0),
+                       .ngpio  = S5P6450_GPIO_G_NR,
+                       .label  = "GPG",
+               },
+       }, {
+               .base   = S5P64X0_GPH_BASE + 0x4,
+               .chip   = {
+                       .base   = S5P6450_GPH(0),
+                       .ngpio  = S5P6450_GPIO_H_NR,
+                       .label  = "GPH",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
+#ifdef CONFIG_CPU_S5P6450
+       {
+               .base   = S5P64X0_GPR_BASE + 0x4,
+               .config = &s5p64x0_gpio_cfg_rbank,
+               .chip   = {
+                       .base   = S5P6450_GPR(0),
+                       .ngpio  = S5P6450_GPIO_R_NR,
+                       .label  = "GPR",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
+#ifdef CONFIG_CPU_S5P6450
+       {
+               .base   = S5P64X0_GPF_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S5P6450_GPF(0),
+                       .ngpio  = S5P6450_GPIO_F_NR,
+                       .label  = "GPF",
+               },
+       }, {
+               .base   = S5P64X0_GPI_BASE,
+               .config = &samsung_gpio_cfgs[4],
+               .chip   = {
+                       .base   = S5P6450_GPI(0),
+                       .ngpio  = S5P6450_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .base   = S5P64X0_GPJ_BASE,
+               .config = &samsung_gpio_cfgs[4],
+               .chip   = {
+                       .base   = S5P6450_GPJ(0),
+                       .ngpio  = S5P6450_GPIO_J_NR,
+                       .label  = "GPJ",
+               },
+       }, {
+               .base   = S5P64X0_GPN_BASE,
+               .config = &samsung_gpio_cfgs[5],
+               .chip   = {
+                       .base   = S5P6450_GPN(0),
+                       .ngpio  = S5P6450_GPIO_N_NR,
+                       .label  = "GPN",
+               },
+       }, {
+               .base   = S5P64X0_GPP_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S5P6450_GPP(0),
+                       .ngpio  = S5P6450_GPIO_P_NR,
+                       .label  = "GPP",
+               },
+       }, {
+               .base   = S5P6450_GPQ_BASE,
+               .config = &samsung_gpio_cfgs[5],
+               .chip   = {
+                       .base   = S5P6450_GPQ(0),
+                       .ngpio  = S5P6450_GPIO_Q_NR,
+                       .label  = "GPQ",
+               },
+       }, {
+               .base   = S5P6450_GPS_BASE,
+               .config = &samsung_gpio_cfgs[6],
+               .chip   = {
+                       .base   = S5P6450_GPS(0),
+                       .ngpio  = S5P6450_GPIO_S_NR,
+                       .label  = "GPS",
+               },
+       },
+#endif
+};
+
+/*
+ * S5PC100 GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   INT Type
+ * A0  8       4Bit    GPIO_INT0
+ * A1  5       4Bit    GPIO_INT1
+ * B   8       4Bit    GPIO_INT2
+ * C   5       4Bit    GPIO_INT3
+ * D   7       4Bit    GPIO_INT4
+ * E0  8       4Bit    GPIO_INT5
+ * E1  6       4Bit    GPIO_INT6
+ * F0  8       4Bit    GPIO_INT7
+ * F1  8       4Bit    GPIO_INT8
+ * F2  8       4Bit    GPIO_INT9
+ * F3  4       4Bit    GPIO_INT10
+ * G0  8       4Bit    GPIO_INT11
+ * G1  3       4Bit    GPIO_INT12
+ * G2  7       4Bit    GPIO_INT13
+ * G3  7       4Bit    GPIO_INT14
+ * H0  8       4Bit    WKUP_INT
+ * H1  8       4Bit    WKUP_INT
+ * H2  8       4Bit    WKUP_INT
+ * H3  8       4Bit    WKUP_INT
+ * I   8       4Bit    GPIO_INT15
+ * J0  8       4Bit    GPIO_INT16
+ * J1  5       4Bit    GPIO_INT17
+ * J2  8       4Bit    GPIO_INT18
+ * J3  8       4Bit    GPIO_INT19
+ * J4  4       4Bit    GPIO_INT20
+ * K0  8       4Bit    None
+ * K1  6       4Bit    None
+ * K2  8       4Bit    None
+ * K3  8       4Bit    None
+ * L0  8       4Bit    None
+ * L1  8       4Bit    None
+ * L2  8       4Bit    None
+ * L3  8       4Bit    None
+ */
+
+static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
+#ifdef CONFIG_CPU_S5PC100
+       {
+               .chip   = {
+                       .base   = S5PC100_GPA0(0),
+                       .ngpio  = S5PC100_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPA1(0),
+                       .ngpio  = S5PC100_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPB(0),
+                       .ngpio  = S5PC100_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPC(0),
+                       .ngpio  = S5PC100_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPD(0),
+                       .ngpio  = S5PC100_GPIO_D_NR,
+                       .label  = "GPD",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPE0(0),
+                       .ngpio  = S5PC100_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPE1(0),
+                       .ngpio  = S5PC100_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPF0(0),
+                       .ngpio  = S5PC100_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPF1(0),
+                       .ngpio  = S5PC100_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPF2(0),
+                       .ngpio  = S5PC100_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPF3(0),
+                       .ngpio  = S5PC100_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPG0(0),
+                       .ngpio  = S5PC100_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPG1(0),
+                       .ngpio  = S5PC100_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPG2(0),
+                       .ngpio  = S5PC100_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPG3(0),
+                       .ngpio  = S5PC100_GPIO_G3_NR,
+                       .label  = "GPG3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPI(0),
+                       .ngpio  = S5PC100_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPJ0(0),
+                       .ngpio  = S5PC100_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPJ1(0),
+                       .ngpio  = S5PC100_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPJ2(0),
+                       .ngpio  = S5PC100_GPIO_J2_NR,
+                       .label  = "GPJ2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPJ3(0),
+                       .ngpio  = S5PC100_GPIO_J3_NR,
+                       .label  = "GPJ3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPJ4(0),
+                       .ngpio  = S5PC100_GPIO_J4_NR,
+                       .label  = "GPJ4",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPK0(0),
+                       .ngpio  = S5PC100_GPIO_K0_NR,
+                       .label  = "GPK0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPK1(0),
+                       .ngpio  = S5PC100_GPIO_K1_NR,
+                       .label  = "GPK1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPK2(0),
+                       .ngpio  = S5PC100_GPIO_K2_NR,
+                       .label  = "GPK2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPK3(0),
+                       .ngpio  = S5PC100_GPIO_K3_NR,
+                       .label  = "GPK3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPL0(0),
+                       .ngpio  = S5PC100_GPIO_L0_NR,
+                       .label  = "GPL0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPL1(0),
+                       .ngpio  = S5PC100_GPIO_L1_NR,
+                       .label  = "GPL1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPL2(0),
+                       .ngpio  = S5PC100_GPIO_L2_NR,
+                       .label  = "GPL2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPL3(0),
+                       .ngpio  = S5PC100_GPIO_L3_NR,
+                       .label  = "GPL3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PC100_GPL4(0),
+                       .ngpio  = S5PC100_GPIO_L4_NR,
+                       .label  = "GPL4",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC00),
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = S5PC100_GPH0(0),
+                       .ngpio  = S5PC100_GPIO_H0_NR,
+                       .label  = "GPH0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC20),
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = S5PC100_GPH1(0),
+                       .ngpio  = S5PC100_GPIO_H1_NR,
+                       .label  = "GPH1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC40),
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = S5PC100_GPH2(0),
+                       .ngpio  = S5PC100_GPIO_H2_NR,
+                       .label  = "GPH2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC60),
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = S5PC100_GPH3(0),
+                       .ngpio  = S5PC100_GPIO_H3_NR,
+                       .label  = "GPH3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+/*
+ * Followings are the gpio banks in S5PV210/S5PC110
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure samsung_gpio_cfgs[3] in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of samsung_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+
+static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
+#ifdef CONFIG_CPU_S5PV210
+       {
+               .chip   = {
+                       .base   = S5PV210_GPA0(0),
+                       .ngpio  = S5PV210_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPA1(0),
+                       .ngpio  = S5PV210_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPB(0),
+                       .ngpio  = S5PV210_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC0(0),
+                       .ngpio  = S5PV210_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC1(0),
+                       .ngpio  = S5PV210_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD0(0),
+                       .ngpio  = S5PV210_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD1(0),
+                       .ngpio  = S5PV210_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE0(0),
+                       .ngpio  = S5PV210_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE1(0),
+                       .ngpio  = S5PV210_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF0(0),
+                       .ngpio  = S5PV210_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF1(0),
+                       .ngpio  = S5PV210_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF2(0),
+                       .ngpio  = S5PV210_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF3(0),
+                       .ngpio  = S5PV210_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG0(0),
+                       .ngpio  = S5PV210_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG1(0),
+                       .ngpio  = S5PV210_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG2(0),
+                       .ngpio  = S5PV210_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG3(0),
+                       .ngpio  = S5PV210_GPIO_G3_NR,
+                       .label  = "GPG3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPI(0),
+                       .ngpio  = S5PV210_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ0(0),
+                       .ngpio  = S5PV210_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ1(0),
+                       .ngpio  = S5PV210_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ2(0),
+                       .ngpio  = S5PV210_GPIO_J2_NR,
+                       .label  = "GPJ2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ3(0),
+                       .ngpio  = S5PV210_GPIO_J3_NR,
+                       .label  = "GPJ3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ4(0),
+                       .ngpio  = S5PV210_GPIO_J4_NR,
+                       .label  = "GPJ4",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_MP01(0),
+                       .ngpio  = S5PV210_GPIO_MP01_NR,
+                       .label  = "MP01",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_MP02(0),
+                       .ngpio  = S5PV210_GPIO_MP02_NR,
+                       .label  = "MP02",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_MP03(0),
+                       .ngpio  = S5PV210_GPIO_MP03_NR,
+                       .label  = "MP03",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_MP04(0),
+                       .ngpio  = S5PV210_GPIO_MP04_NR,
+                       .label  = "MP04",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_MP05(0),
+                       .ngpio  = S5PV210_GPIO_MP05_NR,
+                       .label  = "MP05",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC00),
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = S5PV210_GPH0(0),
+                       .ngpio  = S5PV210_GPIO_H0_NR,
+                       .label  = "GPH0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC20),
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = S5PV210_GPH1(0),
+                       .ngpio  = S5PV210_GPIO_H1_NR,
+                       .label  = "GPH1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC40),
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = S5PV210_GPH2(0),
+                       .ngpio  = S5PV210_GPIO_H2_NR,
+                       .label  = "GPH2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC60),
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = S5PV210_GPH3(0),
+                       .ngpio  = S5PV210_GPIO_H3_NR,
+                       .label  = "GPH3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+/*
+ * Followings are the gpio banks in EXYNOS4210
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure samsung_gpio_cfgs[3] in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of samsung_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+
+static struct samsung_gpio_chip exynos4_gpios_1[] = {
+#ifdef CONFIG_ARCH_EXYNOS4
+       {
+               .chip   = {
+                       .base   = EXYNOS4_GPA0(0),
+                       .ngpio  = EXYNOS4_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPA1(0),
+                       .ngpio  = EXYNOS4_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPB(0),
+                       .ngpio  = EXYNOS4_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPC0(0),
+                       .ngpio  = EXYNOS4_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPC1(0),
+                       .ngpio  = EXYNOS4_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPD0(0),
+                       .ngpio  = EXYNOS4_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPD1(0),
+                       .ngpio  = EXYNOS4_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPE0(0),
+                       .ngpio  = EXYNOS4_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPE1(0),
+                       .ngpio  = EXYNOS4_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPE2(0),
+                       .ngpio  = EXYNOS4_GPIO_E2_NR,
+                       .label  = "GPE2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPE3(0),
+                       .ngpio  = EXYNOS4_GPIO_E3_NR,
+                       .label  = "GPE3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPE4(0),
+                       .ngpio  = EXYNOS4_GPIO_E4_NR,
+                       .label  = "GPE4",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPF0(0),
+                       .ngpio  = EXYNOS4_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPF1(0),
+                       .ngpio  = EXYNOS4_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPF2(0),
+                       .ngpio  = EXYNOS4_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPF3(0),
+                       .ngpio  = EXYNOS4_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip exynos4_gpios_2[] = {
+#ifdef CONFIG_ARCH_EXYNOS4
+       {
+               .chip   = {
+                       .base   = EXYNOS4_GPJ0(0),
+                       .ngpio  = EXYNOS4_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPJ1(0),
+                       .ngpio  = EXYNOS4_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPK0(0),
+                       .ngpio  = EXYNOS4_GPIO_K0_NR,
+                       .label  = "GPK0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPK1(0),
+                       .ngpio  = EXYNOS4_GPIO_K1_NR,
+                       .label  = "GPK1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPK2(0),
+                       .ngpio  = EXYNOS4_GPIO_K2_NR,
+                       .label  = "GPK2",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPK3(0),
+                       .ngpio  = EXYNOS4_GPIO_K3_NR,
+                       .label  = "GPK3",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPL0(0),
+                       .ngpio  = EXYNOS4_GPIO_L0_NR,
+                       .label  = "GPL0",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPL1(0),
+                       .ngpio  = EXYNOS4_GPIO_L1_NR,
+                       .label  = "GPL1",
+               },
+       }, {
+               .chip   = {
+                       .base   = EXYNOS4_GPL2(0),
+                       .ngpio  = EXYNOS4_GPIO_L2_NR,
+                       .label  = "GPL2",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY0(0),
+                       .ngpio  = EXYNOS4_GPIO_Y0_NR,
+                       .label  = "GPY0",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY1(0),
+                       .ngpio  = EXYNOS4_GPIO_Y1_NR,
+                       .label  = "GPY1",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY2(0),
+                       .ngpio  = EXYNOS4_GPIO_Y2_NR,
+                       .label  = "GPY2",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY3(0),
+                       .ngpio  = EXYNOS4_GPIO_Y3_NR,
+                       .label  = "GPY3",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY4(0),
+                       .ngpio  = EXYNOS4_GPIO_Y4_NR,
+                       .label  = "GPY4",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY5(0),
+                       .ngpio  = EXYNOS4_GPIO_Y5_NR,
+                       .label  = "GPY5",
+               },
+       }, {
+               .config = &samsung_gpio_cfgs[8],
+               .chip   = {
+                       .base   = EXYNOS4_GPY6(0),
+                       .ngpio  = EXYNOS4_GPIO_Y6_NR,
+                       .label  = "GPY6",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC00),
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = EXYNOS4_GPX0(0),
+                       .ngpio  = EXYNOS4_GPIO_X0_NR,
+                       .label  = "GPX0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC20),
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = EXYNOS4_GPX1(0),
+                       .ngpio  = EXYNOS4_GPIO_X1_NR,
+                       .label  = "GPX1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC40),
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = EXYNOS4_GPX2(0),
+                       .ngpio  = EXYNOS4_GPIO_X2_NR,
+                       .label  = "GPX2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC60),
+               .config = &samsung_gpio_cfgs[9],
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = EXYNOS4_GPX3(0),
+                       .ngpio  = EXYNOS4_GPIO_X3_NR,
+                       .label  = "GPX3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+#endif
+};
+
+static struct samsung_gpio_chip exynos4_gpios_3[] = {
+#ifdef CONFIG_ARCH_EXYNOS4
+       {
+               .chip   = {
+                       .base   = EXYNOS4_GPZ(0),
+                       .ngpio  = EXYNOS4_GPIO_Z_NR,
+                       .label  = "GPZ",
+               },
+       },
+#endif
+};
+
+/* TODO: cleanup soc_is_* */
+static __init int samsung_gpiolib_init(void)
+{
+       struct samsung_gpio_chip *chip;
+       int i, nr_chips;
+       int group = 0;
+
+       samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
+
+       if (soc_is_s3c24xx()) {
+               s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
+                               ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
+       } else if (soc_is_s3c64xx()) {
+               samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
+                               ARRAY_SIZE(s3c64xx_gpios_2bit),
+                               S3C64XX_VA_GPIO + 0xE0, 0x20);
+               samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
+                               ARRAY_SIZE(s3c64xx_gpios_4bit),
+                               S3C64XX_VA_GPIO);
+               samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
+                               ARRAY_SIZE(s3c64xx_gpios_4bit2));
+       } else if (soc_is_s5p6440()) {
+               samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
+                               ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
+               samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
+                               ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
+               samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
+                               ARRAY_SIZE(s5p6440_gpios_4bit2));
+               s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
+                               ARRAY_SIZE(s5p6440_gpios_rbank));
+       } else if (soc_is_s5p6450()) {
+               samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
+                               ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
+               samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
+                               ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
+               samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
+                               ARRAY_SIZE(s5p6450_gpios_4bit2));
+               s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
+                               ARRAY_SIZE(s5p6450_gpios_rbank));
+       } else if (soc_is_s5pc100()) {
+               group = 0;
+               chip = s5pc100_gpios_4bit;
+               nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &samsung_gpio_cfgs[3];
+                               chip->group = group++;
+                       }
+               }
+               samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
+#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
+               s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
+#endif
+       } else if (soc_is_s5pv210()) {
+               group = 0;
+               chip = s5pv210_gpios_4bit;
+               nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &samsung_gpio_cfgs[3];
+                               chip->group = group++;
+                       }
+               }
+               samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
+#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
+               s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
+#endif
+       } else if (soc_is_exynos4210()) {
+               group = 0;
+
+               /* gpio part1 */
+               chip = exynos4_gpios_1;
+               nr_chips = ARRAY_SIZE(exynos4_gpios_1);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos4_gpio_cfg;
+                               chip->group = group++;
+                       }
+               }
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
+
+               /* gpio part2 */
+               chip = exynos4_gpios_2;
+               nr_chips = ARRAY_SIZE(exynos4_gpios_2);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos4_gpio_cfg;
+                               chip->group = group++;
+                       }
+               }
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
+
+               /* gpio part3 */
+               chip = exynos4_gpios_3;
+               nr_chips = ARRAY_SIZE(exynos4_gpios_3);
+
+               for (i = 0; i < nr_chips; i++, chip++) {
+                       if (!chip->config) {
+                               chip->config = &exynos4_gpio_cfg;
+                               chip->group = group++;
+                       }
+               }
+               samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
+
+#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
+               s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
+               s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
+#endif
+       } else {
+               WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+core_initcall(samsung_gpiolib_init);
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       int ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       samsung_gpio_lock(chip, flags);
+       ret = samsung_gpio_do_setcfg(chip, offset, config);
+       samsung_gpio_unlock(chip, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg, samsung_gpio_pull_t pull)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               s3c_gpio_setpull(start, pull);
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       unsigned ret = 0;
+       int offset;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               samsung_gpio_lock(chip, flags);
+               ret = samsung_gpio_do_getcfg(chip, offset);
+               samsung_gpio_unlock(chip, flags);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset, ret;
+
+       if (!chip)
+               return -EINVAL;
+
+       offset = pin - chip->chip.base;
+
+       samsung_gpio_lock(chip, flags);
+       ret = samsung_gpio_do_setpull(chip, offset, pull);
+       samsung_gpio_unlock(chip, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       u32 pup = 0;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               samsung_gpio_lock(chip, flags);
+               pup = samsung_gpio_do_getpull(chip, offset);
+               samsung_gpio_unlock(chip, flags);
+       }
+
+       return (__force samsung_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
+/* gpiolib wrappers until these are totally eliminated */
+
+void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
+{
+       int ret;
+
+       WARN_ON(to);    /* should be none of these left */
+
+       if (!to) {
+               /* if pull is enabled, try first with up, and if that
+                * fails, try using down */
+
+               ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
+               if (ret)
+                       s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
+       } else {
+               s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
+       }
+}
+EXPORT_SYMBOL(s3c2410_gpio_pullup);
+
+void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
+{
+       /* do this via gpiolib until all users removed */
+
+       gpio_request(pin, "temporary");
+       gpio_set_value(pin, to);
+       gpio_free(pin);
+}
+EXPORT_SYMBOL(s3c2410_gpio_setpin);
+
+unsigned int s3c2410_gpio_getpin(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
+
+       return __raw_readl(chip->base + 0x04) & (1 << offs);
+}
+EXPORT_SYMBOL(s3c2410_gpio_getpin);
+
+#ifdef CONFIG_S5P_GPIO_DRVSTR
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 drvstr;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = pin - chip->chip.base;
+       shift = off * 2;
+       reg = chip->base + 0x0C;
+
+       drvstr = __raw_readl(reg);
+       drvstr = drvstr >> shift;
+       drvstr &= 0x3;
+
+       return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
+{
+       struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 tmp;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = pin - chip->chip.base;
+       shift = off * 2;
+       reg = chip->base + 0x0C;
+
+       tmp = __raw_readl(reg);
+       tmp &= ~(0x3 << shift);
+       tmp |= drvstr << shift;
+
+       __raw_writel(tmp, reg);
+
+       return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
+#endif /* CONFIG_S5P_GPIO_DRVSTR */
+
+#ifdef CONFIG_PLAT_S3C24XX
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+       unsigned long flags;
+       unsigned long misccr;
+
+       local_irq_save(flags);
+       misccr = __raw_readl(S3C24XX_MISCCR);
+       misccr &= ~clear;
+       misccr ^= change;
+       __raw_writel(misccr, S3C24XX_MISCCR);
+       local_irq_restore(flags);
+
+       return misccr;
+}
+EXPORT_SYMBOL(s3c2410_modify_misccr);
+#endif
index 846fbd5e31bfffd55e616a89f192cc62e84bb719..0ce6ac9898b113d38fd9a2dd54f70a27d89beb47 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
index 785127cb281b8759b7dd77ab240aedc113621f61..1368826ef28475c0f191510b7016dd1068b55187 100644 (file)
@@ -9,7 +9,6 @@ menuconfig DRM
        depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
        select I2C
        select I2C_ALGOBIT
-       select SLOW_WORK
        help
          Kernel-level support for the Direct Rendering Infrastructure (DRI)
          introduced in XFree86 4.0. If you say Y here, you need to select
@@ -96,6 +95,7 @@ config DRM_I915
        select FB_CFB_IMAGEBLIT
        # i915 depends on ACPI_VIDEO when ACPI is enabled
        # but for select to work, need to select ACPI_VIDEO's dependencies, ick
+       select BACKLIGHT_LCD_SUPPORT if ACPI
        select BACKLIGHT_CLASS_DEVICE if ACPI
        select VIDEO_OUTPUT_CONTROL if ACPI
        select INPUT if ACPI
index 1c3649242208a5f38f8bda017799f4519a14e43d..9afe495c12c7a40b8d58001757ea1ac6e947a938 100644 (file)
@@ -31,6 +31,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "drmP.h"
 
 # define ATI_PCIGART_PAGE_SIZE         4096    /**< PCI GART page size */
index 529a0dbe9fc65960e62bc7840320754fb61393e8..08ccefedb327d9fb5819d719ef3e15cabf9568ee 100644 (file)
@@ -32,6 +32,7 @@
  * Pauli Nieminen <suokkos-at-gmail-dot-com>
  */
 
+#include <linux/export.h>
 #include "drm_buffer.h"
 
 /**
index 61e1ef90d4e5190cc9ca515f5f043b55a0465c5f..30372f7b2d457a8803e819d9050ccd3c525e7825 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/log2.h>
+#include <linux/export.h>
 #include <asm/shmparam.h>
 #include "drmP.h"
 
index 0e3bd5b54b78c57ba7fcf3df524aedaa32bf366e..592865381c6e84acb5ec66fef2e865e897d586e0 100644 (file)
@@ -28,6 +28,7 @@
  * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
+#include <linux/export.h>
 #include "drmP.h"
 
 #if defined(CONFIG_X86)
index fe738f05309ba39e6341d0fd79557f153711cb2f..8323fc3898401ac957d9a677b947455f5a598b91 100644 (file)
@@ -31,6 +31,7 @@
  */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drm.h"
 #include "drmP.h"
 #include "drm_crtc.h"
@@ -162,6 +163,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
        { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
        { DRM_MODE_CONNECTOR_TV, "TV", 0 },
        { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
+       { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -170,6 +172,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] =
        { DRM_MODE_ENCODER_TMDS, "TMDS" },
        { DRM_MODE_ENCODER_LVDS, "LVDS" },
        { DRM_MODE_ENCODER_TVDAC, "TV" },
+       { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
 };
 
 char *drm_get_encoder_name(struct drm_encoder *encoder)
@@ -463,8 +466,10 @@ void drm_connector_init(struct drm_device *dev,
        list_add_tail(&connector->head, &dev->mode_config.connector_list);
        dev->mode_config.num_connector++;
 
-       drm_connector_attach_property(connector,
-                                     dev->mode_config.edid_property, 0);
+       if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
+               drm_connector_attach_property(connector,
+                                             dev->mode_config.edid_property,
+                                             0);
 
        drm_connector_attach_property(connector,
                                      dev->mode_config.dpms_property, 0);
@@ -1868,6 +1873,10 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
        }
 
        if (num_clips && clips_ptr) {
+               if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) {
+                       ret = -EINVAL;
+                       goto out_err1;
+               }
                clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
                if (!clips) {
                        ret = -ENOMEM;
@@ -2113,8 +2122,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
        property->num_values = num_values;
        INIT_LIST_HEAD(&property->enum_blob_list);
 
-       if (name)
+       if (name) {
                strncpy(property->name, name, DRM_PROP_NAME_LEN);
+               property->name[DRM_PROP_NAME_LEN-1] = '\0';
+       }
 
        list_add_tail(&property->head, &dev->mode_config.property_list);
        return property;
index f2366440b738a1fe71c105fb8a1eaee88d775fdb..d2619d72ceceb16d7b88a33b09708219483019b4 100644 (file)
@@ -29,6 +29,9 @@
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
 
+#include <linux/export.h>
+#include <linux/moduleparam.h>
+
 #include "drmP.h"
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
@@ -453,6 +456,30 @@ done:
 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
 
 
+static int
+drm_crtc_helper_disable(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_connector *connector;
+       struct drm_encoder *encoder;
+
+       /* Decouple all encoders and their attached connectors from this crtc */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc != crtc)
+                       continue;
+
+               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+                       if (connector->encoder != encoder)
+                               continue;
+
+                       connector->encoder = NULL;
+               }
+       }
+
+       drm_helper_disable_unused_functions(dev);
+       return 0;
+}
+
 /**
  * drm_crtc_helper_set_config - set a new config from userspace
  * @crtc: CRTC to setup
@@ -481,6 +508,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        struct drm_connector *save_connectors, *connector;
        int count = 0, ro, fail = 0;
        struct drm_crtc_helper_funcs *crtc_funcs;
+       struct drm_mode_set save_set;
        int ret = 0;
        int i;
 
@@ -506,8 +534,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                                (int)set->num_connectors, set->x, set->y);
        } else {
                DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
-               set->mode = NULL;
-               set->num_connectors = 0;
+               return drm_crtc_helper_disable(set->crtc);
        }
 
        dev = set->crtc->dev;
@@ -553,6 +580,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                save_connectors[count++] = *connector;
        }
 
+       save_set.crtc = set->crtc;
+       save_set.mode = &set->crtc->mode;
+       save_set.x = set->crtc->x;
+       save_set.y = set->crtc->y;
+       save_set.fb = set->crtc->fb;
+
        /* We should be able to check here if the fb has the same properties
         * and then just flip_or_move it */
        if (set->crtc->fb != set->fb) {
@@ -718,6 +751,12 @@ fail:
                *connector = save_connectors[count++];
        }
 
+       /* Try to restore the config */
+       if (mode_changed &&
+           !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
+                                     save_set.y, save_set.fb))
+               DRM_ERROR("failed to restore config after modeset failure\n");
+
        kfree(save_connectors);
        kfree(save_encoders);
        kfree(save_crtcs);
index b9dc2629ea9aec5f8f7fd583be1e070e4871828f..1c7a1c0d3edd9aa34d7530e04fa5b482a9d07973 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drmP.h"
 
 #if defined(CONFIG_DEBUG_FS)
@@ -117,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
                tmp->minor = minor;
                tmp->dent = ent;
                tmp->info_ent = &files[i];
-               list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+
+               mutex_lock(&minor->debugfs_lock);
+               list_add(&tmp->list, &minor->debugfs_list);
+               mutex_unlock(&minor->debugfs_lock);
        }
        return 0;
 
@@ -145,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
        char name[64];
        int ret;
 
-       INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+       INIT_LIST_HEAD(&minor->debugfs_list);
+       mutex_init(&minor->debugfs_lock);
        sprintf(name, "%d", minor_id);
        minor->debugfs_root = debugfs_create_dir(name, root);
        if (!minor->debugfs_root) {
@@ -191,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
        struct drm_info_node *tmp;
        int i;
 
+       mutex_lock(&minor->debugfs_lock);
        for (i = 0; i < count; i++) {
-               list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+               list_for_each_safe(pos, q, &minor->debugfs_list) {
                        tmp = list_entry(pos, struct drm_info_node, list);
                        if (tmp->info_ent == &files[i]) {
                                debugfs_remove(tmp->dent);
@@ -201,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
                        }
                }
        }
+       mutex_unlock(&minor->debugfs_lock);
        return 0;
 }
 EXPORT_SYMBOL(drm_debugfs_remove_files);
index 252cbd74df0e6b862e07d340ba617cac165f1759..cfb4e333ec0fd1ee5e8b598b2d14fc6f48ad8554 100644 (file)
@@ -33,6 +33,7 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "drmP.h"
 
 /**
index 7a87e0878f3008f5db63d850c9e9603fdbf79de1..40c187c60f44fcb2ea45bedede0fe003f9e8ebb2 100644 (file)
@@ -48,6 +48,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm_core.h"
 
@@ -124,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
        DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 
-       DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
 
        DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
 
index fe39c35705389b5dcaffc76b0061e80548404b00..3e927ce7557d6a41f7bc1a6e27b088be127006d0 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm_edid.h"
 #include "drm_edid_modes.h"
index d62c064fbaa02e747328d8a932fa58eef96cbedb..fb943551060e3b0f4fe1f75715c2a4ebb73329da 100644 (file)
@@ -24,6 +24,8 @@
  *
  */
 
+#include <linux/module.h>
+
 #include "drm_encoder_slave.h"
 
 /**
index f7c6854eb4ddb77943163535a5eb94f78cca6a48..80fe39d98b0c2e2ca7a22b762d3d9dcf87781d1c 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sysrq.h>
 #include <linux/slab.h>
 #include <linux/fb.h>
+#include <linux/module.h>
 #include "drmP.h"
 #include "drm_crtc.h"
 #include "drm_fb_helper.h"
index 2ec7d48fc4a8b18b58bf777b26159849b6ff65d0..4911e1d1dcf2a60d527235c35da7a33edc864be4 100644 (file)
@@ -37,6 +37,7 @@
 #include "drmP.h"
 #include <linux/poll.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 /* from BKL pushdown: note that nothing else serializes idr_find() */
 DEFINE_MUTEX(drm_global_mutex);
index e3a75688f3cdc6543b67fef3d6b8c3c2a6149a8c..68dc8744b63002e34581d4826aab252a7170ef14 100644 (file)
@@ -36,6 +36,7 @@
 #include "drm_hashtab.h"
 #include <linux/hash.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
 {
index 4a058c7af6c096f6dd69dd533701a9adb3091b09..ddd70db45f7611747ee63551db2846d31383bc34 100644 (file)
@@ -29,6 +29,7 @@
  */
 #include <linux/compat.h>
 #include <linux/ratelimit.h>
+#include <linux/export.h>
 
 #include "drmP.h"
 #include "drm_core.h"
index 3830e9e478c0c4af57e2983181bfc545c854ba45..44a5d0ad8b7c56e99c9ce85f2dfcf14d19e855e0 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/slab.h>
 
 #include <linux/vgaarb.h>
+#include <linux/export.h>
 
 /* Access macro for slots in vblank timestamp ringbuffer. */
 #define vblanktimestamp(dev, crtc, count) ( \
@@ -109,10 +110,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
        /* Prevent vblank irq processing while disabling vblank irqs,
         * so no updates of timestamps or count can happen after we've
         * disabled. Needed to prevent races in case of delayed irq's.
-        * Disable preemption, so vblank_time_lock is held as short as
-        * possible, even under a kernel with PREEMPT_RT patches.
         */
-       preempt_disable();
        spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
 
        dev->driver->disable_vblank(dev, crtc);
@@ -163,7 +161,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
        clear_vblank_timestamps(dev, crtc);
 
        spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
-       preempt_enable();
 }
 
 static void vblank_disable_fn(unsigned long arg)
@@ -406,13 +403,16 @@ int drm_irq_uninstall(struct drm_device *dev)
        /*
         * Wake up any waiters so they don't hang.
         */
-       spin_lock_irqsave(&dev->vbl_lock, irqflags);
-       for (i = 0; i < dev->num_crtcs; i++) {
-               DRM_WAKEUP(&dev->vbl_queue[i]);
-               dev->vblank_enabled[i] = 0;
-               dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
+       if (dev->num_crtcs) {
+               spin_lock_irqsave(&dev->vbl_lock, irqflags);
+               for (i = 0; i < dev->num_crtcs; i++) {
+                       DRM_WAKEUP(&dev->vbl_queue[i]);
+                       dev->vblank_enabled[i] = 0;
+                       dev->last_vblank[i] =
+                               dev->driver->get_vblank_counter(dev, i);
+               }
+               spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
        }
-       spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 
        if (!irq_enabled)
                return -EINVAL;
@@ -885,10 +885,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
        /* Going from 0->1 means we have to enable interrupts again */
        if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
-               /* Disable preemption while holding vblank_time_lock. Do
-                * it explicitely to guard against PREEMPT_RT kernel.
-                */
-               preempt_disable();
                spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
                if (!dev->vblank_enabled[crtc]) {
                        /* Enable vblank irqs under vblank_time_lock protection.
@@ -908,7 +904,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
                        }
                }
                spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
-               preempt_enable();
        } else {
                if (!dev->vblank_enabled[crtc]) {
                        atomic_dec(&dev->vblank_refcount[crtc]);
@@ -1124,6 +1119,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
                trace_drm_vblank_event_delivered(current->pid, pipe,
                                                 vblwait->request.sequence);
        } else {
+               /* drm_handle_vblank_events will call drm_vblank_put */
                list_add_tail(&e->base.link, &dev->vblank_event_list);
                vblwait->reply.sequence = vblwait->request.sequence;
        }
@@ -1204,8 +1200,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
                goto done;
        }
 
-       if (flags & _DRM_VBLANK_EVENT)
+       if (flags & _DRM_VBLANK_EVENT) {
+               /* must hold on to the vblank ref until the event fires
+                * drm_vblank_put will be called asynchronously
+                */
                return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
+       }
 
        if ((flags & _DRM_VBLANK_NEXTONMISS) &&
            (seq - vblwait->request.sequence) <= (1<<23)) {
index c9b805000a11e827c1677c0d81ccb33c5be1442c..c8b6b66d428da7ae167425b8d01f60acebfc30e5 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/highmem.h>
+#include <linux/export.h>
 #include "drmP.h"
 
 /**
index 959186cbf3280b90b911ff54373531ee577eef97..961fb54f4266e9fd3595873f61281393765cf5b2 100644 (file)
@@ -45,6 +45,7 @@
 #include "drm_mm.h"
 #include <linux/slab.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 #define MM_UNUSED_TARGET 4
 
index ad74fb4dc5422925f954142c0aae322c2e2f2572..fb8e46b4e8bc9b7f2a4b0e05ae38a49c99b82b2b 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/list.h>
 #include <linux/list_sort.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
index b6a19cb07cafc3591f2ff946532851f63a14270d..d4d10b7880cf8b96303d6c539ff09a08299241f2 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include "drmP.h"
 
 /**********************************************************************/
index 2a8b6265ad3d61822e15b678dbaeb88e30dc7445..ae9db5e2b27c2449b04150be14eee439a608c0db 100644 (file)
@@ -25,6 +25,7 @@
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "drmP.h"
 
 /**
index 0f3c4e3cafc3454ec0d826cc0530f4883655eba7..fff87221f9e973aef715391366293a4b784a0a13 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drmP.h"
 
 /***************************************************
index 34664587a74e08becbd86d223c6a3e2273b6a468..cebce45f442943efe4202d9f8b4b3763cd2b7ab8 100644 (file)
@@ -36,6 +36,7 @@
  * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
+#include <linux/export.h>
 #include "drm_sman.h"
 
 struct drm_owner_item {
index 2eee8e016b38530f0ddc4d1e46d4e89ff9419ffd..0f9ef9bf6730aa6ee68b9ce763f1e76bd62ee63a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/gfp.h>
 #include <linux/err.h>
+#include <linux/export.h>
 
 #include "drm_sysfs.h"
 #include "drm_core.h"
index 206d2300d873bab2c2a6c06b79a0fd2f06a3d48c..445003f4dc939cbc731a915551b509633f2f6769 100644 (file)
@@ -1,5 +1,6 @@
 #include "drmP.h"
 #include <linux/usb.h>
+#include <linux/export.h>
 
 #ifdef CONFIG_USB
 int drm_get_usb_dev(struct usb_interface *interface,
index 5db96d45fc71677fcf0b6432e0f32dfd22b774d4..8c03eaf414486c9590c830d2e551369406afff84 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include "drmP.h"
+#include <linux/export.h>
 #if defined(__ia64__)
 #include <linux/efi.h>
 #include <linux/slab.h>
index 6f8afea94fc979b74476746aca1ae32341846357..2bb07bca511a12b6949892186565cfde960db8ca 100644 (file)
 #include "drm.h"
 
 #include "exynos_drm_drv.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
-static DEFINE_MUTEX(exynos_drm_buf_lock);
-
 static int lowlevel_buffer_allocate(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       entry->vaddr = dma_alloc_writecombine(dev->dev, entry->size,
-                       (dma_addr_t *)&entry->paddr, GFP_KERNEL);
-       if (!entry->paddr) {
+       buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size,
+                       &buffer->dma_addr, GFP_KERNEL);
+       if (!buffer->kvaddr) {
                DRM_ERROR("failed to allocate buffer.\n");
                return -ENOMEM;
        }
 
-       DRM_DEBUG_KMS("allocated : vaddr(0x%x), paddr(0x%x), size(0x%x)\n",
-                       (unsigned int)entry->vaddr, entry->paddr, entry->size);
+       DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
+                       (unsigned long)buffer->kvaddr,
+                       (unsigned long)buffer->dma_addr,
+                       buffer->size);
 
        return 0;
 }
 
 static void lowlevel_buffer_deallocate(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s.\n", __FILE__);
 
-       if (entry->paddr && entry->vaddr && entry->size)
-               dma_free_writecombine(dev->dev, entry->size, entry->vaddr,
-                               entry->paddr);
+       if (buffer->dma_addr && buffer->size)
+               dma_free_writecombine(dev->dev, buffer->size, buffer->kvaddr,
+                               (dma_addr_t)buffer->dma_addr);
        else
-               DRM_DEBUG_KMS("entry data is null.\n");
+               DRM_DEBUG_KMS("buffer data are invalid.\n");
 }
 
-struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev,
+struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev,
                unsigned int size)
 {
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 
        DRM_DEBUG_KMS("%s.\n", __FILE__);
+       DRM_DEBUG_KMS("desired size = 0x%x\n", size);
 
-       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-       if (!entry) {
-               DRM_ERROR("failed to allocate exynos_drm_buf_entry.\n");
+       buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+       if (!buffer) {
+               DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       entry->size = size;
+       buffer->size = size;
 
        /*
         * allocate memory region with size and set the memory information
-        * to vaddr and paddr of a entry object.
+        * to vaddr and dma_addr of a buffer object.
         */
-       if (lowlevel_buffer_allocate(dev, entry) < 0) {
-               kfree(entry);
-               entry = NULL;
+       if (lowlevel_buffer_allocate(dev, buffer) < 0) {
+               kfree(buffer);
+               buffer = NULL;
                return ERR_PTR(-ENOMEM);
        }
 
-       return entry;
+       return buffer;
 }
 
 void exynos_drm_buf_destroy(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry)
+               struct exynos_drm_gem_buf *buffer)
 {
        DRM_DEBUG_KMS("%s.\n", __FILE__);
 
-       if (!entry) {
-               DRM_DEBUG_KMS("entry is null.\n");
+       if (!buffer) {
+               DRM_DEBUG_KMS("buffer is null.\n");
                return;
        }
 
-       lowlevel_buffer_deallocate(dev, entry);
+       lowlevel_buffer_deallocate(dev, buffer);
 
-       kfree(entry);
-       entry = NULL;
+       kfree(buffer);
+       buffer = NULL;
 }
 
 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
index 045d59eab01a29b5270410d661968d408dcfa663..6e91f9caa5dbdfe12aade5461c3ad253888f20bf 100644 (file)
 #ifndef _EXYNOS_DRM_BUF_H_
 #define _EXYNOS_DRM_BUF_H_
 
-/*
- * exynos drm buffer entry structure.
- *
- * @paddr: physical address of allocated memory.
- * @vaddr: kernel virtual address of allocated memory.
- * @size: size of allocated memory.
- */
-struct exynos_drm_buf_entry {
-       dma_addr_t paddr;
-       void __iomem *vaddr;
-       unsigned int size;
-};
-
 /* allocate physical memory. */
-struct exynos_drm_buf_entry *exynos_drm_buf_create(struct drm_device *dev,
+struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev,
                unsigned int size);
 
-/* get physical memory information of a drm framebuffer. */
-struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb);
+/* get memory information of a drm framebuffer. */
+struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb);
 
 /* remove allocated physical memory. */
 void exynos_drm_buf_destroy(struct drm_device *dev,
-               struct exynos_drm_buf_entry *entry);
+               struct exynos_drm_gem_buf *buffer);
 
 #endif
index 985d9e7687287d915c6a76e2b7219f9e7840e7f8..d620b0784257f05cab7c52b121a460c99f6f7daf 100644 (file)
@@ -37,6 +37,8 @@
 
 struct exynos_drm_connector {
        struct drm_connector    drm_connector;
+       uint32_t                encoder_id;
+       struct exynos_drm_manager *manager;
 };
 
 /* convert exynos_video_timings to drm_display_mode */
@@ -47,6 +49,7 @@ convert_to_display_mode(struct drm_display_mode *mode,
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        mode->clock = timing->pixclock / 1000;
+       mode->vrefresh = timing->refresh;
 
        mode->hdisplay = timing->xres;
        mode->hsync_start = mode->hdisplay + timing->left_margin;
@@ -57,6 +60,12 @@ convert_to_display_mode(struct drm_display_mode *mode,
        mode->vsync_start = mode->vdisplay + timing->upper_margin;
        mode->vsync_end = mode->vsync_start + timing->vsync_len;
        mode->vtotal = mode->vsync_end + timing->lower_margin;
+
+       if (timing->vmode & FB_VMODE_INTERLACED)
+               mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+       if (timing->vmode & FB_VMODE_DOUBLE)
+               mode->flags |= DRM_MODE_FLAG_DBLSCAN;
 }
 
 /* convert drm_display_mode to exynos_video_timings */
@@ -69,7 +78,7 @@ convert_to_video_timing(struct fb_videomode *timing,
        memset(timing, 0, sizeof(*timing));
 
        timing->pixclock = mode->clock * 1000;
-       timing->refresh = mode->vrefresh;
+       timing->refresh = drm_mode_vrefresh(mode);
 
        timing->xres = mode->hdisplay;
        timing->left_margin = mode->hsync_start - mode->hdisplay;
@@ -92,15 +101,16 @@ convert_to_video_timing(struct fb_videomode *timing,
 
 static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops = manager->display_ops;
        unsigned int count;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (!display) {
-               DRM_DEBUG_KMS("display is null.\n");
+       if (!display_ops) {
+               DRM_DEBUG_KMS("display_ops is null.\n");
                return 0;
        }
 
@@ -112,7 +122,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
         * P.S. in case of lcd panel, count is always 1 if success
         * because lcd panel has only one mode.
         */
-       if (display->get_edid) {
+       if (display_ops->get_edid) {
                int ret;
                void *edid;
 
@@ -122,7 +132,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                        return 0;
                }
 
-               ret = display->get_edid(manager->dev, connector,
+               ret = display_ops->get_edid(manager->dev, connector,
                                                edid, MAX_EDID);
                if (ret < 0) {
                        DRM_ERROR("failed to get edid data.\n");
@@ -140,8 +150,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
                struct drm_display_mode *mode = drm_mode_create(connector->dev);
                struct fb_videomode *timing;
 
-               if (display->get_timing)
-                       timing = display->get_timing(manager->dev);
+               if (display_ops->get_timing)
+                       timing = display_ops->get_timing(manager->dev);
                else {
                        drm_mode_destroy(connector->dev, mode);
                        return 0;
@@ -162,9 +172,10 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
                                            struct drm_display_mode *mode)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops = manager->display_ops;
        struct fb_videomode timing;
        int ret = MODE_BAD;
 
@@ -172,8 +183,8 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
 
        convert_to_video_timing(&timing, mode);
 
-       if (display && display->check_timing)
-               if (!display->check_timing(manager->dev, (void *)&timing))
+       if (display_ops && display_ops->check_timing)
+               if (!display_ops->check_timing(manager->dev, (void *)&timing))
                        ret = MODE_OK;
 
        return ret;
@@ -181,9 +192,25 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
 
 struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
 {
+       struct drm_device *dev = connector->dev;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct drm_mode_object *obj;
+       struct drm_encoder *encoder;
+
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       return connector->encoder;
+       obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
+                                  DRM_MODE_OBJECT_ENCODER);
+       if (!obj) {
+               DRM_DEBUG_KMS("Unknown ENCODER ID %d\n",
+                               exynos_connector->encoder_id);
+               return NULL;
+       }
+
+       encoder = obj_to_encoder(obj);
+
+       return encoder;
 }
 
 static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
@@ -196,15 +223,17 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
 static enum drm_connector_status
 exynos_drm_connector_detect(struct drm_connector *connector, bool force)
 {
-       struct exynos_drm_manager *manager =
-                               exynos_drm_get_manager(connector->encoder);
-       struct exynos_drm_display *display = manager->display;
+       struct exynos_drm_connector *exynos_connector =
+                                       to_exynos_connector(connector);
+       struct exynos_drm_manager *manager = exynos_connector->manager;
+       struct exynos_drm_display_ops *display_ops =
+                                       manager->display_ops;
        enum drm_connector_status status = connector_status_disconnected;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (display && display->is_connected) {
-               if (display->is_connected(manager->dev))
+       if (display_ops && display_ops->is_connected) {
+               if (display_ops->is_connected(manager->dev))
                        status = connector_status_connected;
                else
                        status = connector_status_disconnected;
@@ -251,9 +280,11 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
 
        connector = &exynos_connector->drm_connector;
 
-       switch (manager->display->type) {
+       switch (manager->display_ops->type) {
        case EXYNOS_DISPLAY_TYPE_HDMI:
                type = DRM_MODE_CONNECTOR_HDMIA;
+               connector->interlace_allowed = true;
+               connector->polled = DRM_CONNECTOR_POLL_HPD;
                break;
        default:
                type = DRM_MODE_CONNECTOR_Unknown;
@@ -267,7 +298,10 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
        if (err)
                goto err_connector;
 
+       exynos_connector->encoder_id = encoder->base.id;
+       exynos_connector->manager = manager;
        connector->encoder = encoder;
+
        err = drm_mode_connector_attach_encoder(connector, encoder);
        if (err) {
                DRM_ERROR("failed to attach a connector to a encoder\n");
index 9337e5e2dbb6204428178c8c3a962ebb3d61fab0..ee43cc22085304f7f07f267cd63a7d2be05d249a 100644 (file)
 #include "drmP.h"
 #include "drm_crtc_helper.h"
 
+#include "exynos_drm_crtc.h"
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_encoder.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
 #define to_exynos_crtc(x)      container_of(x, struct exynos_drm_crtc,\
                                drm_crtc)
 
-/*
- * Exynos specific crtc postion structure.
- *
- * @fb_x: offset x on a framebuffer to be displyed
- *     - the unit is screen coordinates.
- * @fb_y: offset y on a framebuffer to be displayed
- *     - the unit is screen coordinates.
- * @crtc_x: offset x on hardware screen.
- * @crtc_y: offset y on hardware screen.
- * @crtc_w: width of hardware screen.
- * @crtc_h: height of hardware screen.
- */
-struct exynos_drm_crtc_pos {
-       unsigned int fb_x;
-       unsigned int fb_y;
-       unsigned int crtc_x;
-       unsigned int crtc_y;
-       unsigned int crtc_w;
-       unsigned int crtc_h;
-};
-
 /*
  * Exynos specific crtc structure.
  *
@@ -85,30 +66,31 @@ static void exynos_drm_crtc_apply(struct drm_crtc *crtc)
 
        exynos_drm_fn_encoder(crtc, overlay,
                        exynos_drm_encoder_crtc_mode_set);
-       exynos_drm_fn_encoder(crtc, NULL, exynos_drm_encoder_crtc_commit);
+       exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                       exynos_drm_encoder_crtc_commit);
 }
 
-static int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
-                                      struct drm_framebuffer *fb,
-                                      struct drm_display_mode *mode,
-                                      struct exynos_drm_crtc_pos *pos)
+int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
+                             struct drm_framebuffer *fb,
+                             struct drm_display_mode *mode,
+                             struct exynos_drm_crtc_pos *pos)
 {
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
        unsigned int actual_w;
        unsigned int actual_h;
 
-       entry = exynos_drm_fb_get_buf(fb);
-       if (!entry) {
-               DRM_LOG_KMS("entry is null.\n");
+       buffer = exynos_drm_fb_get_buf(fb);
+       if (!buffer) {
+               DRM_LOG_KMS("buffer is null.\n");
                return -EFAULT;
        }
 
-       overlay->paddr = entry->paddr;
-       overlay->vaddr = entry->vaddr;
+       overlay->dma_addr = buffer->dma_addr;
+       overlay->vaddr = buffer->kvaddr;
 
-       DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
+       DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n",
                        (unsigned long)overlay->vaddr,
-                       (unsigned long)overlay->paddr);
+                       (unsigned long)overlay->dma_addr);
 
        actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w);
        actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h);
@@ -171,9 +153,26 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc)
 
 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
-       DRM_DEBUG_KMS("%s\n", __FILE__);
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-       /* TODO */
+       DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                               exynos_drm_encoder_crtc_commit);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               /* TODO */
+               exynos_drm_fn_encoder(crtc, NULL,
+                               exynos_drm_encoder_crtc_disable);
+               break;
+       default:
+               DRM_DEBUG_KMS("unspecified mode %d\n", mode);
+               break;
+       }
 }
 
 static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
@@ -185,9 +184,12 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
 
 static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
 {
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       /* drm framework doesn't check NULL. */
+       exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
+                       exynos_drm_encoder_crtc_commit);
 }
 
 static bool
index c584042d6d2cb21c8282975f9edf28898b4e56e0..25f72a62cb880b757b54e0514693eedd624ce27b 100644 (file)
@@ -35,4 +35,29 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr);
 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
 void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
 
+/*
+ * Exynos specific crtc postion structure.
+ *
+ * @fb_x: offset x on a framebuffer to be displyed
+ *     - the unit is screen coordinates.
+ * @fb_y: offset y on a framebuffer to be displayed
+ *     - the unit is screen coordinates.
+ * @crtc_x: offset x on hardware screen.
+ * @crtc_y: offset y on hardware screen.
+ * @crtc_w: width of hardware screen.
+ * @crtc_h: height of hardware screen.
+ */
+struct exynos_drm_crtc_pos {
+       unsigned int fb_x;
+       unsigned int fb_y;
+       unsigned int crtc_x;
+       unsigned int crtc_y;
+       unsigned int crtc_w;
+       unsigned int crtc_h;
+};
+
+int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay,
+                             struct drm_framebuffer *fb,
+                             struct drm_display_mode *mode,
+                             struct exynos_drm_crtc_pos *pos);
 #endif
index 83810cbe3c1770aeea62814dfdd98c2e1b33df2e..53e2216de61dd5c42c35eaa7f0c23ca1e991a621 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "drmP.h"
 #include "drm.h"
+#include "drm_crtc_helper.h"
 
 #include <drm/exynos_drm.h>
 
@@ -61,6 +62,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
 
        drm_mode_config_init(dev);
 
+       /* init kms poll for handling hpd */
+       drm_kms_helper_poll_init(dev);
+
        exynos_drm_mode_config_init(dev);
 
        /*
@@ -116,6 +120,7 @@ static int exynos_drm_unload(struct drm_device *dev)
        exynos_drm_fbdev_fini(dev);
        exynos_drm_device_unregister(dev);
        drm_vblank_cleanup(dev);
+       drm_kms_helper_poll_fini(dev);
        drm_mode_config_cleanup(dev);
        kfree(dev->dev_private);
 
index c03683f2ae72dffb084aaede5dba582a68c835f9..5e02e6ecc2e026955c9bf88bd5461bf893c1dbec 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _EXYNOS_DRM_DRV_H_
 #define _EXYNOS_DRM_DRV_H_
 
+#include <linux/module.h>
 #include "drm.h"
 
 #define MAX_CRTC       2
@@ -79,8 +80,8 @@ struct exynos_drm_overlay_ops {
  * @scan_flag: interlace or progressive way.
  *     (it could be DRM_MODE_FLAG_*)
  * @bpp: pixel size.(in bit)
- * @paddr: bus(accessed by dma) physical memory address to this overlay
- *             and this is physically continuous.
+ * @dma_addr: bus(accessed by dma) address to the memory region allocated
+ *     for a overlay.
  * @vaddr: virtual memory addresss to this overlay.
  * @default_win: a window to be enabled.
  * @color_key: color key on or off.
@@ -108,7 +109,7 @@ struct exynos_drm_overlay {
        unsigned int scan_flag;
        unsigned int bpp;
        unsigned int pitch;
-       dma_addr_t paddr;
+       dma_addr_t dma_addr;
        void __iomem *vaddr;
 
        bool default_win;
@@ -130,7 +131,7 @@ struct exynos_drm_overlay {
  * @check_timing: check if timing is valid or not.
  * @power_on: display device on or off.
  */
-struct exynos_drm_display {
+struct exynos_drm_display_ops {
        enum exynos_drm_output_type type;
        bool (*is_connected)(struct device *dev);
        int (*get_edid)(struct device *dev, struct drm_connector *connector,
@@ -146,12 +147,14 @@ struct exynos_drm_display {
  * @mode_set: convert drm_display_mode to hw specific display mode and
  *           would be called by encoder->mode_set().
  * @commit: set current hw specific display mode to hw.
+ * @disable: disable hardware specific display mode.
  * @enable_vblank: specific driver callback for enabling vblank interrupt.
  * @disable_vblank: specific driver callback for disabling vblank interrupt.
  */
 struct exynos_drm_manager_ops {
        void (*mode_set)(struct device *subdrv_dev, void *mode);
        void (*commit)(struct device *subdrv_dev);
+       void (*disable)(struct device *subdrv_dev);
        int (*enable_vblank)(struct device *subdrv_dev);
        void (*disable_vblank)(struct device *subdrv_dev);
 };
@@ -178,7 +181,7 @@ struct exynos_drm_manager {
        int pipe;
        struct exynos_drm_manager_ops *ops;
        struct exynos_drm_overlay_ops *overlay_ops;
-       struct exynos_drm_display *display;
+       struct exynos_drm_display_ops *display_ops;
 };
 
 /*
index 7cf6fa86a67efb57e10407213639e8084d2c2138..153061415bafba2d3c83d155a7e86a4901db0b52 100644 (file)
@@ -53,15 +53,36 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
        struct drm_device *dev = encoder->dev;
        struct drm_connector *connector;
        struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+       struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
        DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
 
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               if (manager_ops && manager_ops->commit)
+                       manager_ops->commit(manager->dev);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               /* TODO */
+               if (manager_ops && manager_ops->disable)
+                       manager_ops->disable(manager->dev);
+               break;
+       default:
+               DRM_ERROR("unspecified mode %d\n", mode);
+               break;
+       }
+
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                if (connector->encoder == encoder) {
-                       struct exynos_drm_display *display = manager->display;
+                       struct exynos_drm_display_ops *display_ops =
+                                                       manager->display_ops;
 
-                       if (display && display->power_on)
-                               display->power_on(manager->dev, mode);
+                       DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
+                                       connector->base.id, mode);
+                       if (display_ops && display_ops->power_on)
+                               display_ops->power_on(manager->dev, mode);
                }
        }
 }
@@ -116,15 +137,11 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
 {
        struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
        struct exynos_drm_manager_ops *manager_ops = manager->ops;
-       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
        if (manager_ops && manager_ops->commit)
                manager_ops->commit(manager->dev);
-
-       if (overlay_ops && overlay_ops->commit)
-               overlay_ops->commit(manager->dev);
 }
 
 static struct drm_crtc *
@@ -208,10 +225,23 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_encoder *encoder;
+       struct exynos_drm_private *private = dev->dev_private;
+       struct exynos_drm_manager *manager;
 
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               if (encoder->crtc != crtc)
-                       continue;
+               /*
+                * if crtc is detached from encoder, check pipe,
+                * otherwise check crtc attached to encoder
+                */
+               if (!encoder->crtc) {
+                       manager = to_exynos_encoder(encoder)->manager;
+                       if (manager->pipe < 0 ||
+                                       private->crtc[manager->pipe] != crtc)
+                               continue;
+               } else {
+                       if (encoder->crtc != crtc)
+                               continue;
+               }
 
                fn(encoder, data);
        }
@@ -250,8 +280,18 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data)
        struct exynos_drm_manager *manager =
                to_exynos_encoder(encoder)->manager;
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+       int crtc = *(int *)data;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /*
+        * when crtc is detached from encoder, this pipe is used
+        * to select manager operation
+        */
+       manager->pipe = crtc;
 
-       overlay_ops->commit(manager->dev);
+       if (overlay_ops && overlay_ops->commit)
+               overlay_ops->commit(manager->dev);
 }
 
 void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data)
@@ -261,7 +301,28 @@ void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data)
        struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
        struct exynos_drm_overlay *overlay = data;
 
-       overlay_ops->mode_set(manager->dev, overlay);
+       if (overlay_ops && overlay_ops->mode_set)
+               overlay_ops->mode_set(manager->dev, overlay);
+}
+
+void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data)
+{
+       struct exynos_drm_manager *manager =
+               to_exynos_encoder(encoder)->manager;
+       struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
+
+       DRM_DEBUG_KMS("\n");
+
+       if (overlay_ops && overlay_ops->disable)
+               overlay_ops->disable(manager->dev);
+
+       /*
+        * crtc is already detached from encoder and last
+        * function for detaching is properly done, so
+        * clear pipe from manager to prevent repeated call
+        */
+       if (!encoder->crtc)
+               manager->pipe = -1;
 }
 
 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
index 5ecd645d06a97e1959599ecfd94d2b7ba2d50847..a22acfbf0e4ed6dc31894d03f7a5369158ded8a2 100644 (file)
@@ -41,5 +41,6 @@ void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data);
 void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data);
 void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data);
+void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data);
 
 #endif
index 48d29cfd5240197f645c6732a9360bb255656f97..5bf4a1ac7f828cd26509857e5ed9b024f094f831 100644 (file)
@@ -29,7 +29,9 @@
 #include "drmP.h"
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
 
+#include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_buf.h"
 #include "exynos_drm_gem.h"
  *
  * @fb: drm framebuffer obejct.
  * @exynos_gem_obj: exynos specific gem object containing a gem object.
- * @entry: pointer to exynos drm buffer entry object.
- *     - containing only the information to physically continuous memory
- *     region allocated at default framebuffer creation.
+ * @buffer: pointer to exynos_drm_gem_buffer object.
+ *     - contain the memory information to memory region allocated
+ *     at default framebuffer creation.
  */
 struct exynos_drm_fb {
        struct drm_framebuffer          fb;
        struct exynos_drm_gem_obj       *exynos_gem_obj;
-       struct exynos_drm_buf_entry     *entry;
+       struct exynos_drm_gem_buf       *buffer;
 };
 
 static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
@@ -63,8 +65,8 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
         * default framebuffer has no gem object so
         * a buffer of the default framebuffer should be released at here.
         */
-       if (!exynos_fb->exynos_gem_obj && exynos_fb->entry)
-               exynos_drm_buf_destroy(fb->dev, exynos_fb->entry);
+       if (!exynos_fb->exynos_gem_obj && exynos_fb->buffer)
+               exynos_drm_buf_destroy(fb->dev, exynos_fb->buffer);
 
        kfree(exynos_fb);
        exynos_fb = NULL;
@@ -143,29 +145,29 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev,
         */
        if (!mode_cmd->handle) {
                if (!file_priv) {
-                       struct exynos_drm_buf_entry *entry;
+                       struct exynos_drm_gem_buf *buffer;
 
                        /*
                         * in case that file_priv is NULL, it allocates
                         * only buffer and this buffer would be used
                         * for default framebuffer.
                         */
-                       entry = exynos_drm_buf_create(dev, size);
-                       if (IS_ERR(entry)) {
-                               ret = PTR_ERR(entry);
+                       buffer = exynos_drm_buf_create(dev, size);
+                       if (IS_ERR(buffer)) {
+                               ret = PTR_ERR(buffer);
                                goto err_buffer;
                        }
 
-                       exynos_fb->entry = entry;
+                       exynos_fb->buffer = buffer;
 
-                       DRM_LOG_KMS("default fb: paddr = 0x%lx, size = 0x%x\n",
-                                       (unsigned long)entry->paddr, size);
+                       DRM_LOG_KMS("default: dma_addr = 0x%lx, size = 0x%x\n",
+                                       (unsigned long)buffer->dma_addr, size);
 
                        goto out;
                } else {
-                       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev,
-                                                       size,
-                                                       &mode_cmd->handle);
+                       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv,
+                                                       &mode_cmd->handle,
+                                                       size);
                        if (IS_ERR(exynos_gem_obj)) {
                                ret = PTR_ERR(exynos_gem_obj);
                                goto err_buffer;
@@ -189,10 +191,10 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev,
         * so that default framebuffer has no its own gem object,
         * only its own buffer object.
         */
-       exynos_fb->entry = exynos_gem_obj->entry;
+       exynos_fb->buffer = exynos_gem_obj->buffer;
 
-       DRM_LOG_KMS("paddr = 0x%lx, size = 0x%x, gem object = 0x%x\n",
-                       (unsigned long)exynos_fb->entry->paddr, size,
+       DRM_LOG_KMS("dma_addr = 0x%lx, size = 0x%x, gem object = 0x%x\n",
+                       (unsigned long)exynos_fb->buffer->dma_addr, size,
                        (unsigned int)&exynos_gem_obj->base);
 
 out:
@@ -220,26 +222,36 @@ struct drm_framebuffer *exynos_drm_fb_create(struct drm_device *dev,
        return exynos_drm_fb_init(file_priv, dev, mode_cmd);
 }
 
-struct exynos_drm_buf_entry *exynos_drm_fb_get_buf(struct drm_framebuffer *fb)
+struct exynos_drm_gem_buf *exynos_drm_fb_get_buf(struct drm_framebuffer *fb)
 {
        struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       entry = exynos_fb->entry;
-       if (!entry)
+       buffer = exynos_fb->buffer;
+       if (!buffer)
                return NULL;
 
-       DRM_DEBUG_KMS("vaddr = 0x%lx, paddr = 0x%lx\n",
-                       (unsigned long)entry->vaddr,
-                       (unsigned long)entry->paddr);
+       DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n",
+                       (unsigned long)buffer->kvaddr,
+                       (unsigned long)buffer->dma_addr);
 
-       return entry;
+       return buffer;
+}
+
+static void exynos_drm_output_poll_changed(struct drm_device *dev)
+{
+       struct exynos_drm_private *private = dev->dev_private;
+       struct drm_fb_helper *fb_helper = private->fb_helper;
+
+       if (fb_helper)
+               drm_fb_helper_hotplug_event(fb_helper);
 }
 
 static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
        .fb_create = exynos_drm_fb_create,
+       .output_poll_changed = exynos_drm_output_poll_changed,
 };
 
 void exynos_drm_mode_config_init(struct drm_device *dev)
index 1f4b3d1a77134d46ae193446a2720020dfd745cf..836f4100818710e830229b985591bfc85a047f03 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
+#include "exynos_drm_gem.h"
 #include "exynos_drm_buf.h"
 
 #define MAX_CONNECTOR          4
@@ -85,15 +86,13 @@ static struct fb_ops exynos_drm_fb_ops = {
 };
 
 static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
-                                    struct drm_framebuffer *fb,
-                                    unsigned int fb_width,
-                                    unsigned int fb_height)
+                                    struct drm_framebuffer *fb)
 {
        struct fb_info *fbi = helper->fbdev;
        struct drm_device *dev = helper->dev;
        struct exynos_drm_fbdev *exynos_fb = to_exynos_fbdev(helper);
-       struct exynos_drm_buf_entry *entry;
-       unsigned int size = fb_width * fb_height * (fb->bits_per_pixel >> 3);
+       struct exynos_drm_gem_buf *buffer;
+       unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
        unsigned long offset;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -101,20 +100,20 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
        exynos_fb->fb = fb;
 
        drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
-       drm_fb_helper_fill_var(fbi, helper, fb_width, fb_height);
+       drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
 
-       entry = exynos_drm_fb_get_buf(fb);
-       if (!entry) {
-               DRM_LOG_KMS("entry is null.\n");
+       buffer = exynos_drm_fb_get_buf(fb);
+       if (!buffer) {
+               DRM_LOG_KMS("buffer is null.\n");
                return -EFAULT;
        }
 
        offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
        offset += fbi->var.yoffset * fb->pitch;
 
-       dev->mode_config.fb_base = entry->paddr;
-       fbi->screen_base = entry->vaddr + offset;
-       fbi->fix.smem_start = entry->paddr + offset;
+       dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
+       fbi->screen_base = buffer->kvaddr + offset;
+       fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
        fbi->screen_size = size;
        fbi->fix.smem_len = size;
 
@@ -171,8 +170,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
                goto out;
        }
 
-       ret = exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
-                       sizes->fb_height);
+       ret = exynos_drm_fbdev_update(helper, helper->fb);
        if (ret < 0)
                fb_dealloc_cmap(&fbi->cmap);
 
@@ -235,8 +233,7 @@ static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
        }
 
        helper->fb = exynos_fbdev->fb;
-       return exynos_drm_fbdev_update(helper, helper->fb, sizes->fb_width,
-                       sizes->fb_height);
+       return exynos_drm_fbdev_update(helper, helper->fb);
 }
 
 static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
@@ -405,6 +402,18 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
        fb_helper = private->fb_helper;
 
        if (fb_helper) {
+               struct list_head temp_list;
+
+               INIT_LIST_HEAD(&temp_list);
+
+               /*
+                * fb_helper is reintialized but kernel fb is reused
+                * so kernel_fb_list need to be backuped and restored
+                */
+               if (!list_empty(&fb_helper->kernel_fb_list))
+                       list_replace_init(&fb_helper->kernel_fb_list,
+                                       &temp_list);
+
                drm_fb_helper_fini(fb_helper);
 
                ret = drm_fb_helper_init(dev, fb_helper,
@@ -414,6 +423,9 @@ int exynos_drm_fbdev_reinit(struct drm_device *dev)
                        return ret;
                }
 
+               if (!list_empty(&temp_list))
+                       list_replace(&temp_list, &fb_helper->kernel_fb_list);
+
                ret = drm_fb_helper_single_add_all_connectors(fb_helper);
                if (ret < 0) {
                        DRM_ERROR("failed to add fb helper to connectors\n");
index 4659c88cdd9bbaec81e6d6d1d9fe1d7b03964dec..db3b3d9e731d86475d734884e2ec113a8be5f914 100644 (file)
@@ -64,7 +64,7 @@ struct fimd_win_data {
        unsigned int            fb_width;
        unsigned int            fb_height;
        unsigned int            bpp;
-       dma_addr_t              paddr;
+       dma_addr_t              dma_addr;
        void __iomem            *vaddr;
        unsigned int            buf_offsize;
        unsigned int            line_size;      /* bytes */
@@ -124,7 +124,7 @@ static int fimd_display_power_on(struct device *dev, int mode)
        return 0;
 }
 
-static struct exynos_drm_display fimd_display = {
+static struct exynos_drm_display_ops fimd_display_ops = {
        .type = EXYNOS_DISPLAY_TYPE_LCD,
        .is_connected = fimd_display_is_connected,
        .get_timing = fimd_get_timing,
@@ -177,6 +177,40 @@ static void fimd_commit(struct device *dev)
        writel(val, ctx->regs + VIDCON0);
 }
 
+static void fimd_disable(struct device *dev)
+{
+       struct fimd_context *ctx = get_fimd_context(dev);
+       struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+       struct drm_device *drm_dev = subdrv->drm_dev;
+       struct exynos_drm_manager *manager = &subdrv->manager;
+       u32 val;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       /* fimd dma off */
+       val = readl(ctx->regs + VIDCON0);
+       val &= ~(VIDCON0_ENVID | VIDCON0_ENVID_F);
+       writel(val, ctx->regs + VIDCON0);
+
+       /*
+        * if vblank is enabled status with dma off then
+        * it disables vsync interrupt.
+        */
+       if (drm_dev->vblank_enabled[manager->pipe] &&
+               atomic_read(&drm_dev->vblank_refcount[manager->pipe])) {
+               drm_vblank_put(drm_dev, manager->pipe);
+
+               /*
+                * if vblank_disable_allowed is 0 then disable
+                * vsync interrupt right now else the vsync interrupt
+                * would be disabled by drm timer once a current process
+                * gives up ownershop of vblank event.
+                */
+               if (!drm_dev->vblank_disable_allowed)
+                       drm_vblank_off(drm_dev, manager->pipe);
+       }
+}
+
 static int fimd_enable_vblank(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
@@ -220,6 +254,7 @@ static void fimd_disable_vblank(struct device *dev)
 
 static struct exynos_drm_manager_ops fimd_manager_ops = {
        .commit = fimd_commit,
+       .disable = fimd_disable,
        .enable_vblank = fimd_enable_vblank,
        .disable_vblank = fimd_disable_vblank,
 };
@@ -251,7 +286,7 @@ static void fimd_win_mode_set(struct device *dev,
        win_data->ovl_height = overlay->crtc_height;
        win_data->fb_width = overlay->fb_width;
        win_data->fb_height = overlay->fb_height;
-       win_data->paddr = overlay->paddr + offset;
+       win_data->dma_addr = overlay->dma_addr + offset;
        win_data->vaddr = overlay->vaddr + offset;
        win_data->bpp = overlay->bpp;
        win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
@@ -263,7 +298,7 @@ static void fimd_win_mode_set(struct device *dev,
        DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
                        win_data->ovl_width, win_data->ovl_height);
        DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n",
-                       (unsigned long)win_data->paddr,
+                       (unsigned long)win_data->dma_addr,
                        (unsigned long)win_data->vaddr);
        DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
                        overlay->fb_width, overlay->crtc_width);
@@ -376,16 +411,16 @@ static void fimd_win_commit(struct device *dev)
        writel(val, ctx->regs + SHADOWCON);
 
        /* buffer start address */
-       val = win_data->paddr;
+       val = (unsigned long)win_data->dma_addr;
        writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
 
        /* buffer end address */
        size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3);
-       val = win_data->paddr + size;
+       val = (unsigned long)(win_data->dma_addr + size);
        writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
 
        DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n",
-                       (unsigned long)win_data->paddr, val, size);
+                       (unsigned long)win_data->dma_addr, val, size);
        DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
                        win_data->ovl_width, win_data->ovl_height);
 
@@ -447,7 +482,6 @@ static void fimd_win_commit(struct device *dev)
 static void fimd_win_disable(struct device *dev)
 {
        struct fimd_context *ctx = get_fimd_context(dev);
-       struct fimd_win_data *win_data;
        int win = ctx->default_win;
        u32 val;
 
@@ -456,8 +490,6 @@ static void fimd_win_disable(struct device *dev)
        if (win < 0 || win > WINDOWS_NR)
                return;
 
-       win_data = &ctx->win_data[win];
-
        /* protect windows */
        val = readl(ctx->regs + SHADOWCON);
        val |= SHADOWCON_WINx_PROTECT(win);
@@ -528,6 +560,16 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
                /* VSYNC interrupt */
                writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
 
+       /*
+        * in case that vblank_disable_allowed is 1, it could induce
+        * the problem that manager->pipe could be -1 because with
+        * disable callback, vsync interrupt isn't disabled and at this moment,
+        * vsync interrupt could occur. the vsync interrupt would be disabled
+        * by timer handler later.
+        */
+       if (manager->pipe == -1)
+               return IRQ_HANDLED;
+
        drm_handle_vblank(drm_dev, manager->pipe);
        fimd_finish_pageflip(drm_dev, manager->pipe);
 
@@ -548,13 +590,6 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
         */
        drm_dev->irq_enabled = 1;
 
-       /*
-        * with vblank_disable_allowed = 1, vblank interrupt will be disabled
-        * by drm timer once a current process gives up ownership of
-        * vblank event.(drm_vblank_put function was called)
-        */
-       drm_dev->vblank_disable_allowed = 1;
-
        return 0;
 }
 
@@ -731,7 +766,7 @@ static int __devinit fimd_probe(struct platform_device *pdev)
        subdrv->manager.pipe = -1;
        subdrv->manager.ops = &fimd_manager_ops;
        subdrv->manager.overlay_ops = &fimd_overlay_ops;
-       subdrv->manager.display = &fimd_display;
+       subdrv->manager.display_ops = &fimd_display_ops;
        subdrv->manager.dev = dev;
 
        platform_set_drvdata(pdev, ctx);
index a8e7a88906ed22e43fb23d23a859dc825a335451..aba0fe47f7eaae47c10ac4b0839eba8c1edf7f54 100644 (file)
@@ -62,40 +62,28 @@ static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj)
        return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT;
 }
 
-struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv,
-               struct drm_device *dev, unsigned int size,
-               unsigned int *handle)
+static struct exynos_drm_gem_obj
+               *exynos_drm_gem_init(struct drm_device *drm_dev,
+                       struct drm_file *file_priv, unsigned int *handle,
+                       unsigned int size)
 {
        struct exynos_drm_gem_obj *exynos_gem_obj;
-       struct exynos_drm_buf_entry *entry;
        struct drm_gem_object *obj;
        int ret;
 
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       size = roundup(size, PAGE_SIZE);
-
        exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL);
        if (!exynos_gem_obj) {
                DRM_ERROR("failed to allocate exynos gem object.\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       /* allocate the new buffer object and memory region. */
-       entry = exynos_drm_buf_create(dev, size);
-       if (!entry) {
-               kfree(exynos_gem_obj);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       exynos_gem_obj->entry = entry;
-
        obj = &exynos_gem_obj->base;
 
-       ret = drm_gem_object_init(dev, obj, size);
+       ret = drm_gem_object_init(drm_dev, obj, size);
        if (ret < 0) {
-               DRM_ERROR("failed to initailize gem object.\n");
-               goto err_obj_init;
+               DRM_ERROR("failed to initialize gem object.\n");
+               ret = -EINVAL;
+               goto err_object_init;
        }
 
        DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp);
@@ -127,24 +115,50 @@ err_handle_create:
 err_create_mmap_offset:
        drm_gem_object_release(obj);
 
-err_obj_init:
-       exynos_drm_buf_destroy(dev, exynos_gem_obj->entry);
-
+err_object_init:
        kfree(exynos_gem_obj);
 
        return ERR_PTR(ret);
 }
 
+struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
+                               struct drm_file *file_priv,
+                               unsigned int *handle, unsigned long size)
+{
+
+       struct exynos_drm_gem_obj *exynos_gem_obj = NULL;
+       struct exynos_drm_gem_buf *buffer;
+
+       size = roundup(size, PAGE_SIZE);
+
+       DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+
+       buffer = exynos_drm_buf_create(dev, size);
+       if (IS_ERR(buffer)) {
+               return ERR_CAST(buffer);
+       }
+
+       exynos_gem_obj = exynos_drm_gem_init(dev, file_priv, handle, size);
+       if (IS_ERR(exynos_gem_obj)) {
+               exynos_drm_buf_destroy(dev, buffer);
+               return exynos_gem_obj;
+       }
+
+       exynos_gem_obj->buffer = buffer;
+
+       return exynos_gem_obj;
+}
+
 int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
-               struct drm_file *file_priv)
+                                       struct drm_file *file_priv)
 {
        struct drm_exynos_gem_create *args = data;
-       struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct exynos_drm_gem_obj *exynos_gem_obj = NULL;
 
-       DRM_DEBUG_KMS("%s : size = 0x%x\n", __FILE__, args->size);
+       DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size,
-                       &args->handle);
+       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv,
+                                               &args->handle, args->size);
        if (IS_ERR(exynos_gem_obj))
                return PTR_ERR(exynos_gem_obj);
 
@@ -175,7 +189,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
 {
        struct drm_gem_object *obj = filp->private_data;
        struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
        unsigned long pfn, vm_size;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -187,20 +201,20 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
 
        vm_size = vma->vm_end - vma->vm_start;
        /*
-        * a entry contains information to physically continuous memory
+        * a buffer contains information to physically continuous memory
         * allocated by user request or at framebuffer creation.
         */
-       entry = exynos_gem_obj->entry;
+       buffer = exynos_gem_obj->buffer;
 
        /* check if user-requested size is valid. */
-       if (vm_size > entry->size)
+       if (vm_size > buffer->size)
                return -EINVAL;
 
        /*
         * get page frame number to physical memory to be mapped
         * to user space.
         */
-       pfn = exynos_gem_obj->entry->paddr >> PAGE_SHIFT;
+       pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> PAGE_SHIFT;
 
        DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn);
 
@@ -281,7 +295,7 @@ void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj)
 
        exynos_gem_obj = to_exynos_gem_obj(gem_obj);
 
-       exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->entry);
+       exynos_drm_buf_destroy(gem_obj->dev, exynos_gem_obj->buffer);
 
        kfree(exynos_gem_obj);
 }
@@ -302,8 +316,8 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
        args->pitch = args->width * args->bpp >> 3;
        args->size = args->pitch * args->height;
 
-       exynos_gem_obj = exynos_drm_gem_create(file_priv, dev, args->size,
-                                                       &args->handle);
+       exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, &args->handle,
+                                                       args->size);
        if (IS_ERR(exynos_gem_obj))
                return PTR_ERR(exynos_gem_obj);
 
@@ -360,7 +374,8 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
        mutex_lock(&dev->struct_mutex);
 
-       pfn = (exynos_gem_obj->entry->paddr >> PAGE_SHIFT) + page_offset;
+       pfn = (((unsigned long)exynos_gem_obj->buffer->dma_addr) >>
+                       PAGE_SHIFT) + page_offset;
 
        ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
 
index e5fc0148277bf84b5fe8c9a31365256c940da802..ef8797334e6da746c54eed761521aacdc7afd7a8 100644 (file)
 #define to_exynos_gem_obj(x)   container_of(x,\
                        struct exynos_drm_gem_obj, base)
 
+/*
+ * exynos drm gem buffer structure.
+ *
+ * @kvaddr: kernel virtual address to allocated memory region.
+ * @dma_addr: bus address(accessed by dma) to allocated memory region.
+ *     - this address could be physical address without IOMMU and
+ *     device address with IOMMU.
+ * @size: size of allocated memory region.
+ */
+struct exynos_drm_gem_buf {
+       void __iomem            *kvaddr;
+       dma_addr_t              dma_addr;
+       unsigned long           size;
+};
+
 /*
  * exynos drm buffer structure.
  *
  * @base: a gem object.
  *     - a new handle to this gem object would be created
  *     by drm_gem_handle_create().
- * @entry: pointer to exynos drm buffer entry object.
- *     - containing the information to physically
+ * @buffer: a pointer to exynos_drm_gem_buffer object.
+ *     - contain the information to memory region allocated
+ *     by user request or at framebuffer creation.
  *     continuous memory region allocated by user request
  *     or at framebuffer creation.
  *
  */
 struct exynos_drm_gem_obj {
        struct drm_gem_object base;
-       struct exynos_drm_buf_entry *entry;
+       struct exynos_drm_gem_buf *buffer;
 };
 
 /* create a new buffer and get a new gem handle. */
-struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_file *file_priv,
-               struct drm_device *dev, unsigned int size,
-               unsigned int *handle);
+struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
+               struct drm_file *file_priv,
+               unsigned int *handle, unsigned long size);
 
 /*
  * request gem object creation and buffer allocation as the size
index 08792a740f188b1bae1d8a4acf3c7d30d7c89cbb..07d55df6623e2db921dc337003f9406af7e5e7c8 100644 (file)
@@ -24,6 +24,8 @@
  *
  */
 
+#include <linux/module.h>
+
 #include "ch7006_priv.h"
 
 /* DRM encoder functions */
index 0b6773290c08c392ae6d9f33021b77570ccd0519..b7d45ab4ba699d12590ab74489ebf6f58ba25cfe 100644 (file)
@@ -24,6 +24,8 @@
  *
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm_crtc_helper.h"
 #include "drm_encoder_slave.h"
index 6f98d059f68a73d47720611f98ef578819058afe..d4266bdf6fb4eb3d3cb6ac6ea991b0de8a8cd7c9 100644 (file)
@@ -30,6 +30,8 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "i810_drm.h"
index 8e95d66800b09abdcd38f196b6503990eed7ccd3..d09a6e02dc95374caf456923cba25efa94aafa94 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm.h"
 #include "intel_drv.h"
@@ -635,11 +636,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
+       int ret;
 
        ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];
        if (ring->size == 0)
                return 0;
 
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
        seq_printf(m, "Ring %s:\n", ring->name);
        seq_printf(m, "  Head :    %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR);
        seq_printf(m, "  Tail :    %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR);
@@ -653,6 +659,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
        seq_printf(m, "  Control : %08x\n", I915_READ_CTL(ring));
        seq_printf(m, "  Start :   %08x\n", I915_READ_START(ring));
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -841,7 +849,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u16 crstanddelay = I915_READ16(CRSTANDVID);
+       u16 crstanddelay;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       crstanddelay = I915_READ16(CRSTANDVID);
+
+       mutex_unlock(&dev->struct_mutex);
 
        seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
 
@@ -939,7 +956,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 delayfreq;
-       int i;
+       int ret, i;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        for (i = 0; i < 16; i++) {
                delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
@@ -947,6 +968,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
                           (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
        }
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -961,13 +984,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused)
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 inttoext;
-       int i;
+       int ret, i;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        for (i = 1; i <= 32; i++) {
                inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
                seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
        }
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -976,9 +1005,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       u32 rgvmodectl = I915_READ(MEMMODECTL);
-       u32 rstdbyctl = I915_READ(RSTDBYCTL);
-       u16 crstandvid = I915_READ16(CRSTANDVID);
+       u32 rgvmodectl, rstdbyctl;
+       u16 crstandvid;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       rgvmodectl = I915_READ(MEMMODECTL);
+       rstdbyctl = I915_READ(RSTDBYCTL);
+       crstandvid = I915_READ16(CRSTANDVID);
+
+       mutex_unlock(&dev->struct_mutex);
 
        seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
                   "yes" : "no");
@@ -1166,9 +1205,16 @@ static int i915_gfxec(struct seq_file *m, void *unused)
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
 
        seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -1505,7 +1551,10 @@ drm_add_fake_info_node(struct drm_minor *minor,
        node->minor = minor;
        node->dent = ent;
        node->info_ent = (void *) key;
-       list_add(&node->list, &minor->debugfs_nodes.list);
+
+       mutex_lock(&minor->debugfs_lock);
+       list_add(&node->list, &minor->debugfs_list);
+       mutex_unlock(&minor->debugfs_lock);
 
        return 0;
 }
index 2eac955dee187337e7a4ff0e4f309a8aa8ce66a4..a9533c54c93c766a73acc453d38377a9e0ef5a64 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/pnp.h>
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <acpi/video.h>
 
 static void i915_write_hws_pga(struct drm_device *dev)
index 4c8d681c2151e751dab7f33cbce4e75d899a9e47..15bfa9145d2b7f007b21f54ecee19b8b502648f2 100644 (file)
@@ -35,6 +35,7 @@
 #include "intel_drv.h"
 
 #include <linux/console.h>
+#include <linux/module.h>
 #include "drm_crtc_helper.h"
 
 static int i915_modeset __read_mostly = -1;
@@ -67,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6 (default: true)");
 
-unsigned int i915_enable_fbc __read_mostly = -1;
+int i915_enable_fbc __read_mostly = -1;
 module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
 MODULE_PARM_DESC(i915_enable_fbc,
                "Enable frame buffer compression for power savings "
@@ -79,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock,
                "Use panel (LVDS/eDP) downclocking for power savings "
                "(default: false)");
 
-unsigned int i915_panel_use_ssc __read_mostly = -1;
+int i915_panel_use_ssc __read_mostly = -1;
 module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);
 MODULE_PARM_DESC(lvds_use_ssc,
                "Use Spread Spectrum Clock with panels [LVDS/eDP] "
@@ -106,7 +107,7 @@ static struct drm_driver driver;
 extern int intel_agp_enabled;
 
 #define INTEL_VGA_DEVICE(id, info) {           \
-       .class = PCI_CLASS_DISPLAY_VGA << 8,    \
+       .class = PCI_BASE_CLASS_DISPLAY << 16,  \
        .class_mask = 0xff0000,                 \
        .vendor = 0x8086,                       \
        .device = id,                           \
@@ -788,8 +789,8 @@ static struct vm_operations_struct i915_gem_vm_ops = {
 };
 
 static struct drm_driver driver = {
-       /* don't use mtrr's here, the Xserver or user space app should
-        * deal with them for intel hardware.
+       /* Don't use MTRRs here; the Xserver or userspace app should
+        * deal with them for Intel hardware.
         */
        .driver_features =
            DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
index 06a37f4fd74b17ad82a0ba912da22d9df63e0dba..4a9c1b97980493b47c1f4e03a7e299f800a7f4e0 100644 (file)
@@ -126,6 +126,9 @@ struct drm_i915_master_private {
        struct _drm_i915_sarea *sarea_priv;
 };
 #define I915_FENCE_REG_NONE -1
+#define I915_MAX_NUM_FENCES 16
+/* 16 fences + sign bit for FENCE_REG_NONE */
+#define I915_MAX_NUM_FENCE_BITS 5
 
 struct drm_i915_fence_reg {
        struct list_head lru_list;
@@ -168,7 +171,7 @@ struct drm_i915_error_state {
        u32 instdone1;
        u32 seqno;
        u64 bbaddr;
-       u64 fence[16];
+       u64 fence[I915_MAX_NUM_FENCES];
        struct timeval time;
        struct drm_i915_error_object {
                int page_count;
@@ -182,7 +185,7 @@ struct drm_i915_error_state {
                u32 gtt_offset;
                u32 read_domains;
                u32 write_domain;
-               s32 fence_reg:5;
+               s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
                s32 pinned:2;
                u32 tiling:2;
                u32 dirty:1;
@@ -375,7 +378,7 @@ typedef struct drm_i915_private {
        struct notifier_block lid_notifier;
 
        int crt_ddc_pin;
-       struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
+       struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
        int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
        int num_fence_regs; /* 8 on pre-965, 16 otherwise */
 
@@ -506,7 +509,7 @@ typedef struct drm_i915_private {
        u8 saveAR[21];
        u8 saveDACMASK;
        u8 saveCR[37];
-       uint64_t saveFENCE[16];
+       uint64_t saveFENCE[I915_MAX_NUM_FENCES];
        u32 saveCURACNTR;
        u32 saveCURAPOS;
        u32 saveCURABASE;
@@ -777,10 +780,8 @@ struct drm_i915_gem_object {
         * Fence register bits (if any) for this object.  Will be set
         * as needed when mapped into the GTT.
         * Protected by dev->struct_mutex.
-        *
-        * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
         */
-       signed int fence_reg:5;
+       signed int fence_reg:I915_MAX_NUM_FENCE_BITS;
 
        /**
         * Advice: are the backing pages purgeable?
@@ -999,10 +1000,10 @@ extern int i915_panel_ignore_lid __read_mostly;
 extern unsigned int i915_powersave __read_mostly;
 extern unsigned int i915_semaphores __read_mostly;
 extern unsigned int i915_lvds_downclock __read_mostly;
-extern unsigned int i915_panel_use_ssc __read_mostly;
+extern int i915_panel_use_ssc __read_mostly;
 extern int i915_vbt_sdvo_panel_type __read_mostly;
 extern unsigned int i915_enable_rc6 __read_mostly;
-extern unsigned int i915_enable_fbc __read_mostly;
+extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
index 6651c36b6e8a16a59231fafb83d24709732a7b7f..60ff1b63b568c464248fb5651d16fb550d54c69b 100644 (file)
@@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
 
        if (obj->base.size > dev_priv->mm.gtt_mappable_end) {
                ret = -E2BIG;
-               goto unlock;
+               goto out;
        }
 
        if (obj->madv != I915_MADV_WILLNEED) {
@@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
 
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < dev_priv->num_fence_regs; i++) {
                struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
                struct drm_i915_gem_object *obj = reg->obj;
 
@@ -2026,8 +2026,13 @@ i915_wait_request(struct intel_ring_buffer *ring,
         * to handle this, the waiter on a request often wants an associated
         * buffer to have made it to the inactive list, and we would need
         * a separate wait queue to handle that.
+        *
+        * To avoid a recursion with the ilk VT-d workaround (that calls
+        * gpu_idle when unbinding objects with interruptible==false) don't
+        * retire requests in that case (because it might call unbind if the
+        * active list holds the last reference to the object).
         */
-       if (ret == 0)
+       if (ret == 0 && dev_priv->mm.interruptible)
                i915_gem_retire_requests_ring(ring);
 
        return ret;
@@ -3512,9 +3517,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                         * so emit a request to do so.
                         */
                        request = kzalloc(sizeof(*request), GFP_KERNEL);
-                       if (request)
+                       if (request) {
                                ret = i915_add_request(obj->ring, NULL, request);
-                       else
+                               if (ret)
+                                       kfree(request);
+                       } else
                                ret = -ENOMEM;
                }
 
@@ -3613,7 +3620,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
        obj->base.write_domain = I915_GEM_DOMAIN_CPU;
        obj->base.read_domains = I915_GEM_DOMAIN_CPU;
 
-       if (IS_GEN6(dev)) {
+       if (IS_GEN6(dev) || IS_GEN7(dev)) {
                /* On Gen6, we can have the GPU use the LLC (the CPU
                 * cache) for about a 10% performance improvement
                 * compared to uncached.  Graphics requests other than
@@ -3877,7 +3884,7 @@ i915_gem_load(struct drm_device *dev)
        INIT_LIST_HEAD(&dev_priv->mm.gtt_list);
        for (i = 0; i < I915_NUM_RINGS; i++)
                init_ring_lists(&dev_priv->ring[i]);
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < I915_MAX_NUM_FENCES; i++)
                INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
                          i915_gem_retire_work_handler);
index 9ee2729fe5c65ec3690a1f9dcf403045c79a4907..b40004b559771dc0244814335d44fb1537625087 100644 (file)
@@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev,
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
index 5a09416e611f566774e18ad7095d3c007ea1876b..b080cc82400153a68aed7cca1f3319de361a1f93 100644 (file)
  */
 #define   PP_READY             (1 << 30)
 #define   PP_SEQUENCE_NONE     (0 << 28)
-#define   PP_SEQUENCE_ON       (1 << 28)
-#define   PP_SEQUENCE_OFF      (2 << 28)
-#define   PP_SEQUENCE_MASK     0x30000000
+#define   PP_SEQUENCE_POWER_UP (1 << 28)
+#define   PP_SEQUENCE_POWER_DOWN (2 << 28)
+#define   PP_SEQUENCE_MASK     (3 << 28)
+#define   PP_SEQUENCE_SHIFT    28
 #define   PP_CYCLE_DELAY_ACTIVE        (1 << 27)
-#define   PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
 #define   PP_SEQUENCE_STATE_MASK 0x0000000f
+#define   PP_SEQUENCE_STATE_OFF_IDLE   (0x0 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_1   (0x1 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_2   (0x2 << 0)
+#define   PP_SEQUENCE_STATE_OFF_S0_3   (0x3 << 0)
+#define   PP_SEQUENCE_STATE_ON_IDLE    (0x8 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_0    (0x9 << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_2    (0xa << 0)
+#define   PP_SEQUENCE_STATE_ON_S1_3    (0xb << 0)
+#define   PP_SEQUENCE_STATE_RESET      (0xf << 0)
 #define PP_CONTROL     0x61204
 #define   POWER_TARGET_ON      (1 << 0)
 #define PP_ON_DELAYS   0x61208
 #define  GT_FIFO_FREE_ENTRIES                  0x120008
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
+#define GEN6_UCGCTL2                           0x9404
+# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
+# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE               (1 << 11)
+
 #define GEN6_RPNSWREQ                          0xA008
 #define   GEN6_TURBO_DISABLE                   (1<<31)
 #define   GEN6_FREQUENCY(x)                    ((x)<<25)
index f8f602d76650177c1d7b3a11c9cac3b185fee1bf..7886e4fb60e3e23fb283461a690dbe43a928fc6e 100644 (file)
@@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
@@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
 
        /* Fences */
        switch (INTEL_INFO(dev)->gen) {
+       case 7:
        case 6:
                for (i = 0; i < 16; i++)
                        I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
index 981b1f1c04d8da4459f9ae776cf0681576eb915f..e77a863a3833f63511a98991508b2f5c1a6ee0d1 100644 (file)
@@ -2933,7 +2933,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev) &&
-           intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
+           (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
+            intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5;
                reg = TRANS_DP_CTL(pipe);
                temp = I915_READ(reg);
@@ -4711,7 +4712,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                                lvds_bpc = 6;
 
                        if (lvds_bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
                                display_bpc = lvds_bpc;
                        }
                        continue;
@@ -4722,7 +4723,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        unsigned int edp_bpc = dev_priv->edp.bpp / 3;
 
                        if (edp_bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
                                display_bpc = edp_bpc;
                        }
                        continue;
@@ -4737,7 +4738,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                        /* Don't use an invalid EDID bpc value */
                        if (connector->display_info.bpc &&
                            connector->display_info.bpc < display_bpc) {
-                               DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
+                               DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
                                display_bpc = connector->display_info.bpc;
                        }
                }
@@ -4748,10 +4749,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
                 */
                if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
                        if (display_bpc > 8 && display_bpc < 12) {
-                               DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n");
+                               DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
                                display_bpc = 12;
                        } else {
-                               DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n");
+                               DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
                                display_bpc = 8;
                        }
                }
@@ -4789,8 +4790,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
 
        display_bpc = min(display_bpc, bpc);
 
-       DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",
-                        bpc, display_bpc);
+       DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
+                     bpc, display_bpc);
 
        *pipe_bpp = display_bpc * 3;
 
@@ -5671,7 +5672,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
        pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
        if ((is_lvds && dev_priv->lvds_dither) || dither) {
                pipeconf |= PIPECONF_DITHER_EN;
-               pipeconf |= PIPECONF_DITHER_TYPE_ST1;
+               pipeconf |= PIPECONF_DITHER_TYPE_SP;
        }
        if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
                intel_dp_set_m_n(crtc, mode, adjusted_mode);
@@ -8148,6 +8149,20 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
+        * gating disable must be set.  Failure to set it results in
+        * flickering pixels due to Z write ordering failures after
+        * some amount of runtime in the Mesa "fire" demo, and Unigine
+        * Sanctuary and Tropics, and apparently anything else with
+        * alpha test or pixel discard.
+        *
+        * According to the spec, bit 11 (RCCUNIT) must also be set,
+        * but we didn't debug actual testcases to find it out.
+        */
+       I915_WRITE(GEN6_UCGCTL2,
+                  GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
+                  GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
+
        /*
         * According to the spec the following bits should be
         * set in order to enable memory self-refresh and fbc:
index fc1a0832af4fed4a131c8611c4a1e3f3fc0e655b..4d0358fad93795c31dd9d4229daa3c7c2ecedcc5 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
@@ -58,7 +59,6 @@ struct intel_dp {
        struct i2c_algo_dp_aux_data algo;
        bool is_pch_edp;
        uint8_t train_set[4];
-       uint8_t link_status[DP_LINK_STATUS_SIZE];
        int panel_power_up_delay;
        int panel_power_down_delay;
        int panel_power_cycle_delay;
@@ -67,7 +67,6 @@ struct intel_dp {
        struct drm_display_mode *panel_fixed_mode;  /* for eDP */
        struct delayed_work panel_vdd_work;
        bool want_panel_vdd;
-       unsigned long panel_off_jiffies;
 };
 
 /**
@@ -156,16 +155,12 @@ intel_edp_link_config(struct intel_encoder *intel_encoder,
 static int
 intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
-       int max_lane_count = 4;
-
-       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
-               max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
-               switch (max_lane_count) {
-               case 1: case 2: case 4:
-                       break;
-               default:
-                       max_lane_count = 4;
-               }
+       int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f;
+       switch (max_lane_count) {
+       case 1: case 2: case 4:
+               break;
+       default:
+               max_lane_count = 4;
        }
        return max_lane_count;
 }
@@ -767,12 +762,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                        continue;
 
                intel_dp = enc_to_intel_dp(encoder);
-               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
+                   intel_dp->base.type == INTEL_OUTPUT_EDP)
+               {
                        lane_count = intel_dp->lane_count;
                        break;
-               } else if (is_edp(intel_dp)) {
-                       lane_count = dev_priv->edp.lanes;
-                       break;
                }
        }
 
@@ -809,6 +803,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                  struct drm_display_mode *adjusted_mode)
 {
        struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        struct drm_crtc *crtc = intel_dp->base.base.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -821,18 +816,31 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                        ironlake_edp_pll_off(encoder);
        }
 
-       intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
-       intel_dp->DP |= intel_dp->color_range;
+       /*
+        * There are three kinds of DP registers:
+        *
+        *      IBX PCH
+        *      CPU
+        *      CPT PCH
+        *
+        * IBX PCH and CPU are the same for almost everything,
+        * except that the CPU DP PLL is configured in this
+        * register
+        *
+        * CPT PCH is quite different, having many bits moved
+        * to the TRANS_DP_CTL register instead. That
+        * configuration happens (oddly) in ironlake_pch_enable
+        */
 
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
-               intel_dp->DP |= DP_SYNC_HS_HIGH;
-       if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
-               intel_dp->DP |= DP_SYNC_VS_HIGH;
+       /* Preserve the BIOS-computed detected bit. This is
+        * supposed to be read-only.
+        */
+       intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
+       intel_dp->DP |=  DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 
-       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
-               intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
-       else
-               intel_dp->DP |= DP_LINK_TRAIN_OFF;
+       /* Handle DP bits in common between all three register formats */
+
+       intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 
        switch (intel_dp->lane_count) {
        case 1:
@@ -851,59 +859,106 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
                intel_write_eld(encoder, adjusted_mode);
        }
-
        memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
        intel_dp->link_configuration[0] = intel_dp->link_bw;
        intel_dp->link_configuration[1] = intel_dp->lane_count;
        intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
-
        /*
         * Check for DPCD version > 1.1 and enhanced framing support
         */
        if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
            (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
                intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
-               intel_dp->DP |= DP_ENHANCED_FRAMING;
        }
 
-       /* CPT DP's pipe select is decided in TRANS_DP_CTL */
-       if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev))
-               intel_dp->DP |= DP_PIPEB_SELECT;
+       /* Split out the IBX/CPU vs CPT settings */
 
-       if (is_cpu_edp(intel_dp)) {
-               /* don't miss out required setting for eDP */
-               intel_dp->DP |= DP_PLL_ENABLE;
-               if (adjusted_mode->clock < 200000)
-                       intel_dp->DP |= DP_PLL_FREQ_160MHZ;
-               else
-                       intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+       if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+               intel_dp->DP |= intel_dp->color_range;
+
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+                       intel_dp->DP |= DP_SYNC_HS_HIGH;
+               if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       intel_dp->DP |= DP_SYNC_VS_HIGH;
+               intel_dp->DP |= DP_LINK_TRAIN_OFF;
+
+               if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+                       intel_dp->DP |= DP_ENHANCED_FRAMING;
+
+               if (intel_crtc->pipe == 1)
+                       intel_dp->DP |= DP_PIPEB_SELECT;
+
+               if (is_cpu_edp(intel_dp)) {
+                       /* don't miss out required setting for eDP */
+                       intel_dp->DP |= DP_PLL_ENABLE;
+                       if (adjusted_mode->clock < 200000)
+                               intel_dp->DP |= DP_PLL_FREQ_160MHZ;
+                       else
+                               intel_dp->DP |= DP_PLL_FREQ_270MHZ;
+               }
+       } else {
+               intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
        }
 }
 
-static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
+#define IDLE_ON_MASK           (PP_ON | 0        | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
+#define IDLE_ON_VALUE          (PP_ON | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_ON_IDLE)
+
+#define IDLE_OFF_MASK          (PP_ON | 0        | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
+#define IDLE_OFF_VALUE         (0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE)
+
+#define IDLE_CYCLE_MASK                (PP_ON | 0        | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
+#define IDLE_CYCLE_VALUE       (0     | 0        | PP_SEQUENCE_NONE | 0                     | PP_SEQUENCE_STATE_OFF_IDLE)
+
+static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
+                                      u32 mask,
+                                      u32 value)
 {
-       unsigned long   off_time;
-       unsigned long   delay;
+       struct drm_device *dev = intel_dp->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 
-       DRM_DEBUG_KMS("Wait for panel power off time\n");
+       DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
+                     mask, value,
+                     I915_READ(PCH_PP_STATUS),
+                     I915_READ(PCH_PP_CONTROL));
 
-       if (ironlake_edp_have_panel_power(intel_dp) ||
-           ironlake_edp_have_panel_vdd(intel_dp))
-       {
-               DRM_DEBUG_KMS("Panel still on, no delay needed\n");
-               return;
+       if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
+               DRM_ERROR("Panel status timeout: status %08x control %08x\n",
+                         I915_READ(PCH_PP_STATUS),
+                         I915_READ(PCH_PP_CONTROL));
        }
+}
 
-       off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay);
-       if (time_after(jiffies, off_time)) {
-               DRM_DEBUG_KMS("Time already passed");
-               return;
-       }
-       delay = jiffies_to_msecs(off_time - jiffies);
-       if (delay > intel_dp->panel_power_down_delay)
-               delay = intel_dp->panel_power_down_delay;
-       DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay);
-       msleep(delay);
+static void ironlake_wait_panel_on(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power on\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
+}
+
+static void ironlake_wait_panel_off(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power off time\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
+}
+
+static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
+{
+       DRM_DEBUG_KMS("Wait for panel power cycle\n");
+       ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
+}
+
+
+/* Read the current pp_control value, unlocking the register if it
+ * is locked
+ */
+
+static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
+{
+       u32     control = I915_READ(PCH_PP_CONTROL);
+
+       control &= ~PANEL_UNLOCK_MASK;
+       control |= PANEL_UNLOCK_REGS;
+       return control;
 }
 
 static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
@@ -920,15 +975,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
             "eDP VDD already requested on\n");
 
        intel_dp->want_panel_vdd = true;
+
        if (ironlake_edp_have_panel_vdd(intel_dp)) {
                DRM_DEBUG_KMS("eDP VDD already on\n");
                return;
        }
 
-       ironlake_wait_panel_off(intel_dp);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       if (!ironlake_edp_have_panel_power(intel_dp))
+               ironlake_wait_panel_power_cycle(intel_dp);
+
+       pp = ironlake_get_pp_control(dev_priv);
        pp |= EDP_FORCE_VDD;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -951,9 +1007,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
        u32 pp;
 
        if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
-               pp = I915_READ(PCH_PP_CONTROL);
-               pp &= ~PANEL_UNLOCK_MASK;
-               pp |= PANEL_UNLOCK_REGS;
+               pp = ironlake_get_pp_control(dev_priv);
                pp &= ~EDP_FORCE_VDD;
                I915_WRITE(PCH_PP_CONTROL, pp);
                POSTING_READ(PCH_PP_CONTROL);
@@ -961,7 +1015,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
                /* Make sure sequencer is idle before allowing subsequent activity */
                DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
                              I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
-               intel_dp->panel_off_jiffies = jiffies;
+
+               msleep(intel_dp->panel_power_down_delay);
        }
 }
 
@@ -971,9 +1026,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work)
                                                 struct intel_dp, panel_vdd_work);
        struct drm_device *dev = intel_dp->base.base.dev;
 
-       mutex_lock(&dev->struct_mutex);
+       mutex_lock(&dev->mode_config.mutex);
        ironlake_panel_vdd_off_sync(intel_dp);
-       mutex_unlock(&dev->struct_mutex);
+       mutex_unlock(&dev->mode_config.mutex);
 }
 
 static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
@@ -983,7 +1038,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
 
        DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd);
        WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
-       
+
        intel_dp->want_panel_vdd = false;
 
        if (sync) {
@@ -999,23 +1054,25 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
        }
 }
 
-/* Returns true if the panel was already on when called */
 static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 {
        struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE;
+       u32 pp;
 
        if (!is_edp(intel_dp))
                return;
-       if (ironlake_edp_have_panel_power(intel_dp))
+
+       DRM_DEBUG_KMS("Turn eDP power on\n");
+
+       if (ironlake_edp_have_panel_power(intel_dp)) {
+               DRM_DEBUG_KMS("eDP power already on\n");
                return;
+       }
 
-       ironlake_wait_panel_off(intel_dp);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       ironlake_wait_panel_power_cycle(intel_dp);
 
+       pp = ironlake_get_pp_control(dev_priv);
        if (IS_GEN5(dev)) {
                /* ILK workaround: disable reset around power sequence */
                pp &= ~PANEL_POWER_RESET;
@@ -1024,13 +1081,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
        }
 
        pp |= POWER_TARGET_ON;
+       if (!IS_GEN5(dev))
+               pp |= PANEL_POWER_RESET;
+
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
 
-       if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask,
-                    5000))
-               DRM_ERROR("panel on wait timed out: 0x%08x\n",
-                         I915_READ(PCH_PP_STATUS));
+       ironlake_wait_panel_on(intel_dp);
 
        if (IS_GEN5(dev)) {
                pp |= PANEL_POWER_RESET; /* restore panel reset bit */
@@ -1039,46 +1096,25 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
        }
 }
 
-static void ironlake_edp_panel_off(struct drm_encoder *encoder)
+static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 {
-       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-       struct drm_device *dev = encoder->dev;
+       struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK |
-               PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK;
+       u32 pp;
 
        if (!is_edp(intel_dp))
                return;
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
 
-       if (IS_GEN5(dev)) {
-               /* ILK workaround: disable reset around power sequence */
-               pp &= ~PANEL_POWER_RESET;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-       }
+       DRM_DEBUG_KMS("Turn eDP power off\n");
 
-       intel_dp->panel_off_jiffies = jiffies;
+       WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
 
-       if (IS_GEN5(dev)) {
-               pp &= ~POWER_TARGET_ON;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-               pp &= ~POWER_TARGET_ON;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-               msleep(intel_dp->panel_power_cycle_delay);
-
-               if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000))
-                       DRM_ERROR("panel off wait timed out: 0x%08x\n",
-                                 I915_READ(PCH_PP_STATUS));
+       pp = ironlake_get_pp_control(dev_priv);
+       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       I915_WRITE(PCH_PP_CONTROL, pp);
+       POSTING_READ(PCH_PP_CONTROL);
 
-               pp |= PANEL_POWER_RESET; /* restore panel reset bit */
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
-       }
+       ironlake_wait_panel_off(intel_dp);
 }
 
 static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
@@ -1098,9 +1134,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
         * allowing it to appear.
         */
        msleep(intel_dp->backlight_on_delay);
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       pp = ironlake_get_pp_control(dev_priv);
        pp |= EDP_BLC_ENABLE;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -1116,9 +1150,7 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
                return;
 
        DRM_DEBUG_KMS("\n");
-       pp = I915_READ(PCH_PP_CONTROL);
-       pp &= ~PANEL_UNLOCK_MASK;
-       pp |= PANEL_UNLOCK_REGS;
+       pp = ironlake_get_pp_control(dev_priv);
        pp &= ~EDP_BLC_ENABLE;
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
@@ -1186,17 +1218,18 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
+       ironlake_edp_backlight_off(intel_dp);
+       ironlake_edp_panel_off(intel_dp);
+
        /* Wake up the sink first */
        ironlake_edp_panel_vdd_on(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       intel_dp_link_down(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, false);
 
        /* Make sure the panel is off before trying to
         * change the mode
         */
-       ironlake_edp_backlight_off(intel_dp);
-       intel_dp_link_down(intel_dp);
-       ironlake_edp_panel_off(encoder);
 }
 
 static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1210,7 +1243,6 @@ static void intel_dp_commit(struct drm_encoder *encoder)
        intel_dp_start_link_train(intel_dp);
        ironlake_edp_panel_on(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, true);
-
        intel_dp_complete_link_train(intel_dp);
        ironlake_edp_backlight_on(intel_dp);
 
@@ -1229,16 +1261,20 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
+               ironlake_edp_backlight_off(intel_dp);
+               ironlake_edp_panel_off(intel_dp);
+
                ironlake_edp_panel_vdd_on(intel_dp);
-               if (is_edp(intel_dp))
-                       ironlake_edp_backlight_off(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                intel_dp_link_down(intel_dp);
-               ironlake_edp_panel_off(encoder);
-               if (is_edp(intel_dp) && !is_pch_edp(intel_dp))
-                       ironlake_edp_pll_off(encoder);
                ironlake_edp_panel_vdd_off(intel_dp, false);
+
+               if (is_cpu_edp(intel_dp))
+                       ironlake_edp_pll_off(encoder);
        } else {
+               if (is_cpu_edp(intel_dp))
+                       ironlake_edp_pll_on(encoder);
+
                ironlake_edp_panel_vdd_on(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                if (!(dp_reg & DP_PORT_EN)) {
@@ -1246,7 +1282,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
                        ironlake_edp_panel_on(intel_dp);
                        ironlake_edp_panel_vdd_off(intel_dp, true);
                        intel_dp_complete_link_train(intel_dp);
-                       ironlake_edp_backlight_on(intel_dp);
                } else
                        ironlake_edp_panel_vdd_off(intel_dp, false);
                ironlake_edp_backlight_on(intel_dp);
@@ -1284,11 +1319,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_dp *intel_dp)
+intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        return intel_dp_aux_native_read_retry(intel_dp,
                                              DP_LANE0_1_STATUS,
-                                             intel_dp->link_status,
+                                             link_status,
                                              DP_LINK_STATUS_SIZE);
 }
 
@@ -1300,27 +1335,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 }
 
 static uint8_t
-intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+intel_get_adjust_request_voltage(uint8_t adjust_request[2],
                                 int lane)
 {
-       int         i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
        int         s = ((lane & 1) ?
                         DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
                         DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = adjust_request[lane>>1];
 
        return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
 }
 
 static uint8_t
-intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2],
                                      int lane)
 {
-       int         i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
        int         s = ((lane & 1) ?
                         DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
                         DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = adjust_request[lane>>1];
 
        return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 }
@@ -1343,6 +1376,7 @@ static char       *link_train_names[] = {
  * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
  */
 #define I830_DP_VOLTAGE_MAX        DP_TRAIN_VOLTAGE_SWING_800
+#define I830_DP_VOLTAGE_MAX_CPT            DP_TRAIN_VOLTAGE_SWING_1200
 
 static uint8_t
 intel_dp_pre_emphasis_max(uint8_t voltage_swing)
@@ -1361,15 +1395,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_dp *intel_dp)
+intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
+       struct drm_device *dev = intel_dp->base.base.dev;
        uint8_t v = 0;
        uint8_t p = 0;
        int lane;
+       uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS);
+       int voltage_max;
 
        for (lane = 0; lane < intel_dp->lane_count; lane++) {
-               uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane);
-               uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane);
+               uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane);
+               uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane);
 
                if (this_v > v)
                        v = this_v;
@@ -1377,8 +1414,12 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
                        p = this_p;
        }
 
-       if (v >= I830_DP_VOLTAGE_MAX)
-               v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+       if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+               voltage_max = I830_DP_VOLTAGE_MAX_CPT;
+       else
+               voltage_max = I830_DP_VOLTAGE_MAX;
+       if (v >= voltage_max)
+               v = voltage_max | DP_TRAIN_MAX_SWING_REACHED;
 
        if (p >= intel_dp_pre_emphasis_max(v))
                p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
@@ -1388,7 +1429,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
 }
 
 static uint32_t
-intel_dp_signal_levels(uint8_t train_set, int lane_count)
+intel_dp_signal_levels(uint8_t train_set)
 {
        uint32_t        signal_levels = 0;
 
@@ -1457,9 +1498,8 @@ static uint8_t
 intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
                      int lane)
 {
-       int i = DP_LANE0_1_STATUS + (lane >> 1);
        int s = (lane & 1) * 4;
-       uint8_t l = intel_dp_link_status(link_status, i);
+       uint8_t l = link_status[lane>>1];
 
        return (l >> s) & 0xf;
 }
@@ -1484,18 +1524,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count
                         DP_LANE_CHANNEL_EQ_DONE|\
                         DP_LANE_SYMBOL_LOCKED)
 static bool
-intel_channel_eq_ok(struct intel_dp *intel_dp)
+intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        uint8_t lane_align;
        uint8_t lane_status;
        int lane;
 
-       lane_align = intel_dp_link_status(intel_dp->link_status,
+       lane_align = intel_dp_link_status(link_status,
                                          DP_LANE_ALIGN_STATUS_UPDATED);
        if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
                return false;
        for (lane = 0; lane < intel_dp->lane_count; lane++) {
-               lane_status = intel_get_lane_status(intel_dp->link_status, lane);
+               lane_status = intel_get_lane_status(link_status, lane);
                if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
                        return false;
        }
@@ -1520,8 +1560,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 
        ret = intel_dp_aux_native_write(intel_dp,
                                        DP_TRAINING_LANE0_SET,
-                                       intel_dp->train_set, 4);
-       if (ret != 4)
+                                       intel_dp->train_set,
+                                       intel_dp->lane_count);
+       if (ret != intel_dp->lane_count)
                return false;
 
        return true;
@@ -1537,7 +1578,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
        int i;
        uint8_t voltage;
        bool clock_recovery = false;
-       int tries;
+       int voltage_tries, loop_tries;
        u32 reg;
        uint32_t DP = intel_dp->DP;
 
@@ -1564,16 +1605,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                DP &= ~DP_LINK_TRAIN_MASK;
        memset(intel_dp->train_set, 0, 4);
        voltage = 0xff;
-       tries = 0;
+       voltage_tries = 0;
+       loop_tries = 0;
        clock_recovery = false;
        for (;;) {
                /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
+               uint8_t     link_status[DP_LINK_STATUS_SIZE];
                uint32_t    signal_levels;
-               if (IS_GEN6(dev) && is_edp(intel_dp)) {
+
+               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
+                       DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1589,10 +1634,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                /* Set training pattern 1 */
 
                udelay(100);
-               if (!intel_dp_get_link_status(intel_dp))
+               if (!intel_dp_get_link_status(intel_dp, link_status)) {
+                       DRM_ERROR("failed to get link status\n");
                        break;
+               }
 
-               if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+               if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+                       DRM_DEBUG_KMS("clock recovery OK\n");
                        clock_recovery = true;
                        break;
                }
@@ -1601,20 +1649,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
                for (i = 0; i < intel_dp->lane_count; i++)
                        if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
                                break;
-               if (i == intel_dp->lane_count)
-                       break;
+               if (i == intel_dp->lane_count) {
+                       ++loop_tries;
+                       if (loop_tries == 5) {
+                               DRM_DEBUG_KMS("too many full retries, give up\n");
+                               break;
+                       }
+                       memset(intel_dp->train_set, 0, 4);
+                       voltage_tries = 0;
+                       continue;
+               }
 
                /* Check to see if we've tried the same voltage 5 times */
                if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-                       ++tries;
-                       if (tries == 5)
+                       ++voltage_tries;
+                       if (voltage_tries == 5) {
+                               DRM_DEBUG_KMS("too many voltage retries, give up\n");
                                break;
+                       }
                } else
-                       tries = 0;
+                       voltage_tries = 0;
                voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp);
+               intel_get_adjust_train(intel_dp, link_status);
        }
 
        intel_dp->DP = DP;
@@ -1637,6 +1695,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
        for (;;) {
                /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
                uint32_t    signal_levels;
+               uint8_t     link_status[DP_LINK_STATUS_SIZE];
 
                if (cr_tries > 5) {
                        DRM_ERROR("failed to train DP, aborting\n");
@@ -1644,11 +1703,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        break;
                }
 
-               if (IS_GEN6(dev) && is_edp(intel_dp)) {
+               if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
                        signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
                } else {
-                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
+                       signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]);
                        DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
                }
 
@@ -1664,17 +1723,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                        break;
 
                udelay(400);
-               if (!intel_dp_get_link_status(intel_dp))
+               if (!intel_dp_get_link_status(intel_dp, link_status))
                        break;
 
                /* Make sure clock is still ok */
-               if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+               if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) {
                        intel_dp_start_link_train(intel_dp);
                        cr_tries++;
                        continue;
                }
 
-               if (intel_channel_eq_ok(intel_dp)) {
+               if (intel_channel_eq_ok(intel_dp, link_status)) {
                        channel_eq = true;
                        break;
                }
@@ -1689,7 +1748,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
                }
 
                /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp);
+               intel_get_adjust_train(intel_dp, link_status);
                ++tries;
        }
 
@@ -1734,8 +1793,12 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
        msleep(17);
 
-       if (is_edp(intel_dp))
-               DP |= DP_LINK_TRAIN_OFF;
+       if (is_edp(intel_dp)) {
+               if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+                       DP |= DP_LINK_TRAIN_OFF_CPT;
+               else
+                       DP |= DP_LINK_TRAIN_OFF;
+       }
 
        if (!HAS_PCH_CPT(dev) &&
            I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
@@ -1821,6 +1884,7 @@ static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
        u8 sink_irq_vector;
+       u8 link_status[DP_LINK_STATUS_SIZE];
 
        if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON)
                return;
@@ -1829,7 +1893,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                return;
 
        /* Try to read receiver status if the link appears to be up */
-       if (!intel_dp_get_link_status(intel_dp)) {
+       if (!intel_dp_get_link_status(intel_dp, link_status)) {
                intel_dp_link_down(intel_dp);
                return;
        }
@@ -1854,7 +1918,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
                        DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
        }
 
-       if (!intel_channel_eq_ok(intel_dp)) {
+       if (!intel_channel_eq_ok(intel_dp, link_status)) {
                DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
                              drm_get_encoder_name(&intel_dp->base.base));
                intel_dp_start_link_train(intel_dp);
@@ -2178,7 +2242,8 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc)
                        continue;
 
                intel_dp = enc_to_intel_dp(encoder);
-               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
+               if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
+                   intel_dp->base.type == INTEL_OUTPUT_EDP)
                        return intel_dp->output_reg;
        }
 
@@ -2320,7 +2385,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
                cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
                        PANEL_LIGHT_ON_DELAY_SHIFT;
-               
+
                cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
                        PANEL_LIGHT_OFF_DELAY_SHIFT;
 
@@ -2353,11 +2418,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
                              intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
 
-               intel_dp->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay;
-
                ironlake_edp_panel_vdd_on(intel_dp);
                ret = intel_dp_get_dpcd(intel_dp);
                ironlake_edp_panel_vdd_off(intel_dp, false);
+
                if (ret) {
                        if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
                                dev_priv->no_aux_handshake =
index 9ed5380e5a53795db3bd73fa73fa5407c8dc727a..d30ccccb9d738ad4f1f893ec15b5df9fb90bd50f 100644 (file)
@@ -28,6 +28,7 @@
  */
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm.h"
 #include "intel_drv.h"
index 499d4c0dbeebd93f944d338ffc29184ed5103617..21f60b7d69a30819d13f7e0fd942e3ebe4fe7bbd 100644 (file)
@@ -326,7 +326,8 @@ static int intel_panel_update_status(struct backlight_device *bd)
 static int intel_panel_get_brightness(struct backlight_device *bd)
 {
        struct drm_device *dev = bl_get_data(bd);
-       return intel_panel_get_backlight(dev);
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       return dev_priv->backlight_level;
 }
 
 static const struct backlight_ops intel_panel_bl_ops = {
index 6db3b1ccb6ebda273255f50bfd931f5e7acd14de..3003fb25aefde4ac697a5d2694d825faec76fe0d 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
index 42d31874edf2c44187020eb1ab963b9b60b8b753..33daa29eea6652e0afa9888cecb840f2eda1e9bd 100644 (file)
@@ -29,6 +29,8 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
index f172bd5c257f48600c4ab17c991460dd99b02ea8..722a91b69b0cc55d0ac4658de03e67f912d4d2d4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/firmware.h>
 #include <linux/ihex.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include "drmP.h"
 #include "drm.h"
index 032a820981363c3d4422fba06ab93d7c8c0f1621..5fc201b49d3070721cade7821c3d259f15b5f441 100644 (file)
@@ -640,10 +640,9 @@ static int
 nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       uint32_t reg0 = nv_rd32(dev, reg + 0);
-       uint32_t reg1 = nv_rd32(dev, reg + 4);
        struct nouveau_pll_vals pll;
        struct pll_lims pll_limits;
+       u32 ctrl, mask, coef;
        int ret;
 
        ret = get_pll_limits(dev, reg, &pll_limits);
@@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
        if (!clk)
                return -ERANGE;
 
-       reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16);
-       reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1;
-
-       if (dev_priv->vbios.execute) {
-               still_alive();
-               nv_wr32(dev, reg + 4, reg1);
-               nv_wr32(dev, reg + 0, reg0);
+       coef = pll.N1 << 8 | pll.M1;
+       ctrl = pll.log2P << 16;
+       mask = 0x00070000;
+       if (reg == 0x004008) {
+               mask |= 0x01f80000;
+               ctrl |= (pll_limits.log2p_bias << 19);
+               ctrl |= (pll.log2P << 22);
        }
 
+       if (!dev_priv->vbios.execute)
+               return 0;
+
+       nv_mask(dev, reg + 0, mask, ctrl);
+       nv_wr32(dev, reg + 4, coef);
        return 0;
 }
 
index 7226f419e178b64e76d9a65a7d341f1de874b746..7cc37e69086012594a1dff3a2e255f66e396e656 100644 (file)
@@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
 
        if (dev_priv->card_type == NV_10 &&
            nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
-           nvbo->bo.mem.num_pages < vram_pages / 2) {
+           nvbo->bo.mem.num_pages < vram_pages / 4) {
                /*
                 * Make sure that the color and depth buffers are handled
                 * by independent memory controller units. Up to a 9x
index a319d5646ea9c98430eddab17c0a45f0f8307b3f..bb6ec9ef8676a6300f6de6fc221cc5b5c7c7199e 100644 (file)
@@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
        INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
        INIT_LIST_HEAD(&chan->nvsw.flip);
        INIT_LIST_HEAD(&chan->fence.pending);
+       spin_lock_init(&chan->fence.lock);
 
        /* setup channel's memory and vm */
        ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
index e0d275e1c96c05c302693c49b7093cde95eccc40..cea6696b19064e48a7c4f1e94bef793377962db8 100644 (file)
@@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
        case OUTPUT_DP:
                max_clock  = nv_encoder->dp.link_nr;
                max_clock *= nv_encoder->dp.link_bw;
-               clock = clock * nouveau_connector_bpp(connector) / 8;
+               clock = clock * nouveau_connector_bpp(connector) / 10;
                break;
        default:
                BUG_ON(1);
index ddbabefb4273ffa0fe071d49422dd448d21875d9..b12fd2c80812d002e0840787e8ff47481a3691a2 100644 (file)
@@ -369,3 +369,48 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
        spin_unlock_irqrestore(&dev->event_lock, flags);
        return 0;
 }
+
+int
+nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
+                           struct drm_mode_create_dumb *args)
+{
+       struct nouveau_bo *bo;
+       int ret;
+
+       args->pitch = roundup(args->width * (args->bpp / 8), 256);
+       args->size = args->pitch * args->height;
+       args->size = roundup(args->size, PAGE_SIZE);
+
+       ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo);
+       if (ret)
+               return ret;
+
+       ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle);
+       drm_gem_object_unreference_unlocked(bo->gem);
+       return ret;
+}
+
+int
+nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev,
+                            uint32_t handle)
+{
+       return drm_gem_handle_delete(file_priv, handle);
+}
+
+int
+nouveau_display_dumb_map_offset(struct drm_file *file_priv,
+                               struct drm_device *dev,
+                               uint32_t handle, uint64_t *poffset)
+{
+       struct drm_gem_object *gem;
+
+       gem = drm_gem_object_lookup(dev, file_priv, handle);
+       if (gem) {
+               struct nouveau_bo *bo = gem->driver_private;
+               *poffset = bo->bo.addr_space_offset;
+               drm_gem_object_unreference_unlocked(gem);
+               return 0;
+       }
+
+       return -ENOENT;
+}
index c1e01f37b9d19967291f77d4e19faa9840624bd5..9791d13c9e3b8d9d223bd5bb1cae182de4bc89ee 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/console.h>
+#include <linux/module.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -432,6 +433,10 @@ static struct drm_driver driver = {
        .gem_open_object = nouveau_gem_object_open,
        .gem_close_object = nouveau_gem_object_close,
 
+       .dumb_create = nouveau_display_dumb_create,
+       .dumb_map_offset = nouveau_display_dumb_map_offset,
+       .dumb_destroy = nouveau_display_dumb_destroy,
+
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
 #ifdef GIT_REVISION
index 29837da1098b3a85a50bbc9ee4ccc2b0a4901dab..4c0be3a4ed882f5430ea628ba4d80fef1f1d3690 100644 (file)
@@ -1418,6 +1418,12 @@ int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                           struct drm_pending_vblank_event *event);
 int nouveau_finish_page_flip(struct nouveau_channel *,
                             struct nouveau_page_flip_state *);
+int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
+                               struct drm_mode_create_dumb *args);
+int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
+                                   uint32_t handle, uint64_t *offset);
+int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
+                                uint32_t handle);
 
 /* nv10_gpio.c */
 int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
index 14a8627efe4d0499515d596cbaf665fbfbade690..3a4cc32b9e44c44f92fab174792778def49197f4 100644 (file)
@@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_fbdev *nfbdev;
+       int preferred_bpp;
        int ret;
 
        nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
@@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev)
        }
 
        drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
-       drm_fb_helper_initial_config(&nfbdev->helper, 32);
+
+       if (dev_priv->vram_size <= 32 * 1024 * 1024)
+               preferred_bpp = 8;
+       else if (dev_priv->vram_size <= 64 * 1024 * 1024)
+               preferred_bpp = 16;
+       else
+               preferred_bpp = 32;
+
+       drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);
        return 0;
 }
 
index 81116cfea275f70fc5011a23c4284b51fc2fcf4a..2f6daae68b9d7e24830bb9f2cc5e5af09cbe4f8b 100644 (file)
@@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
                        return ret;
        }
 
-       INIT_LIST_HEAD(&chan->fence.pending);
-       spin_lock_init(&chan->fence.lock);
        atomic_set(&chan->fence.last_sequence_irq, 0);
        return 0;
 }
index f6a27fabcfe028f4f224bf64ae01503b09a9bbc8..d39b2202b197521473129d8c5e3cf1ccd6d34031 100644 (file)
@@ -22,6 +22,8 @@
  * Authors: Ben Skeggs
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include "nouveau_i2c.h"
@@ -331,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what,
 
        NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
 
-       for (i = 0; info[i].addr; i++) {
+       for (i = 0; i2c && info[i].addr; i++) {
                if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
                    (!match || match(i2c, &info[i]))) {
                        NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
index 02222c540aee1a38f963dd13eeda7f0f7c7e8844..960c0ae0c0c3de650dac30beaec208b9bfd3558d 100644 (file)
@@ -680,7 +680,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
                return ret;
        }
 
-       ret = drm_mm_init(&chan->ramin_heap, base, size);
+       ret = drm_mm_init(&chan->ramin_heap, base, size - base);
        if (ret) {
                NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
                nouveau_gpuobj_ref(NULL, &chan->ramin);
index 9f178aa94162cdc69ac943066272fd3ba899a062..33d03fbf00df56c7523bf8909168d267f0a1d197 100644 (file)
@@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev)
        if(version == 0x15) {
                memtimings->timing =
                                kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL);
-               if(!memtimings) {
+               if (!memtimings->timing) {
                        NV_WARN(dev,"Could not allocate memtiming table\n");
                        return;
                }
index b75258a9fe44d544521431133ecd64ec0136637d..c8a463b76c89f03f96f68e48107d9993d2a2bda1 100644 (file)
@@ -67,7 +67,10 @@ nouveau_sgdma_clear(struct ttm_backend *be)
                        pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
                                       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
                }
+               nvbe->unmap_pages = false;
        }
+
+       nvbe->pages = NULL;
 }
 
 static void
index 82478e0998e5c7bb1109e17a37c90005491fddbf..d8831ab42bb90344a28b8a146624aa4aca69d8c5 100644 (file)
@@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_display_early;
 
+       /* workaround an odd issue on nvc1 by disabling the device's
+        * nosnoop capability.  hopefully won't cause issues until a
+        * better fix is found - assuming there is one...
+        */
+       if (dev_priv->chipset == 0xc1) {
+               nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
+       }
+
        nouveau_pm_init(dev);
 
        ret = engine->vram.init(dev);
@@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
        dev_priv->noaccel = !!nouveau_noaccel;
        if (nouveau_noaccel == -1) {
                switch (dev_priv->chipset) {
-               case 0xc1: /* known broken */
-               case 0xc8: /* never tested */
+#if 0
+               case 0xXX: /* known broken */
                        NV_INFO(dev, "acceleration disabled by default, pass "
                                     "noaccel=0 to force enable\n");
                        dev_priv->noaccel = true;
                        break;
+#endif
                default:
                        dev_priv->noaccel = false;
                        break;
index 081ca7b03e8aa53bbb692173f910862a55bc5950..5a46446dd5a8682e4773b8a0ff60724ef7de3514 100644 (file)
@@ -22,6 +22,8 @@
  * Authors: Martin Peres
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 
 #include "nouveau_drv.h"
index bbc0b9c7e1f7f53ba099c57a8c408024feb32fca..e676b0d534786ee140017691b83c4580e0e6bbc3 100644 (file)
@@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg)
        int P = (ctrl & 0x00070000) >> 16;
        u32 ref = 27000, clk = 0;
 
-       if (ctrl & 0x80000000)
+       if ((ctrl & 0x80000000) && M1) {
                clk = ref * N1 / M1;
-
-       if (!(ctrl & 0x00000100)) {
-               if (ctrl & 0x40000000)
-                       clk = clk * N2 / M2;
+               if ((ctrl & 0x40000100) == 0x40000000) {
+                       if (M2)
+                               clk = clk * N2 / M2;
+                       else
+                               clk = 0;
+               }
        }
 
        return clk >> P;
@@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
        }
 
        /* memory clock */
+       if (!perflvl->memory) {
+               info->mpll_ctrl = 0x00000000;
+               goto out;
+       }
+
        ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory,
                            &N1, &M1, &N2, &M2, &log2P);
        if (ret < 0)
@@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state)
        mdelay(5);
        nv_mask(dev, 0x00c040, 0x00000333, info->ctrl);
 
+       if (!info->mpll_ctrl)
+               goto resume;
+
        /* wait for vblank start on active crtcs, disable memory access */
        for (i = 0; i < 2; i++) {
                if (!(crtc_mask & (1 << i)))
index d23ca00e7d627c65e3814891c0a8aa0136f58395..06de250fe617df89ad4e05a34d3e05be8907f126 100644 (file)
@@ -616,7 +616,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nv50_display *disp = nv50_display(dev);
        u32 unk30 = nv_rd32(dev, 0x610030), mc;
-       int i, crtc, or, type = OUTPUT_ANY;
+       int i, crtc, or = 0, type = OUTPUT_ANY;
 
        NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
        disp->irq.dcb = NULL;
@@ -708,7 +708,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
        struct nv50_display *disp = nv50_display(dev);
        u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
        struct dcb_entry *dcb;
-       int i, crtc, or, type = OUTPUT_ANY;
+       int i, crtc, or = 0, type = OUTPUT_ANY;
 
        NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
        dcb = disp->irq.dcb;
index 8c979b31ff61b36bf8714fd6b5baa3bad58d268e..ac601f7c4e1a01c7175c9a201f3474e958ef98b7 100644 (file)
@@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine)
        NV_DEBUG(dev, "\n");
 
        /* master reset */
-       nv_mask(dev, 0x000200, 0x00200100, 0x00000000);
-       nv_mask(dev, 0x000200, 0x00200100, 0x00200100);
+       nv_mask(dev, 0x000200, 0x00201000, 0x00000000);
+       nv_mask(dev, 0x000200, 0x00201000, 0x00201000);
        nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
 
        /* reset/enable traps and interrupts */
index d05c2c3b244491001dbcba21c2d3dc32fc3a7d59..4b46d69685664fcc14f096c644395a43316a6421 100644 (file)
@@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                                        gr_def(ctx, offset + 0x1c, 0x00880000);
                                        break;
                                case 0x86:
-                                       gr_def(ctx, offset + 0x1c, 0x008c0000);
+                                       gr_def(ctx, offset + 0x1c, 0x018c0000);
                                        break;
                                case 0x92:
                                case 0x96:
index 9da23838e63e0d04d6e24f51e8a45e835cfb2979..2e45e57fd8698e03a2b8fdf3fcd04b69ddf86290 100644 (file)
@@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev)
        colbits  =  (r4 & 0x0000f000) >> 12;
        rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
        rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
-       banks    = ((r4 & 0x01000000) ? 8 : 4);
+       banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);
 
        rowsize = parts * banks * (1 << colbits) * 8;
        predicted = rowsize << rowbitsa;
index 4b8d0b3f7d2b1f38fb30fd1b9118916b23123b62..ecfafd70cf0ed2b6f9ee0b51c74031caa337de27 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/module.h>
 
 #include "drmP.h"
 
@@ -156,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
        struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
        struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
        struct drm_device *dev = chan->dev;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
        int i = 0, gpc, tp, ret;
-       u32 magic;
 
        ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,
                                 &grch->unk408004);
@@ -206,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
        nv_wo32(grch->mmio, i++ * 4, 0x0041880c);
        nv_wo32(grch->mmio, i++ * 4, 0x80000018);
 
-       magic = 0x02180000;
-       nv_wo32(grch->mmio, i++ * 4, 0x00405830);
-       nv_wo32(grch->mmio, i++ * 4, magic);
-       for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-               for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) {
-                       u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800);
-                       nv_wo32(grch->mmio, i++ * 4, reg);
-                       nv_wo32(grch->mmio, i++ * 4, magic);
+       if (dev_priv->chipset != 0xc1) {
+               u32 magic = 0x02180000;
+               nv_wo32(grch->mmio, i++ * 4, 0x00405830);
+               nv_wo32(grch->mmio, i++ * 4, magic);
+               for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+                       for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+                               u32 reg = TP_UNIT(gpc, tp, 0x520);
+                               nv_wo32(grch->mmio, i++ * 4, reg);
+                               nv_wo32(grch->mmio, i++ * 4, magic);
+                               magic += 0x0324;
+                       }
+               }
+       } else {
+               u32 magic = 0x02180000;
+               nv_wo32(grch->mmio, i++ * 4, 0x00405830);
+               nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218);
+               nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
+               nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
+               for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+                       for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+                               u32 reg = TP_UNIT(gpc, tp, 0x520);
+                               nv_wo32(grch->mmio, i++ * 4, reg);
+                               nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
+                               magic += 0x0324;
+                       }
+                       for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
+                               u32 reg = TP_UNIT(gpc, tp, 0x544);
+                               nv_wo32(grch->mmio, i++ * 4, reg);
+                               nv_wo32(grch->mmio, i++ * 4, magic);
+                               magic += 0x0324;
+                       }
                }
        }
 
@@ -357,6 +381,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
        u8  tpnr[GPC_MAX];
        int i, gpc, tpc;
 
+       nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
+
        /*
         *      TP      ROP UNKVAL(magic_not_rop_nr)
         * 450: 4/0/0/0 2        3
index dd0e6a736b3b9254933e2d58b51c0502bf353aa8..96b0b93d94ca8b11466145ddd2c2ce050eee5ffb 100644 (file)
@@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
                /* calculate first set of magics */
                memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
 
+               gpc = -1;
                for (tp = 0; tp < priv->tp_total; tp++) {
                        do {
                                gpc = (gpc + 1) % priv->gpc_nr;
@@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
 
        if (1) {
                u32 tp_mask = 0, tp_set = 0;
-               u8  tpnr[GPC_MAX];
+               u8  tpnr[GPC_MAX], a, b;
 
                memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
                for (gpc = 0; gpc < priv->gpc_nr; gpc++)
                        tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8);
 
-               gpc = -1;
-               for (i = 0, gpc = -1; i < 32; i++) {
-                       int ltp = i * (priv->tp_total - 1) / 32;
-
-                       do {
-                               gpc = (gpc + 1) % priv->gpc_nr;
-                       } while (!tpnr[gpc]);
-                       tp = priv->tp_nr[gpc] - tpnr[gpc]--;
+               for (i = 0, gpc = -1, b = -1; i < 32; i++) {
+                       a = (i * (priv->tp_total - 1)) / 32;
+                       if (a != b) {
+                               b = a;
+                               do {
+                                       gpc = (gpc + 1) % priv->gpc_nr;
+                               } while (!tpnr[gpc]);
+                               tp = priv->tp_nr[gpc] - tpnr[gpc]--;
 
-                       tp_set |= 1 << ((gpc * 8) + tp);
+                               tp_set |= 1 << ((gpc * 8) + tp);
+                       }
 
-                       do {
-                               nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
-                               tp_set ^= tp_mask;
-                               nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set);
-                               tp_set ^= tp_mask;
-                       } while (ltp == (++i * (priv->tp_total - 1) / 32));
-                       i--;
+                       nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
+                       nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);
                }
        }
 
index edbfe9360ae2f0a2703176c0ea1fcd1dfeed83a0..ce984d573a51d03bb6df5b6cc171ed4721a60533 100644 (file)
@@ -43,7 +43,7 @@ static const u8 types[256] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-       3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
+       3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
        3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
        3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
@@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev)
        u32 bsize = nv_rd32(dev, 0x10f20c);
        u32 offset, length;
        bool uniform = true;
-       int ret, i;
+       int ret, part;
 
        NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
        NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize);
 
        /* read amount of vram attached to each memory controller */
-       for (i = 0; i < parts; i++) {
-               u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000));
+       part = 0;
+       while (parts) {
+               u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000));
+               if (psize == 0)
+                       continue;
+               parts--;
+
                if (psize != bsize) {
                        if (psize < bsize)
                                bsize = psize;
                        uniform = false;
                }
 
-               NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize);
-
+               NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
                dev_priv->vram_size += (u64)psize << 20;
        }
 
index 23d63b4b3d77078ce4a351f82b8d7cba16d280b7..cb006a718e700f2c72cf06dfdac0c7f22e8cbdac 100644 (file)
@@ -780,7 +780,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
                        continue;
 
                if (nv_partner != nv_encoder &&
-                   nv_partner->dcb->or == nv_encoder->or) {
+                   nv_partner->dcb->or == nv_encoder->dcb->or) {
                        if (nv_partner->last_dpms == DRM_MODE_DPMS_ON)
                                return;
                        break;
index 570e190710bd0cb0afa4ed36b1a5cb22f940197b..bcac90b543ad02f78c88cbb8e6dc6718e5e7bc21 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "drmP.h"
 #include "drm.h"
index b9e8efd2b754744efe29867bdbdbd701b74a381f..4c8796ba6dd8d3adf07f0760c436b6b55dfba7f9 100644 (file)
@@ -29,6 +29,8 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
index 9f363e0c4b6082561295eb5f5e8a78559e42dccd..cf8b4bc3e73ddfc6804beba647fb4a8b1988ccc6 100644 (file)
@@ -70,7 +70,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
        r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
        r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
        evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
-       radeon_trace_points.o ni.o cayman_blit_shaders.o
+       radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
index a515b2a09d856c1c49d2a38096dda8c76ccc92b5..2b97262e3ab14af5af32b4d85711828563450b09 100644 (file)
@@ -558,7 +558,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                bpc = connector->display_info.bpc;
                        encoder_mode = atombios_get_encoder_mode(encoder);
                        if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
-                           radeon_encoder_is_dp_bridge(encoder)) {
+                           (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
                                if (connector) {
                                        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
                                        struct radeon_connector_atom_dig *dig_connector =
@@ -638,44 +638,29 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                if (ss_enabled && ss->percentage)
                                        args.v3.sInput.ucDispPllConfig |=
                                                DISPPLL_CONFIG_SS_ENABLE;
-                               if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) ||
-                                   radeon_encoder_is_dp_bridge(encoder)) {
+                               if (ENCODER_MODE_IS_DP(encoder_mode)) {
+                                       args.v3.sInput.ucDispPllConfig |=
+                                               DISPPLL_CONFIG_COHERENT_MODE;
+                                       /* 16200 or 27000 */
+                                       args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
+                               } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                                        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-                                       if (encoder_mode == ATOM_ENCODER_MODE_DP) {
+                                       if (encoder_mode == ATOM_ENCODER_MODE_HDMI)
+                                               /* deep color support */
+                                               args.v3.sInput.usPixelClock =
+                                                       cpu_to_le16((mode->clock * bpc / 8) / 10);
+                                       if (dig->coherent_mode)
                                                args.v3.sInput.ucDispPllConfig |=
                                                        DISPPLL_CONFIG_COHERENT_MODE;
-                                               /* 16200 or 27000 */
-                                               args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
-                                       } else {
-                                               if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
-                                                       /* deep color support */
-                                                       args.v3.sInput.usPixelClock =
-                                                               cpu_to_le16((mode->clock * bpc / 8) / 10);
-                                               }
-                                               if (dig->coherent_mode)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_COHERENT_MODE;
-                                               if (mode->clock > 165000)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_DUAL_LINK;
-                                       }
-                               } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                                       if (encoder_mode == ATOM_ENCODER_MODE_DP) {
+                                       if (mode->clock > 165000)
                                                args.v3.sInput.ucDispPllConfig |=
-                                                       DISPPLL_CONFIG_COHERENT_MODE;
-                                               /* 16200 or 27000 */
-                                               args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
-                                       } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) {
-                                               if (mode->clock > 165000)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_DUAL_LINK;
-                                       }
+                                                       DISPPLL_CONFIG_DUAL_LINK;
                                }
-                               if (radeon_encoder_is_dp_bridge(encoder)) {
-                                       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-                                       struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
-                                       args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id;
-                               else
+                               if (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
+                                   ENCODER_OBJECT_ID_NONE)
+                                       args.v3.sInput.ucExtTransmitterID =
+                                               radeon_encoder_get_dp_bridge_encoder_id(encoder);
+                               else
                                        args.v3.sInput.ucExtTransmitterID = 0;
 
                                atom_execute_table(rdev->mode_info.atom_context,
@@ -945,6 +930,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
                bpc = connector->display_info.bpc;
 
                switch (encoder_mode) {
+               case ATOM_ENCODER_MODE_DP_MST:
                case ATOM_ENCODER_MODE_DP:
                        /* DP/eDP */
                        dp_clock = dig_connector->dp_clock / 10;
@@ -1121,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
                return -EINVAL;
        }
 
-       if (tiling_flags & RADEON_TILING_MACRO)
+       if (tiling_flags & RADEON_TILING_MACRO) {
+               if (rdev->family >= CHIP_CAYMAN)
+                       tmp = rdev->config.cayman.tile_config;
+               else
+                       tmp = rdev->config.evergreen.tile_config;
+
+               switch ((tmp & 0xf0) >> 4) {
+               case 0: /* 4 banks */
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
+                       break;
+               case 1: /* 8 banks */
+               default:
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
+                       break;
+               case 2: /* 16 banks */
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
+                       break;
+               }
+
+               switch ((tmp & 0xf000) >> 12) {
+               case 0: /* 1KB rows */
+               default:
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
+                       break;
+               case 1: /* 2KB rows */
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
+                       break;
+               case 2: /* 4KB rows */
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
+                       break;
+               }
+
                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
-       else if (tiling_flags & RADEON_TILING_MICRO)
+       else if (tiling_flags & RADEON_TILING_MICRO)
                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
 
        switch (radeon_crtc->crtc_id) {
@@ -1450,7 +1467,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                                 * PPLL/DCPLL programming and only program the DP DTO for the
                                 * crtc virtual pixel clock.
                                 */
-                               if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
+                               if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
                                        if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk)
                                                return ATOM_PPLL_INVALID;
                                }
@@ -1536,12 +1553,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
                                     struct drm_display_mode *mode,
                                     struct drm_display_mode *adjusted_mode)
 {
-       struct drm_device *dev = crtc->dev;
-       struct radeon_device *rdev = dev->dev_private;
-
-       /* adjust pm to upcoming mode change */
-       radeon_pm_compute_clocks(rdev);
-
        if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
                return false;
        return true;
index 79e8ebc0530723e9df8a8aa5f448b3b8068fab62..6fb335a4fddafee8bdf3bfc0bbe48e54df265106 100644 (file)
@@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
                }
        }
 
-       DRM_ERROR("aux i2c too many retries, giving up\n");
+       DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
        return -EREMOTEIO;
 }
 
@@ -482,7 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
        int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
        int lane_num, max_pix_clock;
 
-       if (radeon_connector_encoder_is_dp_bridge(connector))
+       if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+           ENCODER_OBJECT_ID_NUTMEG)
                return 270000;
 
        lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
@@ -553,17 +554,32 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_device *rdev = dev->dev_private;
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
 
        if (!ASIC_IS_DCE4(rdev))
                return;
 
-       if (radeon_connector_encoder_is_dp_bridge(connector))
+       if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+           ENCODER_OBJECT_ID_NUTMEG)
                panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+       else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+                ENCODER_OBJECT_ID_TRAVIS)
+               panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+       else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+               u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
+               if (tmp & 1)
+                       panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+       }
 
        atombios_dig_encoder_setup(encoder,
                                   ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
                                   panel_mode);
+
+       if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
+           (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
+               radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
+       }
 }
 
 void radeon_dp_set_link_config(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
new file mode 100644 (file)
index 0000000..39c04c1
--- /dev/null
@@ -0,0 +1,2369 @@
+/*
+ * Copyright 2007-11 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ */
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+#include "atom.h"
+
+extern int atom_debug;
+
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+                               struct drm_display_mode *mode);
+
+
+static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_connector *connector;
+       struct radeon_connector *radeon_connector;
+
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               radeon_connector = to_radeon_connector(connector);
+               if (radeon_encoder->devices & radeon_connector->devices)
+                       return connector;
+       }
+       return NULL;
+}
+
+static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
+                                  struct drm_display_mode *mode,
+                                  struct drm_display_mode *adjusted_mode)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+
+       /* set the active encoder to connector routing */
+       radeon_encoder_set_active_device(encoder);
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+       /* hw bug */
+       if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
+           && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
+               adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
+
+       /* get the native mode for LVDS */
+       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+               radeon_panel_mode_fixup(encoder, adjusted_mode);
+
+       /* get the native mode for TV */
+       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+               if (tv_dac) {
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J ||
+                           tv_dac->tv_std == TV_STD_PAL_M)
+                               radeon_atom_get_tv_timings(rdev, 0, adjusted_mode);
+                       else
+                               radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);
+               }
+       }
+
+       if (ASIC_IS_DCE3(rdev) &&
+           ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
+            (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) {
+               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+               radeon_dp_set_link_config(connector, mode);
+       }
+
+       return true;
+}
+
+static void
+atombios_dac_setup(struct drm_encoder *encoder, int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       DAC_ENCODER_CONTROL_PS_ALLOCATION args;
+       int index = 0;
+       struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
+
+       memset(&args, 0, sizeof(args));
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+               index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
+               break;
+       }
+
+       args.ucAction = action;
+
+       if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT))
+               args.ucDacStandard = ATOM_DAC1_PS2;
+       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+               args.ucDacStandard = ATOM_DAC1_CV;
+       else {
+               switch (dac_info->tv_std) {
+               case TV_STD_PAL:
+               case TV_STD_PAL_M:
+               case TV_STD_SCART_PAL:
+               case TV_STD_SECAM:
+               case TV_STD_PAL_CN:
+                       args.ucDacStandard = ATOM_DAC1_PAL;
+                       break;
+               case TV_STD_NTSC:
+               case TV_STD_NTSC_J:
+               case TV_STD_PAL_60:
+               default:
+                       args.ucDacStandard = ATOM_DAC1_NTSC;
+                       break;
+               }
+       }
+       args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+}
+
+static void
+atombios_tv_setup(struct drm_encoder *encoder, int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       TV_ENCODER_CONTROL_PS_ALLOCATION args;
+       int index = 0;
+       struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
+
+       memset(&args, 0, sizeof(args));
+
+       index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
+
+       args.sTVEncoder.ucAction = action;
+
+       if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+               args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
+       else {
+               switch (dac_info->tv_std) {
+               case TV_STD_NTSC:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
+                       break;
+               case TV_STD_PAL:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
+                       break;
+               case TV_STD_PAL_M:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
+                       break;
+               case TV_STD_PAL_60:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
+                       break;
+               case TV_STD_NTSC_J:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
+                       break;
+               case TV_STD_SCART_PAL:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
+                       break;
+               case TV_STD_SECAM:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
+                       break;
+               case TV_STD_PAL_CN:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
+                       break;
+               default:
+                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
+                       break;
+               }
+       }
+
+       args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+}
+
+union dvo_encoder_control {
+       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+};
+
+void
+atombios_dvo_setup(struct drm_encoder *encoder, int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       union dvo_encoder_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+       uint8_t frev, crev;
+
+       memset(&args, 0, sizeof(args));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               switch (crev) {
+               case 1:
+                       /* R4xx, R5xx */
+                       args.ext_tmds.sXTmdsEncoder.ucEnable = action;
+
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
+
+                       args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
+                       break;
+               case 2:
+                       /* RS600/690/740 */
+                       args.dvo.sDVOEncoder.ucAction = action;
+                       args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       /* DFP1, CRT1, TV1 depending on the type of port */
+                       args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
+
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
+                       break;
+               case 3:
+                       /* R6xx */
+                       args.dvo_v3.ucAction = action;
+                       args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.dvo_v3.ucDVOConfig = 0; /* XXX */
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+               break;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+union lvds_encoder_control {
+       LVDS_ENCODER_CONTROL_PS_ALLOCATION    v1;
+       LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
+};
+
+void
+atombios_digital_setup(struct drm_encoder *encoder, int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+       union lvds_encoder_control args;
+       int index = 0;
+       int hdmi_detected = 0;
+       uint8_t frev, crev;
+
+       if (!dig)
+               return;
+
+       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+               hdmi_detected = 1;
+
+       memset(&args, 0, sizeof(args));
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+               index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+               index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
+               break;
+       }
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+       case 2:
+               switch (crev) {
+               case 1:
+                       args.v1.ucMisc = 0;
+                       args.v1.ucAction = action;
+                       if (hdmi_detected)
+                               args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
+                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
+                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
+                               if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
+                                       args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
+                       } else {
+                               if (dig->linkb)
+                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
+                               /*if (pScrn->rgbBits == 8) */
+                               args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
+                       }
+                       break;
+               case 2:
+               case 3:
+                       args.v2.ucMisc = 0;
+                       args.v2.ucAction = action;
+                       if (crev == 3) {
+                               if (dig->coherent_mode)
+                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
+                       }
+                       if (hdmi_detected)
+                               args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
+                       args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.v2.ucTruncate = 0;
+                       args.v2.ucSpatial = 0;
+                       args.v2.ucTemporal = 0;
+                       args.v2.ucFRC = 0;
+                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                               if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
+                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
+                               if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) {
+                                       args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
+                                       if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
+                                               args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
+                               }
+                               if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) {
+                                       args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
+                                       if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
+                                               args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
+                                       if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)
+                                               args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
+                               }
+                       } else {
+                               if (dig->linkb)
+                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
+                       }
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+               break;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+int
+atombios_get_encoder_mode(struct drm_encoder *encoder)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_connector *connector;
+       struct radeon_connector *radeon_connector;
+       struct radeon_connector_atom_dig *dig_connector;
+
+       /* dp bridges are always DP */
+       if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)
+               return ATOM_ENCODER_MODE_DP;
+
+       /* DVO is always DVO */
+       if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO)
+               return ATOM_ENCODER_MODE_DVO;
+
+       connector = radeon_get_connector_for_encoder(encoder);
+       /* if we don't have an active device yet, just use one of
+        * the connectors tied to the encoder.
+        */
+       if (!connector)
+               connector = radeon_get_connector_for_encoder_init(encoder);
+       radeon_connector = to_radeon_connector(connector);
+
+       switch (connector->connector_type) {
+       case DRM_MODE_CONNECTOR_DVII:
+       case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
+               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
+                       /* fix me */
+                       if (ASIC_IS_DCE4(rdev))
+                               return ATOM_ENCODER_MODE_DVI;
+                       else
+                               return ATOM_ENCODER_MODE_HDMI;
+               } else if (radeon_connector->use_digital)
+                       return ATOM_ENCODER_MODE_DVI;
+               else
+                       return ATOM_ENCODER_MODE_CRT;
+               break;
+       case DRM_MODE_CONNECTOR_DVID:
+       case DRM_MODE_CONNECTOR_HDMIA:
+       default:
+               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
+                       /* fix me */
+                       if (ASIC_IS_DCE4(rdev))
+                               return ATOM_ENCODER_MODE_DVI;
+                       else
+                               return ATOM_ENCODER_MODE_HDMI;
+               } else
+                       return ATOM_ENCODER_MODE_DVI;
+               break;
+       case DRM_MODE_CONNECTOR_LVDS:
+               return ATOM_ENCODER_MODE_LVDS;
+               break;
+       case DRM_MODE_CONNECTOR_DisplayPort:
+               dig_connector = radeon_connector->con_priv;
+               if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+                   (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+                       return ATOM_ENCODER_MODE_DP;
+               else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
+                       /* fix me */
+                       if (ASIC_IS_DCE4(rdev))
+                               return ATOM_ENCODER_MODE_DVI;
+                       else
+                               return ATOM_ENCODER_MODE_HDMI;
+               } else
+                       return ATOM_ENCODER_MODE_DVI;
+               break;
+       case DRM_MODE_CONNECTOR_eDP:
+               return ATOM_ENCODER_MODE_DP;
+       case DRM_MODE_CONNECTOR_DVIA:
+       case DRM_MODE_CONNECTOR_VGA:
+               return ATOM_ENCODER_MODE_CRT;
+               break;
+       case DRM_MODE_CONNECTOR_Composite:
+       case DRM_MODE_CONNECTOR_SVIDEO:
+       case DRM_MODE_CONNECTOR_9PinDIN:
+               /* fix me */
+               return ATOM_ENCODER_MODE_TV;
+               /*return ATOM_ENCODER_MODE_CV;*/
+               break;
+       }
+}
+
+/*
+ * DIG Encoder/Transmitter Setup
+ *
+ * DCE 3.0/3.1
+ * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
+ * Supports up to 3 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1 can drive UNIPHY link A or link B
+ * DIG2 can drive UNIPHY link B or LVTMA
+ *
+ * DCE 3.2
+ * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
+ * Supports up to 5 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1/2 can drive UNIPHY0/1/2 link A or link B
+ *
+ * DCE 4.0/5.0
+ * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
+ * Supports up to 6 digital outputs
+ * - 6 DIG encoder blocks.
+ * - DIG to PHY mapping is hardcoded
+ * DIG1 drives UNIPHY0 link A, A+B
+ * DIG2 drives UNIPHY0 link B
+ * DIG3 drives UNIPHY1 link A, A+B
+ * DIG4 drives UNIPHY1 link B
+ * DIG5 drives UNIPHY2 link A, A+B
+ * DIG6 drives UNIPHY2 link B
+ *
+ * DCE 4.1
+ * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
+ * Supports up to 6 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1/2 can drive UNIPHY0/1/2 link A or link B
+ *
+ * Routing
+ * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
+ * Examples:
+ * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI
+ * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP
+ * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
+ * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
+ */
+
+union dig_encoder_control {
+       DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
+       DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
+       DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
+       DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;
+};
+
+void
+atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       union dig_encoder_control args;
+       int index = 0;
+       uint8_t frev, crev;
+       int dp_clock = 0;
+       int dp_lane_count = 0;
+       int hpd_id = RADEON_HPD_NONE;
+       int bpc = 8;
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               struct radeon_connector_atom_dig *dig_connector =
+                       radeon_connector->con_priv;
+
+               dp_clock = dig_connector->dp_clock;
+               dp_lane_count = dig_connector->dp_lane_count;
+               hpd_id = radeon_connector->hpd.hpd;
+               bpc = connector->display_info.bpc;
+       }
+
+       /* no dig encoder assigned */
+       if (dig->dig_encoder == -1)
+               return;
+
+       memset(&args, 0, sizeof(args));
+
+       if (ASIC_IS_DCE4(rdev))
+               index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
+       else {
+               if (dig->dig_encoder)
+                       index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+       }
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               switch (crev) {
+               case 1:
+                       args.v1.ucAction = action;
+                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
+                               args.v3.ucPanelMode = panel_mode;
+                       else
+                               args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+                               args.v1.ucLaneNum = dp_lane_count;
+                       else if (radeon_encoder->pixel_clock > 165000)
+                               args.v1.ucLaneNum = 8;
+                       else
+                               args.v1.ucLaneNum = 4;
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                               args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+                               args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                               args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+                               break;
+                       }
+                       if (dig->linkb)
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+                       else
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+                       break;
+               case 2:
+               case 3:
+                       args.v3.ucAction = action;
+                       args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
+                               args.v3.ucPanelMode = panel_mode;
+                       else
+                               args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+                               args.v3.ucLaneNum = dp_lane_count;
+                       else if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.ucLaneNum = 8;
+                       else
+                               args.v3.ucLaneNum = 4;
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
+                       args.v3.acConfig.ucDigSel = dig->dig_encoder;
+                       switch (bpc) {
+                       case 0:
+                               args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
+                               break;
+                       case 6:
+                               args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+                               break;
+                       case 8:
+                       default:
+                               args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                               break;
+                       case 10:
+                               args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+                               break;
+                       case 12:
+                               args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+                               break;
+                       case 16:
+                               args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+                               break;
+                       }
+                       break;
+               case 4:
+                       args.v4.ucAction = action;
+                       args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
+                               args.v4.ucPanelMode = panel_mode;
+                       else
+                               args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+                               args.v4.ucLaneNum = dp_lane_count;
+                       else if (radeon_encoder->pixel_clock > 165000)
+                               args.v4.ucLaneNum = 8;
+                       else
+                               args.v4.ucLaneNum = 4;
+
+                       if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) {
+                               if (dp_clock == 270000)
+                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
+                               else if (dp_clock == 540000)
+                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
+                       }
+                       args.v4.acConfig.ucDigSel = dig->dig_encoder;
+                       switch (bpc) {
+                       case 0:
+                               args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
+                               break;
+                       case 6:
+                               args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+                               break;
+                       case 8:
+                       default:
+                               args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                               break;
+                       case 10:
+                               args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+                               break;
+                       case 12:
+                               args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+                               break;
+                       case 16:
+                               args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+                               break;
+                       }
+                       if (hpd_id == RADEON_HPD_NONE)
+                               args.v4.ucHPD_ID = 0;
+                       else
+                               args.v4.ucHPD_ID = hpd_id + 1;
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+               break;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+}
+
+union dig_transmitter_control {
+       DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
+       DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
+       DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
+       DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
+};
+
+void
+atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+       struct drm_connector *connector;
+       union dig_transmitter_control args;
+       int index = 0;
+       uint8_t frev, crev;
+       bool is_dp = false;
+       int pll_id = 0;
+       int dp_clock = 0;
+       int dp_lane_count = 0;
+       int connector_object_id = 0;
+       int igp_lane_info = 0;
+       int dig_encoder = dig->dig_encoder;
+
+       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+               connector = radeon_get_connector_for_encoder_init(encoder);
+               /* just needed to avoid bailing in the encoder check.  the encoder
+                * isn't used for init
+                */
+               dig_encoder = 0;
+       } else
+               connector = radeon_get_connector_for_encoder(encoder);
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               struct radeon_connector_atom_dig *dig_connector =
+                       radeon_connector->con_priv;
+
+               dp_clock = dig_connector->dp_clock;
+               dp_lane_count = dig_connector->dp_lane_count;
+               connector_object_id =
+                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+               igp_lane_info = dig_connector->igp_lane_info;
+       }
+
+       if (encoder->crtc) {
+               struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+               pll_id = radeon_crtc->pll_id;
+       }
+
+       /* no dig encoder assigned */
+       if (dig_encoder == -1)
+               return;
+
+       if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)))
+               is_dp = true;
+
+       memset(&args, 0, sizeof(args));
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl);
+               break;
+       }
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               switch (crev) {
+               case 1:
+                       args.v1.ucAction = action;
+                       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+                               args.v1.usInitInfo = cpu_to_le16(connector_object_id);
+                       } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+                               args.v1.asMode.ucLaneSel = lane_num;
+                               args.v1.asMode.ucLaneSet = lane_set;
+                       } else {
+                               if (is_dp)
+                                       args.v1.usPixelClock =
+                                               cpu_to_le16(dp_clock / 10);
+                               else if (radeon_encoder->pixel_clock > 165000)
+                                       args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+                               else
+                                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       }
+
+                       args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
+
+                       if (dig_encoder)
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+                       else
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+
+                       if ((rdev->flags & RADEON_IS_IGP) &&
+                           (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
+                               if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+                                       if (igp_lane_info & 0x1)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+                                       else if (igp_lane_info & 0x2)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+                                       else if (igp_lane_info & 0x4)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+                                       else if (igp_lane_info & 0x8)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+                               } else {
+                                       if (igp_lane_info & 0x3)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+                                       else if (igp_lane_info & 0xc)
+                                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
+                               }
+                       }
+
+                       if (dig->linkb)
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
+                       else
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+
+                       if (is_dp)
+                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+                       else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+                               if (dig->coherent_mode)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
+                       }
+                       break;
+               case 2:
+                       args.v2.ucAction = action;
+                       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+                               args.v2.usInitInfo = cpu_to_le16(connector_object_id);
+                       } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+                               args.v2.asMode.ucLaneSel = lane_num;
+                               args.v2.asMode.ucLaneSet = lane_set;
+                       } else {
+                               if (is_dp)
+                                       args.v2.usPixelClock =
+                                               cpu_to_le16(dp_clock / 10);
+                               else if (radeon_encoder->pixel_clock > 165000)
+                                       args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+                               else
+                                       args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       }
+
+                       args.v2.acConfig.ucEncoderSel = dig_encoder;
+                       if (dig->linkb)
+                               args.v2.acConfig.ucLinkSel = 1;
+
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                               args.v2.acConfig.ucTransmitterSel = 0;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                               args.v2.acConfig.ucTransmitterSel = 1;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                               args.v2.acConfig.ucTransmitterSel = 2;
+                               break;
+                       }
+
+                       if (is_dp) {
+                               args.v2.acConfig.fCoherentMode = 1;
+                               args.v2.acConfig.fDPConnector = 1;
+                       } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+                               if (dig->coherent_mode)
+                                       args.v2.acConfig.fCoherentMode = 1;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v2.acConfig.fDualLinkConnector = 1;
+                       }
+                       break;
+               case 3:
+                       args.v3.ucAction = action;
+                       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+                               args.v3.usInitInfo = cpu_to_le16(connector_object_id);
+                       } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+                               args.v3.asMode.ucLaneSel = lane_num;
+                               args.v3.asMode.ucLaneSet = lane_set;
+                       } else {
+                               if (is_dp)
+                                       args.v3.usPixelClock =
+                                               cpu_to_le16(dp_clock / 10);
+                               else if (radeon_encoder->pixel_clock > 165000)
+                                       args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+                               else
+                                       args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       }
+
+                       if (is_dp)
+                               args.v3.ucLaneNum = dp_lane_count;
+                       else if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.ucLaneNum = 8;
+                       else
+                               args.v3.ucLaneNum = 4;
+
+                       if (dig->linkb)
+                               args.v3.acConfig.ucLinkSel = 1;
+                       if (dig_encoder & 1)
+                               args.v3.acConfig.ucEncoderSel = 1;
+
+                       /* Select the PLL for the PHY
+                        * DP PHY should be clocked from external src if there is
+                        * one.
+                        */
+                       /* On DCE4, if there is an external clock, it generates the DP ref clock */
+                       if (is_dp && rdev->clock.dp_extclk)
+                               args.v3.acConfig.ucRefClkSource = 2; /* external src */
+                       else
+                               args.v3.acConfig.ucRefClkSource = pll_id;
+
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                               args.v3.acConfig.ucTransmitterSel = 0;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                               args.v3.acConfig.ucTransmitterSel = 1;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                               args.v3.acConfig.ucTransmitterSel = 2;
+                               break;
+                       }
+
+                       if (is_dp)
+                               args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */
+                       else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+                               if (dig->coherent_mode)
+                                       args.v3.acConfig.fCoherentMode = 1;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v3.acConfig.fDualLinkConnector = 1;
+                       }
+                       break;
+               case 4:
+                       args.v4.ucAction = action;
+                       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+                               args.v4.usInitInfo = cpu_to_le16(connector_object_id);
+                       } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+                               args.v4.asMode.ucLaneSel = lane_num;
+                               args.v4.asMode.ucLaneSet = lane_set;
+                       } else {
+                               if (is_dp)
+                                       args.v4.usPixelClock =
+                                               cpu_to_le16(dp_clock / 10);
+                               else if (radeon_encoder->pixel_clock > 165000)
+                                       args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+                               else
+                                       args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       }
+
+                       if (is_dp)
+                               args.v4.ucLaneNum = dp_lane_count;
+                       else if (radeon_encoder->pixel_clock > 165000)
+                               args.v4.ucLaneNum = 8;
+                       else
+                               args.v4.ucLaneNum = 4;
+
+                       if (dig->linkb)
+                               args.v4.acConfig.ucLinkSel = 1;
+                       if (dig_encoder & 1)
+                               args.v4.acConfig.ucEncoderSel = 1;
+
+                       /* Select the PLL for the PHY
+                        * DP PHY should be clocked from external src if there is
+                        * one.
+                        */
+                       /* On DCE5 DCPLL usually generates the DP ref clock */
+                       if (is_dp) {
+                               if (rdev->clock.dp_extclk)
+                                       args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK;
+                               else
+                                       args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL;
+                       } else
+                               args.v4.acConfig.ucRefClkSource = pll_id;
+
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                               args.v4.acConfig.ucTransmitterSel = 0;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                               args.v4.acConfig.ucTransmitterSel = 1;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                               args.v4.acConfig.ucTransmitterSel = 2;
+                               break;
+                       }
+
+                       if (is_dp)
+                               args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */
+                       else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+                               if (dig->coherent_mode)
+                                       args.v4.acConfig.fCoherentMode = 1;
+                               if (radeon_encoder->pixel_clock > 165000)
+                                       args.v4.acConfig.fDualLinkConnector = 1;
+                       }
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+               break;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+bool
+atombios_set_edp_panel_power(struct drm_connector *connector, int action)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_device *dev = radeon_connector->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       union dig_transmitter_control args;
+       int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+       uint8_t frev, crev;
+
+       if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+               goto done;
+
+       if (!ASIC_IS_DCE4(rdev))
+               goto done;
+
+       if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) &&
+           (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
+               goto done;
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               goto done;
+
+       memset(&args, 0, sizeof(args));
+
+       args.v1.ucAction = action;
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       /* wait for the panel to power up */
+       if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {
+               int i;
+
+               for (i = 0; i < 300; i++) {
+                       if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
+                               return true;
+                       mdelay(1);
+               }
+               return false;
+       }
+done:
+       return true;
+}
+
+union external_encoder_control {
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
+       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
+};
+
+static void
+atombios_external_encoder_setup(struct drm_encoder *encoder,
+                               struct drm_encoder *ext_encoder,
+                               int action)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
+       union external_encoder_control args;
+       struct drm_connector *connector;
+       int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
+       u8 frev, crev;
+       int dp_clock = 0;
+       int dp_lane_count = 0;
+       int connector_object_id = 0;
+       u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+       int bpc = 8;
+
+       if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
+               connector = radeon_get_connector_for_encoder_init(encoder);
+       else
+               connector = radeon_get_connector_for_encoder(encoder);
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               struct radeon_connector_atom_dig *dig_connector =
+                       radeon_connector->con_priv;
+
+               dp_clock = dig_connector->dp_clock;
+               dp_lane_count = dig_connector->dp_lane_count;
+               connector_object_id =
+                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+               bpc = connector->display_info.bpc;
+       }
+
+       memset(&args, 0, sizeof(args));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               /* no params on frev 1 */
+               break;
+       case 2:
+               switch (crev) {
+               case 1:
+               case 2:
+                       args.v1.sDigEncoder.ucAction = action;
+                       args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) {
+                               if (dp_clock == 270000)
+                                       args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+                               args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
+                       } else if (radeon_encoder->pixel_clock > 165000)
+                               args.v1.sDigEncoder.ucLaneNum = 8;
+                       else
+                               args.v1.sDigEncoder.ucLaneNum = 4;
+                       break;
+               case 3:
+                       args.v3.sExtEncoder.ucAction = action;
+                       if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
+                               args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id);
+                       else
+                               args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+                       if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) {
+                               if (dp_clock == 270000)
+                                       args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
+                               else if (dp_clock == 540000)
+                                       args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
+                               args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
+                       } else if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.sExtEncoder.ucLaneNum = 8;
+                       else
+                               args.v3.sExtEncoder.ucLaneNum = 4;
+                       switch (ext_enum) {
+                       case GRAPH_OBJECT_ENUM_ID1:
+                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
+                               break;
+                       case GRAPH_OBJECT_ENUM_ID2:
+                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
+                               break;
+                       case GRAPH_OBJECT_ENUM_ID3:
+                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
+                               break;
+                       }
+                       switch (bpc) {
+                       case 0:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE;
+                               break;
+                       case 6:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+                               break;
+                       case 8:
+                       default:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+                               break;
+                       case 10:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+                               break;
+                       case 12:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+                               break;
+                       case 16:
+                               args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+                               break;
+                       }
+                       break;
+               default:
+                       DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+                       return;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+               return;
+       }
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+static void
+atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+       ENABLE_YUV_PS_ALLOCATION args;
+       int index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
+       uint32_t temp, reg;
+
+       memset(&args, 0, sizeof(args));
+
+       if (rdev->family >= CHIP_R600)
+               reg = R600_BIOS_3_SCRATCH;
+       else
+               reg = RADEON_BIOS_3_SCRATCH;
+
+       /* XXX: fix up scratch reg handling */
+       temp = RREG32(reg);
+       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+               WREG32(reg, (ATOM_S3_TV1_ACTIVE |
+                            (radeon_crtc->crtc_id << 18)));
+       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+               WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
+       else
+               WREG32(reg, 0);
+
+       if (enable)
+               args.ucEnable = ATOM_ENABLE;
+       args.ucCRTC = radeon_crtc->crtc_id;
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       WREG32(reg, temp);
+}
+
+static void
+radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
+       int index = 0;
+
+       memset(&args, 0, sizeof(args));
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+               index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+               index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                       index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+               else
+                       index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+               break;
+       default:
+               return;
+       }
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               args.ucAction = ATOM_ENABLE;
+               /* workaround for DVOOutputControl on some RS690 systems */
+               if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) {
+                       u32 reg = RREG32(RADEON_BIOS_3_SCRATCH);
+                       WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE);
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+                       WREG32(RADEON_BIOS_3_SCRATCH, reg);
+               } else
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       args.ucAction = ATOM_LCD_BLON;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               }
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               args.ucAction = ATOM_DISABLE;
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       args.ucAction = ATOM_LCD_BLOFF;
+                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+               }
+               break;
+       }
+}
+
+static void
+radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+       struct radeon_connector *radeon_connector = NULL;
+       struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
+
+       if (connector) {
+               radeon_connector = to_radeon_connector(connector);
+               radeon_dig_connector = radeon_connector->con_priv;
+       }
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               /* some early dce3.2 boards have a bug in their transmitter control table */
+               if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+               else
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+               if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
+                       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+                               atombios_set_edp_panel_power(connector,
+                                                            ATOM_TRANSMITTER_ACTION_POWER_ON);
+                               radeon_dig_connector->edp_on = true;
+                       }
+                       if (ASIC_IS_DCE4(rdev))
+                               atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
+                       radeon_dp_link_train(encoder, connector);
+                       if (ASIC_IS_DCE4(rdev))
+                               atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
+               }
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+               if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
+                       if (ASIC_IS_DCE4(rdev))
+                               atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
+                       if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+                               atombios_set_edp_panel_power(connector,
+                                                            ATOM_TRANSMITTER_ACTION_POWER_OFF);
+                               radeon_dig_connector->edp_on = false;
+                       }
+               }
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
+               break;
+       }
+}
+
+static void
+radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder,
+                            struct drm_encoder *ext_encoder,
+                            int mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+       default:
+               if (ASIC_IS_DCE41(rdev)) {
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
+               } else
+                       atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               if (ASIC_IS_DCE41(rdev)) {
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
+               } else
+                       atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
+               break;
+       }
+}
+
+static void
+radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+
+       DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
+                 radeon_encoder->encoder_id, mode, radeon_encoder->devices,
+                 radeon_encoder->active_device);
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               radeon_atom_encoder_dpms_avivo(encoder, mode);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               radeon_atom_encoder_dpms_dig(encoder, mode);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               if (ASIC_IS_DCE5(rdev)) {
+                       switch (mode) {
+                       case DRM_MODE_DPMS_ON:
+                               atombios_dvo_setup(encoder, ATOM_ENABLE);
+                               break;
+                       case DRM_MODE_DPMS_STANDBY:
+                       case DRM_MODE_DPMS_SUSPEND:
+                       case DRM_MODE_DPMS_OFF:
+                               atombios_dvo_setup(encoder, ATOM_DISABLE);
+                               break;
+                       }
+               } else if (ASIC_IS_DCE3(rdev))
+                       radeon_atom_encoder_dpms_dig(encoder, mode);
+               else
+                       radeon_atom_encoder_dpms_avivo(encoder, mode);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+               if (ASIC_IS_DCE5(rdev)) {
+                       switch (mode) {
+                       case DRM_MODE_DPMS_ON:
+                               atombios_dac_setup(encoder, ATOM_ENABLE);
+                               break;
+                       case DRM_MODE_DPMS_STANDBY:
+                       case DRM_MODE_DPMS_SUSPEND:
+                       case DRM_MODE_DPMS_OFF:
+                               atombios_dac_setup(encoder, ATOM_DISABLE);
+                               break;
+                       }
+               } else
+                       radeon_atom_encoder_dpms_avivo(encoder, mode);
+               break;
+       default:
+               return;
+       }
+
+       if (ext_encoder)
+               radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode);
+
+       radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
+
+}
+
+union crtc_source_param {
+       SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
+       SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
+};
+
+static void
+atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+       union crtc_source_param args;
+       int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
+       uint8_t frev, crev;
+       struct radeon_encoder_atom_dig *dig;
+
+       memset(&args, 0, sizeof(args));
+
+       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+               return;
+
+       switch (frev) {
+       case 1:
+               switch (crev) {
+               case 1:
+               default:
+                       if (ASIC_IS_AVIVO(rdev))
+                               args.v1.ucCRTC = radeon_crtc->crtc_id;
+                       else {
+                               if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) {
+                                       args.v1.ucCRTC = radeon_crtc->crtc_id;
+                               } else {
+                                       args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
+                               }
+                       }
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+                               args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+                       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+                               if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)
+                                       args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
+                               else
+                                       args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+                       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+                               args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                                       args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
+                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                                       args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
+                               else
+                                       args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                                       args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
+                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                                       args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
+                               else
+                                       args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
+                               break;
+                       }
+                       break;
+               case 2:
+                       args.v2.ucCRTC = radeon_crtc->crtc_id;
+                       if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) {
+                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
+                               if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+                               else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)
+                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+                               else
+                                       args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+                       } else
+                               args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+                               dig = radeon_encoder->enc_priv;
+                               switch (dig->dig_encoder) {
+                               case 0:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+                                       break;
+                               case 1:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+                                       break;
+                               case 2:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
+                                       break;
+                               case 3:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
+                                       break;
+                               case 4:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
+                                       break;
+                               case 5:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
+                                       break;
+                               }
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+                               args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+                               else
+                                       args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
+                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+                               else
+                                       args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
+                               break;
+                       }
+                       break;
+               }
+               break;
+       default:
+               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+               return;
+       }
+
+       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       /* update scratch regs with new routing */
+       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
+}
+
+static void
+atombios_apply_encoder_quirks(struct drm_encoder *encoder,
+                             struct drm_display_mode *mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+
+       /* Funky macbooks */
+       if ((dev->pdev->device == 0x71C5) &&
+           (dev->pdev->subsystem_vendor == 0x106b) &&
+           (dev->pdev->subsystem_device == 0x0080)) {
+               if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
+                       uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
+
+                       lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;
+                       lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
+
+                       WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);
+               }
+       }
+
+       /* set scaler clears this on some chips */
+       if (ASIC_IS_AVIVO(rdev) &&
+           (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
+               if (ASIC_IS_DCE4(rdev)) {
+                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
+                                      EVERGREEN_INTERLEAVE_EN);
+                       else
+                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+               } else {
+                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+                                      AVIVO_D1MODE_INTERLEAVE_EN);
+                       else
+                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+               }
+       }
+}
+
+static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *test_encoder;
+       struct radeon_encoder_atom_dig *dig;
+       uint32_t dig_enc_in_use = 0;
+
+       /* DCE4/5 */
+       if (ASIC_IS_DCE4(rdev)) {
+               dig = radeon_encoder->enc_priv;
+               if (ASIC_IS_DCE41(rdev)) {
+                       /* ontario follows DCE4 */
+                       if (rdev->family == CHIP_PALM) {
+                               if (dig->linkb)
+                                       return 1;
+                               else
+                                       return 0;
+                       } else
+                               /* llano follows DCE3.2 */
+                               return radeon_crtc->crtc_id;
+               } else {
+                       switch (radeon_encoder->encoder_id) {
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+                               if (dig->linkb)
+                                       return 1;
+                               else
+                                       return 0;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+                               if (dig->linkb)
+                                       return 3;
+                               else
+                                       return 2;
+                               break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                               if (dig->linkb)
+                                       return 5;
+                               else
+                                       return 4;
+                               break;
+                       }
+               }
+       }
+
+       /* on DCE32 and encoder can driver any block so just crtc id */
+       if (ASIC_IS_DCE32(rdev)) {
+               return radeon_crtc->crtc_id;
+       }
+
+       /* on DCE3 - LVTMA can only be driven by DIGB */
+       list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
+               struct radeon_encoder *radeon_test_encoder;
+
+               if (encoder == test_encoder)
+                       continue;
+
+               if (!radeon_encoder_is_digital(test_encoder))
+                       continue;
+
+               radeon_test_encoder = to_radeon_encoder(test_encoder);
+               dig = radeon_test_encoder->enc_priv;
+
+               if (dig->dig_encoder >= 0)
+                       dig_enc_in_use |= (1 << dig->dig_encoder);
+       }
+
+       if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {
+               if (dig_enc_in_use & 0x2)
+                       DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");
+               return 1;
+       }
+       if (!(dig_enc_in_use & 1))
+               return 0;
+       return 1;
+}
+
+/* This only needs to be called once at startup */
+void
+radeon_atom_encoder_init(struct radeon_device *rdev)
+{
+       struct drm_device *dev = rdev->ddev;
+       struct drm_encoder *encoder;
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+               struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+
+               switch (radeon_encoder->encoder_id) {
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+                       break;
+               default:
+                       break;
+               }
+
+               if (ext_encoder && ASIC_IS_DCE41(rdev))
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
+       }
+}
+
+static void
+radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
+                            struct drm_display_mode *mode,
+                            struct drm_display_mode *adjusted_mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+
+       radeon_encoder->pixel_clock = adjusted_mode->clock;
+
+       if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
+               if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
+                       atombios_yuv_setup(encoder, true);
+               else
+                       atombios_yuv_setup(encoder, false);
+       }
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+               atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               if (ASIC_IS_DCE4(rdev)) {
+                       /* disable the transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+                       /* setup and enable the encoder */
+                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+
+                       /* enable the transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+               } else {
+                       /* disable the encoder and transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
+
+                       /* setup and enable the encoder and transmitter */
+                       atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+               }
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               atombios_dvo_setup(encoder, ATOM_ENABLE);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               atombios_dac_setup(encoder, ATOM_ENABLE);
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+                               atombios_tv_setup(encoder, ATOM_ENABLE);
+                       else
+                               atombios_tv_setup(encoder, ATOM_DISABLE);
+               }
+               break;
+       }
+
+       if (ext_encoder) {
+               if (ASIC_IS_DCE41(rdev))
+                       atombios_external_encoder_setup(encoder, ext_encoder,
+                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
+               else
+                       atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
+       }
+
+       atombios_apply_encoder_quirks(encoder, adjusted_mode);
+
+       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+               r600_hdmi_enable(encoder);
+               r600_hdmi_setmode(encoder, adjusted_mode);
+       }
+}
+
+static bool
+atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+       if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
+                                      ATOM_DEVICE_CV_SUPPORT |
+                                      ATOM_DEVICE_CRT_SUPPORT)) {
+               DAC_LOAD_DETECTION_PS_ALLOCATION args;
+               int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
+               uint8_t frev, crev;
+
+               memset(&args, 0, sizeof(args));
+
+               if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+                       return false;
+
+               args.sDacload.ucMisc = 0;
+
+               if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
+                   (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
+                       args.sDacload.ucDacType = ATOM_DAC_A;
+               else
+                       args.sDacload.ucDacType = ATOM_DAC_B;
+
+               if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)
+                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
+               else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)
+                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
+               else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
+                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
+                       if (crev >= 3)
+                               args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
+               } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
+                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
+                       if (crev >= 3)
+                               args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
+               }
+
+               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+               return true;
+       } else
+               return false;
+}
+
+static enum drm_connector_status
+radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       uint32_t bios_0_scratch;
+
+       if (!atombios_dac_load_detect(encoder, connector)) {
+               DRM_DEBUG_KMS("detect returned false \n");
+               return connector_status_unknown;
+       }
+
+       if (rdev->family >= CHIP_R600)
+               bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
+       else
+               bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
+
+       DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
+       if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+               if (bios_0_scratch & ATOM_S0_CRT1_MASK)
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+               if (bios_0_scratch & ATOM_S0_CRT2_MASK)
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
+               if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
+               if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
+                       return connector_status_connected; /* CTV */
+               else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
+                       return connector_status_connected; /* STV */
+       }
+       return connector_status_disconnected;
+}
+
+static enum drm_connector_status
+radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+       u32 bios_0_scratch;
+
+       if (!ASIC_IS_DCE4(rdev))
+               return connector_status_unknown;
+
+       if (!ext_encoder)
+               return connector_status_unknown;
+
+       if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)
+               return connector_status_unknown;
+
+       /* load detect on the dp bridge */
+       atombios_external_encoder_setup(encoder, ext_encoder,
+                                       EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);
+
+       bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
+
+       DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
+       if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+               if (bios_0_scratch & ATOM_S0_CRT1_MASK)
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+               if (bios_0_scratch & ATOM_S0_CRT2_MASK)
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
+               if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
+                       return connector_status_connected;
+       }
+       if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
+               if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
+                       return connector_status_connected; /* CTV */
+               else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
+                       return connector_status_connected; /* STV */
+       }
+       return connector_status_disconnected;
+}
+
+void
+radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)
+{
+       struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+
+       if (ext_encoder)
+               /* ddc_setup on the dp bridge */
+               atombios_external_encoder_setup(encoder, ext_encoder,
+                                               EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
+
+}
+
+static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
+       if ((radeon_encoder->active_device &
+            (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
+           (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
+            ENCODER_OBJECT_ID_NONE)) {
+               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+               if (dig)
+                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
+       }
+
+       radeon_atom_output_lock(encoder, true);
+       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+               /* select the clock/data port if it uses a router */
+               if (radeon_connector->router.cd_valid)
+                       radeon_router_select_cd_port(radeon_connector);
+
+               /* turn eDP panel on for mode set */
+               if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+                       atombios_set_edp_panel_power(connector,
+                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
+       }
+
+       /* this is needed for the pll/ss setup to work correctly in some cases */
+       atombios_set_encoder_crtc_source(encoder);
+}
+
+static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
+{
+       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+       radeon_atom_output_lock(encoder, false);
+}
+
+static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
+{
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct radeon_encoder_atom_dig *dig;
+
+       /* check for pre-DCE3 cards with shared encoders;
+        * can't really use the links individually, so don't disable
+        * the encoder if it's in use by another connector
+        */
+       if (!ASIC_IS_DCE3(rdev)) {
+               struct drm_encoder *other_encoder;
+               struct radeon_encoder *other_radeon_encoder;
+
+               list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
+                       other_radeon_encoder = to_radeon_encoder(other_encoder);
+                       if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) &&
+                           drm_helper_encoder_in_use(other_encoder))
+                               goto disable_done;
+               }
+       }
+
+       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+               atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+               if (ASIC_IS_DCE4(rdev))
+                       /* disable the transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+               else {
+                       /* disable the encoder and transmitter */
+                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
+               }
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+               atombios_dvo_setup(encoder, ATOM_DISABLE);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               atombios_dac_setup(encoder, ATOM_DISABLE);
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+                       atombios_tv_setup(encoder, ATOM_DISABLE);
+               break;
+       }
+
+disable_done:
+       if (radeon_encoder_is_digital(encoder)) {
+               if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+                       r600_hdmi_disable(encoder);
+               dig = radeon_encoder->enc_priv;
+               dig->dig_encoder = -1;
+       }
+       radeon_encoder->active_device = 0;
+}
+
+/* these are handled by the primary encoders */
+static void radeon_atom_ext_prepare(struct drm_encoder *encoder)
+{
+
+}
+
+static void radeon_atom_ext_commit(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+
+}
+
+static void radeon_atom_ext_disable(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
+{
+
+}
+
+static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
+                                      struct drm_display_mode *mode,
+                                      struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
+       .dpms = radeon_atom_ext_dpms,
+       .mode_fixup = radeon_atom_ext_mode_fixup,
+       .prepare = radeon_atom_ext_prepare,
+       .mode_set = radeon_atom_ext_mode_set,
+       .commit = radeon_atom_ext_commit,
+       .disable = radeon_atom_ext_disable,
+       /* no detect for TMDS/LVDS yet */
+};
+
+static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
+       .dpms = radeon_atom_encoder_dpms,
+       .mode_fixup = radeon_atom_mode_fixup,
+       .prepare = radeon_atom_encoder_prepare,
+       .mode_set = radeon_atom_encoder_mode_set,
+       .commit = radeon_atom_encoder_commit,
+       .disable = radeon_atom_encoder_disable,
+       .detect = radeon_atom_dig_detect,
+};
+
+static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
+       .dpms = radeon_atom_encoder_dpms,
+       .mode_fixup = radeon_atom_mode_fixup,
+       .prepare = radeon_atom_encoder_prepare,
+       .mode_set = radeon_atom_encoder_mode_set,
+       .commit = radeon_atom_encoder_commit,
+       .detect = radeon_atom_dac_detect,
+};
+
+void radeon_enc_destroy(struct drm_encoder *encoder)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       kfree(radeon_encoder->enc_priv);
+       drm_encoder_cleanup(encoder);
+       kfree(radeon_encoder);
+}
+
+static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
+       .destroy = radeon_enc_destroy,
+};
+
+struct radeon_encoder_atom_dac *
+radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
+{
+       struct drm_device *dev = radeon_encoder->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
+
+       if (!dac)
+               return NULL;
+
+       dac->tv_std = radeon_atombios_get_tv_info(rdev);
+       return dac;
+}
+
+struct radeon_encoder_atom_dig *
+radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
+{
+       int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+       struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
+
+       if (!dig)
+               return NULL;
+
+       /* coherent mode by default */
+       dig->coherent_mode = true;
+       dig->dig_encoder = -1;
+
+       if (encoder_enum == 2)
+               dig->linkb = true;
+       else
+               dig->linkb = false;
+
+       return dig;
+}
+
+void
+radeon_add_atom_encoder(struct drm_device *dev,
+                       uint32_t encoder_enum,
+                       uint32_t supported_device,
+                       u16 caps)
+{
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_encoder *encoder;
+       struct radeon_encoder *radeon_encoder;
+
+       /* see if we already added it */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               radeon_encoder = to_radeon_encoder(encoder);
+               if (radeon_encoder->encoder_enum == encoder_enum) {
+                       radeon_encoder->devices |= supported_device;
+                       return;
+               }
+
+       }
+
+       /* add a new one */
+       radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
+       if (!radeon_encoder)
+               return;
+
+       encoder = &radeon_encoder->base;
+       switch (rdev->num_crtc) {
+       case 1:
+               encoder->possible_crtcs = 0x1;
+               break;
+       case 2:
+       default:
+               encoder->possible_crtcs = 0x3;
+               break;
+       case 4:
+               encoder->possible_crtcs = 0xf;
+               break;
+       case 6:
+               encoder->possible_crtcs = 0x3f;
+               break;
+       }
+
+       radeon_encoder->enc_priv = NULL;
+
+       radeon_encoder->encoder_enum = encoder_enum;
+       radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+       radeon_encoder->devices = supported_device;
+       radeon_encoder->rmx_type = RMX_OFF;
+       radeon_encoder->underscan_type = UNDERSCAN_OFF;
+       radeon_encoder->is_ext_encoder = false;
+       radeon_encoder->caps = caps;
+
+       switch (radeon_encoder->encoder_id) {
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       radeon_encoder->rmx_type = RMX_FULL;
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+                       radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+               } else {
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+               }
+               drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+               drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
+               drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+               drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
+               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
+               drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
+               break;
+       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+                       radeon_encoder->rmx_type = RMX_FULL;
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+                       radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+               } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+               } else {
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+               }
+               drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
+               break;
+       case ENCODER_OBJECT_ID_SI170B:
+       case ENCODER_OBJECT_ID_CH7303:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
+       case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
+       case ENCODER_OBJECT_ID_TITFP513:
+       case ENCODER_OBJECT_ID_VT1623:
+       case ENCODER_OBJECT_ID_HDMI_SI1930:
+       case ENCODER_OBJECT_ID_TRAVIS:
+       case ENCODER_OBJECT_ID_NUTMEG:
+               /* these are handled by the primary encoders */
+               radeon_encoder->is_ext_encoder = true;
+               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+               else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               else
+                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+               drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
+               break;
+       }
+}
index ed406e8404a3498870d517fd286b5824a8665e22..5e00d1670aa9964b8d49d0e289e9da5211e501d2 100644 (file)
@@ -82,6 +82,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
@@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
@@ -157,6 +162,57 @@ int sumo_get_temp(struct radeon_device *rdev)
        return actual_temp * 1000;
 }
 
+void sumo_pm_init_profile(struct radeon_device *rdev)
+{
+       int idx;
+
+       /* default */
+       rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
+       rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
+       rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
+
+       /* low,mid sh/mh */
+       if (rdev->flags & RADEON_IS_MOBILITY)
+               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
+       else
+               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+
+       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
+
+       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
+
+       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
+
+       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
+
+       /* high sh/mh */
+       idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx =
+               rdev->pm.power_state[idx].num_clock_modes - 1;
+
+       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
+       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
+       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx =
+               rdev->pm.power_state[idx].num_clock_modes - 1;
+}
+
 void evergreen_pm_misc(struct radeon_device *rdev)
 {
        int req_ps_idx = rdev->pm.requested_power_state_index;
@@ -353,6 +409,7 @@ void evergreen_hpd_init(struct radeon_device *rdev)
                default:
                        break;
                }
+               radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
        }
        if (rdev->irq.installed)
                evergreen_irq_set(rdev);
@@ -893,7 +950,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
        u32 tmp;
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -945,7 +1002,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
 void evergreen_pcie_gart_disable(struct radeon_device *rdev)
 {
        u32 tmp;
-       int r;
 
        /* Disable all tables */
        WREG32(VM_CONTEXT0_CNTL, 0);
@@ -965,14 +1021,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void evergreen_pcie_gart_fini(struct radeon_device *rdev)
@@ -1226,7 +1275,7 @@ void evergreen_mc_program(struct radeon_device *rdev)
                WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
                        rdev->mc.vram_end >> 12);
        }
-       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
        if (rdev->flags & RADEON_IS_IGP) {
                tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
                tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
@@ -3031,6 +3080,10 @@ static int evergreen_startup(struct radeon_device *rdev)
                }
        }
 
+       r = r600_vram_scratch_init(rdev);
+       if (r)
+               return r;
+
        evergreen_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                evergreen_agp_enable(rdev);
@@ -3235,6 +3288,7 @@ void evergreen_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        evergreen_pcie_gart_fini(rdev);
+       r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_agp_fini(rdev);
index dcf11bbc06d90d1f7762782d491820ad3f2b5c53..914e5af84163cc38b9e03e214af13db747b7dd80 100644 (file)
@@ -94,6 +94,15 @@ cp_set_surface_sync(struct radeon_device *rdev,
        else
                cp_coher_size = ((size + 255) >> 8);
 
+       if (rdev->family >= CHIP_CAYMAN) {
+               /* CP_COHER_CNTL2 has to be set manually when submitting a surface_sync
+                * to the RB directly. For IBs, the CP programs this as part of the
+                * surface_sync packet.
+                */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+               radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2);
+               radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */
+       }
        radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
        radeon_ring_write(rdev, sync_type);
        radeon_ring_write(rdev, cp_coher_size);
@@ -174,7 +183,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 static void
 set_tex_resource(struct radeon_device *rdev,
                 int format, int w, int h, int pitch,
-                u64 gpu_addr)
+                u64 gpu_addr, u32 size)
 {
        u32 sq_tex_resource_word0, sq_tex_resource_word1;
        u32 sq_tex_resource_word4, sq_tex_resource_word7;
@@ -196,6 +205,9 @@ set_tex_resource(struct radeon_device *rdev,
        sq_tex_resource_word7 = format |
                S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE);
 
+       cp_set_surface_sync(rdev,
+                           PACKET3_TC_ACTION_ENA, size, gpu_addr);
+
        radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8));
        radeon_ring_write(rdev, 0);
        radeon_ring_write(rdev, sq_tex_resource_word0);
@@ -613,11 +625,13 @@ int evergreen_blit_init(struct radeon_device *rdev)
        rdev->r600_blit.primitives.set_default_state = set_default_state;
 
        rdev->r600_blit.ring_size_common = 55; /* shaders + def state */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
        rdev->r600_blit.ring_size_common += 5; /* done copy */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */
 
        rdev->r600_blit.ring_size_per_loop = 74;
+       if (rdev->family >= CHIP_CAYMAN)
+               rdev->r600_blit.ring_size_per_loop += 9; /* additional DWs for surface sync */
 
        rdev->r600_blit.max_dim = 16384;
 
index 7fdfa8ea7570654b6d3faf70e410e5ff6b9554d7..cd4590aae154154d62906d901a63b8b368fea861 100644 (file)
@@ -38,6 +38,7 @@ struct evergreen_cs_track {
        u32                     group_size;
        u32                     nbanks;
        u32                     npipes;
+       u32                     row_size;
        /* value we track */
        u32                     nsamples;
        u32                     cb_color_base_last[12];
@@ -77,6 +78,44 @@ struct evergreen_cs_track {
        struct radeon_bo        *db_s_write_bo;
 };
 
+static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
+{
+       if (tiling_flags & RADEON_TILING_MACRO)
+               return ARRAY_2D_TILED_THIN1;
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               return ARRAY_1D_TILED_THIN1;
+       else
+               return ARRAY_LINEAR_GENERAL;
+}
+
+static u32 evergreen_cs_get_num_banks(u32 nbanks)
+{
+       switch (nbanks) {
+       case 2:
+               return ADDR_SURF_2_BANK;
+       case 4:
+               return ADDR_SURF_4_BANK;
+       case 8:
+       default:
+               return ADDR_SURF_8_BANK;
+       case 16:
+               return ADDR_SURF_16_BANK;
+       }
+}
+
+static u32 evergreen_cs_get_tile_split(u32 row_size)
+{
+       switch (row_size) {
+       case 1:
+       default:
+               return ADDR_SURF_TILE_SPLIT_1KB;
+       case 2:
+               return ADDR_SURF_TILE_SPLIT_2KB;
+       case 4:
+               return ADDR_SURF_TILE_SPLIT_4KB;
+       }
+}
+
 static void evergreen_cs_track_init(struct evergreen_cs_track *track)
 {
        int i;
@@ -480,21 +519,22 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                }
                break;
        case DB_Z_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                track->db_z_info = radeon_get_ib_value(p, idx);
-               ib[idx] &= ~Z_ARRAY_MODE(0xf);
-               track->db_z_info &= ~Z_ARRAY_MODE(0xf);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else {
-                       ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       ib[idx] &= ~Z_ARRAY_MODE(0xf);
+                       track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+                       ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                               ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                               ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+                       }
                }
                break;
        case DB_STENCIL_INFO:
@@ -607,40 +647,34 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case CB_COLOR5_INFO:
        case CB_COLOR6_INFO:
        case CB_COLOR7_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                tmp = (reg - CB_COLOR0_INFO) / 0x3c;
                track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
                }
                break;
        case CB_COLOR8_INFO:
        case CB_COLOR9_INFO:
        case CB_COLOR10_INFO:
        case CB_COLOR11_INFO:
-               r = evergreen_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
-                                       "0x%04X\n", reg);
-                       return -EINVAL;
-               }
                tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
                track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-               } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                       ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+               if (!p->keep_tiling_flags) {
+                       r = evergreen_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                               "0x%04X\n", reg);
+                               return -EINVAL;
+                       }
+                       ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
                }
                break;
        case CB_COLOR0_PITCH:
@@ -695,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case CB_COLOR9_ATTRIB:
        case CB_COLOR10_ATTRIB:
        case CB_COLOR11_ATTRIB:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                       ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                       ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+               }
                break;
        case CB_COLOR0_DIM:
        case CB_COLOR1_DIM:
@@ -1311,10 +1355,16 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                                       ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               if (!p->keep_tiling_flags) {
+                                       ib[idx+1+(i*8)+1] |=
+                                               TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                                               ib[idx+1+(i*8)+6] |=
+                                                       TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+                                               ib[idx+1+(i*8)+7] |=
+                                                       TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                                       }
+                               }
                                texture = reloc->robj;
                                /* tex mip base */
                                r = evergreen_cs_packet_next_reloc(p, &reloc);
@@ -1414,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
 {
        struct radeon_cs_packet pkt;
        struct evergreen_cs_track *track;
+       u32 tmp;
        int r;
 
        if (p->track == NULL) {
@@ -1422,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
                if (track == NULL)
                        return -ENOMEM;
                evergreen_cs_track_init(track);
-               track->npipes = p->rdev->config.evergreen.tiling_npipes;
-               track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
-               track->group_size = p->rdev->config.evergreen.tiling_group_size;
+               if (p->rdev->family >= CHIP_CAYMAN)
+                       tmp = p->rdev->config.cayman.tile_config;
+               else
+                       tmp = p->rdev->config.evergreen.tile_config;
+
+               switch (tmp & 0xf) {
+               case 0:
+                       track->npipes = 1;
+                       break;
+               case 1:
+               default:
+                       track->npipes = 2;
+                       break;
+               case 2:
+                       track->npipes = 4;
+                       break;
+               case 3:
+                       track->npipes = 8;
+                       break;
+               }
+
+               switch ((tmp & 0xf0) >> 4) {
+               case 0:
+                       track->nbanks = 4;
+                       break;
+               case 1:
+               default:
+                       track->nbanks = 8;
+                       break;
+               case 2:
+                       track->nbanks = 16;
+                       break;
+               }
+
+               switch ((tmp & 0xf00) >> 8) {
+               case 0:
+                       track->group_size = 256;
+                       break;
+               case 1:
+               default:
+                       track->group_size = 512;
+                       break;
+               }
+
+               switch ((tmp & 0xf000) >> 12) {
+               case 0:
+                       track->row_size = 1;
+                       break;
+               case 1:
+               default:
+                       track->row_size = 2;
+                       break;
+               case 2:
+                       track->row_size = 4;
+                       break;
+               }
+
                p->track = track;
        }
        do {
index c781c92c3451285a14360f57bf18a53802dca1ab..7d7f2155e34c305729f8487c55fc8c2c741ccc44 100644 (file)
 #       define EVERGREEN_GRPH_DEPTH_8BPP                0
 #       define EVERGREEN_GRPH_DEPTH_16BPP               1
 #       define EVERGREEN_GRPH_DEPTH_32BPP               2
+#       define EVERGREEN_GRPH_NUM_BANKS(x)              (((x) & 0x3) << 2)
+#       define EVERGREEN_ADDR_SURF_2_BANK               0
+#       define EVERGREEN_ADDR_SURF_4_BANK               1
+#       define EVERGREEN_ADDR_SURF_8_BANK               2
+#       define EVERGREEN_ADDR_SURF_16_BANK              3
+#       define EVERGREEN_GRPH_Z(x)                      (((x) & 0x3) << 4)
+#       define EVERGREEN_GRPH_BANK_WIDTH(x)             (((x) & 0x3) << 6)
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_1         0
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_2         1
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_4         2
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_8         3
 #       define EVERGREEN_GRPH_FORMAT(x)                 (((x) & 0x7) << 8)
 /* 8 BPP */
 #       define EVERGREEN_GRPH_FORMAT_INDEXED            0
 #       define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102     5
 #       define EVERGREEN_GRPH_FORMAT_RGB111110          6
 #       define EVERGREEN_GRPH_FORMAT_BGR101111          7
+#       define EVERGREEN_GRPH_BANK_HEIGHT(x)            (((x) & 0x3) << 11)
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1        0
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2        1
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4        2
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8        3
+#       define EVERGREEN_GRPH_TILE_SPLIT(x)             (((x) & 0x7) << 13)
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B       0
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B      1
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B      2
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B      3
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB       4
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB       5
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB       6
+#       define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x)      (((x) & 0x3) << 18)
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1  0
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2  1
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4  2
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8  3
 #       define EVERGREEN_GRPH_ARRAY_MODE(x)             (((x) & 0x7) << 20)
 #       define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL      0
 #       define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED      1
index b937c49054d9df9d63fea1279d6a1e123fd899e0..e00039e59a75b2bceb45ff69f63b740fd3193f40 100644 (file)
 #define DB_HTILE_DATA_BASE                             0x28014
 #define DB_Z_INFO                                      0x28040
 #       define Z_ARRAY_MODE(x)                          ((x) << 4)
+#       define DB_TILE_SPLIT(x)                         (((x) & 0x7) << 8)
+#       define DB_NUM_BANKS(x)                          (((x) & 0x3) << 12)
+#       define DB_BANK_WIDTH(x)                         (((x) & 0x3) << 16)
+#       define DB_BANK_HEIGHT(x)                        (((x) & 0x3) << 20)
 #define DB_STENCIL_INFO                                        0x28044
 #define DB_Z_READ_BASE                                 0x28048
 #define DB_STENCIL_READ_BASE                           0x2804c
 #      define CB_SF_EXPORT_FULL                        0
 #      define CB_SF_EXPORT_NORM                        1
 #define        CB_COLOR0_ATTRIB                                0x28c74
+#       define CB_TILE_SPLIT(x)                         (((x) & 0x7) << 5)
+#       define ADDR_SURF_TILE_SPLIT_64B                 0
+#       define ADDR_SURF_TILE_SPLIT_128B                1
+#       define ADDR_SURF_TILE_SPLIT_256B                2
+#       define ADDR_SURF_TILE_SPLIT_512B                3
+#       define ADDR_SURF_TILE_SPLIT_1KB                 4
+#       define ADDR_SURF_TILE_SPLIT_2KB                 5
+#       define ADDR_SURF_TILE_SPLIT_4KB                 6
+#       define CB_NUM_BANKS(x)                          (((x) & 0x3) << 10)
+#       define ADDR_SURF_2_BANK                         0
+#       define ADDR_SURF_4_BANK                         1
+#       define ADDR_SURF_8_BANK                         2
+#       define ADDR_SURF_16_BANK                        3
+#       define CB_BANK_WIDTH(x)                         (((x) & 0x3) << 13)
+#       define ADDR_SURF_BANK_WIDTH_1                   0
+#       define ADDR_SURF_BANK_WIDTH_2                   1
+#       define ADDR_SURF_BANK_WIDTH_4                   2
+#       define ADDR_SURF_BANK_WIDTH_8                   3
+#       define CB_BANK_HEIGHT(x)                        (((x) & 0x3) << 16)
+#       define ADDR_SURF_BANK_HEIGHT_1                  0
+#       define ADDR_SURF_BANK_HEIGHT_2                  1
+#       define ADDR_SURF_BANK_HEIGHT_4                  2
+#       define ADDR_SURF_BANK_HEIGHT_8                  3
 #define        CB_COLOR0_DIM                                   0x28c78
 /* only CB0-7 blocks have these regs */
 #define        CB_COLOR0_CMASK                                 0x28c7c
 #      define SQ_SEL_1                                 5
 #define SQ_TEX_RESOURCE_WORD5_0                         0x30014
 #define SQ_TEX_RESOURCE_WORD6_0                         0x30018
+#       define TEX_TILE_SPLIT(x)                        (((x) & 0x7) << 29)
 #define SQ_TEX_RESOURCE_WORD7_0                         0x3001c
+#       define TEX_BANK_WIDTH(x)                        (((x) & 0x3) << 8)
+#       define TEX_BANK_HEIGHT(x)                       (((x) & 0x3) << 10)
+#       define TEX_NUM_BANKS(x)                         (((x) & 0x3) << 16)
 
 #define SQ_VTX_CONSTANT_WORD0_0                                0x30000
 #define SQ_VTX_CONSTANT_WORD1_0                                0x30004
index 556b7bc3418b9da6d0aa5bb61bdf31e83ce89059..0e579985746535d211d26bc1350bdf60e851bdb8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "drmP.h"
 #include "radeon.h"
 #include "radeon_asic.h"
@@ -261,8 +262,11 @@ int ni_mc_load_microcode(struct radeon_device *rdev)
                WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
 
                /* wait for training to complete */
-               while (!(RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD))
-                       udelay(10);
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
+                               break;
+                       udelay(1);
+               }
 
                if (running)
                        WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
@@ -932,7 +936,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -977,8 +981,6 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
 
 void cayman_pcie_gart_disable(struct radeon_device *rdev)
 {
-       int r;
-
        /* Disable all tables */
        WREG32(VM_CONTEXT0_CNTL, 0);
        WREG32(VM_CONTEXT1_CNTL, 0);
@@ -994,14 +996,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev)
        WREG32(VM_L2_CNTL2, 0);
        WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
               L2_CACHE_BIGK_FRAGMENT_SIZE(6));
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void cayman_pcie_gart_fini(struct radeon_device *rdev)
@@ -1361,6 +1356,10 @@ static int cayman_startup(struct radeon_device *rdev)
                return r;
        }
 
+       r = r600_vram_scratch_init(rdev);
+       if (r)
+               return r;
+
        evergreen_mc_program(rdev);
        r = cayman_pcie_gart_enable(rdev);
        if (r)
@@ -1556,6 +1555,7 @@ void cayman_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        cayman_pcie_gart_fini(rdev);
+       r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_bo_fini(rdev);
index 8f8b8fa143570c116960befda9c048837cf974e3..bfc08f6320f83b83569bec08a2968014c9e90a4f 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include "r100_reg_safe.h"
 #include "rn50_reg_safe.h"
@@ -186,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
+       int i;
 
        /* Lock the graphics update lock */
        /* update the scanout addresses */
        WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
@@ -536,6 +542,7 @@ void r100_hpd_init(struct radeon_device *rdev)
                default:
                        break;
                }
+               radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
        }
        if (rdev->irq.installed)
                r100_irq_set(rdev);
@@ -576,7 +583,7 @@ int r100_pci_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.ram.ptr) {
+       if (rdev->gart.ptr) {
                WARN(1, "R100 PCI GART already initialized\n");
                return 0;
        }
@@ -635,10 +642,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev)
 
 int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
+       u32 *gtt = rdev->gart.ptr;
+
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr));
+       gtt[i] = cpu_to_le32(lower_32_bits(addr));
        return 0;
 }
 
index 33f2b68c680b349a5d9e097776d329fc047a37ef..c93bc64707e1d6e3b59a5e2a7fe632b19e6efe99 100644 (file)
@@ -74,7 +74,7 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
 
 int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
-       void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+       void __iomem *ptr = rdev->gart.ptr;
 
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
@@ -93,7 +93,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj) {
+       if (rdev->gart.robj) {
                WARN(1, "RV370 PCIE GART already initialized\n");
                return 0;
        }
@@ -116,7 +116,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
        uint32_t tmp;
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -154,7 +154,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
 void rv370_pcie_gart_disable(struct radeon_device *rdev)
 {
        u32 tmp;
-       int r;
 
        WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0);
        WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0);
@@ -163,14 +162,7 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
        tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
        tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
        WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void rv370_pcie_gart_fini(struct radeon_device *rdev)
@@ -709,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        return r;
                }
 
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_TXO_MACRO_TILE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_TXO_MICRO_TILE;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
-
-               tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+               if (p->keep_tiling_flags) {
+                       ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */
+                                 ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset);
+               } else {
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_TXO_MACRO_TILE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_TXO_MICRO_TILE;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
+
+                       tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                track->textures[i].robj = reloc->robj;
                track->tex_dirty = true;
                break;
@@ -768,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* RB3D_COLORPITCH1 */
                /* RB3D_COLORPITCH2 */
                /* RB3D_COLORPITCH3 */
-               r = r100_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-                                 idx, reg);
-                       r100_cs_dump_packet(p, pkt);
-                       return r;
-               }
+               if (!p->keep_tiling_flags) {
+                       r = r100_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                         idx, reg);
+                               r100_cs_dump_packet(p, pkt);
+                               return r;
+                       }
 
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_COLOR_TILE_ENABLE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_COLOR_MICROTILE_ENABLE;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_COLOR_TILE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_COLOR_MICROTILE_ENABLE;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
 
-               tmp = idx_value & ~(0x7 << 16);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+                       tmp = idx_value & ~(0x7 << 16);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = idx_value & 0x3FFE;
                switch (((idx_value >> 21) & 0xF)) {
@@ -851,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4F24:
                /* ZB_DEPTHPITCH */
-               r = r100_cs_packet_next_reloc(p, &reloc);
-               if (r) {
-                       DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-                                 idx, reg);
-                       r100_cs_dump_packet(p, pkt);
-                       return r;
-               }
-
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                       tile_flags |= R300_DEPTHMACROTILE_ENABLE;
-               if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                       tile_flags |= R300_DEPTHMICROTILE_TILED;
-               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
-                       tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
+               if (!p->keep_tiling_flags) {
+                       r = r100_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                         idx, reg);
+                               r100_cs_dump_packet(p, pkt);
+                               return r;
+                       }
 
-               tmp = idx_value & ~(0x7 << 16);
-               tmp |= tile_flags;
-               ib[idx] = tmp;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                               tile_flags |= R300_DEPTHMACROTILE_ENABLE;
+                       if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                               tile_flags |= R300_DEPTHMICROTILE_TILED;
+                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
+                               tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
 
+                       tmp = idx_value & ~(0x7 << 16);
+                       tmp |= tile_flags;
+                       ib[idx] = tmp;
+               }
                track->zb.pitch = idx_value & 0x3FFC;
                track->zb_dirty = true;
                break;
index 12470b090ddf871a62e478d2bca0c340792175d3..9cdda0b3b081e879f165f322e23780b338b583d9 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/seq_file.h>
 #include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon.h"
@@ -287,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev)
                  pcie_lanes);
 }
 
-static int r600_pm_get_type_index(struct radeon_device *rdev,
-                                 enum radeon_pm_state_type ps_type,
-                                 int instance)
-{
-       int i;
-       int found_instance = -1;
-
-       for (i = 0; i < rdev->pm.num_power_states; i++) {
-               if (rdev->pm.power_state[i].type == ps_type) {
-                       found_instance++;
-                       if (found_instance == instance)
-                               return i;
-               }
-       }
-       /* return default if no match */
-       return rdev->pm.default_power_state_index;
-}
-
 void rs780_pm_init_profile(struct radeon_device *rdev)
 {
        if (rdev->pm.num_power_states == 2) {
@@ -420,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev)
 
 void r600_pm_init_profile(struct radeon_device *rdev)
 {
+       int idx;
+
        if (rdev->family == CHIP_R600) {
                /* XXX */
                /* default */
@@ -501,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev)
                        rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
                        rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
                        /* low sh */
-                       if (rdev->flags & RADEON_IS_MOBILITY) {
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
-                       } else {
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
-                       }
+                       if (rdev->flags & RADEON_IS_MOBILITY)
+                               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
+                       else
+                               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+                       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
+                       rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
                        /* mid sh */
-                       if (rdev->flags & RADEON_IS_MOBILITY) {
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
-                       } else {
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
-                       }
+                       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
+                       rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
                        /* high sh */
-                       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx =
-                               r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
-                       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx =
-                               r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+                       idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
+                       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
                        rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
                        rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
                        /* low mh */
-                       if (rdev->flags & RADEON_IS_MOBILITY) {
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
-                       } else {
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
-                       }
+                       if (rdev->flags & RADEON_IS_MOBILITY)
+                               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
+                       else
+                               idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+                       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
+                       rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
                        /* mid mh */
-                       if (rdev->flags & RADEON_IS_MOBILITY) {
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
-                       } else {
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx =
-                                       r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
-                               rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
-                       }
+                       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
+                       rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
                        /* high mh */
-                       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx =
-                               r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
-                       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx =
-                               r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+                       idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
+                       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
+                       rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
                        rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
                        rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
                }
@@ -762,13 +709,14 @@ void r600_hpd_init(struct radeon_device *rdev)
        struct drm_device *dev = rdev->ddev;
        struct drm_connector *connector;
 
-       if (ASIC_IS_DCE3(rdev)) {
-               u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
-               if (ASIC_IS_DCE32(rdev))
-                       tmp |= DC_HPDx_EN;
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+               if (ASIC_IS_DCE3(rdev)) {
+                       u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
+                       if (ASIC_IS_DCE32(rdev))
+                               tmp |= DC_HPDx_EN;
 
-               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
                        switch (radeon_connector->hpd.hpd) {
                        case RADEON_HPD_1:
                                WREG32(DC_HPD1_CONTROL, tmp);
@@ -798,10 +746,7 @@ void r600_hpd_init(struct radeon_device *rdev)
                        default:
                                break;
                        }
-               }
-       } else {
-               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               } else {
                        switch (radeon_connector->hpd.hpd) {
                        case RADEON_HPD_1:
                                WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
@@ -819,6 +764,7 @@ void r600_hpd_init(struct radeon_device *rdev)
                                break;
                        }
                }
+               radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
        }
        if (rdev->irq.installed)
                r600_irq_set(rdev);
@@ -896,7 +842,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        /* flush hdp cache so updates hit vram */
        if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
            !(rdev->flags & RADEON_IS_AGP)) {
-               void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+               void __iomem *ptr = (void *)rdev->gart.ptr;
                u32 tmp;
 
                /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
@@ -931,7 +877,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj) {
+       if (rdev->gart.robj) {
                WARN(1, "R600 PCIE GART already initialized\n");
                return 0;
        }
@@ -948,7 +894,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
        u32 tmp;
        int r, i;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -1003,7 +949,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
 void r600_pcie_gart_disable(struct radeon_device *rdev)
 {
        u32 tmp;
-       int i, r;
+       int i;
 
        /* Disable all tables */
        for (i = 0; i < 7; i++)
@@ -1030,14 +976,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
        WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
        WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
        WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void r600_pcie_gart_fini(struct radeon_device *rdev)
@@ -1137,7 +1076,7 @@ static void r600_mc_program(struct radeon_device *rdev)
                WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
                WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
        }
-       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
        tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
        tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
        WREG32(MC_VM_FB_LOCATION, tmp);
@@ -1276,6 +1215,53 @@ int r600_mc_init(struct radeon_device *rdev)
        return 0;
 }
 
+int r600_vram_scratch_init(struct radeon_device *rdev)
+{
+       int r;
+
+       if (rdev->vram_scratch.robj == NULL) {
+               r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
+                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+                                    &rdev->vram_scratch.robj);
+               if (r) {
+                       return r;
+               }
+       }
+
+       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+       if (unlikely(r != 0))
+               return r;
+       r = radeon_bo_pin(rdev->vram_scratch.robj,
+                         RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr);
+       if (r) {
+               radeon_bo_unreserve(rdev->vram_scratch.robj);
+               return r;
+       }
+       r = radeon_bo_kmap(rdev->vram_scratch.robj,
+                               (void **)&rdev->vram_scratch.ptr);
+       if (r)
+               radeon_bo_unpin(rdev->vram_scratch.robj);
+       radeon_bo_unreserve(rdev->vram_scratch.robj);
+
+       return r;
+}
+
+void r600_vram_scratch_fini(struct radeon_device *rdev)
+{
+       int r;
+
+       if (rdev->vram_scratch.robj == NULL) {
+               return;
+       }
+       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+       if (likely(r == 0)) {
+               radeon_bo_kunmap(rdev->vram_scratch.robj);
+               radeon_bo_unpin(rdev->vram_scratch.robj);
+               radeon_bo_unreserve(rdev->vram_scratch.robj);
+       }
+       radeon_bo_unref(&rdev->vram_scratch.robj);
+}
+
 /* We doesn't check that the GPU really needs a reset we simply do the
  * reset, it's up to the caller to determine if the GPU needs one. We
  * might add an helper function to check that.
@@ -2331,6 +2317,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
        if (rdev->wb.use_event) {
                u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET +
                        (u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base);
+               /* flush read cache over gart */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
+               radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
+                                       PACKET3_VC_ACTION_ENA |
+                                       PACKET3_SH_ACTION_ENA);
+               radeon_ring_write(rdev, 0xFFFFFFFF);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, 10); /* poll interval */
                /* EVENT_WRITE_EOP - flush caches, send int */
                radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
                radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
@@ -2339,6 +2333,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
                radeon_ring_write(rdev, fence->seq);
                radeon_ring_write(rdev, 0);
        } else {
+               /* flush read cache over gart */
+               radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
+               radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA |
+                                       PACKET3_VC_ACTION_ENA |
+                                       PACKET3_SH_ACTION_ENA);
+               radeon_ring_write(rdev, 0xFFFFFFFF);
+               radeon_ring_write(rdev, 0);
+               radeon_ring_write(rdev, 10); /* poll interval */
                radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
                radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0));
                /* wait for 3D idle clean */
@@ -2420,6 +2422,10 @@ int r600_startup(struct radeon_device *rdev)
                }
        }
 
+       r = r600_vram_scratch_init(rdev);
+       if (r)
+               return r;
+
        r600_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                r600_agp_enable(rdev);
@@ -2640,6 +2646,7 @@ void r600_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        r600_pcie_gart_fini(rdev);
+       r600_vram_scratch_fini(rdev);
        radeon_agp_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
index c4cf1308d4a1e72ad7933bd0de0b091ea354a0f6..e09d2818f949f55615c8e33723f14d73bdb69660 100644 (file)
@@ -201,7 +201,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 static void
 set_tex_resource(struct radeon_device *rdev,
                 int format, int w, int h, int pitch,
-                u64 gpu_addr)
+                u64 gpu_addr, u32 size)
 {
        uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
 
@@ -222,6 +222,9 @@ set_tex_resource(struct radeon_device *rdev,
                S_038010_DST_SEL_Z(SQ_SEL_Z) |
                S_038010_DST_SEL_W(SQ_SEL_W);
 
+       cp_set_surface_sync(rdev,
+                           PACKET3_TC_ACTION_ENA, size, gpu_addr);
+
        radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
        radeon_ring_write(rdev, 0);
        radeon_ring_write(rdev, sq_tex_resource_word0);
@@ -500,9 +503,9 @@ int r600_blit_init(struct radeon_device *rdev)
        rdev->r600_blit.primitives.set_default_state = set_default_state;
 
        rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
        rdev->r600_blit.ring_size_common += 5; /* done copy */
-       rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */
 
        rdev->r600_blit.ring_size_per_loop = 76;
        /* set_render_target emits 2 extra dwords on rv6xx */
@@ -760,10 +763,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                vb[11] = i2f(h);
 
                rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
-                                                           w, h, w, src_gpu_addr);
-               rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
-                                                              PACKET3_TC_ACTION_ENA,
-                                                              size_in_bytes, src_gpu_addr);
+                                                           w, h, w, src_gpu_addr, size_in_bytes);
                rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8,
                                                             w, h, dst_gpu_addr);
                rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);
index 45fd592f9606c0ee651631e2ce72656e733a7331..c9db4931913f3fd2c1539f56fa50fe1bbe0833e9 100644 (file)
@@ -26,6 +26,8 @@
  *     Alex Deucher <alexander.deucher@amd.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
index 0a2e023c15570ffdbd8c78280ac84123b6b17034..cb1acffd24303aca4c49b11e62b74719a527d51b 100644 (file)
@@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                track->db_depth_control = radeon_get_ib_value(p, idx);
                break;
        case R_028010_DB_DEPTH_INFO:
-               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+               if (!p->keep_tiling_flags &&
+                   r600_cs_packet_next_is_pkt3_nop(p)) {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_warn(p->dev, "bad SET_CONTEXT_REG "
@@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case R_0280B4_CB_COLOR5_INFO:
        case R_0280B8_CB_COLOR6_INFO:
        case R_0280BC_CB_COLOR7_INFO:
-               if (r600_cs_packet_next_is_pkt3_nop(p)) {
+               if (!p->keep_tiling_flags &&
+                    r600_cs_packet_next_is_pkt3_nop(p)) {
                        r = r600_cs_packet_next_reloc(p, &reloc);
                        if (r) {
                                dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
@@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
        mip_offset <<= 8;
 
        word0 = radeon_get_ib_value(p, idx + 0);
-       if (tiling_flags & RADEON_TILING_MACRO)
-               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
-       else if (tiling_flags & RADEON_TILING_MICRO)
-               word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+       if (!p->keep_tiling_flags) {
+               if (tiling_flags & RADEON_TILING_MACRO)
+                       word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+               else if (tiling_flags & RADEON_TILING_MICRO)
+                       word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+       }
        word1 = radeon_get_ib_value(p, idx + 1);
        w0 = G_038000_TEX_WIDTH(word0) + 1;
        h0 = G_038004_TEX_HEIGHT(word1) + 1;
@@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                                        return -EINVAL;
                                }
                                base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-                               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
-                               else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                                       ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+                               if (!p->keep_tiling_flags) {
+                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+                                               ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+                                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+                                               ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+                               }
                                texture = reloc->robj;
                                /* tex mip base */
                                r = r600_cs_packet_next_reloc(p, &reloc);
index e3170c794c1d98ba58fcc02cb6a94e8d2cf4533c..8227e76b5c70a1d1b97bcac741f1559272a2250e 100644 (file)
@@ -93,6 +93,7 @@ extern int radeon_audio;
 extern int radeon_disp_priority;
 extern int radeon_hw_i2c;
 extern int radeon_pcie_gen2;
+extern int radeon_msi;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -306,30 +307,17 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
  */
 struct radeon_mc;
 
-struct radeon_gart_table_ram {
-       volatile uint32_t               *ptr;
-};
-
-struct radeon_gart_table_vram {
-       struct radeon_bo                *robj;
-       volatile uint32_t               *ptr;
-};
-
-union radeon_gart_table {
-       struct radeon_gart_table_ram    ram;
-       struct radeon_gart_table_vram   vram;
-};
-
 #define RADEON_GPU_PAGE_SIZE 4096
 #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
 #define RADEON_GPU_PAGE_SHIFT 12
 
 struct radeon_gart {
        dma_addr_t                      table_addr;
+       struct radeon_bo                *robj;
+       void                            *ptr;
        unsigned                        num_gpu_pages;
        unsigned                        num_cpu_pages;
        unsigned                        table_size;
-       union radeon_gart_table         table;
        struct page                     **pages;
        dma_addr_t                      *pages_addr;
        bool                            *ttm_alloced;
@@ -340,6 +328,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev);
 void radeon_gart_table_ram_free(struct radeon_device *rdev);
 int radeon_gart_table_vram_alloc(struct radeon_device *rdev);
 void radeon_gart_table_vram_free(struct radeon_device *rdev);
+int radeon_gart_table_vram_pin(struct radeon_device *rdev);
+void radeon_gart_table_vram_unpin(struct radeon_device *rdev);
 int radeon_gart_init(struct radeon_device *rdev);
 void radeon_gart_fini(struct radeon_device *rdev);
 void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
@@ -347,6 +337,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
 int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
                     int pages, struct page **pagelist,
                     dma_addr_t *dma_addr);
+void radeon_gart_restore(struct radeon_device *rdev);
 
 
 /*
@@ -437,25 +428,26 @@ union radeon_irq_stat_regs {
        struct evergreen_irq_stat_regs evergreen;
 };
 
+#define RADEON_MAX_HPD_PINS 6
+#define RADEON_MAX_CRTCS 6
+#define RADEON_MAX_HDMI_BLOCKS 2
+
 struct radeon_irq {
        bool            installed;
        bool            sw_int;
-       /* FIXME: use a define max crtc rather than hardcode it */
-       bool            crtc_vblank_int[6];
-       bool            pflip[6];
+       bool            crtc_vblank_int[RADEON_MAX_CRTCS];
+       bool            pflip[RADEON_MAX_CRTCS];
        wait_queue_head_t       vblank_queue;
-       /* FIXME: use defines for max hpd/dacs */
-       bool            hpd[6];
+       bool            hpd[RADEON_MAX_HPD_PINS];
        bool            gui_idle;
        bool            gui_idle_acked;
        wait_queue_head_t       idle_queue;
-       /* FIXME: use defines for max HDMI blocks */
-       bool            hdmi[2];
+       bool            hdmi[RADEON_MAX_HDMI_BLOCKS];
        spinlock_t sw_lock;
        int sw_refcount;
        union radeon_irq_stat_regs stat_regs;
-       spinlock_t pflip_lock[6];
-       int pflip_refcount[6];
+       spinlock_t pflip_lock[RADEON_MAX_CRTCS];
+       int pflip_refcount[RADEON_MAX_CRTCS];
 };
 
 int radeon_irq_kms_init(struct radeon_device *rdev);
@@ -533,7 +525,7 @@ struct r600_blit_cp_primitives {
        void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr);
        void (*set_tex_resource)(struct radeon_device *rdev,
                                 int format, int w, int h, int pitch,
-                                u64 gpu_addr);
+                                u64 gpu_addr, u32 size);
        void (*set_scissors)(struct radeon_device *rdev, int x1, int y1,
                             int x2, int y2);
        void (*draw_auto)(struct radeon_device *rdev);
@@ -619,7 +611,8 @@ struct radeon_cs_parser {
        struct radeon_ib        *ib;
        void                    *track;
        unsigned                family;
-       int parser_error;
+       int                     parser_error;
+       bool                    keep_tiling_flags;
 };
 
 extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
@@ -792,8 +785,7 @@ struct radeon_pm_clock_info {
 
 struct radeon_power_state {
        enum radeon_pm_state_type type;
-       /* XXX: use a define for num clock modes */
-       struct radeon_pm_clock_info clock_info[8];
+       struct radeon_pm_clock_info *clock_info;
        /* number of valid clock modes in this power state */
        int num_clock_modes;
        struct radeon_pm_clock_info *default_clock_mode;
@@ -863,6 +855,9 @@ struct radeon_pm {
        struct device           *int_hwmon_dev;
 };
 
+int radeon_pm_get_type_index(struct radeon_device *rdev,
+                            enum radeon_pm_state_type ps_type,
+                            int instance);
 
 /*
  * Benchmarking
@@ -1143,12 +1138,55 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
 int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *filp);
 
-/* VRAM scratch page for HDP bug */
-struct r700_vram_scratch {
+/* VRAM scratch page for HDP bug, default vram page */
+struct r600_vram_scratch {
        struct radeon_bo                *robj;
        volatile uint32_t               *ptr;
+       u64                             gpu_addr;
 };
 
+
+/*
+ * Mutex which allows recursive locking from the same process.
+ */
+struct radeon_mutex {
+       struct mutex            mutex;
+       struct task_struct      *owner;
+       int                     level;
+};
+
+static inline void radeon_mutex_init(struct radeon_mutex *mutex)
+{
+       mutex_init(&mutex->mutex);
+       mutex->owner = NULL;
+       mutex->level = 0;
+}
+
+static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
+{
+       if (mutex_trylock(&mutex->mutex)) {
+               /* The mutex was unlocked before, so it's ours now */
+               mutex->owner = current;
+       } else if (mutex->owner != current) {
+               /* Another process locked the mutex, take it */
+               mutex_lock(&mutex->mutex);
+               mutex->owner = current;
+       }
+       /* Otherwise the mutex was already locked by this process */
+
+       mutex->level++;
+}
+
+static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
+{
+       if (--mutex->level > 0)
+               return;
+
+       mutex->owner = NULL;
+       mutex_unlock(&mutex->mutex);
+}
+
+
 /*
  * Core structure, functions and helpers.
  */
@@ -1204,7 +1242,7 @@ struct radeon_device {
        struct radeon_gem               gem;
        struct radeon_pm                pm;
        uint32_t                        bios_scratch[RADEON_BIOS_NUM_SCRATCH];
-       struct mutex                    cs_mutex;
+       struct radeon_mutex             cs_mutex;
        struct radeon_wb                wb;
        struct radeon_dummy_page        dummy_page;
        bool                            gpu_lockup;
@@ -1218,7 +1256,7 @@ struct radeon_device {
        const struct firmware *rlc_fw;  /* r6/700 RLC firmware */
        const struct firmware *mc_fw;   /* NI MC firmware */
        struct r600_blit r600_blit;
-       struct r700_vram_scratch vram_scratch;
+       struct r600_vram_scratch vram_scratch;
        int msi_enabled; /* msi enabled */
        struct r600_ih ih; /* r6/700 interrupt ring */
        struct work_struct hotplug_work;
@@ -1442,8 +1480,6 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v);
 /* AGP */
 extern int radeon_gpu_reset(struct radeon_device *rdev);
 extern void radeon_agp_disable(struct radeon_device *rdev);
-extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
-extern void radeon_gart_restore(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern void radeon_modeset_fini(struct radeon_device *rdev);
 extern bool radeon_card_posted(struct radeon_device *rdev);
@@ -1466,6 +1502,12 @@ extern int radeon_resume_kms(struct drm_device *dev);
 extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
 extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size);
 
+/*
+ * R600 vram scratch functions
+ */
+int r600_vram_scratch_init(struct radeon_device *rdev);
+void r600_vram_scratch_fini(struct radeon_device *rdev);
+
 /*
  * r600 functions used by radeon_encoder.c
  */
index 3f6636bb2d7f874abf0208cff67010f82c2f4e75..3516a6081dcfcc3acb35d4d64286ea0f321da01e 100644 (file)
@@ -35,7 +35,8 @@ static int radeon_atif_call(acpi_handle handle)
 
        /* Fail only if calling the method fails and ATIF is supported */
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-               printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status));
+               DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
+                                acpi_format_exception(status));
                kfree(buffer.pointer);
                return 1;
        }
@@ -50,13 +51,13 @@ int radeon_acpi_init(struct radeon_device *rdev)
        acpi_handle handle;
        int ret;
 
-       /* No need to proceed if we're sure that ATIF is not supported */
-       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios)
-               return 0;
-
        /* Get the device handle */
        handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
 
+       /* No need to proceed if we're sure that ATIF is not supported */
+       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
+               return 0;
+
        /* Call the ATIF method */
        ret = radeon_atif_call(handle);
        if (ret)
index e2944566ffea5a6942cfb0ab17c89316cacc49a1..a2e1eae114ef9ec1048e8b455bd5dee29fe28277 100644 (file)
@@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = {
        .pm_misc = &evergreen_pm_misc,
        .pm_prepare = &evergreen_pm_prepare,
        .pm_finish = &evergreen_pm_finish,
-       .pm_init_profile = &rs780_pm_init_profile,
+       .pm_init_profile = &sumo_pm_init_profile,
        .pm_get_dynpm_state = &r600_pm_get_dynpm_state,
        .pre_page_flip = &evergreen_pre_page_flip,
        .page_flip = &evergreen_page_flip,
index 85f14f0337e402f8d978cf7219e9861ef276aa5c..59914842a7292c63b5bad6032d3b1a496ed06e7d 100644 (file)
@@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p);
 extern void evergreen_pm_misc(struct radeon_device *rdev);
 extern void evergreen_pm_prepare(struct radeon_device *rdev);
 extern void evergreen_pm_finish(struct radeon_device *rdev);
+extern void sumo_pm_init_profile(struct radeon_device *rdev);
 extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc);
 extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base);
 extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc);
index 08d0b94332e6f19c72babaedd8828e69444b4ea1..d24baf30efcb8e583ab38b0540fe508369e47423 100644 (file)
@@ -62,6 +62,87 @@ union atom_supported_devices {
        struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
 };
 
+static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev,
+                                         ATOM_GPIO_I2C_ASSIGMENT *gpio,
+                                         u8 index)
+{
+       /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */
+       if ((rdev->family == CHIP_R420) ||
+           (rdev->family == CHIP_R423) ||
+           (rdev->family == CHIP_RV410)) {
+               if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) ||
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) ||
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) {
+                       gpio->ucClkMaskShift = 0x19;
+                       gpio->ucDataMaskShift = 0x18;
+               }
+       }
+
+       /* some evergreen boards have bad data for this entry */
+       if (ASIC_IS_DCE4(rdev)) {
+               if ((index == 7) &&
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
+                   (gpio->sucI2cId.ucAccess == 0)) {
+                       gpio->sucI2cId.ucAccess = 0x97;
+                       gpio->ucDataMaskShift = 8;
+                       gpio->ucDataEnShift = 8;
+                       gpio->ucDataY_Shift = 8;
+                       gpio->ucDataA_Shift = 8;
+               }
+       }
+
+       /* some DCE3 boards have bad data for this entry */
+       if (ASIC_IS_DCE3(rdev)) {
+               if ((index == 4) &&
+                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
+                   (gpio->sucI2cId.ucAccess == 0x94))
+                       gpio->sucI2cId.ucAccess = 0x14;
+       }
+}
+
+static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
+{
+       struct radeon_i2c_bus_rec i2c;
+
+       memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
+
+       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
+       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
+       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
+       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
+       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
+       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
+
+       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+               i2c.hw_capable = true;
+       else
+               i2c.hw_capable = false;
+
+       if (gpio->sucI2cId.ucAccess == 0xa0)
+               i2c.mm_i2c = true;
+       else
+               i2c.mm_i2c = false;
+
+       i2c.i2c_id = gpio->sucI2cId.ucAccess;
+
+       if (i2c.mask_clk_reg)
+               i2c.valid = true;
+       else
+               i2c.valid = false;
+
+       return i2c;
+}
+
 static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev,
                                                               uint8_t id)
 {
@@ -85,59 +166,10 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd
                for (i = 0; i < num_indices; i++) {
                        gpio = &i2c_info->asGPIO_Info[i];
 
-                       /* some evergreen boards have bad data for this entry */
-                       if (ASIC_IS_DCE4(rdev)) {
-                               if ((i == 7) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
-                                   (gpio->sucI2cId.ucAccess == 0)) {
-                                       gpio->sucI2cId.ucAccess = 0x97;
-                                       gpio->ucDataMaskShift = 8;
-                                       gpio->ucDataEnShift = 8;
-                                       gpio->ucDataY_Shift = 8;
-                                       gpio->ucDataA_Shift = 8;
-                               }
-                       }
-
-                       /* some DCE3 boards have bad data for this entry */
-                       if (ASIC_IS_DCE3(rdev)) {
-                               if ((i == 4) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
-                                   (gpio->sucI2cId.ucAccess == 0x94))
-                                       gpio->sucI2cId.ucAccess = 0x14;
-                       }
+                       radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
 
                        if (gpio->sucI2cId.ucAccess == id) {
-                               i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-                               i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-                               i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-                               i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-                               i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-                               i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-                               i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-                               i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-                               i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-                               i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-                               i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-                               i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-                               i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-                               i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-                               i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-                               i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
-                               if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-                                       i2c.hw_capable = true;
-                               else
-                                       i2c.hw_capable = false;
-
-                               if (gpio->sucI2cId.ucAccess == 0xa0)
-                                       i2c.mm_i2c = true;
-                               else
-                                       i2c.mm_i2c = false;
-
-                               i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
-                               if (i2c.mask_clk_reg)
-                                       i2c.valid = true;
+                               i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
                                break;
                        }
                }
@@ -157,8 +189,6 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
        int i, num_indices;
        char stmp[32];
 
-       memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
-
        if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
                i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
@@ -167,60 +197,12 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
 
                for (i = 0; i < num_indices; i++) {
                        gpio = &i2c_info->asGPIO_Info[i];
-                       i2c.valid = false;
-
-                       /* some evergreen boards have bad data for this entry */
-                       if (ASIC_IS_DCE4(rdev)) {
-                               if ((i == 7) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
-                                   (gpio->sucI2cId.ucAccess == 0)) {
-                                       gpio->sucI2cId.ucAccess = 0x97;
-                                       gpio->ucDataMaskShift = 8;
-                                       gpio->ucDataEnShift = 8;
-                                       gpio->ucDataY_Shift = 8;
-                                       gpio->ucDataA_Shift = 8;
-                               }
-                       }
 
-                       /* some DCE3 boards have bad data for this entry */
-                       if (ASIC_IS_DCE3(rdev)) {
-                               if ((i == 4) &&
-                                   (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) &&
-                                   (gpio->sucI2cId.ucAccess == 0x94))
-                                       gpio->sucI2cId.ucAccess = 0x14;
-                       }
+                       radeon_lookup_i2c_gpio_quirks(rdev, gpio, i);
 
-                       i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
-                       i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
-                       i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
-                       i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
-                       i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
-                       i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
-                       i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
-                       i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
-                       i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
-                       i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
-                       i2c.en_clk_mask = (1 << gpio->ucClkEnShift);
-                       i2c.en_data_mask = (1 << gpio->ucDataEnShift);
-                       i2c.y_clk_mask = (1 << gpio->ucClkY_Shift);
-                       i2c.y_data_mask = (1 << gpio->ucDataY_Shift);
-                       i2c.a_clk_mask = (1 << gpio->ucClkA_Shift);
-                       i2c.a_data_mask = (1 << gpio->ucDataA_Shift);
-
-                       if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
-                               i2c.hw_capable = true;
-                       else
-                               i2c.hw_capable = false;
-
-                       if (gpio->sucI2cId.ucAccess == 0xa0)
-                               i2c.mm_i2c = true;
-                       else
-                               i2c.mm_i2c = false;
+                       i2c = radeon_get_bus_rec_for_i2c_gpio(gpio);
 
-                       i2c.i2c_id = gpio->sucI2cId.ucAccess;
-
-                       if (i2c.mask_clk_reg) {
-                               i2c.valid = true;
+                       if (i2c.valid) {
                                sprintf(stmp, "0x%x", i2c.i2c_id);
                                rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
                        }
@@ -1996,10 +1978,14 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                return state_index;
        /* last mode is usually default, array is low to high */
        for (i = 0; i < num_modes; i++) {
+               rdev->pm.power_state[state_index].clock_info =
+                       kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+               if (!rdev->pm.power_state[state_index].clock_info)
+                       return state_index;
+               rdev->pm.power_state[state_index].num_clock_modes = 1;
                rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
                switch (frev) {
                case 1:
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
@@ -2035,7 +2021,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                        state_index++;
                        break;
                case 2:
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
@@ -2072,7 +2057,6 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
                        state_index++;
                        break;
                case 3:
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
                        rdev->pm.power_state[state_index].clock_info[0].mclk =
                                le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
                        rdev->pm.power_state[state_index].clock_info[0].sclk =
@@ -2257,7 +2241,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
                rdev->pm.default_power_state_index = state_index;
                rdev->pm.power_state[state_index].default_clock_mode =
                        &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
-               if (ASIC_IS_DCE5(rdev)) {
+               if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
                        /* NI chips post without MC ucode, so default clocks are strobe mode only */
                        rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
                        rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
@@ -2377,17 +2361,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
                         le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
                         (power_state->v1.ucNonClockStateIndex *
                          power_info->pplib.ucNonClockSize));
-               for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
-                       clock_info = (union pplib_clock_info *)
-                               (mode_info->atom_context->bios + data_offset +
-                                le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
-                                (power_state->v1.ucClockStateIndices[j] *
-                                 power_info->pplib.ucClockInfoSize));
-                       valid = radeon_atombios_parse_pplib_clock_info(rdev,
-                                                                      state_index, mode_index,
-                                                                      clock_info);
-                       if (valid)
-                               mode_index++;
+               rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
+                                                            ((power_info->pplib.ucStateEntrySize - 1) ?
+                                                             (power_info->pplib.ucStateEntrySize - 1) : 1),
+                                                            GFP_KERNEL);
+               if (!rdev->pm.power_state[i].clock_info)
+                       return state_index;
+               if (power_info->pplib.ucStateEntrySize - 1) {
+                       for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
+                               clock_info = (union pplib_clock_info *)
+                                       (mode_info->atom_context->bios + data_offset +
+                                        le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+                                        (power_state->v1.ucClockStateIndices[j] *
+                                         power_info->pplib.ucClockInfoSize));
+                               valid = radeon_atombios_parse_pplib_clock_info(rdev,
+                                                                              state_index, mode_index,
+                                                                              clock_info);
+                               if (valid)
+                                       mode_index++;
+                       }
+               } else {
+                       rdev->pm.power_state[state_index].clock_info[0].mclk =
+                               rdev->clock.default_mclk;
+                       rdev->pm.power_state[state_index].clock_info[0].sclk =
+                               rdev->clock.default_sclk;
+                       mode_index++;
                }
                rdev->pm.power_state[state_index].num_clock_modes = mode_index;
                if (mode_index) {
@@ -2456,18 +2454,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
                non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
                non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
                        &non_clock_info_array->nonClockInfo[non_clock_array_index];
-               for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
-                       clock_array_index = power_state->v2.clockInfoIndex[j];
-                       /* XXX this might be an inagua bug... */
-                       if (clock_array_index >= clock_info_array->ucNumEntries)
-                               continue;
-                       clock_info = (union pplib_clock_info *)
-                               &clock_info_array->clockInfo[clock_array_index];
-                       valid = radeon_atombios_parse_pplib_clock_info(rdev,
-                                                                      state_index, mode_index,
-                                                                      clock_info);
-                       if (valid)
-                               mode_index++;
+               rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
+                                                            (power_state->v2.ucNumDPMLevels ?
+                                                             power_state->v2.ucNumDPMLevels : 1),
+                                                            GFP_KERNEL);
+               if (!rdev->pm.power_state[i].clock_info)
+                       return state_index;
+               if (power_state->v2.ucNumDPMLevels) {
+                       for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
+                               clock_array_index = power_state->v2.clockInfoIndex[j];
+                               /* XXX this might be an inagua bug... */
+                               if (clock_array_index >= clock_info_array->ucNumEntries)
+                                       continue;
+                               clock_info = (union pplib_clock_info *)
+                                       &clock_info_array->clockInfo[clock_array_index];
+                               valid = radeon_atombios_parse_pplib_clock_info(rdev,
+                                                                              state_index, mode_index,
+                                                                              clock_info);
+                               if (valid)
+                                       mode_index++;
+                       }
+               } else {
+                       rdev->pm.power_state[state_index].clock_info[0].mclk =
+                               rdev->clock.default_mclk;
+                       rdev->pm.power_state[state_index].clock_info[0].sclk =
+                               rdev->clock.default_sclk;
+                       mode_index++;
                }
                rdev->pm.power_state[state_index].num_clock_modes = mode_index;
                if (mode_index) {
@@ -2524,19 +2536,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
        } else {
                rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
                if (rdev->pm.power_state) {
-                       /* add the default mode */
-                       rdev->pm.power_state[state_index].type =
-                               POWER_STATE_TYPE_DEFAULT;
-                       rdev->pm.power_state[state_index].num_clock_modes = 1;
-                       rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
-                       rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
-                       rdev->pm.power_state[state_index].default_clock_mode =
-                               &rdev->pm.power_state[state_index].clock_info[0];
-                       rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
-                       rdev->pm.power_state[state_index].pcie_lanes = 16;
-                       rdev->pm.default_power_state_index = state_index;
-                       rdev->pm.power_state[state_index].flags = 0;
-                       state_index++;
+                       rdev->pm.power_state[0].clock_info =
+                               kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+                       if (rdev->pm.power_state[0].clock_info) {
+                               /* add the default mode */
+                               rdev->pm.power_state[state_index].type =
+                                       POWER_STATE_TYPE_DEFAULT;
+                               rdev->pm.power_state[state_index].num_clock_modes = 1;
+                               rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
+                               rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
+                               rdev->pm.power_state[state_index].default_clock_mode =
+                                       &rdev->pm.power_state[state_index].clock_info[0];
+                               rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
+                               rdev->pm.power_state[state_index].pcie_lanes = 16;
+                               rdev->pm.default_power_state_index = state_index;
+                               rdev->pm.power_state[state_index].flags = 0;
+                               state_index++;
+                       }
                }
        }
 
index 5cafc90de7f8cec757fa5695db9865ccc621cabc..17e1a9b2d8fbf3e1dedce2923a7e5b726aea284c 100644 (file)
@@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
        struct radeon_bo *sobj = NULL;
        uint64_t saddr, daddr;
        int r, n;
-       unsigned int time;
+       int time;
 
        n = RADEON_BENCHMARK_ITERATIONS;
        r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj);
index 8bf83c4b4147541b0379f75dcec3e36177848dd1..81fc100be7e18c321c088bc787e1154de96e11e3 100644 (file)
@@ -2563,14 +2563,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
 
        /* allocate 2 power states */
        rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL);
-       if (!rdev->pm.power_state) {
-               rdev->pm.default_power_state_index = state_index;
-               rdev->pm.num_power_states = 0;
-
-               rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
-               rdev->pm.current_clock_mode_index = 0;
-               return;
-       }
+       if (rdev->pm.power_state) {
+               /* allocate 1 clock mode per state */
+               rdev->pm.power_state[0].clock_info =
+                       kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+               rdev->pm.power_state[1].clock_info =
+                       kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
+               if (!rdev->pm.power_state[0].clock_info ||
+                   !rdev->pm.power_state[1].clock_info)
+                       goto pm_failed;
+       } else
+               goto pm_failed;
 
        /* check for a thermal chip */
        offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
@@ -2733,6 +2736,14 @@ default_mode:
        rdev->pm.default_power_state_index = state_index;
        rdev->pm.num_power_states = state_index + 1;
 
+       rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
+       rdev->pm.current_clock_mode_index = 0;
+       return;
+
+pm_failed:
+       rdev->pm.default_power_state_index = state_index;
+       rdev->pm.num_power_states = 0;
+
        rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
        rdev->pm.current_clock_mode_index = 0;
 }
index dec6cbe6a0a6a4ef5a1b59be5b63e037521870a4..e7cb3ab09243165c57d261944cd30b489703e149 100644 (file)
@@ -44,8 +44,6 @@ extern void
 radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
                             struct drm_connector *drm_connector);
 
-bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
-
 void radeon_connector_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
@@ -432,55 +430,6 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
        return 0;
 }
 
-/*
- * Some integrated ATI Radeon chipset implementations (e. g.
- * Asus M2A-VM HDMI) may indicate the availability of a DDC,
- * even when there's no monitor connected. For these connectors
- * following DDC probe extension will be applied: check also for the
- * availability of EDID with at least a correct EDID header. Only then,
- * DDC is assumed to be available. This prevents drm_get_edid() and
- * drm_edid_block_valid() from periodically dumping data and kernel
- * errors into the logs and onto the terminal.
- */
-static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
-                                    uint32_t supported_device,
-                                    int connector_type)
-{
-       /* Asus M2A-VM HDMI board sends data to i2c bus even,
-        * if HDMI add-on card is not plugged in or HDMI is disabled in
-        * BIOS. Valid DDC can only be assumed, if also a valid EDID header
-        * can be retrieved via i2c bus during DDC probe */
-       if ((dev->pdev->device == 0x791e) &&
-           (dev->pdev->subsystem_vendor == 0x1043) &&
-           (dev->pdev->subsystem_device == 0x826d)) {
-               if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
-                   (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
-                       return true;
-       }
-       /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus
-        * for a DVI connector that is not implemented */
-       if ((dev->pdev->device == 0x796e) &&
-           (dev->pdev->subsystem_vendor == 0x1019) &&
-           (dev->pdev->subsystem_device == 0x2615)) {
-               if ((connector_type == DRM_MODE_CONNECTOR_DVID) &&
-                   (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
-                       return true;
-       }
-       /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100
-        * (RS690M) sends data to i2c bus for a HDMI connector that
-        * is not implemented */
-       if ((dev->pdev->device == 0x791f) &&
-           (dev->pdev->subsystem_vendor == 0x1179) &&
-           (dev->pdev->subsystem_device == 0xff68)) {
-               if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
-                   (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
-                       return true;
-       }
-
-       /* Default: no EDID header probe required for DDC probing */
-       return false;
-}
-
 static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
                                          struct drm_connector *connector)
 {
@@ -721,8 +670,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
                ret = connector_status_disconnected;
 
        if (radeon_connector->ddc_bus)
-               dret = radeon_ddc_probe(radeon_connector,
-                                       radeon_connector->requires_extended_probe);
+               dret = radeon_ddc_probe(radeon_connector);
        if (dret) {
                radeon_connector->detected_by_load = false;
                if (radeon_connector->edid) {
@@ -764,7 +712,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
                if (radeon_connector->dac_load_detect && encoder) {
                        encoder_funcs = encoder->helper_private;
                        ret = encoder_funcs->detect(encoder, connector);
-                       if (ret == connector_status_connected)
+                       if (ret != connector_status_disconnected)
                                radeon_connector->detected_by_load = true;
                }
        }
@@ -904,8 +852,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
        bool dret = false;
 
        if (radeon_connector->ddc_bus)
-               dret = radeon_ddc_probe(radeon_connector,
-                                       radeon_connector->requires_extended_probe);
+               dret = radeon_ddc_probe(radeon_connector);
        if (dret) {
                radeon_connector->detected_by_load = false;
                if (radeon_connector->edid) {
@@ -1005,8 +952,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                                        ret = encoder_funcs->detect(encoder, connector);
                                        if (ret == connector_status_connected) {
                                                radeon_connector->use_digital = false;
-                                               radeon_connector->detected_by_load = true;
                                        }
+                                       if (ret != connector_status_disconnected)
+                                               radeon_connector->detected_by_load = true;
                                }
                                break;
                        }
@@ -1203,7 +1151,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
                }
        } else {
                /* need to setup ddc on the bridge */
-               if (radeon_connector_encoder_is_dp_bridge(connector)) {
+               if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+                       ENCODER_OBJECT_ID_NONE) {
                        if (encoder)
                                radeon_atom_ext_encoder_setup_ddc(encoder);
                }
@@ -1213,13 +1162,12 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
        return ret;
 }
 
-bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector)
+u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)
 {
        struct drm_mode_object *obj;
        struct drm_encoder *encoder;
        struct radeon_encoder *radeon_encoder;
        int i;
-       bool found = false;
 
        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
                if (connector->encoder_ids[i] == 0)
@@ -1235,14 +1183,13 @@ bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector)
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_TRAVIS:
                case ENCODER_OBJECT_ID_NUTMEG:
-                       found = true;
-                       break;
+                       return radeon_encoder->encoder_id;
                default:
                        break;
                }
        }
 
-       return found;
+       return ENCODER_OBJECT_ID_NONE;
 }
 
 bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
@@ -1319,7 +1266,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
                if (!radeon_dig_connector->edp_on)
                        atombios_set_edp_panel_power(connector,
                                                     ATOM_TRANSMITTER_ACTION_POWER_OFF);
-       } else if (radeon_connector_encoder_is_dp_bridge(connector)) {
+       } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+                  ENCODER_OBJECT_ID_NONE) {
                /* DP bridges are always DP */
                radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
                /* get the DPCD from the bridge */
@@ -1328,8 +1276,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
                if (encoder) {
                        /* setup ddc on the bridge */
                        radeon_atom_ext_encoder_setup_ddc(encoder);
-                       if (radeon_ddc_probe(radeon_connector,
-                                            radeon_connector->requires_extended_probe)) /* try DDC */
+                       if (radeon_ddc_probe(radeon_connector)) /* try DDC */
                                ret = connector_status_connected;
                        else if (radeon_connector->dac_load_detect) { /* try load detection */
                                struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -1347,8 +1294,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
                                if (radeon_dp_getdpcd(radeon_connector))
                                        ret = connector_status_connected;
                        } else {
-                               if (radeon_ddc_probe(radeon_connector,
-                                                    radeon_connector->requires_extended_probe))
+                               if (radeon_ddc_probe(radeon_connector))
                                        ret = connector_status_connected;
                        }
                }
@@ -1493,9 +1439,7 @@ radeon_add_atom_connector(struct drm_device *dev,
        radeon_connector->shared_ddc = shared_ddc;
        radeon_connector->connector_object_id = connector_object_id;
        radeon_connector->hpd = *hpd;
-       radeon_connector->requires_extended_probe =
-               radeon_connector_needs_extended_probe(rdev, supported_device,
-                                                       connector_type);
+
        radeon_connector->router = *router;
        if (router->ddc_valid || router->cd_valid) {
                radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
@@ -1842,9 +1786,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
        radeon_connector->devices = supported_device;
        radeon_connector->connector_object_id = connector_object_id;
        radeon_connector->hpd = *hpd;
-       radeon_connector->requires_extended_probe =
-               radeon_connector_needs_extended_probe(rdev, supported_device,
-                                                       connector_type);
+
        switch (connector_type) {
        case DRM_MODE_CONNECTOR_VGA:
                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
index 045ec59478f98210567375c9fa2d5a8c5f9493ac..72ae8266b8e9d88edaa7d8369e7512cbde13c734 100644 (file)
@@ -29,6 +29,8 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
index fae00c0d75aaf1fae7fcbfc9b504370f560f5d42..29afd71e0840a0b9995b5e30027577adeec45b92 100644 (file)
@@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 {
        struct drm_radeon_cs *cs = data;
        uint64_t *chunk_array_ptr;
-       unsigned size, i;
+       unsigned size, i, flags = 0;
 
        if (!cs->num_chunks) {
                return 0;
@@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                        if (p->chunks[i].length_dw == 0)
                                return -EINVAL;
                }
+               if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS &&
+                   !p->chunks[i].length_dw) {
+                       return -EINVAL;
+               }
 
                p->chunks[i].length_dw = user_chunk.length_dw;
                p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
@@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                                               p->chunks[i].user_ptr, size)) {
                                return -EFAULT;
                        }
+                       if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
+                               flags = p->chunks[i].kdata[0];
+                       }
                } else {
                        p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
                        p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
                          p->chunks[p->chunk_ib_idx].length_dw);
                return -EINVAL;
        }
+
+       p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0;
        return 0;
 }
 
@@ -222,7 +231,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        struct radeon_cs_chunk *ib_chunk;
        int r;
 
-       mutex_lock(&rdev->cs_mutex);
+       radeon_mutex_lock(&rdev->cs_mutex);
        /* initialize parser */
        memset(&parser, 0, sizeof(struct radeon_cs_parser));
        parser.filp = filp;
@@ -233,14 +242,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        if (r) {
                DRM_ERROR("Failed to initialize parser !\n");
                radeon_cs_parser_fini(&parser, r);
-               mutex_unlock(&rdev->cs_mutex);
+               radeon_mutex_unlock(&rdev->cs_mutex);
                return r;
        }
        r =  radeon_ib_get(rdev, &parser.ib);
        if (r) {
                DRM_ERROR("Failed to get ib !\n");
                radeon_cs_parser_fini(&parser, r);
-               mutex_unlock(&rdev->cs_mutex);
+               radeon_mutex_unlock(&rdev->cs_mutex);
                return r;
        }
        r = radeon_cs_parser_relocs(&parser);
@@ -248,7 +257,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                if (r != -ERESTARTSYS)
                        DRM_ERROR("Failed to parse relocation %d!\n", r);
                radeon_cs_parser_fini(&parser, r);
-               mutex_unlock(&rdev->cs_mutex);
+               radeon_mutex_unlock(&rdev->cs_mutex);
                return r;
        }
        /* Copy the packet into the IB, the parser will read from the
@@ -260,14 +269,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        if (r || parser.parser_error) {
                DRM_ERROR("Invalid command stream !\n");
                radeon_cs_parser_fini(&parser, r);
-               mutex_unlock(&rdev->cs_mutex);
+               radeon_mutex_unlock(&rdev->cs_mutex);
                return r;
        }
        r = radeon_cs_finish_pages(&parser);
        if (r) {
                DRM_ERROR("Invalid command stream !\n");
                radeon_cs_parser_fini(&parser, r);
-               mutex_unlock(&rdev->cs_mutex);
+               radeon_mutex_unlock(&rdev->cs_mutex);
                return r;
        }
        r = radeon_ib_schedule(rdev, parser.ib);
@@ -275,7 +284,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                DRM_ERROR("Failed to schedule IB !\n");
        }
        radeon_cs_parser_fini(&parser, r);
-       mutex_unlock(&rdev->cs_mutex);
+       radeon_mutex_unlock(&rdev->cs_mutex);
        return r;
 }
 
index c33bc914d93df9fce399c09d69fb770708c90393..c4d00a171411890fe701ea853ca084c39e4ac3b7 100644 (file)
@@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev,
 
        /* mutex initialization are all done here so we
         * can recall function without having locking issues */
-       mutex_init(&rdev->cs_mutex);
+       radeon_mutex_init(&rdev->cs_mutex);
        mutex_init(&rdev->ib_pool.mutex);
        mutex_init(&rdev->cp.mutex);
        mutex_init(&rdev->dc_hw_i2c_mutex);
@@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev)
        int r;
        int resched;
 
+       /* Prevent CS ioctl from interfering */
+       radeon_mutex_lock(&rdev->cs_mutex);
+
        radeon_save_bios_scratch_regs(rdev);
        /* block TTM */
        resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
@@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev)
                radeon_restore_bios_scratch_regs(rdev);
                drm_helper_resume_force_mode(rdev->ddev);
                ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
-               return 0;
        }
-       /* bad news, how to tell it to userspace ? */
-       dev_info(rdev->dev, "GPU reset failed\n");
+
+       radeon_mutex_unlock(&rdev->cs_mutex);
+
+       if (r) {
+               /* bad news, how to tell it to userspace ? */
+               dev_info(rdev->dev, "GPU reset failed\n");
+       }
+
        return r;
 }
 
index 6adb3e58affdc3fccbce06e254cf648c6f4de5cb..a22d6e6a49a2649796a119c2b642a83659f8edd3 100644 (file)
@@ -33,8 +33,6 @@
 #include "drm_crtc_helper.h"
 #include "drm_edid.h"
 
-static int radeon_ddc_dump(struct drm_connector *connector);
-
 static void avivo_crtc_load_lut(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -669,7 +667,6 @@ static void radeon_print_display_setup(struct drm_device *dev)
 static bool radeon_setup_enc_conn(struct drm_device *dev)
 {
        struct radeon_device *rdev = dev->dev_private;
-       struct drm_connector *drm_connector;
        bool ret = false;
 
        if (rdev->bios) {
@@ -689,8 +686,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
        if (ret) {
                radeon_setup_encoder_clones(dev);
                radeon_print_display_setup(dev);
-               list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head)
-                       radeon_ddc_dump(drm_connector);
        }
 
        return ret;
@@ -708,7 +703,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 
        if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
            (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) ||
-           radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) {
+           (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
+            ENCODER_OBJECT_ID_NONE)) {
                struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
 
                if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
@@ -743,34 +739,6 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
        return 0;
 }
 
-static int radeon_ddc_dump(struct drm_connector *connector)
-{
-       struct edid *edid;
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-       int ret = 0;
-
-       /* on hw with routers, select right port */
-       if (radeon_connector->router.ddc_valid)
-               radeon_router_select_ddc_port(radeon_connector);
-
-       if (!radeon_connector->ddc_bus)
-               return -1;
-       edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
-       /* Log EDID retrieval status here. In particular with regard to
-        * connectors with requires_extended_probe flag set, that will prevent
-        * function radeon_dvi_detect() to fetch EDID on this connector,
-        * as long as there is no valid EDID header found */
-       if (edid) {
-               DRM_INFO("Radeon display connector %s: Found valid EDID",
-                               drm_get_connector_name(connector));
-               kfree(edid);
-       } else {
-               DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID",
-                               drm_get_connector_name(connector));
-       }
-       return ret;
-}
-
 /* avivo */
 static void avivo_get_fb_div(struct radeon_pll *pll,
                             u32 target_clock,
index e71d2ed7fa113126e7cacb06b1553f8767b948e6..71499fc3daf524f8b719692e9ff7aacb6219b2e9 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "drm_pciids.h"
 #include <linux/console.h>
+#include <linux/module.h>
 
 
 /*
  *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
  *   2.10.0 - fusion 2D tiling
  *   2.11.0 - backend map, initial compute support for the CS checker
+ *   2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       11
+#define KMS_DRIVER_MINOR       12
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -118,6 +120,7 @@ int radeon_audio = 0;
 int radeon_disp_priority = 0;
 int radeon_hw_i2c = 0;
 int radeon_pcie_gen2 = 0;
+int radeon_msi = -1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -164,6 +167,9 @@ module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
 MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)");
 module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444);
 
+MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)");
+module_param_named(msi, radeon_msi, int, 0444);
+
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
index eb3f6dc6df835050dfacaae3a663f4a79f7f254c..4b27efa4405b94b63011b2e8948d678c35ccfd62 100644 (file)
 #include "radeon.h"
 #include "atom.h"
 
-extern int atom_debug;
-
-/* evil but including atombios.h is much worse */
-bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
-                               struct drm_display_mode *mode);
-
 static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
@@ -156,27 +150,6 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8
        return ret;
 }
 
-static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
-{
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-               return true;
-       default:
-               return false;
-       }
-}
-
 void
 radeon_link_encoder_connector(struct drm_device *dev)
 {
@@ -229,23 +202,7 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
        return NULL;
 }
 
-static struct drm_connector *
-radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_connector *connector;
-       struct radeon_connector *radeon_connector;
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               radeon_connector = to_radeon_connector(connector);
-               if (radeon_encoder->devices & radeon_connector->devices)
-                       return connector;
-       }
-       return NULL;
-}
-
-struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
+struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
 {
        struct drm_device *dev = encoder->dev;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -266,9 +223,9 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder
        return NULL;
 }
 
-bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder)
+u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
 {
-       struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder);
+       struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
 
        if (other_encoder) {
                struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
@@ -276,13 +233,12 @@ bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder)
                switch (radeon_encoder->encoder_id) {
                case ENCODER_OBJECT_ID_TRAVIS:
                case ENCODER_OBJECT_ID_NUTMEG:
-                       return true;
+                       return radeon_encoder->encoder_id;
                default:
-                       return false;
+                       return ENCODER_OBJECT_ID_NONE;
                }
        }
-
-       return false;
+       return ENCODER_OBJECT_ID_NONE;
 }
 
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
@@ -332,2105 +288,3 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 
 }
 
-static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
-                                  struct drm_display_mode *mode,
-                                  struct drm_display_mode *adjusted_mode)
-{
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-
-       /* set the active encoder to connector routing */
-       radeon_encoder_set_active_device(encoder);
-       drm_mode_set_crtcinfo(adjusted_mode, 0);
-
-       /* hw bug */
-       if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
-           && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
-               adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
-
-       /* get the native mode for LVDS */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
-               radeon_panel_mode_fixup(encoder, adjusted_mode);
-
-       /* get the native mode for TV */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
-               struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
-               if (tv_dac) {
-                       if (tv_dac->tv_std == TV_STD_NTSC ||
-                           tv_dac->tv_std == TV_STD_NTSC_J ||
-                           tv_dac->tv_std == TV_STD_PAL_M)
-                               radeon_atom_get_tv_timings(rdev, 0, adjusted_mode);
-                       else
-                               radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);
-               }
-       }
-
-       if (ASIC_IS_DCE3(rdev) &&
-           ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
-            radeon_encoder_is_dp_bridge(encoder))) {
-               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-               radeon_dp_set_link_config(connector, mode);
-       }
-
-       return true;
-}
-
-static void
-atombios_dac_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       DAC_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0;
-       struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-
-       memset(&args, 0, sizeof(args));
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-               index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
-               break;
-       }
-
-       args.ucAction = action;
-
-       if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT))
-               args.ucDacStandard = ATOM_DAC1_PS2;
-       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-               args.ucDacStandard = ATOM_DAC1_CV;
-       else {
-               switch (dac_info->tv_std) {
-               case TV_STD_PAL:
-               case TV_STD_PAL_M:
-               case TV_STD_SCART_PAL:
-               case TV_STD_SECAM:
-               case TV_STD_PAL_CN:
-                       args.ucDacStandard = ATOM_DAC1_PAL;
-                       break;
-               case TV_STD_NTSC:
-               case TV_STD_NTSC_J:
-               case TV_STD_PAL_60:
-               default:
-                       args.ucDacStandard = ATOM_DAC1_NTSC;
-                       break;
-               }
-       }
-       args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
-
-static void
-atombios_tv_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       TV_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0;
-       struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-
-       memset(&args, 0, sizeof(args));
-
-       index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
-
-       args.sTVEncoder.ucAction = action;
-
-       if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-               args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
-       else {
-               switch (dac_info->tv_std) {
-               case TV_STD_NTSC:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
-                       break;
-               case TV_STD_PAL:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL;
-                       break;
-               case TV_STD_PAL_M:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_PALM;
-                       break;
-               case TV_STD_PAL_60:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;
-                       break;
-               case TV_STD_NTSC_J:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;
-                       break;
-               case TV_STD_SCART_PAL:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */
-                       break;
-               case TV_STD_SECAM:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;
-                       break;
-               case TV_STD_PAL_CN:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;
-                       break;
-               default:
-                       args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
-                       break;
-               }
-       }
-
-       args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
-
-union dvo_encoder_control {
-       ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
-       DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
-       DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
-};
-
-void
-atombios_dvo_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       union dvo_encoder_control args;
-       int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
-
-       memset(&args, 0, sizeof(args));
-
-       if (ASIC_IS_DCE3(rdev)) {
-               /* DCE3+ */
-               args.dvo_v3.ucAction = action;
-               args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-               args.dvo_v3.ucDVOConfig = 0; /* XXX */
-       } else if (ASIC_IS_DCE2(rdev)) {
-               /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
-               args.dvo.sDVOEncoder.ucAction = action;
-               args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-               /* DFP1, CRT1, TV1 depending on the type of port */
-               args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
-
-               if (radeon_encoder->pixel_clock > 165000)
-                       args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
-       } else {
-               /* R4xx, R5xx */
-               args.ext_tmds.sXTmdsEncoder.ucEnable = action;
-
-               if (radeon_encoder->pixel_clock > 165000)
-                       args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-
-               /*if (pScrn->rgbBits == 8)*/
-               args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
-       }
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-}
-
-union lvds_encoder_control {
-       LVDS_ENCODER_CONTROL_PS_ALLOCATION    v1;
-       LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;
-};
-
-void
-atombios_digital_setup(struct drm_encoder *encoder, int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-       union lvds_encoder_control args;
-       int index = 0;
-       int hdmi_detected = 0;
-       uint8_t frev, crev;
-
-       if (!dig)
-               return;
-
-       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
-               hdmi_detected = 1;
-
-       memset(&args, 0, sizeof(args));
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-               index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-               index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
-               break;
-       }
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               return;
-
-       switch (frev) {
-       case 1:
-       case 2:
-               switch (crev) {
-               case 1:
-                       args.v1.ucMisc = 0;
-                       args.v1.ucAction = action;
-                       if (hdmi_detected)
-                               args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
-                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                               if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
-                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-                               if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
-                                       args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
-                       } else {
-                               if (dig->linkb)
-                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
-                               if (radeon_encoder->pixel_clock > 165000)
-                                       args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-                               /*if (pScrn->rgbBits == 8) */
-                               args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
-                       }
-                       break;
-               case 2:
-               case 3:
-                       args.v2.ucMisc = 0;
-                       args.v2.ucAction = action;
-                       if (crev == 3) {
-                               if (dig->coherent_mode)
-                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
-                       }
-                       if (hdmi_detected)
-                               args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
-                       args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-                       args.v2.ucTruncate = 0;
-                       args.v2.ucSpatial = 0;
-                       args.v2.ucTemporal = 0;
-                       args.v2.ucFRC = 0;
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                               if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
-                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-                               if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) {
-                                       args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
-                                       if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
-                                               args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
-                               }
-                               if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) {
-                                       args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
-                                       if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
-                                               args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
-                                       if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)
-                                               args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
-                               }
-                       } else {
-                               if (dig->linkb)
-                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
-                               if (radeon_encoder->pixel_clock > 165000)
-                                       args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-                       }
-                       break;
-               default:
-                       DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
-                       break;
-               }
-               break;
-       default:
-               DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
-               break;
-       }
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-}
-
-int
-atombios_get_encoder_mode(struct drm_encoder *encoder)
-{
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct drm_connector *connector;
-       struct radeon_connector *radeon_connector;
-       struct radeon_connector_atom_dig *dig_connector;
-
-       /* dp bridges are always DP */
-       if (radeon_encoder_is_dp_bridge(encoder))
-               return ATOM_ENCODER_MODE_DP;
-
-       /* DVO is always DVO */
-       if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO)
-               return ATOM_ENCODER_MODE_DVO;
-
-       connector = radeon_get_connector_for_encoder(encoder);
-       /* if we don't have an active device yet, just use one of
-        * the connectors tied to the encoder.
-        */
-       if (!connector)
-               connector = radeon_get_connector_for_encoder_init(encoder);
-       radeon_connector = to_radeon_connector(connector);
-
-       switch (connector->connector_type) {
-       case DRM_MODE_CONNECTOR_DVII:
-       case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
-               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
-                       /* fix me */
-                       if (ASIC_IS_DCE4(rdev))
-                               return ATOM_ENCODER_MODE_DVI;
-                       else
-                               return ATOM_ENCODER_MODE_HDMI;
-               } else if (radeon_connector->use_digital)
-                       return ATOM_ENCODER_MODE_DVI;
-               else
-                       return ATOM_ENCODER_MODE_CRT;
-               break;
-       case DRM_MODE_CONNECTOR_DVID:
-       case DRM_MODE_CONNECTOR_HDMIA:
-       default:
-               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
-                       /* fix me */
-                       if (ASIC_IS_DCE4(rdev))
-                               return ATOM_ENCODER_MODE_DVI;
-                       else
-                               return ATOM_ENCODER_MODE_HDMI;
-               } else
-                       return ATOM_ENCODER_MODE_DVI;
-               break;
-       case DRM_MODE_CONNECTOR_LVDS:
-               return ATOM_ENCODER_MODE_LVDS;
-               break;
-       case DRM_MODE_CONNECTOR_DisplayPort:
-               dig_connector = radeon_connector->con_priv;
-               if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
-                   (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
-                       return ATOM_ENCODER_MODE_DP;
-               else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
-                       /* fix me */
-                       if (ASIC_IS_DCE4(rdev))
-                               return ATOM_ENCODER_MODE_DVI;
-                       else
-                               return ATOM_ENCODER_MODE_HDMI;
-               } else
-                       return ATOM_ENCODER_MODE_DVI;
-               break;
-       case DRM_MODE_CONNECTOR_eDP:
-               return ATOM_ENCODER_MODE_DP;
-       case DRM_MODE_CONNECTOR_DVIA:
-       case DRM_MODE_CONNECTOR_VGA:
-               return ATOM_ENCODER_MODE_CRT;
-               break;
-       case DRM_MODE_CONNECTOR_Composite:
-       case DRM_MODE_CONNECTOR_SVIDEO:
-       case DRM_MODE_CONNECTOR_9PinDIN:
-               /* fix me */
-               return ATOM_ENCODER_MODE_TV;
-               /*return ATOM_ENCODER_MODE_CV;*/
-               break;
-       }
-}
-
-/*
- * DIG Encoder/Transmitter Setup
- *
- * DCE 3.0/3.1
- * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
- * Supports up to 3 digital outputs
- * - 2 DIG encoder blocks.
- * DIG1 can drive UNIPHY link A or link B
- * DIG2 can drive UNIPHY link B or LVTMA
- *
- * DCE 3.2
- * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
- * Supports up to 5 digital outputs
- * - 2 DIG encoder blocks.
- * DIG1/2 can drive UNIPHY0/1/2 link A or link B
- *
- * DCE 4.0/5.0
- * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
- * Supports up to 6 digital outputs
- * - 6 DIG encoder blocks.
- * - DIG to PHY mapping is hardcoded
- * DIG1 drives UNIPHY0 link A, A+B
- * DIG2 drives UNIPHY0 link B
- * DIG3 drives UNIPHY1 link A, A+B
- * DIG4 drives UNIPHY1 link B
- * DIG5 drives UNIPHY2 link A, A+B
- * DIG6 drives UNIPHY2 link B
- *
- * DCE 4.1
- * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
- * Supports up to 6 digital outputs
- * - 2 DIG encoder blocks.
- * DIG1/2 can drive UNIPHY0/1/2 link A or link B
- *
- * Routing
- * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
- * Examples:
- * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI
- * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP
- * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
- * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
- */
-
-union dig_encoder_control {
-       DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
-       DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
-       DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
-       DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;
-};
-
-void
-atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-       union dig_encoder_control args;
-       int index = 0;
-       uint8_t frev, crev;
-       int dp_clock = 0;
-       int dp_lane_count = 0;
-       int hpd_id = RADEON_HPD_NONE;
-       int bpc = 8;
-
-       if (connector) {
-               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-               struct radeon_connector_atom_dig *dig_connector =
-                       radeon_connector->con_priv;
-
-               dp_clock = dig_connector->dp_clock;
-               dp_lane_count = dig_connector->dp_lane_count;
-               hpd_id = radeon_connector->hpd.hpd;
-               bpc = connector->display_info.bpc;
-       }
-
-       /* no dig encoder assigned */
-       if (dig->dig_encoder == -1)
-               return;
-
-       memset(&args, 0, sizeof(args));
-
-       if (ASIC_IS_DCE4(rdev))
-               index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);
-       else {
-               if (dig->dig_encoder)
-                       index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
-       }
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               return;
-
-       args.v1.ucAction = action;
-       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-       if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
-               args.v3.ucPanelMode = panel_mode;
-       else
-               args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
-
-       if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
-           (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST))
-               args.v1.ucLaneNum = dp_lane_count;
-       else if (radeon_encoder->pixel_clock > 165000)
-               args.v1.ucLaneNum = 8;
-       else
-               args.v1.ucLaneNum = 4;
-
-       if (ASIC_IS_DCE5(rdev)) {
-               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
-                   (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) {
-                       if (dp_clock == 270000)
-                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
-                       else if (dp_clock == 540000)
-                               args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
-               }
-               args.v4.acConfig.ucDigSel = dig->dig_encoder;
-               switch (bpc) {
-               case 0:
-                       args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
-                       break;
-               case 6:
-                       args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
-                       break;
-               case 8:
-               default:
-                       args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
-                       break;
-               case 10:
-                       args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
-                       break;
-               case 12:
-                       args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
-                       break;
-               case 16:
-                       args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
-                       break;
-               }
-               if (hpd_id == RADEON_HPD_NONE)
-                       args.v4.ucHPD_ID = 0;
-               else
-                       args.v4.ucHPD_ID = hpd_id + 1;
-       } else if (ASIC_IS_DCE4(rdev)) {
-               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
-                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
-               args.v3.acConfig.ucDigSel = dig->dig_encoder;
-               switch (bpc) {
-               case 0:
-                       args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
-                       break;
-               case 6:
-                       args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
-                       break;
-               case 8:
-               default:
-                       args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
-                       break;
-               case 10:
-                       args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
-                       break;
-               case 12:
-                       args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
-                       break;
-               case 16:
-                       args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
-                       break;
-               }
-       } else {
-               if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
-                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
-               switch (radeon_encoder->encoder_id) {
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                       args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-                       args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-                       args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
-                       break;
-               }
-               if (dig->linkb)
-                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
-               else
-                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
-       }
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
-
-union dig_transmitter_control {
-       DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
-       DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
-       DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
-       DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
-};
-
-void
-atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-       struct drm_connector *connector;
-       union dig_transmitter_control args;
-       int index = 0;
-       uint8_t frev, crev;
-       bool is_dp = false;
-       int pll_id = 0;
-       int dp_clock = 0;
-       int dp_lane_count = 0;
-       int connector_object_id = 0;
-       int igp_lane_info = 0;
-       int dig_encoder = dig->dig_encoder;
-
-       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
-               connector = radeon_get_connector_for_encoder_init(encoder);
-               /* just needed to avoid bailing in the encoder check.  the encoder
-                * isn't used for init
-                */
-               dig_encoder = 0;
-       } else
-               connector = radeon_get_connector_for_encoder(encoder);
-
-       if (connector) {
-               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-               struct radeon_connector_atom_dig *dig_connector =
-                       radeon_connector->con_priv;
-
-               dp_clock = dig_connector->dp_clock;
-               dp_lane_count = dig_connector->dp_lane_count;
-               connector_object_id =
-                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-               igp_lane_info = dig_connector->igp_lane_info;
-       }
-
-       /* no dig encoder assigned */
-       if (dig_encoder == -1)
-               return;
-
-       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
-               is_dp = true;
-
-       memset(&args, 0, sizeof(args));
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-               index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl);
-               break;
-       }
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               return;
-
-       args.v1.ucAction = action;
-       if (action == ATOM_TRANSMITTER_ACTION_INIT) {
-               args.v1.usInitInfo = cpu_to_le16(connector_object_id);
-       } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
-               args.v1.asMode.ucLaneSel = lane_num;
-               args.v1.asMode.ucLaneSet = lane_set;
-       } else {
-               if (is_dp)
-                       args.v1.usPixelClock =
-                               cpu_to_le16(dp_clock / 10);
-               else if (radeon_encoder->pixel_clock > 165000)
-                       args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
-               else
-                       args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-       }
-       if (ASIC_IS_DCE4(rdev)) {
-               if (is_dp)
-                       args.v3.ucLaneNum = dp_lane_count;
-               else if (radeon_encoder->pixel_clock > 165000)
-                       args.v3.ucLaneNum = 8;
-               else
-                       args.v3.ucLaneNum = 4;
-
-               if (dig->linkb)
-                       args.v3.acConfig.ucLinkSel = 1;
-               if (dig_encoder & 1)
-                       args.v3.acConfig.ucEncoderSel = 1;
-
-               /* Select the PLL for the PHY
-                * DP PHY should be clocked from external src if there is
-                * one.
-                */
-               if (encoder->crtc) {
-                       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-                       pll_id = radeon_crtc->pll_id;
-               }
-
-               if (ASIC_IS_DCE5(rdev)) {
-                       /* On DCE5 DCPLL usually generates the DP ref clock */
-                       if (is_dp) {
-                               if (rdev->clock.dp_extclk)
-                                       args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK;
-                               else
-                                       args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL;
-                       } else
-                               args.v4.acConfig.ucRefClkSource = pll_id;
-               } else {
-                       /* On DCE4, if there is an external clock, it generates the DP ref clock */
-                       if (is_dp && rdev->clock.dp_extclk)
-                               args.v3.acConfig.ucRefClkSource = 2; /* external src */
-                       else
-                               args.v3.acConfig.ucRefClkSource = pll_id;
-               }
-
-               switch (radeon_encoder->encoder_id) {
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                       args.v3.acConfig.ucTransmitterSel = 0;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-                       args.v3.acConfig.ucTransmitterSel = 1;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-                       args.v3.acConfig.ucTransmitterSel = 2;
-                       break;
-               }
-
-               if (is_dp)
-                       args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */
-               else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
-                       if (dig->coherent_mode)
-                               args.v3.acConfig.fCoherentMode = 1;
-                       if (radeon_encoder->pixel_clock > 165000)
-                               args.v3.acConfig.fDualLinkConnector = 1;
-               }
-       } else if (ASIC_IS_DCE32(rdev)) {
-               args.v2.acConfig.ucEncoderSel = dig_encoder;
-               if (dig->linkb)
-                       args.v2.acConfig.ucLinkSel = 1;
-
-               switch (radeon_encoder->encoder_id) {
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                       args.v2.acConfig.ucTransmitterSel = 0;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-                       args.v2.acConfig.ucTransmitterSel = 1;
-                       break;
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-                       args.v2.acConfig.ucTransmitterSel = 2;
-                       break;
-               }
-
-               if (is_dp) {
-                       args.v2.acConfig.fCoherentMode = 1;
-                       args.v2.acConfig.fDPConnector = 1;
-               } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
-                       if (dig->coherent_mode)
-                               args.v2.acConfig.fCoherentMode = 1;
-                       if (radeon_encoder->pixel_clock > 165000)
-                               args.v2.acConfig.fDualLinkConnector = 1;
-               }
-       } else {
-               args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-
-               if (dig_encoder)
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-               else
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
-
-               if ((rdev->flags & RADEON_IS_IGP) &&
-                   (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
-                       if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
-                               if (igp_lane_info & 0x1)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-                               else if (igp_lane_info & 0x2)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
-                               else if (igp_lane_info & 0x4)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
-                               else if (igp_lane_info & 0x8)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
-                       } else {
-                               if (igp_lane_info & 0x3)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
-                               else if (igp_lane_info & 0xc)
-                                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
-                       }
-               }
-
-               if (dig->linkb)
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
-               else
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
-
-               if (is_dp)
-                       args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
-               else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
-                       if (dig->coherent_mode)
-                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
-                       if (radeon_encoder->pixel_clock > 165000)
-                               args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
-               }
-       }
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-}
-
-bool
-atombios_set_edp_panel_power(struct drm_connector *connector, int action)
-{
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-       struct drm_device *dev = radeon_connector->base.dev;
-       struct radeon_device *rdev = dev->dev_private;
-       union dig_transmitter_control args;
-       int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
-       uint8_t frev, crev;
-
-       if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
-               goto done;
-
-       if (!ASIC_IS_DCE4(rdev))
-               goto done;
-
-       if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) &&
-           (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
-               goto done;
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               goto done;
-
-       memset(&args, 0, sizeof(args));
-
-       args.v1.ucAction = action;
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-       /* wait for the panel to power up */
-       if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {
-               int i;
-
-               for (i = 0; i < 300; i++) {
-                       if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
-                               return true;
-                       mdelay(1);
-               }
-               return false;
-       }
-done:
-       return true;
-}
-
-union external_encoder_control {
-       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
-       EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
-};
-
-static void
-atombios_external_encoder_setup(struct drm_encoder *encoder,
-                               struct drm_encoder *ext_encoder,
-                               int action)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
-       union external_encoder_control args;
-       struct drm_connector *connector;
-       int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
-       u8 frev, crev;
-       int dp_clock = 0;
-       int dp_lane_count = 0;
-       int connector_object_id = 0;
-       u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
-       int bpc = 8;
-
-       if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
-               connector = radeon_get_connector_for_encoder_init(encoder);
-       else
-               connector = radeon_get_connector_for_encoder(encoder);
-
-       if (connector) {
-               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-               struct radeon_connector_atom_dig *dig_connector =
-                       radeon_connector->con_priv;
-
-               dp_clock = dig_connector->dp_clock;
-               dp_lane_count = dig_connector->dp_lane_count;
-               connector_object_id =
-                       (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-               bpc = connector->display_info.bpc;
-       }
-
-       memset(&args, 0, sizeof(args));
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               return;
-
-       switch (frev) {
-       case 1:
-               /* no params on frev 1 */
-               break;
-       case 2:
-               switch (crev) {
-               case 1:
-               case 2:
-                       args.v1.sDigEncoder.ucAction = action;
-                       args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-                       args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
-
-                       if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
-                               if (dp_clock == 270000)
-                                       args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
-                               args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
-                       } else if (radeon_encoder->pixel_clock > 165000)
-                               args.v1.sDigEncoder.ucLaneNum = 8;
-                       else
-                               args.v1.sDigEncoder.ucLaneNum = 4;
-                       break;
-               case 3:
-                       args.v3.sExtEncoder.ucAction = action;
-                       if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
-                               args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id);
-                       else
-                               args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-                       args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
-
-                       if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
-                               if (dp_clock == 270000)
-                                       args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
-                               else if (dp_clock == 540000)
-                                       args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
-                               args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
-                       } else if (radeon_encoder->pixel_clock > 165000)
-                               args.v3.sExtEncoder.ucLaneNum = 8;
-                       else
-                               args.v3.sExtEncoder.ucLaneNum = 4;
-                       switch (ext_enum) {
-                       case GRAPH_OBJECT_ENUM_ID1:
-                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
-                               break;
-                       case GRAPH_OBJECT_ENUM_ID2:
-                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
-                               break;
-                       case GRAPH_OBJECT_ENUM_ID3:
-                               args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
-                               break;
-                       }
-                       switch (bpc) {
-                       case 0:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE;
-                               break;
-                       case 6:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR;
-                               break;
-                       case 8:
-                       default:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
-                               break;
-                       case 10:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR;
-                               break;
-                       case 12:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR;
-                               break;
-                       case 16:
-                               args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR;
-                               break;
-                       }
-                       break;
-               default:
-                       DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
-                       return;
-               }
-               break;
-       default:
-               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
-               return;
-       }
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-}
-
-static void
-atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-       ENABLE_YUV_PS_ALLOCATION args;
-       int index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
-       uint32_t temp, reg;
-
-       memset(&args, 0, sizeof(args));
-
-       if (rdev->family >= CHIP_R600)
-               reg = R600_BIOS_3_SCRATCH;
-       else
-               reg = RADEON_BIOS_3_SCRATCH;
-
-       /* XXX: fix up scratch reg handling */
-       temp = RREG32(reg);
-       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-               WREG32(reg, (ATOM_S3_TV1_ACTIVE |
-                            (radeon_crtc->crtc_id << 18)));
-       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-               WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
-       else
-               WREG32(reg, 0);
-
-       if (enable)
-               args.ucEnable = ATOM_ENABLE;
-       args.ucCRTC = radeon_crtc->crtc_id;
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-       WREG32(reg, temp);
-}
-
-static void
-radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-       DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
-       int index = 0;
-       bool is_dig = false;
-       bool is_dce5_dac = false;
-       bool is_dce5_dvo = false;
-
-       memset(&args, 0, sizeof(args));
-
-       DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
-                 radeon_encoder->encoder_id, mode, radeon_encoder->devices,
-                 radeon_encoder->active_device);
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-               index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               is_dig = true;
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-               index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               if (ASIC_IS_DCE5(rdev))
-                       is_dce5_dvo = true;
-               else if (ASIC_IS_DCE3(rdev))
-                       is_dig = true;
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-               index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-               if (ASIC_IS_DCE5(rdev))
-                       is_dce5_dac = true;
-               else {
-                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                               index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-                       else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                               index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
-                       else
-                               index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
-               }
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                       index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
-               else
-                       index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
-               break;
-       }
-
-       if (is_dig) {
-               switch (mode) {
-               case DRM_MODE_DPMS_ON:
-                       /* some early dce3.2 boards have a bug in their transmitter control table */
-                       if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
-                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-                       else
-                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
-                       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
-                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-
-                               if (connector &&
-                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
-                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-                                       struct radeon_connector_atom_dig *radeon_dig_connector =
-                                               radeon_connector->con_priv;
-                                       atombios_set_edp_panel_power(connector,
-                                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
-                                       radeon_dig_connector->edp_on = true;
-                               }
-                               if (ASIC_IS_DCE4(rdev))
-                                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
-                               radeon_dp_link_train(encoder, connector);
-                               if (ASIC_IS_DCE4(rdev))
-                                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
-                       }
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
-                       break;
-               case DRM_MODE_DPMS_STANDBY:
-               case DRM_MODE_DPMS_SUSPEND:
-               case DRM_MODE_DPMS_OFF:
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
-                       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
-                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-
-                               if (ASIC_IS_DCE4(rdev))
-                                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
-                               if (connector &&
-                                   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
-                                       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-                                       struct radeon_connector_atom_dig *radeon_dig_connector =
-                                               radeon_connector->con_priv;
-                                       atombios_set_edp_panel_power(connector,
-                                                                    ATOM_TRANSMITTER_ACTION_POWER_OFF);
-                                       radeon_dig_connector->edp_on = false;
-                               }
-                       }
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                               atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
-                       break;
-               }
-       } else if (is_dce5_dac) {
-               switch (mode) {
-               case DRM_MODE_DPMS_ON:
-                       atombios_dac_setup(encoder, ATOM_ENABLE);
-                       break;
-               case DRM_MODE_DPMS_STANDBY:
-               case DRM_MODE_DPMS_SUSPEND:
-               case DRM_MODE_DPMS_OFF:
-                       atombios_dac_setup(encoder, ATOM_DISABLE);
-                       break;
-               }
-       } else if (is_dce5_dvo) {
-               switch (mode) {
-               case DRM_MODE_DPMS_ON:
-                       atombios_dvo_setup(encoder, ATOM_ENABLE);
-                       break;
-               case DRM_MODE_DPMS_STANDBY:
-               case DRM_MODE_DPMS_SUSPEND:
-               case DRM_MODE_DPMS_OFF:
-                       atombios_dvo_setup(encoder, ATOM_DISABLE);
-                       break;
-               }
-       } else {
-               switch (mode) {
-               case DRM_MODE_DPMS_ON:
-                       args.ucAction = ATOM_ENABLE;
-                       /* workaround for DVOOutputControl on some RS690 systems */
-                       if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) {
-                               u32 reg = RREG32(RADEON_BIOS_3_SCRATCH);
-                               WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE);
-                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-                               WREG32(RADEON_BIOS_3_SCRATCH, reg);
-                       } else
-                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                               args.ucAction = ATOM_LCD_BLON;
-                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-                       }
-                       break;
-               case DRM_MODE_DPMS_STANDBY:
-               case DRM_MODE_DPMS_SUSPEND:
-               case DRM_MODE_DPMS_OFF:
-                       args.ucAction = ATOM_DISABLE;
-                       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-                       if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                               args.ucAction = ATOM_LCD_BLOFF;
-                               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-                       }
-                       break;
-               }
-       }
-
-       if (ext_encoder) {
-               switch (mode) {
-               case DRM_MODE_DPMS_ON:
-               default:
-                       if (ASIC_IS_DCE41(rdev)) {
-                               atombios_external_encoder_setup(encoder, ext_encoder,
-                                                               EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
-                               atombios_external_encoder_setup(encoder, ext_encoder,
-                                                               EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
-                       } else
-                               atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
-                       break;
-               case DRM_MODE_DPMS_STANDBY:
-               case DRM_MODE_DPMS_SUSPEND:
-               case DRM_MODE_DPMS_OFF:
-                       if (ASIC_IS_DCE41(rdev)) {
-                               atombios_external_encoder_setup(encoder, ext_encoder,
-                                                               EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
-                               atombios_external_encoder_setup(encoder, ext_encoder,
-                                                               EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
-                       } else
-                               atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
-                       break;
-               }
-       }
-
-       radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
-
-}
-
-union crtc_source_param {
-       SELECT_CRTC_SOURCE_PS_ALLOCATION v1;
-       SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;
-};
-
-static void
-atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-       union crtc_source_param args;
-       int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
-       uint8_t frev, crev;
-       struct radeon_encoder_atom_dig *dig;
-
-       memset(&args, 0, sizeof(args));
-
-       if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-               return;
-
-       switch (frev) {
-       case 1:
-               switch (crev) {
-               case 1:
-               default:
-                       if (ASIC_IS_AVIVO(rdev))
-                               args.v1.ucCRTC = radeon_crtc->crtc_id;
-                       else {
-                               if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) {
-                                       args.v1.ucCRTC = radeon_crtc->crtc_id;
-                               } else {
-                                       args.v1.ucCRTC = radeon_crtc->crtc_id << 2;
-                               }
-                       }
-                       switch (radeon_encoder->encoder_id) {
-                       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-                               args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-                       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-                               if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)
-                                       args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;
-                               else
-                                       args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-                       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-                               args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                                       args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
-                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                                       args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
-                               else
-                                       args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                                       args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
-                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                                       args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
-                               else
-                                       args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
-                               break;
-                       }
-                       break;
-               case 2:
-                       args.v2.ucCRTC = radeon_crtc->crtc_id;
-                       if (radeon_encoder_is_dp_bridge(encoder)) {
-                               struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-
-                               if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
-                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
-                               else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)
-                                       args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
-                               else
-                                       args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
-                       } else
-                               args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
-                       switch (radeon_encoder->encoder_id) {
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-                               dig = radeon_encoder->enc_priv;
-                               switch (dig->dig_encoder) {
-                               case 0:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-                                       break;
-                               case 1:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-                                       break;
-                               case 2:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;
-                                       break;
-                               case 3:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;
-                                       break;
-                               case 4:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;
-                                       break;
-                               case 5:
-                                       args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
-                                       break;
-                               }
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-                               args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-                               else
-                                       args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
-                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-                               else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
-                                       args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-                               else
-                                       args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
-                               break;
-                       }
-                       break;
-               }
-               break;
-       default:
-               DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
-               return;
-       }
-
-       atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-       /* update scratch regs with new routing */
-       radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
-}
-
-static void
-atombios_apply_encoder_quirks(struct drm_encoder *encoder,
-                             struct drm_display_mode *mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-
-       /* Funky macbooks */
-       if ((dev->pdev->device == 0x71C5) &&
-           (dev->pdev->subsystem_vendor == 0x106b) &&
-           (dev->pdev->subsystem_device == 0x0080)) {
-               if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-                       uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL);
-
-                       lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;
-                       lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;
-
-                       WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);
-               }
-       }
-
-       /* set scaler clears this on some chips */
-       if (ASIC_IS_AVIVO(rdev) &&
-           (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
-               if (ASIC_IS_DCE4(rdev)) {
-                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
-                                      EVERGREEN_INTERLEAVE_EN);
-                       else
-                               WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
-               } else {
-                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
-                                      AVIVO_D1MODE_INTERLEAVE_EN);
-                       else
-                               WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
-               }
-       }
-}
-
-static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_encoder *test_encoder;
-       struct radeon_encoder_atom_dig *dig;
-       uint32_t dig_enc_in_use = 0;
-
-       /* DCE4/5 */
-       if (ASIC_IS_DCE4(rdev)) {
-               dig = radeon_encoder->enc_priv;
-               if (ASIC_IS_DCE41(rdev)) {
-                       /* ontario follows DCE4 */
-                       if (rdev->family == CHIP_PALM) {
-                               if (dig->linkb)
-                                       return 1;
-                               else
-                                       return 0;
-                       } else
-                               /* llano follows DCE3.2 */
-                               return radeon_crtc->crtc_id;
-               } else {
-                       switch (radeon_encoder->encoder_id) {
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-                               if (dig->linkb)
-                                       return 1;
-                               else
-                                       return 0;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-                               if (dig->linkb)
-                                       return 3;
-                               else
-                                       return 2;
-                               break;
-                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-                               if (dig->linkb)
-                                       return 5;
-                               else
-                                       return 4;
-                               break;
-                       }
-               }
-       }
-
-       /* on DCE32 and encoder can driver any block so just crtc id */
-       if (ASIC_IS_DCE32(rdev)) {
-               return radeon_crtc->crtc_id;
-       }
-
-       /* on DCE3 - LVTMA can only be driven by DIGB */
-       list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
-               struct radeon_encoder *radeon_test_encoder;
-
-               if (encoder == test_encoder)
-                       continue;
-
-               if (!radeon_encoder_is_digital(test_encoder))
-                       continue;
-
-               radeon_test_encoder = to_radeon_encoder(test_encoder);
-               dig = radeon_test_encoder->enc_priv;
-
-               if (dig->dig_encoder >= 0)
-                       dig_enc_in_use |= (1 << dig->dig_encoder);
-       }
-
-       if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {
-               if (dig_enc_in_use & 0x2)
-                       DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");
-               return 1;
-       }
-       if (!(dig_enc_in_use & 1))
-               return 0;
-       return 1;
-}
-
-/* This only needs to be called once at startup */
-void
-radeon_atom_encoder_init(struct radeon_device *rdev)
-{
-       struct drm_device *dev = rdev->ddev;
-       struct drm_encoder *encoder;
-
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-               struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-
-               switch (radeon_encoder->encoder_id) {
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-               case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
-                       break;
-               default:
-                       break;
-               }
-
-               if (ext_encoder && ASIC_IS_DCE41(rdev))
-                       atombios_external_encoder_setup(encoder, ext_encoder,
-                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
-       }
-}
-
-static void
-radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
-                            struct drm_display_mode *mode,
-                            struct drm_display_mode *adjusted_mode)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-
-       radeon_encoder->pixel_clock = adjusted_mode->clock;
-
-       if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
-               if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
-                       atombios_yuv_setup(encoder, true);
-               else
-                       atombios_yuv_setup(encoder, false);
-       }
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               if (ASIC_IS_DCE4(rdev)) {
-                       /* disable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       /* setup and enable the encoder */
-                       atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
-
-                       /* enable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-               } else {
-                       /* disable the encoder and transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
-
-                       /* setup and enable the encoder and transmitter */
-                       atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
-               }
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_dvo_setup(encoder, ATOM_ENABLE);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               atombios_dac_setup(encoder, ATOM_ENABLE);
-               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
-                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                               atombios_tv_setup(encoder, ATOM_ENABLE);
-                       else
-                               atombios_tv_setup(encoder, ATOM_DISABLE);
-               }
-               break;
-       }
-
-       if (ext_encoder) {
-               if (ASIC_IS_DCE41(rdev))
-                       atombios_external_encoder_setup(encoder, ext_encoder,
-                                                       EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
-               else
-                       atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
-       }
-
-       atombios_apply_encoder_quirks(encoder, adjusted_mode);
-
-       if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
-               r600_hdmi_enable(encoder);
-               r600_hdmi_setmode(encoder, adjusted_mode);
-       }
-}
-
-static bool
-atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-
-       if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
-                                      ATOM_DEVICE_CV_SUPPORT |
-                                      ATOM_DEVICE_CRT_SUPPORT)) {
-               DAC_LOAD_DETECTION_PS_ALLOCATION args;
-               int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
-               uint8_t frev, crev;
-
-               memset(&args, 0, sizeof(args));
-
-               if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-                       return false;
-
-               args.sDacload.ucMisc = 0;
-
-               if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||
-                   (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))
-                       args.sDacload.ucDacType = ATOM_DAC_A;
-               else
-                       args.sDacload.ucDacType = ATOM_DAC_B;
-
-               if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)
-                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
-               else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)
-                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
-               else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
-                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
-                       if (crev >= 3)
-                               args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
-               } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
-                       args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
-                       if (crev >= 3)
-                               args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
-               }
-
-               atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-               return true;
-       } else
-               return false;
-}
-
-static enum drm_connector_status
-radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-       uint32_t bios_0_scratch;
-
-       if (!atombios_dac_load_detect(encoder, connector)) {
-               DRM_DEBUG_KMS("detect returned false \n");
-               return connector_status_unknown;
-       }
-
-       if (rdev->family >= CHIP_R600)
-               bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
-       else
-               bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
-
-       DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
-       if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
-               if (bios_0_scratch & ATOM_S0_CRT1_MASK)
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-               if (bios_0_scratch & ATOM_S0_CRT2_MASK)
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
-               if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
-               if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
-                       return connector_status_connected; /* CTV */
-               else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
-                       return connector_status_connected; /* STV */
-       }
-       return connector_status_disconnected;
-}
-
-static enum drm_connector_status
-radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-       u32 bios_0_scratch;
-
-       if (!ASIC_IS_DCE4(rdev))
-               return connector_status_unknown;
-
-       if (!ext_encoder)
-               return connector_status_unknown;
-
-       if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)
-               return connector_status_unknown;
-
-       /* load detect on the dp bridge */
-       atombios_external_encoder_setup(encoder, ext_encoder,
-                                       EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);
-
-       bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
-
-       DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
-       if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
-               if (bios_0_scratch & ATOM_S0_CRT1_MASK)
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-               if (bios_0_scratch & ATOM_S0_CRT2_MASK)
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
-               if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
-                       return connector_status_connected;
-       }
-       if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
-               if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
-                       return connector_status_connected; /* CTV */
-               else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
-                       return connector_status_connected; /* STV */
-       }
-       return connector_status_disconnected;
-}
-
-void
-radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)
-{
-       struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
-
-       if (ext_encoder)
-               /* ddc_setup on the dp bridge */
-               atombios_external_encoder_setup(encoder, ext_encoder,
-                                               EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
-
-}
-
-static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
-
-       if ((radeon_encoder->active_device &
-            (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
-           radeon_encoder_is_dp_bridge(encoder)) {
-               struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
-               if (dig)
-                       dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
-       }
-
-       radeon_atom_output_lock(encoder, true);
-       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-
-       if (connector) {
-               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-
-               /* select the clock/data port if it uses a router */
-               if (radeon_connector->router.cd_valid)
-                       radeon_router_select_cd_port(radeon_connector);
-
-               /* turn eDP panel on for mode set */
-               if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
-                       atombios_set_edp_panel_power(connector,
-                                                    ATOM_TRANSMITTER_ACTION_POWER_ON);
-       }
-
-       /* this is needed for the pll/ss setup to work correctly in some cases */
-       atombios_set_encoder_crtc_source(encoder);
-}
-
-static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
-{
-       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-       radeon_atom_output_lock(encoder, false);
-}
-
-static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
-{
-       struct drm_device *dev = encoder->dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       struct radeon_encoder_atom_dig *dig;
-
-       /* check for pre-DCE3 cards with shared encoders;
-        * can't really use the links individually, so don't disable
-        * the encoder if it's in use by another connector
-        */
-       if (!ASIC_IS_DCE3(rdev)) {
-               struct drm_encoder *other_encoder;
-               struct radeon_encoder *other_radeon_encoder;
-
-               list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
-                       other_radeon_encoder = to_radeon_encoder(other_encoder);
-                       if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) &&
-                           drm_helper_encoder_in_use(other_encoder))
-                               goto disable_done;
-               }
-       }
-
-       radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-               if (ASIC_IS_DCE4(rdev))
-                       /* disable the transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-               else {
-                       /* disable the encoder and transmitter */
-                       atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-                       atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
-               }
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-               atombios_dvo_setup(encoder, ATOM_DISABLE);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               atombios_dac_setup(encoder, ATOM_DISABLE);
-               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                       atombios_tv_setup(encoder, ATOM_DISABLE);
-               break;
-       }
-
-disable_done:
-       if (radeon_encoder_is_digital(encoder)) {
-               if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
-                       r600_hdmi_disable(encoder);
-               dig = radeon_encoder->enc_priv;
-               dig->dig_encoder = -1;
-       }
-       radeon_encoder->active_device = 0;
-}
-
-/* these are handled by the primary encoders */
-static void radeon_atom_ext_prepare(struct drm_encoder *encoder)
-{
-
-}
-
-static void radeon_atom_ext_commit(struct drm_encoder *encoder)
-{
-
-}
-
-static void
-radeon_atom_ext_mode_set(struct drm_encoder *encoder,
-                        struct drm_display_mode *mode,
-                        struct drm_display_mode *adjusted_mode)
-{
-
-}
-
-static void radeon_atom_ext_disable(struct drm_encoder *encoder)
-{
-
-}
-
-static void
-radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
-{
-
-}
-
-static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
-                                      struct drm_display_mode *mode,
-                                      struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
-       .dpms = radeon_atom_ext_dpms,
-       .mode_fixup = radeon_atom_ext_mode_fixup,
-       .prepare = radeon_atom_ext_prepare,
-       .mode_set = radeon_atom_ext_mode_set,
-       .commit = radeon_atom_ext_commit,
-       .disable = radeon_atom_ext_disable,
-       /* no detect for TMDS/LVDS yet */
-};
-
-static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
-       .dpms = radeon_atom_encoder_dpms,
-       .mode_fixup = radeon_atom_mode_fixup,
-       .prepare = radeon_atom_encoder_prepare,
-       .mode_set = radeon_atom_encoder_mode_set,
-       .commit = radeon_atom_encoder_commit,
-       .disable = radeon_atom_encoder_disable,
-       .detect = radeon_atom_dig_detect,
-};
-
-static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
-       .dpms = radeon_atom_encoder_dpms,
-       .mode_fixup = radeon_atom_mode_fixup,
-       .prepare = radeon_atom_encoder_prepare,
-       .mode_set = radeon_atom_encoder_mode_set,
-       .commit = radeon_atom_encoder_commit,
-       .detect = radeon_atom_dac_detect,
-};
-
-void radeon_enc_destroy(struct drm_encoder *encoder)
-{
-       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-       kfree(radeon_encoder->enc_priv);
-       drm_encoder_cleanup(encoder);
-       kfree(radeon_encoder);
-}
-
-static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
-       .destroy = radeon_enc_destroy,
-};
-
-struct radeon_encoder_atom_dac *
-radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
-{
-       struct drm_device *dev = radeon_encoder->base.dev;
-       struct radeon_device *rdev = dev->dev_private;
-       struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
-
-       if (!dac)
-               return NULL;
-
-       dac->tv_std = radeon_atombios_get_tv_info(rdev);
-       return dac;
-}
-
-struct radeon_encoder_atom_dig *
-radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
-{
-       int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
-       struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);
-
-       if (!dig)
-               return NULL;
-
-       /* coherent mode by default */
-       dig->coherent_mode = true;
-       dig->dig_encoder = -1;
-
-       if (encoder_enum == 2)
-               dig->linkb = true;
-       else
-               dig->linkb = false;
-
-       return dig;
-}
-
-void
-radeon_add_atom_encoder(struct drm_device *dev,
-                       uint32_t encoder_enum,
-                       uint32_t supported_device,
-                       u16 caps)
-{
-       struct radeon_device *rdev = dev->dev_private;
-       struct drm_encoder *encoder;
-       struct radeon_encoder *radeon_encoder;
-
-       /* see if we already added it */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               radeon_encoder = to_radeon_encoder(encoder);
-               if (radeon_encoder->encoder_enum == encoder_enum) {
-                       radeon_encoder->devices |= supported_device;
-                       return;
-               }
-
-       }
-
-       /* add a new one */
-       radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);
-       if (!radeon_encoder)
-               return;
-
-       encoder = &radeon_encoder->base;
-       switch (rdev->num_crtc) {
-       case 1:
-               encoder->possible_crtcs = 0x1;
-               break;
-       case 2:
-       default:
-               encoder->possible_crtcs = 0x3;
-               break;
-       case 4:
-               encoder->possible_crtcs = 0xf;
-               break;
-       case 6:
-               encoder->possible_crtcs = 0x3f;
-               break;
-       }
-
-       radeon_encoder->enc_priv = NULL;
-
-       radeon_encoder->encoder_enum = encoder_enum;
-       radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-       radeon_encoder->devices = supported_device;
-       radeon_encoder->rmx_type = RMX_OFF;
-       radeon_encoder->underscan_type = UNDERSCAN_OFF;
-       radeon_encoder->is_ext_encoder = false;
-       radeon_encoder->caps = caps;
-
-       switch (radeon_encoder->encoder_id) {
-       case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                       radeon_encoder->rmx_type = RMX_FULL;
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
-                       radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
-               } else {
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
-                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
-               }
-               drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-               drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
-               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
-               drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-               drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
-               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
-               drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
-               break;
-       case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-       case ENCODER_OBJECT_ID_INTERNAL_DDI:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-                       radeon_encoder->rmx_type = RMX_FULL;
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
-                       radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
-               } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
-                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
-               } else {
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
-                       radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
-               }
-               drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
-               break;
-       case ENCODER_OBJECT_ID_SI170B:
-       case ENCODER_OBJECT_ID_CH7303:
-       case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
-       case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
-       case ENCODER_OBJECT_ID_TITFP513:
-       case ENCODER_OBJECT_ID_VT1623:
-       case ENCODER_OBJECT_ID_HDMI_SI1930:
-       case ENCODER_OBJECT_ID_TRAVIS:
-       case ENCODER_OBJECT_ID_NUTMEG:
-               /* these are handled by the primary encoders */
-               radeon_encoder->is_ext_encoder = true;
-               if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
-               else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
-               else
-                       drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
-               drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
-               break;
-       }
-}
index fdc3a9a54bf8e13cd6e4d9d475630cbec546b3b3..ba7ab79e12c1969793520a0ede951c675a52b469 100644 (file)
@@ -49,27 +49,27 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
                              rdev->gart.table_size >> PAGE_SHIFT);
        }
 #endif
-       rdev->gart.table.ram.ptr = ptr;
-       memset((void *)rdev->gart.table.ram.ptr, 0, rdev->gart.table_size);
+       rdev->gart.ptr = ptr;
+       memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size);
        return 0;
 }
 
 void radeon_gart_table_ram_free(struct radeon_device *rdev)
 {
-       if (rdev->gart.table.ram.ptr == NULL) {
+       if (rdev->gart.ptr == NULL) {
                return;
        }
 #ifdef CONFIG_X86
        if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 ||
            rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
-               set_memory_wb((unsigned long)rdev->gart.table.ram.ptr,
+               set_memory_wb((unsigned long)rdev->gart.ptr,
                              rdev->gart.table_size >> PAGE_SHIFT);
        }
 #endif
        pci_free_consistent(rdev->pdev, rdev->gart.table_size,
-                           (void *)rdev->gart.table.ram.ptr,
+                           (void *)rdev->gart.ptr,
                            rdev->gart.table_addr);
-       rdev->gart.table.ram.ptr = NULL;
+       rdev->gart.ptr = NULL;
        rdev->gart.table_addr = 0;
 }
 
@@ -77,10 +77,10 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                r = radeon_bo_create(rdev, rdev->gart.table_size,
                                     PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
-                                    &rdev->gart.table.vram.robj);
+                                    &rdev->gart.robj);
                if (r) {
                        return r;
                }
@@ -93,38 +93,46 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev)
        uint64_t gpu_addr;
        int r;
 
-       r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+       r = radeon_bo_reserve(rdev->gart.robj, false);
        if (unlikely(r != 0))
                return r;
-       r = radeon_bo_pin(rdev->gart.table.vram.robj,
+       r = radeon_bo_pin(rdev->gart.robj,
                                RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
        if (r) {
-               radeon_bo_unreserve(rdev->gart.table.vram.robj);
+               radeon_bo_unreserve(rdev->gart.robj);
                return r;
        }
-       r = radeon_bo_kmap(rdev->gart.table.vram.robj,
-                               (void **)&rdev->gart.table.vram.ptr);
+       r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr);
        if (r)
-               radeon_bo_unpin(rdev->gart.table.vram.robj);
-       radeon_bo_unreserve(rdev->gart.table.vram.robj);
+               radeon_bo_unpin(rdev->gart.robj);
+       radeon_bo_unreserve(rdev->gart.robj);
        rdev->gart.table_addr = gpu_addr;
        return r;
 }
 
-void radeon_gart_table_vram_free(struct radeon_device *rdev)
+void radeon_gart_table_vram_unpin(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                return;
        }
-       r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
+       r = radeon_bo_reserve(rdev->gart.robj, false);
        if (likely(r == 0)) {
-               radeon_bo_kunmap(rdev->gart.table.vram.robj);
-               radeon_bo_unpin(rdev->gart.table.vram.robj);
-               radeon_bo_unreserve(rdev->gart.table.vram.robj);
+               radeon_bo_kunmap(rdev->gart.robj);
+               radeon_bo_unpin(rdev->gart.robj);
+               radeon_bo_unreserve(rdev->gart.robj);
+               rdev->gart.ptr = NULL;
        }
-       radeon_bo_unref(&rdev->gart.table.vram.robj);
+}
+
+void radeon_gart_table_vram_free(struct radeon_device *rdev)
+{
+       if (rdev->gart.robj == NULL) {
+               return;
+       }
+       radeon_gart_table_vram_unpin(rdev);
+       radeon_bo_unref(&rdev->gart.robj);
 }
 
 
@@ -151,12 +159,14 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
                if (rdev->gart.pages[p]) {
                        if (!rdev->gart.ttm_alloced[p])
                                pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p],
-                                               PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+                                               PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
                        rdev->gart.pages[p] = NULL;
                        rdev->gart.pages_addr[p] = rdev->dummy_page.addr;
                        page_base = rdev->gart.pages_addr[p];
                        for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
-                               radeon_gart_set_page(rdev, t, page_base);
+                               if (rdev->gart.ptr) {
+                                       radeon_gart_set_page(rdev, t, page_base);
+                               }
                                page_base += RADEON_GPU_PAGE_SIZE;
                        }
                }
@@ -199,10 +209,12 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
                        }
                }
                rdev->gart.pages[p] = pagelist[i];
-               page_base = rdev->gart.pages_addr[p];
-               for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
-                       radeon_gart_set_page(rdev, t, page_base);
-                       page_base += RADEON_GPU_PAGE_SIZE;
+               if (rdev->gart.ptr) {
+                       page_base = rdev->gart.pages_addr[p];
+                       for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
+                               radeon_gart_set_page(rdev, t, page_base);
+                               page_base += RADEON_GPU_PAGE_SIZE;
+                       }
                }
        }
        mb();
@@ -215,6 +227,9 @@ void radeon_gart_restore(struct radeon_device *rdev)
        int i, j, t;
        u64 page_base;
 
+       if (!rdev->gart.ptr) {
+               return;
+       }
        for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) {
                page_base = rdev->gart.pages_addr[i];
                for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
index 02cb7da4124d4ce68fa59aa93c7a94395e4fded7..7bb1b079f4806f6d70414809e43e060c1bd1cec2 100644 (file)
@@ -23,6 +23,8 @@
  * Authors: Dave Airlie
  *          Alex Deucher
  */
+#include <linux/export.h>
+
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon.h"
@@ -32,7 +34,7 @@
  * radeon_ddc_probe
  *
  */
-bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe)
+bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
 {
        u8 out = 0x0;
        u8 buf[8];
@@ -47,15 +49,11 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e
                {
                        .addr = 0x50,
                        .flags = I2C_M_RD,
-                       .len = 1,
+                       .len = 8,
                        .buf = buf,
                }
        };
 
-       /* Read 8 bytes from i2c for extended probe of EDID header */
-       if (requires_extended_probe)
-               msgs[1].len = 8;
-
        /* on hw with routers, select right port */
        if (radeon_connector->router.ddc_valid)
                radeon_router_select_ddc_port(radeon_connector);
@@ -64,17 +62,15 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e
        if (ret != 2)
                /* Couldn't find an accessible DDC on this connector */
                return false;
-       if (requires_extended_probe) {
-               /* Probe also for valid EDID header
-                * EDID header starts with:
-                * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
-                * Only the first 6 bytes must be valid as
-                * drm_edid_block_valid() can fix the last 2 bytes */
-               if (drm_edid_header_is_valid(buf) < 6) {
-                       /* Couldn't find an accessible EDID on this
-                        * connector */
-                       return false;
-               }
+       /* Probe also for valid EDID header
+        * EDID header starts with:
+        * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
+        * Only the first 6 bytes must be valid as
+        * drm_edid_block_valid() can fix the last 2 bytes */
+       if (drm_edid_header_is_valid(buf) < 6) {
+               /* Couldn't find an accessible EDID on this
+                * connector */
+               return false;
        }
        return true;
 }
index 9ec830c77af0be7afdba4c9b32f13f1b277bdbe8..8f86aeb266935ef46be2e5dff9022b91c04324c2 100644 (file)
@@ -67,10 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
        /* Disable *all* interrupts */
        rdev->irq.sw_int = false;
        rdev->irq.gui_idle = false;
-       for (i = 0; i < rdev->num_crtc; i++)
-               rdev->irq.crtc_vblank_int[i] = false;
-       for (i = 0; i < 6; i++) {
+       for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
                rdev->irq.hpd[i] = false;
+       for (i = 0; i < RADEON_MAX_CRTCS; i++) {
+               rdev->irq.crtc_vblank_int[i] = false;
                rdev->irq.pflip[i] = false;
        }
        radeon_irq_set(rdev);
@@ -99,15 +99,55 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
        /* Disable *all* interrupts */
        rdev->irq.sw_int = false;
        rdev->irq.gui_idle = false;
-       for (i = 0; i < rdev->num_crtc; i++)
-               rdev->irq.crtc_vblank_int[i] = false;
-       for (i = 0; i < 6; i++) {
+       for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
                rdev->irq.hpd[i] = false;
+       for (i = 0; i < RADEON_MAX_CRTCS; i++) {
+               rdev->irq.crtc_vblank_int[i] = false;
                rdev->irq.pflip[i] = false;
        }
        radeon_irq_set(rdev);
 }
 
+static bool radeon_msi_ok(struct radeon_device *rdev)
+{
+       /* RV370/RV380 was first asic with MSI support */
+       if (rdev->family < CHIP_RV380)
+               return false;
+
+       /* MSIs don't work on AGP */
+       if (rdev->flags & RADEON_IS_AGP)
+               return false;
+
+       /* force MSI on */
+       if (radeon_msi == 1)
+               return true;
+       else if (radeon_msi == 0)
+               return false;
+
+       /* Quirks */
+       /* HP RS690 only seems to work with MSIs. */
+       if ((rdev->pdev->device == 0x791f) &&
+           (rdev->pdev->subsystem_vendor == 0x103c) &&
+           (rdev->pdev->subsystem_device == 0x30c2))
+               return true;
+
+       /* Dell RS690 only seems to work with MSIs. */
+       if ((rdev->pdev->device == 0x791f) &&
+           (rdev->pdev->subsystem_vendor == 0x1028) &&
+           (rdev->pdev->subsystem_device == 0x01fd))
+               return true;
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               /* APUs work fine with MSIs */
+               if (rdev->family >= CHIP_PALM)
+                       return true;
+               /* lots of IGPs have problems with MSIs */
+               return false;
+       }
+
+       return true;
+}
+
 int radeon_irq_kms_init(struct radeon_device *rdev)
 {
        int i;
@@ -124,12 +164,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
        }
        /* enable msi */
        rdev->msi_enabled = 0;
-       /* MSIs don't seem to work reliably on all IGP
-        * chips.  Disable MSI on them for now.
-        */
-       if ((rdev->family >= CHIP_RV380) &&
-           ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) &&
-           (!(rdev->flags & RADEON_IS_AGP))) {
+
+       if (radeon_msi_ok(rdev)) {
                int ret = pci_enable_msi(rdev->pdev);
                if (!ret) {
                        rdev->msi_enabled = 1;
index 41a5d48e657b61b7d511977b81ad1c6622e10554..daadf2111040875d93df8fef9752428dd35f1cae 100644 (file)
@@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc,
                                   struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
 {
-       struct drm_device *dev = crtc->dev;
-       struct radeon_device *rdev = dev->dev_private;
-
-       /* adjust pm to upcoming mode change */
-       radeon_pm_compute_clocks(rdev);
-
        if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
                return false;
        return true;
index ed0178f0323504dfc5d5ab8be18f6c8026b09dd7..2c2e75ef8a372e1011a37c781e857d8d68c9db50 100644 (file)
@@ -438,9 +438,6 @@ struct radeon_connector {
        struct radeon_i2c_chan *ddc_bus;
        /* some systems have an hdmi and vga port with a shared ddc line */
        bool shared_ddc;
-       /* for some Radeon chip families we apply an additional EDID header
-          check as part of the DDC probe */
-       bool requires_extended_probe;
        bool use_digital;
        /* we need to mind the EDID between detect
           and get modes due to analog/digital/tvencoder */
@@ -459,6 +456,8 @@ struct radeon_framebuffer {
        struct drm_gem_object *obj;
 };
 
+#define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
+                               ((em) == ATOM_ENCODER_MODE_DP_MST))
 
 extern enum radeon_tv_std
 radeon_combios_get_tv_info(struct radeon_device *rdev);
@@ -468,8 +467,8 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev);
 extern struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 
-extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder);
-extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
+extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder);
+extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
 extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
 extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
 
@@ -489,7 +488,7 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
                                           int action, uint8_t lane_num,
                                           uint8_t lane_set);
 extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
-extern struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder);
+extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
                                u8 write_byte, u8 *read_byte);
 
@@ -519,8 +518,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
                                u8 val);
 extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
 extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
-extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector,
-                       bool requires_extended_probe);
+extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
 extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
index 6fabe89fa6a18da11ce5636961b717f84b9b9491..78a665bd95198483862ba0c124453a1d14a87d48 100644 (file)
@@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev);
 
 #define ACPI_AC_CLASS           "ac_adapter"
 
+int radeon_pm_get_type_index(struct radeon_device *rdev,
+                            enum radeon_pm_state_type ps_type,
+                            int instance)
+{
+       int i;
+       int found_instance = -1;
+
+       for (i = 0; i < rdev->pm.num_power_states; i++) {
+               if (rdev->pm.power_state[i].type == ps_type) {
+                       found_instance++;
+                       if (found_instance == instance)
+                               return i;
+               }
+       }
+       /* return default if no match */
+       return rdev->pm.default_power_state_index;
+}
+
 #ifdef CONFIG_ACPI
 static int radeon_acpi_event(struct notifier_block *nb,
                             unsigned long val,
index 89a6e1ecea8deb595e8639a459f7aa477e5c287e..06b90c87f8f397012c82d631fa30a5bd57c5da5a 100644 (file)
@@ -77,7 +77,7 @@ int rs400_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.ram.ptr) {
+       if (rdev->gart.ptr) {
                WARN(1, "RS400 GART already initialized\n");
                return 0;
        }
@@ -212,6 +212,7 @@ void rs400_gart_fini(struct radeon_device *rdev)
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
        uint32_t entry;
+       u32 *gtt = rdev->gart.ptr;
 
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
@@ -221,7 +222,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
                ((upper_32_bits(addr) & 0xff) << 4) |
                RS400_PTE_WRITEABLE | RS400_PTE_READABLE;
        entry = cpu_to_le32(entry);
-       rdev->gart.table.ram.ptr[i] = entry;
+       gtt[i] = entry;
        return 0;
 }
 
index 9320dd6404f67cdbe9ac3ba20aa6e4e582745904..b1053d64042313df931b9cde933e121bfa814517 100644 (file)
@@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
@@ -287,6 +292,7 @@ void rs600_hpd_init(struct radeon_device *rdev)
                default:
                        break;
                }
+               radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
        }
        if (rdev->irq.installed)
                rs600_irq_set(rdev);
@@ -413,7 +419,7 @@ int rs600_gart_init(struct radeon_device *rdev)
 {
        int r;
 
-       if (rdev->gart.table.vram.robj) {
+       if (rdev->gart.robj) {
                WARN(1, "RS600 GART already initialized\n");
                return 0;
        }
@@ -431,7 +437,7 @@ static int rs600_gart_enable(struct radeon_device *rdev)
        u32 tmp;
        int r, i;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -494,20 +500,12 @@ static int rs600_gart_enable(struct radeon_device *rdev)
 void rs600_gart_disable(struct radeon_device *rdev)
 {
        u32 tmp;
-       int r;
 
        /* FIXME: disable out of gart access */
        WREG32_MC(R_000100_MC_PT0_CNTL, 0);
        tmp = RREG32_MC(R_000009_MC_CNTL1);
        WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (r == 0) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void rs600_gart_fini(struct radeon_device *rdev)
@@ -525,7 +523,7 @@ void rs600_gart_fini(struct radeon_device *rdev)
 
 int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
-       void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+       void __iomem *ptr = (void *)rdev->gart.ptr;
 
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
index 87cc1feee3ac9e29d10a52cd33d4062342b5cc95..23ae1c60ab3d97b8a1576c567054b736fd70eb93 100644 (file)
@@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
@@ -124,7 +129,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
        u32 tmp;
        int r, i;
 
-       if (rdev->gart.table.vram.robj == NULL) {
+       if (rdev->gart.robj == NULL) {
                dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
                return -EINVAL;
        }
@@ -171,7 +176,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
 void rv770_pcie_gart_disable(struct radeon_device *rdev)
 {
        u32 tmp;
-       int i, r;
+       int i;
 
        /* Disable all tables */
        for (i = 0; i < 7; i++)
@@ -191,14 +196,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
-       if (rdev->gart.table.vram.robj) {
-               r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
-               if (likely(r == 0)) {
-                       radeon_bo_kunmap(rdev->gart.table.vram.robj);
-                       radeon_bo_unpin(rdev->gart.table.vram.robj);
-                       radeon_bo_unreserve(rdev->gart.table.vram.robj);
-               }
-       }
+       radeon_gart_table_vram_unpin(rdev);
 }
 
 void rv770_pcie_gart_fini(struct radeon_device *rdev)
@@ -282,7 +280,7 @@ static void rv770_mc_program(struct radeon_device *rdev)
                WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
                        rdev->mc.vram_end >> 12);
        }
-       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+       WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
        tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
        tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
        WREG32(MC_VM_FB_LOCATION, tmp);
@@ -959,54 +957,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 
 }
 
-static int rv770_vram_scratch_init(struct radeon_device *rdev)
-{
-       int r;
-       u64 gpu_addr;
-
-       if (rdev->vram_scratch.robj == NULL) {
-               r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
-                                    PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
-                                    &rdev->vram_scratch.robj);
-               if (r) {
-                       return r;
-               }
-       }
-
-       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
-       if (unlikely(r != 0))
-               return r;
-       r = radeon_bo_pin(rdev->vram_scratch.robj,
-                         RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
-       if (r) {
-               radeon_bo_unreserve(rdev->vram_scratch.robj);
-               return r;
-       }
-       r = radeon_bo_kmap(rdev->vram_scratch.robj,
-                               (void **)&rdev->vram_scratch.ptr);
-       if (r)
-               radeon_bo_unpin(rdev->vram_scratch.robj);
-       radeon_bo_unreserve(rdev->vram_scratch.robj);
-
-       return r;
-}
-
-static void rv770_vram_scratch_fini(struct radeon_device *rdev)
-{
-       int r;
-
-       if (rdev->vram_scratch.robj == NULL) {
-               return;
-       }
-       r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
-       if (likely(r == 0)) {
-               radeon_bo_kunmap(rdev->vram_scratch.robj);
-               radeon_bo_unpin(rdev->vram_scratch.robj);
-               radeon_bo_unreserve(rdev->vram_scratch.robj);
-       }
-       radeon_bo_unref(&rdev->vram_scratch.robj);
-}
-
 void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
 {
        u64 size_bf, size_af;
@@ -1106,6 +1056,10 @@ static int rv770_startup(struct radeon_device *rdev)
                }
        }
 
+       r = r600_vram_scratch_init(rdev);
+       if (r)
+               return r;
+
        rv770_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                rv770_agp_enable(rdev);
@@ -1114,9 +1068,7 @@ static int rv770_startup(struct radeon_device *rdev)
                if (r)
                        return r;
        }
-       r = rv770_vram_scratch_init(rdev);
-       if (r)
-               return r;
+
        rv770_gpu_init(rdev);
        r = r600_blit_init(rdev);
        if (r) {
@@ -1316,7 +1268,7 @@ void rv770_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        rv770_pcie_gart_fini(rdev);
-       rv770_vram_scratch_fini(rdev);
+       r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_agp_fini(rdev);
index 6464490b240b70d5e7af37704affbfd4266007fb..5468d1cd3296102560aa1653173233c637494bad 100644 (file)
@@ -23,6 +23,8 @@
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "savage_drm.h"
 #include "savage_drv.h"
index 46d5be6e97e520f9835a1f492c531bdd3670aafe..a9c5716bea4eb1f3a155c2d1d15cda3480c0f51d 100644 (file)
@@ -25,6 +25,8 @@
  *
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "sis_drm.h"
 #include "sis_drv.h"
index 8bf98810a8d63b55e441b65a4d1044530ce6f224..cda29911e332edb7d4dc5ed1d024c597fb6cb2bc 100644 (file)
@@ -30,6 +30,8 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "tdfx_drv.h"
 
index 617b64678fc62f24c70df6ae3fd7ba3bc7d6c9bf..0bb0f5f713e6cf9166a1b91eb19ab81b85206716 100644 (file)
@@ -574,10 +574,16 @@ retry:
                return ret;
 
        spin_lock(&glob->lru_lock);
+
+       if (unlikely(list_empty(&bo->ddestroy))) {
+               spin_unlock(&glob->lru_lock);
+               return 0;
+       }
+
        ret = ttm_bo_reserve_locked(bo, interruptible,
                                    no_wait_reserve, false, 0);
 
-       if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) {
+       if (unlikely(ret != 0)) {
                spin_unlock(&glob->lru_lock);
                return ret;
        }
index 58c271ebc0f73f6829dae7cffa9d680480ad0dd1..f9cc548d6d98cddfe0eccb5dcc154b059162b2d1 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/file.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "drm_cache.h"
 #include "drm_mem_util.h"
 #include "ttm/ttm_module.h"
index 920a55214bcfe277cf261281c295c7b70e9dd68a..a83e86d3956cb284a04945b988e7844a248d4e01 100644 (file)
@@ -22,6 +22,8 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <linux/module.h>
+
 #include "drmP.h"
 #include "via_drm.h"
 #include "via_drv.h"
index 13afddc1f034440b054522dfbe85d9640bea2b11..dff8fc7671525d347382261402d60d002a21dbb5 100644 (file)
@@ -24,6 +24,7 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  **************************************************************************/
+#include <linux/module.h>
 
 #include "drmP.h"
 #include "vmwgfx_drv.h"
 #define DRM_IOCTL_VMW_PRESENT_READBACK                         \
        DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK,    \
                 struct drm_vmw_present_readback_arg)
+#define DRM_IOCTL_VMW_UPDATE_LAYOUT                            \
+       DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT,       \
+                struct drm_vmw_update_layout_arg)
 
 /**
  * The core DRM version of this macro doesn't account for
@@ -165,6 +169,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = {
        VMW_IOCTL_DEF(VMW_PRESENT_READBACK,
                      vmw_present_readback_ioctl,
                      DRM_MASTER | DRM_AUTH | DRM_UNLOCKED),
+       VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT,
+                     vmw_kms_update_layout_ioctl,
+                     DRM_MASTER | DRM_UNLOCKED),
 };
 
 static struct pci_device_id vmw_pci_id_list[] = {
index 30589d0aecd985fd6b556793f4ad8f278f46ad81..8cca91a93bde092af78c6c7bdcfb0ffceb3f04a6 100644 (file)
@@ -40,9 +40,9 @@
 #include "ttm/ttm_module.h"
 #include "vmwgfx_fence.h"
 
-#define VMWGFX_DRIVER_DATE "20111008"
+#define VMWGFX_DRIVER_DATE "20111025"
 #define VMWGFX_DRIVER_MAJOR 2
-#define VMWGFX_DRIVER_MINOR 2
+#define VMWGFX_DRIVER_MINOR 3
 #define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
@@ -633,6 +633,8 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
                     struct drm_vmw_fence_rep __user *user_fence_rep,
                     struct drm_vmw_rect *clips,
                     uint32_t num_clips);
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
 
 /**
  * Overlay control - vmwgfx_overlay.c
index 070797b7b03ae6f22f0b8670094c4690b70f40ea..34e51a1695b84f1d438431501f6df60598bbb79b 100644 (file)
@@ -26,6 +26,8 @@
  *
  **************************************************************************/
 
+#include <linux/export.h>
+
 #include "drmP.h"
 #include "vmwgfx_drv.h"
 
index 3f6343502d1f96aea110dccdeb59a39cb9fe0065..5ff561d4e0b496727d0e1e8416da14ce871ffd90 100644 (file)
@@ -140,7 +140,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
                goto out_clips;
        }
 
-       clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+       clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
        if (clips == NULL) {
                DRM_ERROR("Failed to allocate clip rect list.\n");
                ret = -ENOMEM;
@@ -232,7 +232,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
                goto out_clips;
        }
 
-       clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL);
+       clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL);
        if (clips == NULL) {
                DRM_ERROR("Failed to allocate clip rect list.\n");
                ret = -ENOMEM;
index 8b14dfd513a10ece2d9c2fe747e490e08205dd9d..37d40545ed77347007d1051689895d40b116cd1d 100644 (file)
@@ -105,12 +105,17 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
        struct vmw_dma_buffer *dmabuf = NULL;
        int ret;
 
+       /* A lot of the code assumes this */
+       if (handle && (width != 64 || height != 64))
+               return -EINVAL;
+
        if (handle) {
                ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
                                                     handle, &surface);
                if (!ret) {
                        if (!surface->snooper.image) {
                                DRM_ERROR("surface not suitable for cursor\n");
+                               vmw_surface_unreference(&surface);
                                return -EINVAL;
                        }
                } else {
@@ -176,7 +181,9 @@ err_unreserve:
                return 0;
        }
 
-       vmw_cursor_update_position(dev_priv, true, du->cursor_x, du->cursor_y);
+       vmw_cursor_update_position(dev_priv, true,
+                                  du->cursor_x + du->hotspot_x,
+                                  du->cursor_y + du->hotspot_y);
 
        return 0;
 }
@@ -191,7 +198,8 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
        du->cursor_y = y + crtc->y;
 
        vmw_cursor_update_position(dev_priv, shown,
-                                  du->cursor_x, du->cursor_y);
+                                  du->cursor_x + du->hotspot_x,
+                                  du->cursor_y + du->hotspot_y);
 
        return 0;
 }
@@ -212,7 +220,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
                SVGA3dCmdHeader header;
                SVGA3dCmdSurfaceDMA dma;
        } *cmd;
-       int ret;
+       int i, ret;
 
        cmd = container_of(header, struct vmw_dma_cmd, header);
 
@@ -234,16 +242,19 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
        box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
                        sizeof(SVGA3dCopyBox);
 
-       if (cmd->dma.guest.pitch != (64 * 4) ||
-           cmd->dma.guest.ptr.offset % PAGE_SIZE ||
+       if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
            box->x != 0    || box->y != 0    || box->z != 0    ||
            box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
-           box->w != 64   || box->h != 64   || box->d != 1    ||
-           box_count != 1) {
+           box->d != 1    || box_count != 1) {
                /* TODO handle none page aligned offsets */
-               /* TODO handle partial uploads and pitch != 256 */
-               /* TODO handle more then one copy (size != 64) */
-               DRM_ERROR("lazy programmer, can't handle weird stuff\n");
+               /* TODO handle more dst & src != 0 */
+               /* TODO handle more then one copy */
+               DRM_ERROR("Cant snoop dma request for cursor!\n");
+               DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
+                         box->srcx, box->srcy, box->srcz,
+                         box->x, box->y, box->z,
+                         box->w, box->h, box->d, box_count,
+                         cmd->dma.guest.ptr.offset);
                return;
        }
 
@@ -262,7 +273,16 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
 
        virtual = ttm_kmap_obj_virtual(&map, &dummy);
 
-       memcpy(srf->snooper.image, virtual, 64*64*4);
+       if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
+               memcpy(srf->snooper.image, virtual, 64*64*4);
+       } else {
+               /* Image is unsigned pointer. */
+               for (i = 0; i < box->h; i++)
+                       memcpy(srf->snooper.image + i * 64,
+                              virtual + i * cmd->dma.guest.pitch,
+                              box->w * 4);
+       }
+
        srf->snooper.age++;
 
        /* we can't call this function from this function since execbuf has
@@ -394,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
        top = clips->y1;
        bottom = clips->y2;
 
-       clips_ptr = clips;
-       for (i = 1; i < num_clips; i++, clips_ptr += inc) {
+       /* skip the first clip rect */
+       for (i = 1, clips_ptr = clips + inc;
+            i < num_clips; i++, clips_ptr += inc) {
                left = min_t(int, left, (int)clips_ptr->x1);
                right = max_t(int, right, (int)clips_ptr->x2);
                top = min_t(int, top, (int)clips_ptr->y1);
@@ -994,7 +1015,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
        required_size = mode_cmd->pitch * mode_cmd->height;
        if (unlikely(required_size > (u64) dev_priv->vram_size)) {
                DRM_ERROR("VRAM size is too small for requested mode.\n");
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
 
        /*
@@ -1307,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)
         * drm_encoder_cleanup which takes the lock we deadlock.
         */
        drm_mode_config_cleanup(dev_priv->dev);
-       vmw_kms_close_legacy_display_system(dev_priv);
+       if (dev_priv->sou_priv)
+               vmw_kms_close_screen_object_display(dev_priv);
+       else
+               vmw_kms_close_legacy_display_system(dev_priv);
        return 0;
 }
 
@@ -1517,6 +1541,8 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
                        du->pref_width = rects[du->unit].w;
                        du->pref_height = rects[du->unit].h;
                        du->pref_active = true;
+                       du->gui_x = rects[du->unit].x;
+                       du->gui_y = rects[du->unit].y;
                } else {
                        du->pref_width = 800;
                        du->pref_height = 600;
@@ -1572,12 +1598,14 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force)
        uint32_t num_displays;
        struct drm_device *dev = connector->dev;
        struct vmw_private *dev_priv = vmw_priv(dev);
+       struct vmw_display_unit *du = vmw_connector_to_du(connector);
 
        mutex_lock(&dev_priv->hw_mutex);
        num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
        mutex_unlock(&dev_priv->hw_mutex);
 
-       return ((vmw_connector_to_du(connector)->unit < num_displays) ?
+       return ((vmw_connector_to_du(connector)->unit < num_displays &&
+                du->pref_active) ?
                connector_status_connected : connector_status_disconnected);
 }
 
@@ -1658,6 +1686,28 @@ static struct drm_display_mode vmw_kms_connector_builtin[] = {
        { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
 };
 
+/**
+ * vmw_guess_mode_timing - Provide fake timings for a
+ * 60Hz vrefresh mode.
+ *
+ * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay
+ * members filled in.
+ */
+static void vmw_guess_mode_timing(struct drm_display_mode *mode)
+{
+       mode->hsync_start = mode->hdisplay + 50;
+       mode->hsync_end = mode->hsync_start + 50;
+       mode->htotal = mode->hsync_end + 50;
+
+       mode->vsync_start = mode->vdisplay + 50;
+       mode->vsync_end = mode->vsync_start + 50;
+       mode->vtotal = mode->vsync_end + 50;
+
+       mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
+       mode->vrefresh = drm_mode_vrefresh(mode);
+}
+
+
 int vmw_du_connector_fill_modes(struct drm_connector *connector,
                                uint32_t max_width, uint32_t max_height)
 {
@@ -1680,18 +1730,23 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
                        return 0;
                mode->hdisplay = du->pref_width;
                mode->vdisplay = du->pref_height;
-               mode->vrefresh = drm_mode_vrefresh(mode);
+               vmw_guess_mode_timing(mode);
+
                if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2,
                                               mode->vdisplay)) {
                        drm_mode_probed_add(connector, mode);
+               } else {
+                       drm_mode_destroy(dev, mode);
+                       mode = NULL;
+               }
 
-                       if (du->pref_mode) {
-                               list_del_init(&du->pref_mode->head);
-                               drm_mode_destroy(dev, du->pref_mode);
-                       }
-
-                       du->pref_mode = mode;
+               if (du->pref_mode) {
+                       list_del_init(&du->pref_mode->head);
+                       drm_mode_destroy(dev, du->pref_mode);
                }
+
+               /* mode might be null here, this is intended */
+               du->pref_mode = mode;
        }
 
        for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
@@ -1712,6 +1767,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
                drm_mode_probed_add(connector, mode);
        }
 
+       /* Move the prefered mode first, help apps pick the right mode. */
+       if (du->pref_mode)
+               list_move(&du->pref_mode->head, &connector->probed_modes);
+
        drm_mode_connector_list_update(connector);
 
        return 1;
@@ -1723,3 +1782,64 @@ int vmw_du_connector_set_property(struct drm_connector *connector,
 {
        return 0;
 }
+
+
+int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv)
+{
+       struct vmw_private *dev_priv = vmw_priv(dev);
+       struct drm_vmw_update_layout_arg *arg =
+               (struct drm_vmw_update_layout_arg *)data;
+       struct vmw_master *vmaster = vmw_master(file_priv->master);
+       void __user *user_rects;
+       struct drm_vmw_rect *rects;
+       unsigned rects_size;
+       int ret;
+       int i;
+       struct drm_mode_config *mode_config = &dev->mode_config;
+
+       ret = ttm_read_lock(&vmaster->lock, true);
+       if (unlikely(ret != 0))
+               return ret;
+
+       if (!arg->num_outputs) {
+               struct drm_vmw_rect def_rect = {0, 0, 800, 600};
+               vmw_du_update_layout(dev_priv, 1, &def_rect);
+               goto out_unlock;
+       }
+
+       rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
+       rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
+                       GFP_KERNEL);
+       if (unlikely(!rects)) {
+               ret = -ENOMEM;
+               goto out_unlock;
+       }
+
+       user_rects = (void __user *)(unsigned long)arg->rects;
+       ret = copy_from_user(rects, user_rects, rects_size);
+       if (unlikely(ret != 0)) {
+               DRM_ERROR("Failed to get rects.\n");
+               ret = -EFAULT;
+               goto out_free;
+       }
+
+       for (i = 0; i < arg->num_outputs; ++i) {
+               if (rects[i].x < 0 ||
+                   rects[i].y < 0 ||
+                   rects[i].x + rects[i].w > mode_config->max_width ||
+                   rects[i].y + rects[i].h > mode_config->max_height) {
+                       DRM_ERROR("Invalid GUI layout.\n");
+                       ret = -EINVAL;
+                       goto out_free;
+               }
+       }
+
+       vmw_du_update_layout(dev_priv, arg->num_outputs, rects);
+
+out_free:
+       kfree(rects);
+out_unlock:
+       ttm_read_unlock(&vmaster->lock);
+       return ret;
+}
index db0b901f8c3f0f05a76117b92768e7a49a1ba24d..af8e6e5bd964a2dca37f7ba17165256d44a2f8bf 100644 (file)
@@ -96,6 +96,13 @@ struct vmw_display_unit {
        unsigned pref_height;
        bool pref_active;
        struct drm_display_mode *pref_mode;
+
+       /*
+        * Gui positioning
+        */
+       int gui_x;
+       int gui_y;
+       bool is_implicit;
 };
 
 #define vmw_crtc_to_du(x) \
@@ -126,8 +133,7 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
 int vmw_du_connector_set_property(struct drm_connector *connector,
                                  struct drm_property *property,
                                  uint64_t val);
-int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
-                        struct drm_vmw_rect *rects);
+
 
 /*
  * Legacy display unit functions - vmwgfx_ldu.c
index 92f56bc594eb6bcd1f691fc7218316334f9c29ce..90c5e39284913353f68c6e4611d59391d557228c 100644 (file)
@@ -337,13 +337,14 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
        ldu->base.pref_width = 800;
        ldu->base.pref_height = 600;
        ldu->base.pref_mode = NULL;
+       ldu->base.is_implicit = true;
 
        drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
-                          DRM_MODE_CONNECTOR_LVDS);
+                          DRM_MODE_CONNECTOR_VIRTUAL);
        connector->status = vmw_du_connector_detect(connector, true);
 
        drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
-                        DRM_MODE_ENCODER_LVDS);
+                        DRM_MODE_ENCODER_VIRTUAL);
        drm_mode_connector_attach_encoder(connector, encoder);
        encoder->possible_crtcs = (1 << unit);
        encoder->possible_clones = 0;
index 477b2a9eb3c2acdc8ebbfcc3a52eb4991bc8f332..4defdcf1c72e2023eaf23f8598c0b83f2803b289 100644 (file)
        container_of(x, struct vmw_screen_object_unit, base.connector)
 
 struct vmw_screen_object_display {
-       struct list_head active;
+       unsigned num_implicit;
 
-       unsigned num_active;
-       unsigned last_num_active;
-
-       struct vmw_framebuffer *fb;
+       struct vmw_framebuffer *implicit_fb;
 };
 
 /**
@@ -54,13 +51,11 @@ struct vmw_screen_object_unit {
        struct vmw_dma_buffer *buffer; /**< Backing store buffer */
 
        bool defined;
-
-       struct list_head active;
+       bool active_implicit;
 };
 
 static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
 {
-       list_del_init(&sou->active);
        vmw_display_unit_cleanup(&sou->base);
        kfree(sou);
 }
@@ -75,58 +70,31 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc)
        vmw_sou_destroy(vmw_crtc_to_sou(crtc));
 }
 
-static int vmw_sou_del_active(struct vmw_private *vmw_priv,
+static void vmw_sou_del_active(struct vmw_private *vmw_priv,
                              struct vmw_screen_object_unit *sou)
 {
        struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
-       if (list_empty(&sou->active))
-               return 0;
 
-       /* Must init otherwise list_empty(&sou->active) will not work. */
-       list_del_init(&sou->active);
-       if (--(ld->num_active) == 0) {
-               BUG_ON(!ld->fb);
-               if (ld->fb->unpin)
-                       ld->fb->unpin(ld->fb);
-               ld->fb = NULL;
+       if (sou->active_implicit) {
+               if (--(ld->num_implicit) == 0)
+                       ld->implicit_fb = NULL;
+               sou->active_implicit = false;
        }
-
-       return 0;
 }
 
-static int vmw_sou_add_active(struct vmw_private *vmw_priv,
+static void vmw_sou_add_active(struct vmw_private *vmw_priv,
                              struct vmw_screen_object_unit *sou,
                              struct vmw_framebuffer *vfb)
 {
        struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
-       struct vmw_screen_object_unit *entry;
-       struct list_head *at;
-
-       BUG_ON(!ld->num_active && ld->fb);
-       if (vfb != ld->fb) {
-               if (ld->fb && ld->fb->unpin)
-                       ld->fb->unpin(ld->fb);
-               if (vfb->pin)
-                       vfb->pin(vfb);
-               ld->fb = vfb;
-       }
-
-       if (!list_empty(&sou->active))
-               return 0;
 
-       at = &ld->active;
-       list_for_each_entry(entry, &ld->active, active) {
-               if (entry->base.unit > sou->base.unit)
-                       break;
+       BUG_ON(!ld->num_implicit && ld->implicit_fb);
 
-               at = &entry->active;
+       if (!sou->active_implicit && sou->base.is_implicit) {
+               ld->implicit_fb = vfb;
+               sou->active_implicit = true;
+               ld->num_implicit++;
        }
-
-       list_add(&sou->active, at);
-
-       ld->num_active++;
-
-       return 0;
 }
 
 /**
@@ -164,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv,
                (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
        cmd->obj.size.width = mode->hdisplay;
        cmd->obj.size.height = mode->vdisplay;
-       cmd->obj.root.x = x;
-       cmd->obj.root.y = y;
+       if (sou->base.is_implicit) {
+               cmd->obj.root.x = x;
+               cmd->obj.root.y = y;
+       } else {
+               cmd->obj.root.x = sou->base.gui_x;
+               cmd->obj.root.y = sou->base.gui_y;
+       }
 
        /* Ok to assume that buffer is pinned in vram */
        vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
@@ -312,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
        }
 
        /* sou only supports one fb active at the time */
-       if (dev_priv->sou_priv->fb && vfb &&
-           !(dev_priv->sou_priv->num_active == 1 &&
-             !list_empty(&sou->active)) &&
-           dev_priv->sou_priv->fb != vfb) {
+       if (sou->base.is_implicit &&
+           dev_priv->sou_priv->implicit_fb && vfb &&
+           !(dev_priv->sou_priv->num_implicit == 1 &&
+             sou->active_implicit) &&
+           dev_priv->sou_priv->implicit_fb != vfb) {
                DRM_ERROR("Multiple framebuffers not supported\n");
                return -EINVAL;
        }
@@ -471,19 +445,20 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
        encoder = &sou->base.encoder;
        connector = &sou->base.connector;
 
-       INIT_LIST_HEAD(&sou->active);
+       sou->active_implicit = false;
 
        sou->base.pref_active = (unit == 0);
        sou->base.pref_width = 800;
        sou->base.pref_height = 600;
        sou->base.pref_mode = NULL;
+       sou->base.is_implicit = true;
 
        drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
-                          DRM_MODE_CONNECTOR_LVDS);
+                          DRM_MODE_CONNECTOR_VIRTUAL);
        connector->status = vmw_du_connector_detect(connector, true);
 
        drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs,
-                        DRM_MODE_ENCODER_LVDS);
+                        DRM_MODE_ENCODER_VIRTUAL);
        drm_mode_connector_attach_encoder(connector, encoder);
        encoder->possible_crtcs = (1 << unit);
        encoder->possible_clones = 0;
@@ -520,10 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv)
        if (unlikely(!dev_priv->sou_priv))
                goto err_no_mem;
 
-       INIT_LIST_HEAD(&dev_priv->sou_priv->active);
-       dev_priv->sou_priv->num_active = 0;
-       dev_priv->sou_priv->last_num_active = 0;
-       dev_priv->sou_priv->fb = NULL;
+       dev_priv->sou_priv->num_implicit = 0;
+       dev_priv->sou_priv->implicit_fb = NULL;
 
        ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
        if (unlikely(ret != 0))
@@ -558,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
 
        drm_vblank_cleanup(dev);
 
-       if (!list_empty(&dev_priv->sou_priv->active))
-               DRM_ERROR("Still have active outputs when unloading driver");
-
        kfree(dev_priv->sou_priv);
 
        return 0;
index c72f1c0b5e637951a450b21378f2edfeb8e92725..111d956d8e7d0d919d088405ddeaf3b341c87092 100644 (file)
@@ -465,31 +465,29 @@ static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)
        while (new_bus) {
                new_bridge = new_bus->self;
 
-               if (new_bridge) {
-                       /* go through list of devices already registered */
-                       list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
-                               bus = same_bridge_vgadev->pdev->bus;
-                               bridge = bus->self;
-
-                               /* see if the share a bridge with this device */
-                               if (new_bridge == bridge) {
-                                       /* if their direct parent bridge is the same
-                                          as any bridge of this device then it can't be used
-                                          for that device */
-                                       same_bridge_vgadev->bridge_has_one_vga = false;
-                               }
+               /* go through list of devices already registered */
+               list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
+                       bus = same_bridge_vgadev->pdev->bus;
+                       bridge = bus->self;
+
+                       /* see if the share a bridge with this device */
+                       if (new_bridge == bridge) {
+                               /* if their direct parent bridge is the same
+                                  as any bridge of this device then it can't be used
+                                  for that device */
+                               same_bridge_vgadev->bridge_has_one_vga = false;
+                       }
 
-                               /* now iterate the previous devices bridge hierarchy */
-                               /* if the new devices parent bridge is in the other devices
-                                  hierarchy then we can't use it to control this device */
-                               while (bus) {
-                                       bridge = bus->self;
-                                       if (bridge) {
-                                               if (bridge == vgadev->pdev->bus->self)
-                                                       vgadev->bridge_has_one_vga = false;
-                                       }
-                                       bus = bus->parent;
+                       /* now iterate the previous devices bridge hierarchy */
+                       /* if the new devices parent bridge is in the other devices
+                          hierarchy then we can't use it to control this device */
+                       while (bus) {
+                               bridge = bus->self;
+                               if (bridge) {
+                                       if (bridge == vgadev->pdev->bus->self)
+                                               vgadev->bridge_has_one_vga = false;
                                }
+                               bus = bus->parent;
                        }
                }
                new_bus = new_bus->parent;
@@ -993,14 +991,20 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
                                uc = &priv->cards[i];
                }
 
-               if (!uc)
-                       return -EINVAL;
+               if (!uc) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
-               if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0)
-                       return -EINVAL;
+               if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
-               if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0)
-                       return -EINVAL;
+               if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) {
+                       ret_val = -EINVAL;
+                       goto done;
+               }
 
                vga_put(pdev, io_state);
 
index 8cdb4b45b30a26f3dcf44be3c662299e6e92d001..299d23871122f29f8651917caf2ccb461a4c8c1d 100644 (file)
@@ -183,9 +183,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
                                hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
                        table = macbookair_fn_keys;
-               else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI &&
-                               hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS)
-                       table = macbookair_fn_keys;
                else if (hid->product < 0x21d || hid->product >= 0x300)
                        table = powerbook_fn_keys;
                else
index 3bdb4500f95eea6bc7f8b901cc460d3d881ae2b5..5be858dd9a158b004844a0a4ebc93351c1a58965 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/module.h>
 
 #include "hid-ids.h"
 
index 848a56c0279c8ac61687340c732521094428e541..af353842f75feaceadeedcc547eeb880519f86df 100644 (file)
@@ -1771,8 +1771,8 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
index 9a243ca96e6db8fbb754b34e16e8c508ee289eab..ee80d733801d30cc4abe2d5909e682835013b551 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/poll.h>
index 61eece47204d370f4d66de3d672be96468da42e8..e832f44ae38391ae05ba88879d0b6189371d51dd 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/module.h>
 
 #include "hid-ids.h"
 
index a5dc13fe367b7584e8290e1e5dcd29c5cd028df7..9bdde867a02fbad7a6b163d82babb9376dc1f78f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/hid.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 
 #include "hid-ids.h"
 #include "usbhid/usbhid.h"
index 279ba530003cc5dcbcdff46256f18d2e5f112b22..f1e1bcf674270d3f7c90cd41be3c21e50ff369a7 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/module.h>
 #include "hid-ids.h"
 
 #ifdef CONFIG_GREENASIA_FF
index 91e3a032112b205e698549b470889f9941ab0a27..4e7542151e222a0d711c3c844656e829fd2b2fef 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
 
index 06ce996b8b6504f65c9216c3173a38cf5a51cb34..4a441a6f996748a923204fbcb53c4850eb3af061 100644 (file)
 #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
 
 #define USB_VENDOR_ID_GENERAL_TOUCH    0x0dfc
-#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
 
 #define USB_VENDOR_ID_GLAB             0x06c2
 #define USB_DEVICE_ID_4_PHIDGETSERVO_30        0x0038
index 1782693819f37346390704739bc3a3183c5833ef..01e7d2cd7c26a55170d2f7eda4e0a83cb37cb55d 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/completion.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #define PICOLCD_NAME "PicoLCD (graphic)"
 
index 06e5300d43d2945ce9bf644d421bb1f3f8c0ac9c..070f93a5c11b38ce36501594dba191bcc7354369 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <linux/input.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
 
index edf898dee28bd177a0e7c4fc7a40971aee72e457..b07e7f96a3580e0168bce0a89e86b8091c94cd7a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/hid.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "hid-roccat-common.h"
 
 static inline uint16_t roccat_common_feature_report(uint8_t report_id)
index 56ce12c23b02b523ef095615a5e8f6e0f828553a..b685b04dbf9dec295c3842930df65a6a542d8193 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/hid-roccat.h>
+#include <linux/module.h>
 
 #define ROCCAT_FIRST_MINOR 0
 #define ROCCAT_MAX_DEVICES 8
index 670da9109f86fa2b5aba02951eda62593a4e7d33..4b1448613ea65ad4f1c8dc6db4441aead6562f31 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
+#include <linux/module.h>
 #include "hid-ids.h"
 
 #ifdef CONFIG_SMARTJOYPLUS_FF
index 575862b0688e4e233108f155812a5962dd38177b..83a933b9c2e98163004c7c6dc999133196375840 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 
 #include "hid-ids.h"
 
index f31fab012f2f24732aa7934cc732b9e7b7cffb64..f6ba81df71bdedfe7b721c7e12970992fb1c53b0 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 
 #include "hid-ids.h"
 
index 4ea464151c3be0d53de577b0aec833136a5d85b5..5028d60a22a19b6b69cd1c942728f350d40744b7 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/hid.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include "../hid-ids.h"
index 9ec854ae118b91c5fea647d61bab7f29117a10a5..91be41f6080947936bdd355f25500397ecfd1dfe 100644 (file)
@@ -315,7 +315,7 @@ config SENSORS_DS1621
 
 config SENSORS_EXYNOS4_TMU
        tristate "Temperature sensor on Samsung EXYNOS4"
-       depends on EXYNOS4_DEV_TMU
+       depends on ARCH_EXYNOS4
        help
          If you say yes here you get support for TMU (Thermal Managment
          Unit) on SAMSUNG EXYNOS4 series of SoC.
index 318e38e853764eeeea220bfb519079cf20f687bc..5d760f3d21c2d61ee85227ab7107bf4c38e011f9 100644 (file)
@@ -160,7 +160,6 @@ MODULE_DEVICE_TABLE(spi, ad7314_id);
 static struct spi_driver ad7314_driver = {
        .driver = {
                .name = "ad7314",
-               .bus = &spi_bus_type,
                .owner = THIS_MODULE,
        },
        .probe = ad7314_probe,
index 52319340e182da8f189eae518d80bd3674d26425..04450f8bf5da28e4dff56e70ab86e294920c2cf2 100644 (file)
@@ -227,7 +227,6 @@ static int __devexit ads7871_remove(struct spi_device *spi)
 static struct spi_driver ads7871_driver = {
        .driver = {
                .name = DEVICE_NAME,
-               .bus = &spi_bus_type,
                .owner = THIS_MODULE,
        },
 
index ce18c046f72885b09a79e6d9160f4381b004657d..104b3767516cb91b95d310a52c0968adf0d2c639 100644 (file)
@@ -60,14 +60,13 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
 #ifdef CONFIG_SMP
 #define TO_PHYS_ID(cpu)                cpu_data(cpu).phys_proc_id
 #define TO_CORE_ID(cpu)                cpu_data(cpu).cpu_core_id
-#define TO_ATTR_NO(cpu)                (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
 #define for_each_sibling(i, cpu)       for_each_cpu(i, cpu_sibling_mask(cpu))
 #else
 #define TO_PHYS_ID(cpu)                (cpu)
 #define TO_CORE_ID(cpu)                (cpu)
-#define TO_ATTR_NO(cpu)                (cpu)
 #define for_each_sibling(i, cpu)       for (i = 0; false; )
 #endif
+#define TO_ATTR_NO(cpu)                (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
 
 /*
  * Per-Core Temperature Data
index faa0884f61f67bc49e72e93c075160d46078cba4..f2359a0093bd65e52c6985e6a06eef3a0cec8d37 100644 (file)
@@ -506,17 +506,7 @@ static struct platform_driver exynos4_tmu_driver = {
        .resume = exynos4_tmu_resume,
 };
 
-static int __init exynos4_tmu_driver_init(void)
-{
-       return platform_driver_register(&exynos4_tmu_driver);
-}
-module_init(exynos4_tmu_driver_init);
-
-static void __exit exynos4_tmu_driver_exit(void)
-{
-       platform_driver_unregister(&exynos4_tmu_driver);
-}
-module_exit(exynos4_tmu_driver_exit);
+module_platform_driver(exynos4_tmu_driver);
 
 MODULE_DESCRIPTION("EXYNOS4 TMU Driver");
 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
index 89aa9fb743af07260c8deadbc8956eb4c1ada2de..9ba38f318ffb458247dd66b58b77c3c03e203727 100644 (file)
@@ -539,18 +539,7 @@ static struct platform_driver gpio_fan_driver = {
        },
 };
 
-static int __init gpio_fan_init(void)
-{
-       return platform_driver_register(&gpio_fan_driver);
-}
-
-static void __exit gpio_fan_exit(void)
-{
-       platform_driver_unregister(&gpio_fan_driver);
-}
-
-module_init(gpio_fan_init);
-module_exit(gpio_fan_exit);
+module_platform_driver(gpio_fan_driver);
 
 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
 MODULE_DESCRIPTION("GPIO FAN driver");
index fea292d43407cecba6e75b70021617f871d6b1b8..7a48b1eb423334780116f1cb6e16edcec8f19a49 100644 (file)
@@ -212,17 +212,7 @@ struct platform_driver jz4740_hwmon_driver = {
        },
 };
 
-static int __init jz4740_hwmon_init(void)
-{
-       return platform_driver_register(&jz4740_hwmon_driver);
-}
-module_init(jz4740_hwmon_init);
-
-static void __exit jz4740_hwmon_exit(void)
-{
-       platform_driver_unregister(&jz4740_hwmon_driver);
-}
-module_exit(jz4740_hwmon_exit);
+module_platform_driver(jz4740_hwmon_driver);
 
 MODULE_DESCRIPTION("JZ4740 SoC HWMON driver");
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
index eab11615dced6b54e71996bfd4df60c159bbe570..9b382ec2c3bd4de978d98a6d9f24f797684fe534 100644 (file)
@@ -432,19 +432,7 @@ static struct platform_driver ntc_thermistor_driver = {
        .id_table = ntc_thermistor_id,
 };
 
-static int __init ntc_thermistor_init(void)
-{
-       return platform_driver_register(&ntc_thermistor_driver);
-}
-
-module_init(ntc_thermistor_init);
-
-static void __exit ntc_thermistor_cleanup(void)
-{
-       platform_driver_unregister(&ntc_thermistor_driver);
-}
-
-module_exit(ntc_thermistor_cleanup);
+module_platform_driver(ntc_thermistor_driver);
 
 MODULE_DESCRIPTION("NTC Thermistor Driver");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
index b39f52e2752a7bca54a1bb25c7083382b01aa52e..f6c26d19f521aaa98dd2b0596d67ab27028b8d15 100644 (file)
@@ -393,18 +393,7 @@ static struct platform_driver s3c_hwmon_driver = {
        .remove         = __devexit_p(s3c_hwmon_remove),
 };
 
-static int __init s3c_hwmon_init(void)
-{
-       return platform_driver_register(&s3c_hwmon_driver);
-}
-
-static void __exit s3c_hwmon_exit(void)
-{
-       platform_driver_unregister(&s3c_hwmon_driver);
-}
-
-module_init(s3c_hwmon_init);
-module_exit(s3c_hwmon_exit);
+module_platform_driver(s3c_hwmon_driver);
 
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("S3C ADC HWMon driver");
index e3b5c6039c2541e67e63066e4311f2dc6c1021b6..79b6dabe3161461a3f1ccdf277588860f7863df9 100644 (file)
@@ -590,19 +590,8 @@ static struct platform_driver sch5627_driver = {
        .remove         = sch5627_remove,
 };
 
-static int __init sch5627_init(void)
-{
-       return platform_driver_register(&sch5627_driver);
-}
-
-static void __exit sch5627_exit(void)
-{
-       platform_driver_unregister(&sch5627_driver);
-}
+module_platform_driver(sch5627_driver);
 
 MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
-
-module_init(sch5627_init);
-module_exit(sch5627_exit);
index 244407aa79fcbe05dc05b10ae7d88c0327db6d29..9d5236fb09b421e6a1e78cd5b190eaa9d19f6a2d 100644 (file)
@@ -521,19 +521,8 @@ static struct platform_driver sch5636_driver = {
        .remove         = sch5636_remove,
 };
 
-static int __init sch5636_init(void)
-{
-       return platform_driver_register(&sch5636_driver);
-}
-
-static void __exit sch5636_exit(void)
-{
-       platform_driver_unregister(&sch5636_driver);
-}
+module_platform_driver(sch5636_driver);
 
 MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver");
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
-
-module_init(sch5636_init);
-module_exit(sch5636_exit);
index 57240740b161d190329b5ca3b7dfaf0d049ef02e..0018c7dd0097de5045f646d98e715713ea7edba4 100644 (file)
@@ -136,19 +136,7 @@ static struct platform_driver twl4030_madc_hwmon_driver = {
                   },
 };
 
-static int __init twl4030_madc_hwmon_init(void)
-{
-       return platform_driver_register(&twl4030_madc_hwmon_driver);
-}
-
-module_init(twl4030_madc_hwmon_init);
-
-static void __exit twl4030_madc_hwmon_exit(void)
-{
-       platform_driver_unregister(&twl4030_madc_hwmon_driver);
-}
-
-module_exit(twl4030_madc_hwmon_exit);
+module_platform_driver(twl4030_madc_hwmon_driver);
 
 MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
 MODULE_LICENSE("GPL");
index 27a62711e0a6170c4d32fa1c608660af761b9a48..b9a87e89bab4471ce29aba1509f14bd908603b3e 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/io.h>
 #include <linux/hwmon.h>
@@ -308,15 +309,4 @@ static struct platform_driver env_driver = {
        .remove         = __devexit_p(env_remove),
 };
 
-static int __init env_init(void)
-{
-       return platform_driver_register(&env_driver);
-}
-
-static void __exit env_exit(void)
-{
-       platform_driver_unregister(&env_driver);
-}
-
-module_init(env_init);
-module_exit(env_exit);
+module_platform_driver(env_driver);
index 483cb268781e23f37ec6ac3438335cd20ddd7563..93f5fc7d60596c3ab27c23c5794fccd4a53a40a5 100644 (file)
@@ -1835,12 +1835,15 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
                diode = 0x70;
        }
        for (i = 0; i < 3; i++) {
-               const char *label = data->temp_label[data->temp_src[i]];
+               const char *label = NULL;
+
+               if (data->temp_label)
+                       label = data->temp_label[data->temp_src[i]];
 
                /* Digital source overrides analog type */
-               if (strncmp(label, "PECI", 4) == 0)
+               if (label && strncmp(label, "PECI", 4) == 0)
                        data->temp_type[i] = 6;
-               else if (strncmp(label, "AMD", 3) == 0)
+               else if (label && strncmp(label, "AMD", 3) == 0)
                        data->temp_type[i] = 5;
                else if ((tmp & (0x02 << i)))
                        data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
index 97b1f834a4714b540fd95352271bb253ef130c9c..9b598ed26020563978f1142840c4b6a5f0ecad77 100644 (file)
@@ -209,17 +209,7 @@ static struct platform_driver wm831x_hwmon_driver = {
        },
 };
 
-static int __init wm831x_hwmon_init(void)
-{
-       return platform_driver_register(&wm831x_hwmon_driver);
-}
-module_init(wm831x_hwmon_init);
-
-static void __exit wm831x_hwmon_exit(void)
-{
-       platform_driver_unregister(&wm831x_hwmon_driver);
-}
-module_exit(wm831x_hwmon_exit);
+module_platform_driver(wm831x_hwmon_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("WM831x Hardware Monitoring");
index 13290595ca8660f25ebbd0e0c350795dc3d6ccc8..3ff67edbdc44af02a7d0553dd2d74530cc00ca6f 100644 (file)
@@ -133,17 +133,7 @@ static struct platform_driver wm8350_hwmon_driver = {
        },
 };
 
-static int __init wm8350_hwmon_init(void)
-{
-       return platform_driver_register(&wm8350_hwmon_driver);
-}
-module_init(wm8350_hwmon_init);
-
-static void __exit wm8350_hwmon_exit(void)
-{
-       platform_driver_unregister(&wm8350_hwmon_driver);
-}
-module_exit(wm8350_hwmon_exit);
+module_platform_driver(wm8350_hwmon_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
index 143461a95ae4adc8bd75557aa8e76f5a2d298b9f..86980fe041179e388007bb042dfde84a667acf59 100644 (file)
@@ -21,6 +21,7 @@
  * General Public License for more details.
  */
 
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
@@ -108,10 +109,8 @@ static int __devinit u8500_hsem_probe(struct platform_device *pdev)
                return -ENODEV;
 
        io_base = ioremap(res->start, resource_size(res));
-       if (!io_base) {
-               ret = -ENOMEM;
-               goto free_state;
-       }
+       if (!io_base)
+               return -ENOMEM;
 
        /* make sure protocol 1 is selected */
        val = readl(io_base + HSEM_CTRL_REG);
index 85584a547c25201a1375bf92b074af571d37be0e..525c7345fa0b904242a0ef10a5d9502ab5e4baf1 100644 (file)
@@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
 
        if (flags & I2C_M_TEN) {
                /* a ten bit address */
-               addr = 0xf0 | ((msg->addr >> 7) & 0x03);
+               addr = 0xf0 | ((msg->addr >> 7) & 0x06);
                bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
                /* try extended address code...*/
                ret = try_address(i2c_adap, addr, retries);
@@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        return -ENXIO;
                }
                /* the remaining 8 bit address */
-               ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
+               ret = i2c_outb(i2c_adap, msg->addr & 0xff);
                if ((ret != 1) && !nak_ok) {
                        /* the chip did not ack / xmission error occurred */
                        dev_err(&i2c_adap->dev, "died at 2nd address code\n");
index 835e47b39bc264535c567669d12a81784a8c90c7..03b61577888748a4d9a61cfe46b413eaaa219737 100644 (file)
@@ -593,7 +593,7 @@ static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
        i2c->adap.algo_data = i2c;
        i2c->adap.dev.parent = &pdev->dev;
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
 
        clk_get_rate(i2c->clk);
 
index b73da6cd6f915008384d9fd3f20b95ca4d41db8d..632e088760a3fc006147f375bd97d15b453fe961 100644 (file)
@@ -3,6 +3,7 @@
  * It does not support slave mode, the register slightly moved. This PCI
  * device provides three bars, every contains a single I2C controller.
  */
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/pxa-i2c.h>
index c418c41eff3d4ee363a7167b060616b1fcbd858f..a67132b2e0922b893c3920621524a014aabaf4c9 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <asm/clock.h>
 #include <asm/i2c-sh7760.h>
index b0505309faa76d1c474f9cf5f68b9ea6fd2963f1..46b6500c5478e9d3f1eb952848ed2d47dbf52a8f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/i2c-tegra.h>
 #include <linux/of_i2c.h>
+#include <linux/module.h>
 
 #include <asm/unaligned.h>
 
index 3ca2e012e78932ed8cf33339a3a0a0d404026c03..10274ffb66d73693ebbe097026156792ddeb8ea6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/rwsem.h>
 
 #include "i2c-core.h"
index 131079a3e2923a1feaa05248a236d8ee27890c4a..1e5606185b4f581939d6da4334b36747e90c35ba 100644 (file)
@@ -539,8 +539,10 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
        client->dev.type = &i2c_client_type;
        client->dev.of_node = info->of_node;
 
+       /* For 10-bit clients, add an arbitrary offset to avoid collisions */
        dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
-                    client->addr);
+                    client->addr | ((client->flags & I2C_CLIENT_TEN)
+                                    ? 0xa000 : 0));
        status = device_register(&client->dev);
        if (status)
                goto out_err;
index c90ce50b619f7b483b85483a24457a8cab73f3c2..57a45ce84b2d42f893cf45fb6e876bc1904bcfde 100644 (file)
@@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy)
        return 0;
 }
 
-int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
+static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action,
                         void *data)
 {
        struct device *dev = data;
index ab4f169d08373bf0f328e4ce68f07ccef20e8478..b1d38590ac0196f1da49d4d67e411b3741175b9f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/zorro.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
index cb10201a15ede79e7ec474a1dcd2ae709254d5ae..a81bd7575792f996763186339b7e3e40c835ce18 100644 (file)
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 
index 67cbcfa351225b4f7c60dce041562a411d76430e..847553fd8b963beca810aadb548d2f4f96db666e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
- *  Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz
  *
  * CYPRESS CY82C693 chipset IDE controller
  *
@@ -90,7 +90,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
        u8 time_16, time_8;
 
        /* select primary or secondary channel */
-       if (hwif->index > 0) {  /* drive is on the secondary channel */
+       if (drive->dn > 1) {  /* drive is on the secondary channel */
                dev = pci_get_slot(dev->bus, dev->devfn+1);
                if (!dev) {
                        printk(KERN_ERR "%s: tune_drive: "
@@ -141,7 +141,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
                pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);
                pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);
        }
-       if (hwif->index > 0)
+       if (drive->dn > 1)
                pci_dev_put(dev);
 }
 
index 4a697a238e280e2ce14c627d0d1f4bf053b86b45..8716066a2f2b79c1ddeb1236a9b2091d7bd62f63 100644 (file)
@@ -521,8 +521,8 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
                d.init_dma = icside_dma_init;
                d.port_ops = &icside_v6_port_ops;
+       } else
                d.dma_ops = NULL;
-       }
 
        ret = ide_host_register(host, &d, hws);
        if (ret)
index 2af8cb460a3bc7cfd33531c0304d6ca6cff56d90..f22edc66b030b4a58c09caa3952353394686ecce 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/ide.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include <linux/module.h>
 
 #include <acpi/acpi_bus.h>
 
index 6f218e014e9940a4021533159dd72e9b64fac5f5..fac3d9da2e07db38df577c0ed76f5f72202641ea 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
 #include <linux/gfp.h>
index 04b09564bfa902bf84f6a313594112e74a1db2c6..8126824daccba7726b637ef1358b80cfa3b49468 100644 (file)
@@ -43,7 +43,6 @@
 /* For SCSI -> ATAPI command conversion */
 #include <scsi/scsi.h>
 
-#include <linux/irq.h>
 #include <linux/io.h>
 #include <asm/byteorder.h>
 #include <linux/uaccess.h>
index f9bbd904eae72651d65e33b4dba06ec4f95f69ee..8b570a17bcd99476093b93a8e748e66a3ae0b30a 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/seq_file.h>
 
 #include "ide-disk.h"
index e4cdf78cc3e96a4f05522ba8038610ad7c80759c..289d16c87b8ffb41bc4935ff188a2a85e0bd7044 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
index d4136908f9166a6dbb7b6e991397e289e50c5623..17a65ac56491881117edbec9b28518e9cd95f12d 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/types.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
index c0aa93fb7a60e42e8bb43a8cc6e72cbf74de15b1..32970664c275448d65c44f6e8252b5de129c064c 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 #include <linux/delay.h>
 
index 61fdf544fbd63193926010ff33fef34f9d30dbe9..3d42043fec51ee1bf86d204912da85b57242f1e5 100644 (file)
@@ -35,7 +35,6 @@
 #include <scsi/scsi_ioctl.h>
 
 #include <asm/byteorder.h>
-#include <linux/irq.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <asm/unaligned.h>
index d711d9b883dea63124ac11c38907f8ca8a23b36c..1600720f3e8654b93da870db04b90de1dbd92c5d 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
 
index 46721c4545180ec4b8835c1c9be6caad6086f36d..19763977568c5d6fd7ecc87c3f4e7bc47fc0d85e 100644 (file)
@@ -1,5 +1,6 @@
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 
 #if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
index 9965ecd5078c63e37aa4fb34d1b7df722fd22d63..4d19eb9772a12df23d1b70f02e04e783d8a5707f 100644 (file)
@@ -2,6 +2,7 @@
  * IDE ioctls handling.
  */
 
+#include <linux/export.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/slab.h>
index b9654a7bb7becb2d7f2b07aa126b075e4e611b89..30fe3630734fce9ab06edfe7881fe82d86374428 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ide.h>
 
 static void ide_legacy_init_one(struct ide_hw **hws, struct ide_hw *hw,
index e386a32dc9ba888c110b42971d57a1bab2662f49..d9c9829c8b206118b665d282f847e7809887fb33 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/ide.h>
 #include <linux/bitops.h>
index 017b1df3b8054c476b8e7e3dbc3b4112d2d739fc..e5f3db8313733ce8ce9b682cc7b63dc3e5558d38 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/pnp.h>
 #include <linux/ide.h>
+#include <linux/module.h>
 
 #define DRV_NAME "ide-pnp"
 
index 7ecb1ade8874b86c293a5d1a4a2a59ffc7efc860..ce8237d361596840cb679c6f41dbd89bb0ad7d48 100644 (file)
@@ -41,7 +41,6 @@
 #include <scsi/scsi.h>
 
 #include <asm/byteorder.h>
-#include <linux/irq.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <asm/unaligned.h>
index 600c89a3d13759f47ddc82caa06b41dbd039401d..5bc2839ebcfdff11bed95117570cbb9a1092bfe6 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
index 5fc8d5c17de9a243c20b68c2239128e56b9a57f6..eb421883c16d0524d6e80de7d49700723183f574 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/ide.h>
 #include <linux/bitops.h>
index 505ec43e560617c9bfd511ff27d4e8b2d8808167..adc5fe9daafc2185c134a2f5dc4b14c2032ef2ca 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/module.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
index b59d04c720517d722633f9feef63a42505f86625..1892e81fb00f615b80c3dfaa8f10a643037a5eb6 100644 (file)
@@ -331,7 +331,7 @@ static const struct ide_port_ops ich_port_ops = {
                .udma_mask      = udma,                 \
        }
 
-#define DECLARE_ICH_DEV(udma) \
+#define DECLARE_ICH_DEV(mwdma, udma) \
        { \
                .name           = DRV_NAME, \
                .init_chipset   = init_chipset_ich, \
@@ -340,7 +340,7 @@ static const struct ide_port_ops ich_port_ops = {
                .port_ops       = &ich_port_ops, \
                .pio_mask       = ATA_PIO4, \
                .swdma_mask     = ATA_SWDMA2_ONLY, \
-               .mwdma_mask     = ATA_MWDMA12_ONLY, \
+               .mwdma_mask     = mwdma, \
                .udma_mask      = udma, \
        }
 
@@ -362,13 +362,15 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
        /* 2: PIIX4 */
        DECLARE_PIIX_DEV(ATA_UDMA2),
        /* 3: ICH0 */
-       DECLARE_ICH_DEV(ATA_UDMA2),
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA2),
        /* 4: ICH */
-       DECLARE_ICH_DEV(ATA_UDMA4),
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA4),
        /* 5: PIIX4 */
        DECLARE_PIIX_DEV(ATA_UDMA4),
-       /* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
-       DECLARE_ICH_DEV(ATA_UDMA5),
+       /* 6: ICH[2-6]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
+       DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA5),
+       /* 7: ICH7/7-R, no MWDMA1 */
+       DECLARE_ICH_DEV(ATA_MWDMA2_ONLY, ATA_UDMA5),
 };
 
 /**
@@ -438,9 +440,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
 #endif
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2),      6 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19),    6 },
-       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    6 },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21),    7 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1),  6 },
-       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    6 },
+       { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18),    7 },
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6),     6 },
        { 0, },
 };
index 1db7c4368dbf6e3ab8c9b8269c896ee8e03c03d7..e944c7f705f7803ea18dbd8707b48a95f5cff52f 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/notifier.h>
+#include <linux/module.h>
 #include <linux/reboot.h>
 #include <linux/pci.h>
 #include <linux/adb.h>
index 90786083b4393051536366254248373409df5a84..ecd0a69245f65470bfc1ddb8007811c1ded1f50c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/ide.h>
+#include <linux/module.h>
 
 #include <asm/ide.h>
 
index ab3db61d2ba038a84128b08870aa7bd091fc9624..34a5e5223d5004010a03ae4e468e1a2a05e871ba 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
index e444d24934b350472eead452b377063d4123c1af..4799d5c384e7ee8711342d32c4b58af52a13b8f5 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
+#include <linux/module.h>
 
 #define DRV_NAME "tc86c001"
 
index e53a1b78378b02c414c0c292c954974c763d880d..281c91426345946279412880bc804d01d287ec4c 100644 (file)
@@ -113,12 +113,26 @@ static const struct pci_device_id triflex_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
 
+#ifdef CONFIG_PM
+static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state)
+{
+       /*
+        * We must not disable or powerdown the device.
+        * APM bios refuses to suspend if IDE is not accessible.
+        */
+       pci_save_state(dev);
+       return 0;
+}
+#else
+#define triflex_ide_pci_suspend NULL
+#endif
+
 static struct pci_driver triflex_pci_driver = {
        .name           = "TRIFLEX_IDE",
        .id_table       = triflex_pci_tbl,
        .probe          = triflex_init_one,
        .remove         = ide_pci_remove,
-       .suspend        = ide_pci_suspend,
+       .suspend        = triflex_ide_pci_suspend,
        .resume         = ide_pci_resume,
 };
 
index a46dddf6107884deb0852883f7d012d23e05b75e..5d2f8e13cf0e670e83b48b6dc243402d781b9758 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/sched.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/module.h>
 #include <asm/mwait.h>
 #include <asm/msr.h>
 
@@ -81,7 +82,8 @@ static unsigned int mwait_substates;
 static unsigned int lapic_timer_reliable_states = (1 << 1);     /* Default to only C1 */
 
 static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
-static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
+static int intel_idle(struct cpuidle_device *dev,
+                       struct cpuidle_driver *drv, int index);
 
 static struct cpuidle_state *cpuidle_state_table;
 
@@ -109,7 +111,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C1 */
                .name = "C1-NHM",
                .desc = "MWAIT 0x00",
-               .driver_data = (void *) 0x00,
                .flags = CPUIDLE_FLAG_TIME_VALID,
                .exit_latency = 3,
                .target_residency = 6,
@@ -117,7 +118,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C2 */
                .name = "C3-NHM",
                .desc = "MWAIT 0x10",
-               .driver_data = (void *) 0x10,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 20,
                .target_residency = 80,
@@ -125,7 +125,6 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C3 */
                .name = "C6-NHM",
                .desc = "MWAIT 0x20",
-               .driver_data = (void *) 0x20,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 200,
                .target_residency = 800,
@@ -137,7 +136,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C1 */
                .name = "C1-SNB",
                .desc = "MWAIT 0x00",
-               .driver_data = (void *) 0x00,
                .flags = CPUIDLE_FLAG_TIME_VALID,
                .exit_latency = 1,
                .target_residency = 1,
@@ -145,7 +143,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C2 */
                .name = "C3-SNB",
                .desc = "MWAIT 0x10",
-               .driver_data = (void *) 0x10,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 80,
                .target_residency = 211,
@@ -153,7 +150,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C3 */
                .name = "C6-SNB",
                .desc = "MWAIT 0x20",
-               .driver_data = (void *) 0x20,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 104,
                .target_residency = 345,
@@ -161,7 +157,6 @@ static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C4 */
                .name = "C7-SNB",
                .desc = "MWAIT 0x30",
-               .driver_data = (void *) 0x30,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 109,
                .target_residency = 345,
@@ -173,7 +168,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C1 */
                .name = "C1-ATM",
                .desc = "MWAIT 0x00",
-               .driver_data = (void *) 0x00,
                .flags = CPUIDLE_FLAG_TIME_VALID,
                .exit_latency = 1,
                .target_residency = 4,
@@ -181,7 +175,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C2 */
                .name = "C2-ATM",
                .desc = "MWAIT 0x10",
-               .driver_data = (void *) 0x10,
                .flags = CPUIDLE_FLAG_TIME_VALID,
                .exit_latency = 20,
                .target_residency = 80,
@@ -190,7 +183,6 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C4 */
                .name = "C4-ATM",
                .desc = "MWAIT 0x30",
-               .driver_data = (void *) 0x30,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 100,
                .target_residency = 400,
@@ -199,23 +191,55 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
        { /* MWAIT C6 */
                .name = "C6-ATM",
                .desc = "MWAIT 0x52",
-               .driver_data = (void *) 0x52,
                .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
                .exit_latency = 140,
                .target_residency = 560,
                .enter = &intel_idle },
 };
 
+static int get_driver_data(int cstate)
+{
+       int driver_data;
+       switch (cstate) {
+
+       case 1: /* MWAIT C1 */
+               driver_data = 0x00;
+               break;
+       case 2: /* MWAIT C2 */
+               driver_data = 0x10;
+               break;
+       case 3: /* MWAIT C3 */
+               driver_data = 0x20;
+               break;
+       case 4: /* MWAIT C4 */
+               driver_data = 0x30;
+               break;
+       case 5: /* MWAIT C5 */
+               driver_data = 0x40;
+               break;
+       case 6: /* MWAIT C6 */
+               driver_data = 0x52;
+               break;
+       default:
+               driver_data = 0x00;
+       }
+       return driver_data;
+}
+
 /**
  * intel_idle
  * @dev: cpuidle_device
- * @state: cpuidle state
+ * @drv: cpuidle driver
+ * @index: index of cpuidle state
  *
  */
-static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
+static int intel_idle(struct cpuidle_device *dev,
+               struct cpuidle_driver *drv, int index)
 {
        unsigned long ecx = 1; /* break on interrupt flag */
-       unsigned long eax = (unsigned long)cpuidle_get_statedata(state);
+       struct cpuidle_state *state = &drv->states[index];
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
+       unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
        unsigned int cstate;
        ktime_t kt_before, kt_after;
        s64 usec_delta;
@@ -256,7 +280,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
        if (!(lapic_timer_reliable_states & (1 << (cstate))))
                clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
 
-       return usec_delta;
+       /* Update cpuidle counters */
+       dev->last_residency = (int)usec_delta;
+
+       return index;
 }
 
 static void __setup_broadcast_timer(void *arg)
@@ -396,6 +423,60 @@ static void intel_idle_cpuidle_devices_uninit(void)
        free_percpu(intel_idle_cpuidle_devices);
        return;
 }
+/*
+ * intel_idle_cpuidle_driver_init()
+ * allocate, initialize cpuidle_states
+ */
+static int intel_idle_cpuidle_driver_init(void)
+{
+       int cstate;
+       struct cpuidle_driver *drv = &intel_idle_driver;
+
+       drv->state_count = 1;
+
+       for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) {
+               int num_substates;
+
+               if (cstate > max_cstate) {
+                       printk(PREFIX "max_cstate %d reached\n",
+                               max_cstate);
+                       break;
+               }
+
+               /* does the state exist in CPUID.MWAIT? */
+               num_substates = (mwait_substates >> ((cstate) * 4))
+                                       & MWAIT_SUBSTATE_MASK;
+               if (num_substates == 0)
+                       continue;
+               /* is the state not enabled? */
+               if (cpuidle_state_table[cstate].enter == NULL) {
+                       /* does the driver not know about the state? */
+                       if (*cpuidle_state_table[cstate].name == '\0')
+                               pr_debug(PREFIX "unaware of model 0x%x"
+                                       " MWAIT %d please"
+                                       " contact lenb@kernel.org",
+                               boot_cpu_data.x86_model, cstate);
+                       continue;
+               }
+
+               if ((cstate > 2) &&
+                       !boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+                       mark_tsc_unstable("TSC halts in idle"
+                                       " states deeper than C2");
+
+               drv->states[drv->state_count] = /* structure copy */
+                       cpuidle_state_table[cstate];
+
+               drv->state_count += 1;
+       }
+
+       if (auto_demotion_disable_flags)
+               smp_call_function(auto_demotion_disable, NULL, 1);
+
+       return 0;
+}
+
+
 /*
  * intel_idle_cpuidle_devices_init()
  * allocate, initialize, register cpuidle_devices
@@ -430,22 +511,11 @@ static int intel_idle_cpuidle_devices_init(void)
                                continue;
                        /* is the state not enabled? */
                        if (cpuidle_state_table[cstate].enter == NULL) {
-                               /* does the driver not know about the state? */
-                               if (*cpuidle_state_table[cstate].name == '\0')
-                                       pr_debug(PREFIX "unaware of model 0x%x"
-                                               " MWAIT %d please"
-                                               " contact lenb@kernel.org",
-                                       boot_cpu_data.x86_model, cstate);
                                continue;
                        }
 
-                       if ((cstate > 2) &&
-                               !boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
-                               mark_tsc_unstable("TSC halts in idle"
-                                       " states deeper than C2");
-
-                       dev->states[dev->state_count] = /* structure copy */
-                               cpuidle_state_table[cstate];
+                       dev->states_usage[dev->state_count].driver_data =
+                               (void *)get_driver_data(cstate);
 
                        dev->state_count += 1;
                }
@@ -458,8 +528,6 @@ static int intel_idle_cpuidle_devices_init(void)
                        return -EIO;
                }
        }
-       if (auto_demotion_disable_flags)
-               smp_call_function(auto_demotion_disable, NULL, 1);
 
        return 0;
 }
@@ -477,6 +545,7 @@ static int __init intel_idle_init(void)
        if (retval)
                return retval;
 
+       intel_idle_cpuidle_driver_init();
        retval = cpuidle_register_driver(&intel_idle_driver);
        if (retval) {
                printk(KERN_DEBUG PREFIX "intel_idle yielding to %s",
index 236ad9a89c0a403a7cf3a65e17fbbffe1ef14919..e9cf51b1343ba520d8928367a1eca80f9f531657 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/inetdevice.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include <net/arp.h>
 #include <net/neighbour.h>
 #include <net/route.h>
@@ -215,7 +216,9 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 
        neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
        if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+               rcu_read_lock();
                neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+               rcu_read_unlock();
                ret = -ENODATA;
                if (neigh)
                        goto release;
@@ -273,15 +276,16 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                goto put;
        }
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        if (!neigh || !(neigh->nud_state & NUD_VALID)) {
                if (neigh)
                        neigh_event_send(neigh, NULL);
                ret = -ENODATA;
-               goto put;
+       } else {
+               ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
        }
-
-       ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
+       rcu_read_unlock();
 put:
        dst_release(dst);
        return ret;
index 4104ea2427c24dd935a265a0d0148cc6e871d6ca..8b72f39202fb01d7e7bc29d5af45b55b01c0387a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/completion.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/interrupt.h>
index 872b1842598a3693e5ed647bbf7917d6c072f0b2..75ff821c0af07caaef3a0e48c8503489838bd75d 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/idr.h>
 #include <linux/inetdevice.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <net/tcp.h>
 #include <net/ipv6.h>
index 4507043d24c8c7df0580bba9afb7c3ed935c091c..176c8f90f2bb359f0b3a933eae1e9ab696518f79 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/errno.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/jhash.h>
 #include <linux/kthread.h>
index a9c042345c6fe14260d480c355aebea38d240842..1a696f76b61627b77c2653e7c5275ca19b2bb628 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/workqueue.h>
 #include <linux/completion.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <rdma/iw_cm.h>
 #include <rdma/ib_addr.h>
index 056389229ea7d03573e8dfa7b29520ed18a671fd..2fe428bba54ca947bee81df3f78f34f466c20dd8 100644 (file)
@@ -35,6 +35,7 @@
  */
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <rdma/ib_cache.h>
 
 #include "mad_priv.h"
index 68b4162fd9d2b17ee33a2d565b381bafa94c7ae2..d2360a8ef0b29ea6d6c9a3bebc05cf07b087a02f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/random.h>
index 9227f4acd79c7dd457a3188abb8cf327d458bd07..d1c8196d15d7e9b33cafd71606c2cb2383055623 100644 (file)
@@ -32,6 +32,7 @@
 
 #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
 
+#include <linux/export.h>
 #include <net/netlink.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
index 019bd4b0863e2ea34441f5ec10d2d9592d11722e..1b65986c0be3daaf5a437b3f6c3b773f7a26c329 100644 (file)
@@ -31,6 +31,7 @@
  * SOFTWARE.
  */
 
+#include <linux/export.h>
 #include <linux/string.h>
 
 #include <rdma/ib_pack.h>
index 2b59b72b57f9bc4fad122f085164a42a27356a6b..c61bca30fd2dd3d06aa0cc9b6f7d729515af606f 100644 (file)
@@ -35,6 +35,7 @@
 #include "core_priv.h"
 
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/string.h>
 
 #include <rdma/ib_mad.h>
index b69307f4f6d0aad0ba3e8fbd3e832aecad8c9119..b37b0c02a7b9d7d81cd5a55471e28d2780080377 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
+#include <linux/module.h>
 
 #include <rdma/rdma_user_cm.h>
 #include <rdma/ib_marshall.h>
index 9b737ff133e21d143982a57df0a581753450a6f3..72feee620ebfb33300a2121a2a22d0fc1d1eafb3 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <linux/if_ether.h>
 
 #include <rdma/ib_pack.h>
index 9155f91d66bfb654c4118dfbf64175c067aa9d18..71f0c0f7df949ac0a104f50cc3b1900d3751d308 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/sched.h>
+#include <linux/export.h>
 #include <linux/hugetlb.h>
 #include <linux/dma-attrs.h>
 #include <linux/slab.h>
index 1b1146f87124e2618ef80a8303fabe681a464782..e7bee46868d1cc8be8da98eee2e427de6ca37b20 100644 (file)
@@ -30,6 +30,7 @@
  * SOFTWARE.
  */
 
+#include <linux/export.h>
 #include <rdma/ib_marshall.h>
 
 void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
index 42517500b223e98b0e9dd265e799233057dde9f4..602b1bd723a963aa49904fc0a907d12d965b009e 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 
index de6d0774e60990f644e39ca815159f68b5a065d1..c88b12beef25be72383f3423894121882d76d009 100644 (file)
@@ -1375,8 +1375,10 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                goto reject;
        }
        dst = &rt->dst;
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        l2t = t3_l2t_get(tdev, neigh, neigh->dev);
+       rcu_read_unlock();
        if (!l2t) {
                printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
                       __func__);
@@ -1946,10 +1948,12 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
        ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
index b36cdac9c558a35aa78f2061e9f7435dc1504754..0747004313ad5cabdc34a6e206b0fb5d49e25a32 100644 (file)
@@ -542,8 +542,10 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
                     (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0);
        mpa->private_data_size = htons(ep->plen);
        mpa->revision = mpa_rev_to_use;
-       if (mpa_rev_to_use == 1)
+       if (mpa_rev_to_use == 1) {
                ep->tried_with_mpa_v1 = 1;
+               ep->retry_with_mpa_v1 = 0;
+       }
 
        if (mpa_rev_to_use == 2) {
                mpa->private_data_size +=
@@ -1594,6 +1596,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
                goto reject;
        }
        dst = &rt->dst;
+       rcu_read_lock();
        neigh = dst_get_neighbour(dst);
        if (neigh->dev->flags & IFF_LOOPBACK) {
                pdev = ip_dev_find(&init_net, peer_ip);
@@ -1620,6 +1623,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
                rss_qid = dev->rdev.lldi.rxq_ids[
                          cxgb4_port_idx(neigh->dev) * step];
        }
+       rcu_read_unlock();
        if (!l2t) {
                printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
                       __func__);
@@ -1820,6 +1824,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
@@ -1856,6 +1861,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
                ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
                        cxgb4_port_idx(neigh->dev) * step];
        }
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
@@ -2301,6 +2307,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        }
        ep->dst = &rt->dst;
 
+       rcu_read_lock();
        neigh = dst_get_neighbour(ep->dst);
 
        /* get a l2t entry */
@@ -2339,6 +2346,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
                ep->retry_with_mpa_v1 = 0;
                ep->tried_with_mpa_v1 = 0;
        }
+       rcu_read_unlock();
        if (!ep->l2t) {
                printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
                err = -ENOMEM;
index f35a935267e77e7a58c3be85437cbcb1a1f35cb7..0f1607c8325a5bc8a03e3a5d5471d39ed5741e8b 100644 (file)
@@ -311,7 +311,7 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count)
        while (ptr != cq->sw_pidx) {
                cqe = &cq->sw_queue[ptr];
                if (RQ_TYPE(cqe) && (CQE_OPCODE(cqe) != FW_RI_READ_RESP) &&
-                   (CQE_QPID(cqe) == wq->rq.qid) && cqe_completes_wr(cqe, wq))
+                   (CQE_QPID(cqe) == wq->sq.qid) && cqe_completes_wr(cqe, wq))
                        (*count)++;
                if (++ptr == cq->size)
                        ptr = 0;
index d6ccc7e848028f44c4eb6dcb3771191174e64a86..5f940aeaab1e0086140df49d03a94b4c965b23f0 100644 (file)
@@ -29,6 +29,9 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+
+#include <linux/module.h>
+
 #include "iw_cxgb4.h"
 
 static int ocqp_support = 1;
index daef61d5e5bb58afaf224da91a9789869a1224ce..714293b78518598c7fe262315de6cbfaafe9263b 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <linux/export.h>
 #include <asm/uaccess.h>
 
 #include "ipath_kernel.h"
index be24ac726114172eba6bfd64939b480c961c4342..bfca37b2432f44fa3fa5d577aafd352759c68547 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/vmalloc.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
index 8697eca14356a021f24755fc31808f785009417c..736d9edbdbe720bb25a2e1ace073984e43373faa 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/poll.h>
 #include <linux/cdev.h>
 #include <linux/swap.h>
+#include <linux/export.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/highmem.h>
index 824a4d508836835c3e1b74b48f1b3cfc8ec7934e..49b09c697c7c8462800a9737dc6de591879dd5a2 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/vmalloc.h>
index 8991677e9a082fed4827e914eb282d1437adcb41..75558f33f1cb9971c2db3e0a04ba9bf70e993e69 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/ctype.h>
+#include <linux/stat.h>
 
 #include "ipath_kernel.h"
 #include "ipath_verbs.h"
index dd7f26d04d46b6d9def83d3f1b1dcd8d04e75fc7..439c35d4a669978aba8820151f2f6c98f5a47558 100644 (file)
@@ -35,6 +35,7 @@
 #include <rdma/ib_user_verbs.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/utsname.h>
 #include <linux/rculist.h>
 
index e4a08c2819e43f77ac6f79d79dcf5e5eb0c09c76..712d2a30fbe59d8d9b11f327eb95881c9f366d7f 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/jiffies.h>
+#include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 
index 3082b3b3d620aec288d0f5245be798f09a6f65bf..9d3e5c1ac60e44ca5ba1014fa43fa1e6483694ec 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <asm/io.h>
 #include <rdma/ib_mad.h>
index cb9a0b976804fa879f997eff4f6d60b5e9b6ff00..5b71d43bd89c80926f2e1a4d6d3eae7b3ab7e91c 100644 (file)
@@ -40,7 +40,9 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/mm.h>
+#include <linux/export.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
index dfce9ea98a39b3f0f68e6d152d438554ebe8ee84..0a52d72371ee5f6cf2f938ba81fa0c887fd00070 100644 (file)
@@ -1377,9 +1377,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
                neigh_release(neigh);
        }
 
-       if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
+       if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) {
+               rcu_read_lock();
                neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
-
+               rcu_read_unlock();
+       }
        ip_rt_put(rt);
        return rc;
 }
index 204c4dd9dce0608eecfcfa74822e837d9e895916..9892456a4348afde551ed22b8b5814b8d88a608a 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/pci.h>
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 
index 9a9047f385ae55b059339874fbf74fe8755911ce..c90a55f4120fe6b23972a4762b6c0d9ee0e27872 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 
 #include "qib.h"
 
index 77633666f81c385edafc326a815797896a919068..574600ef5b428e4766d8cd431632a0e131c176a9 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/jiffies.h>
 #include <asm/pgtable.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include "qib.h"
 #include "qib_common.h"
index 3f1d562ba89824694808a6bd91f1f94dbaa12e4b..439d3c503cd5d8b66ec06d945e35a4758480ec02 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <rdma/ib_verbs.h>
 
index efd0a110091f754570ac6133cf5973a0cf5104c8..1d5895941e193e35e5ff88804fb00a9c29c8a5fa 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
+#include <linux/module.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_smi.h>
 
@@ -2306,19 +2307,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
                SYM_LSB(IBCCtrlA_0, MaxPktLen);
        ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */
 
-       /* initially come up waiting for TS1, without sending anything. */
-       val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
-               QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
-
-       ppd->cpspec->ibcctrl_a = val;
        /*
         * Reset the PCS interface to the serdes (and also ibc, which is still
         * in reset from above).  Writes new value of ibcctrl_a as last step.
         */
        qib_7322_mini_pcs_reset(ppd);
-       qib_write_kreg(dd, kr_scratch, 0ULL);
-       /* clear the linkinit cmds */
-       ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
 
        if (!ppd->cpspec->ibcctrl_b) {
                unsigned lse = ppd->link_speed_enabled;
@@ -2384,6 +2377,14 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd)
        ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn);
        set_vls(ppd);
 
+       /* initially come up DISABLED, without sending anything. */
+       val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE <<
+                                       QLOGIC_IB_IBCC_LINKINITCMD_SHIFT);
+       qib_write_kreg_port(ppd, krp_ibcctrl_a, val);
+       qib_write_kreg(dd, kr_scratch, 0ULL);
+       /* clear the linkinit cmds */
+       ppd->cpspec->ibcctrl_a = val & ~SYM_MASK(IBCCtrlA_0, LinkInitCmd);
+
        /* be paranoid against later code motion, etc. */
        spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags);
        ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable);
@@ -5240,7 +5241,7 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
                           off */
                        if (ppd->dd->flags & QIB_HAS_QSFP) {
                                qd->t_insert = get_jiffies_64();
-                               schedule_work(&qd->work);
+                               queue_work(ib_wq, &qd->work);
                        }
                        spin_lock_irqsave(&ppd->sdma_lock, flags);
                        if (__qib_sdma_running(ppd))
index b093a0b53b2f1ac79b08c73495bc8cf368f03eb2..58b0f8ad4a2936aed396da2b10361f080d74197a 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/idr.h>
+#include <linux/module.h>
 
 #include "qib.h"
 #include "qib_common.h"
index 4426782ad288930b97ff34f6d892b3a364a8983e..97a8bdf68e605267f635edf4423ccfdf366a4971 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/aer.h>
+#include <linux/module.h>
 
 #include "qib.h"
 
index e06c4ed383f14598674ce8a0847c9780a6231c46..fa71b1e666c5414fbba2357fe531e75cabc7986c 100644 (file)
@@ -480,18 +480,6 @@ void qib_qsfp_init(struct qib_qsfp_data *qd,
        udelay(20); /* Generous RST dwell */
 
        dd->f_gpio_mod(dd, mask, mask, mask);
-       /* Spec says module can take up to two seconds! */
-       mask = QSFP_GPIO_MOD_PRS_N;
-       if (qd->ppd->hw_pidx)
-               mask <<= QSFP_GPIO_PORT2_SHIFT;
-
-       /* Do not try to wait here. Better to let event handle it */
-       if (!qib_qsfp_mod_present(qd->ppd))
-               goto bail;
-       /* We see a module, but it may be unwise to look yet. Just schedule */
-       qd->t_insert = get_jiffies_64();
-       queue_work(ib_wq, &qd->work);
-bail:
        return;
 }
 
index e9f9f8bc3204adf2a3ae0051f10dffbdffc8fed4..de1a4b2f33c084aee485b5ea6454702ea78455d9 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 
 #include "qib.h"
index cad44491320bc52b5f55409568e9f5edba6619f6..12a9604310d7845c0c3aa851d7b07a620d7b0876 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/netdevice.h>
+#include <linux/moduleparam.h>
 
 #include "qib.h"
 #include "qib_common.h"
index 7f36454c225e5a4ca1f9d35c99d6ba67730354f8..1bf626c401728e0925b1ac75cd931f1785dedc5f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
+#include <linux/moduleparam.h>
 
 #include "qib.h"
 
index 9627cb7371250e0bd37355912cd866ff50cfaaa7..a894762da462c73b304e9e2abc314582d84cd6ab 100644 (file)
@@ -35,6 +35,7 @@
 #include <rdma/ib_mad.h>
 #include <rdma/ib_user_verbs.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/utsname.h>
 #include <linux/rculist.h>
 #include <linux/mm.h>
index 231c2f2f52f8ecac55741169701a37fe44bf2a86..014504d8e43c1cf68d94d5ff070e0ed664b57b93 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/moduleparam.h>
 
 #include "ipoib.h"
 
index 0e2fe4631ba86f03d5fc26dbf208e68a61169a42..50061854616ecb9c5ad409e73bf20889a2eab680 100644 (file)
@@ -37,6 +37,7 @@
 struct file_operations;
 
 #include <linux/debugfs.h>
+#include <linux/export.h>
 
 #include "ipoib.h"
 
index 2b060f45bec341d794a8f3a11b732c71df838cae..4115be54ba3b32626dc75c4529a3aa186b6f02c1 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/moduleparam.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
@@ -56,21 +57,24 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
                                 struct ib_pd *pd, struct ib_ah_attr *attr)
 {
        struct ipoib_ah *ah;
+       struct ib_ah *vah;
 
        ah = kmalloc(sizeof *ah, GFP_KERNEL);
        if (!ah)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        ah->dev       = dev;
        ah->last_send = 0;
        kref_init(&ah->ref);
 
-       ah->ah = ib_create_ah(pd, attr);
-       if (IS_ERR(ah->ah)) {
+       vah = ib_create_ah(pd, attr);
+       if (IS_ERR(vah)) {
                kfree(ah);
-               ah = NULL;
-       } else
+               ah = (struct ipoib_ah *)vah;
+       } else {
+               ah->ah = vah;
                ipoib_dbg(netdev_priv(dev), "Created ah %p\n", ah->ah);
+       }
 
        return ah;
 }
index 7567b60002309a19a2d0a4cc13da855a46042be4..83695b48b010a643a9b16d9240fa9a8538fa5d06 100644 (file)
@@ -432,7 +432,7 @@ static void path_rec_completion(int status,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (ah) {
+       if (!IS_ERR_OR_NULL(ah)) {
                path->pathrec = *pathrec;
 
                old_ah   = path->ah;
@@ -555,6 +555,7 @@ static int path_rec_start(struct net_device *dev,
        return 0;
 }
 
+/* called with rcu_read_lock */
 static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -636,6 +637,7 @@ err_drop:
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+/* called with rcu_read_lock */
 static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
@@ -720,13 +722,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct neighbour *n = NULL;
        unsigned long flags;
 
+       rcu_read_lock();
        if (likely(skb_dst(skb)))
                n = dst_get_neighbour(skb_dst(skb));
 
        if (likely(n)) {
                if (unlikely(!*to_ipoib_neigh(n))) {
                        ipoib_path_lookup(skb, dev);
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                neigh = *to_ipoib_neigh(n);
@@ -749,17 +752,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        ipoib_neigh_free(dev, neigh);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        ipoib_path_lookup(skb, dev);
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                if (ipoib_cm_get(neigh)) {
                        if (ipoib_cm_up(neigh)) {
                                ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
-                               return NETDEV_TX_OK;
+                               goto unlock;
                        }
                } else if (neigh->ah) {
                        ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha));
-                       return NETDEV_TX_OK;
+                       goto unlock;
                }
 
                if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
@@ -793,13 +796,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                           phdr->hwaddr + 4);
                                dev_kfree_skb_any(skb);
                                ++dev->stats.tx_dropped;
-                               return NETDEV_TX_OK;
+                               goto unlock;
                        }
 
                        unicast_arp_send(skb, dev, phdr);
                }
        }
-
+unlock:
+       rcu_read_unlock();
        return NETDEV_TX_OK;
 }
 
@@ -837,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
        dst = skb_dst(skb);
        n = NULL;
        if (dst)
-               n = dst_get_neighbour(dst);
+               n = dst_get_neighbour_raw(dst);
        if ((!dst || !n) && daddr) {
                struct ipoib_pseudoheader *phdr =
                        (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
index ecea4fe1ed00e725d1506f3c00700f7e9095f45d..873bff97e69e266f6c39624f5fe3319eb76f7aae 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
+#include <linux/moduleparam.h>
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/igmp.h>
@@ -239,8 +240,11 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                av.grh.dgid = mcast->mcmember.mgid;
 
                ah = ipoib_create_ah(dev, priv->pd, &av);
-               if (!ah) {
-                       ipoib_warn(priv, "ib_address_create failed\n");
+               if (IS_ERR(ah)) {
+                       ipoib_warn(priv, "ib_address_create failed %ld\n",
+                               -PTR_ERR(ah));
+                       /* use original error */
+                       return PTR_ERR(ah);
                } else {
                        spin_lock_irq(&priv->lock);
                        mcast->ah = ah;
@@ -265,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 
                skb->dev = dev;
                if (dst)
-                       n = dst_get_neighbour(dst);
+                       n = dst_get_neighbour_raw(dst);
                if (!dst || !n) {
                        /* put pseudoheader back on for next time */
                        skb_push(skb, sizeof (struct ipoib_pseudoheader));
@@ -721,6 +725,8 @@ out:
        if (mcast && mcast->ah) {
                struct dst_entry *dst = skb_dst(skb);
                struct neighbour *n = NULL;
+
+               rcu_read_lock();
                if (dst)
                        n = dst_get_neighbour(dst);
                if (n && !*to_ipoib_neigh(n)) {
@@ -733,7 +739,7 @@ out:
                                list_add_tail(&neigh->list, &mcast->neigh_list);
                        }
                }
-
+               rcu_read_unlock();
                spin_unlock_irqrestore(&priv->lock, flags);
                ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
                return;
index c42b8f390c0b9cccd3732b455104bc05cbc31a36..7e7373a700e603bc2fed30f974a6e0f2d3b990aa 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/scatterlist.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <net/sock.h>
 
index 1accb89ae66f29430065ad2bac1562871a86a53e..e46a86776a6bd247d47bd92dbbaa2e0c8657c9b7 100644 (file)
@@ -8,6 +8,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/export.h>
 #include <asm/uaccess.h>
 #include "input-compat.h"
 
index 9150ee78e00ad62621de0aaa2740851fc65acbed..f658086fbbe00a56aec8ab3084fa733757107e5f 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/input/mt.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #define TRKID_SGN      ((TRKID_MAX + 1) >> 1)
index b253973881b82f69e7eaaa82c73cdc07fe843f22..7dfe1009fae09b6101133d8e471a0d4b1ef039cd 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include <linux/input-polldev.h>
 
 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
index f6732b57ca0794fc7dc307eeb6905c6e712aac5d..6d6e7418dc21d206f54f3c1ebd0770ebaf9388d4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/input/as5011.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
 #define MODULE_DEVICE_ALIAS "as5011"
index 6e0f230913608a97ad3b8fa85449ef97a33da7d8..fcdec5e2b2977269b8718e84bf6da0991b48bb9c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 
 #include <plat/ske.h>
 
index 1c58681de81fe541338b6ec655ca8a008c305e01..66e55e5cfdd65d5d47d33616d5d2fff8f1413ea4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/module.h>
 
 #define BITS(x)                        (BIT(x) - 1)
 
index ca42c7d2a3c79ab247163eafd7e4d4112b6ee097..0ac75bbad4d69d61e64719d1a2550778f121f599 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/input/ad714x.h>
+#include <linux/module.h>
 #include "ad714x.h"
 
 #define AD714X_PWR_CTRL           0x0
index 144ddbdeb9b32de3fa16527b8c4ff1693d868181..09244804fb97674adfd9d39b28fc94c05bf651a3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/input/adxl34x.h>
+#include <linux/module.h>
 
 #include "adxl34x.h"
 
index 1de58e8a1b71216180808f7bd2c2e7d233f1cce7..8d345e87075e6b8704ef72231f59e4d477374d73 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/usb/input.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_DESC    "ATI/Philips USB RF remote driver"
 #define DRIVER_VERSION "0.3"
index 1633b6342267efea193e6347003f75723000296a..80793f1608eb0d1fd2eaff655cba48ffcc037709 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/cma3000.h>
+#include <linux/module.h>
 
 #include "cma3000_d0x.h"
 
index 19af682c24fb4f567ef0f193b189efe0b177c15e..7283dd2a1ad3b89d349cd80897f204b5dccbe661 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 
 #include <linux/i2c/dm355evm_msp.h>
+#include <linux/module.h>
 
 
 /*
index 09b93b11a274278b399e0adbfb1dc8e6917e35e9..e2a9867c19d52fce53cac578bdaf265d3211bba1 100644 (file)
@@ -1210,18 +1210,28 @@ static int elantech_reconnect(struct psmouse *psmouse)
  */
 static int elantech_set_properties(struct elantech_data *etd)
 {
+       /* This represents the version of IC body. */
        int ver = (etd->fw_version & 0x0f0000) >> 16;
 
+       /* Early version of Elan touchpads doesn't obey the rule. */
        if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600)
                etd->hw_version = 1;
-       else if (etd->fw_version < 0x150600)
-               etd->hw_version = 2;
-       else if (ver == 5)
-               etd->hw_version = 3;
-       else if (ver == 6)
-               etd->hw_version = 4;
-       else
-               return -1;
+       else {
+               switch (ver) {
+               case 2:
+               case 4:
+                       etd->hw_version = 2;
+                       break;
+               case 5:
+                       etd->hw_version = 3;
+                       break;
+               case 6:
+                       etd->hw_version = 4;
+                       break;
+               default:
+                       return -1;
+               }
+       }
 
        /*
         * Turn on packet checking by default.
index 4b2a42f9f0bb471748ee3d6676da48255fd73231..d4d08bd9205b87b7ddc617c55fee84ec6259a2b8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/irq.h>
 #include <linux/serio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/mach-types.h>
 #include <plat/board-ams-delta.h>
index bb9f5d31f0d0616463609f4b20c940ee0ec2d451..b4cfc6c8be89db327134dd7dd722dfa2623d472a 100644 (file)
@@ -431,6 +431,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
                },
        },
+       {
+               /* Newer HP Pavilion dv4 models */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+               },
+       },
        { }
 };
 
@@ -560,6 +567,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
                },
        },
+       {
+               /* Newer HP Pavilion dv4 models */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
+               },
+       },
        { }
 };
 
index fdb6a3976f94cbfb821aa58841d3075afe08f50f..75fb040a3435c246b2077e96b5730f3d7030586b 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
index 714d4e0f9f95f546affadbdbc677d87c27152bc0..400131df677b424c025682f0a61c97fe4bc85109 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ad7877.h>
+#include <linux/module.h>
 #include <asm/irq.h>
 
 #define        TS_PEN_UP_TIMEOUT       msecs_to_jiffies(100)
index ddf732f3cafcd3021c889f435d2d1c662f627663..b1643c8fa7c9a1bca311e90e2cfc39e7ba836e2f 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/input.h>       /* BUS_SPI */
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
+#include <linux/module.h>
 
 #include "ad7879.h"
 
index 131f9d1c921b090ee813e5bc2205fa5a904a0633..3b2e9ed2aeec3482c7ec178b238410fc93424ff2 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/gpio.h>
 
 #include <linux/spi/ad7879.h>
+#include <linux/module.h>
 #include "ad7879.h"
 
 #define AD7879_REG_ZEROS               0
index d507b9b678063031e988ef907308801ff0aa8df1..de31ec6fe9e47005ba94cc9eae222f922bb9c4b9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 #include <asm/irq.h>
 
 /*
index 1507ce108d5b1f418f131265110f174cde22a0f6..902c7214e88739e83db2fd5c45ab90bb27112267 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/input/bu21013.h>
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 
 #define PEN_DOWN_INTR  0
 #define MAX_FINGERS    2
index bb161d2fa03cbc7bbef23977cb5fc7c530329ef2..a004c3945c67c4ca891779e5b776ebfcb9c25b7f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/bitmap.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -3523,7 +3524,7 @@ found:
        return 0;
 }
 
-int dmar_parse_rmrr_atsr_dev(void)
+int __init dmar_parse_rmrr_atsr_dev(void)
 {
        struct dmar_rmrr_unit *rmrr, *rmrr_n;
        struct dmar_atsr_unit *atsr, *atsr_n;
index 07c9f189f3143250e5ea2d0ea20fcdaa2b1674df..6777ca049471728d445ec323e3f051bdc19126f9 100644 (file)
@@ -773,7 +773,7 @@ int __init parse_ioapics_under_ir(void)
        return ir_supported;
 }
 
-int ir_dev_scope_init(void)
+int __init ir_dev_scope_init(void)
 {
        if (!intr_remapping_enabled)
                return 0;
index 9c192e79f806836be3ef688821c897be30dd6142..288da5c1499d5432c14b2410136dfc05f82d18ff 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index e8fdb8830f698184b08cb2a919b1358648ea4efb..46be456fcc00e01c10b2ae8106a83310b41d29b9 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
index ea2dff602e4948a745614f8a825b9256c84d9d4b..8d51cd1bf674f61cec1efd9c4a50f3ccffab68d5 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/export.h>
 
 static char *state2str(unsigned short state)
 {
index 33ec9e4677727800d5439e16300be820c92090b8..9021182c4b766e02454365f1e2b6d22822358f8a 100644 (file)
@@ -242,6 +242,12 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg)
                case IIOCDOCFINT:
                        if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
                                return (-EINVAL);       /* invalid driver */
+                       if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) ==
+                                       sizeof(dioctl.cf_ctrl.msn))
+                               return -EINVAL;
+                       if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) ==
+                                       sizeof(dioctl.cf_ctrl.fwd_nr))
+                               return -EINVAL;
                        if ((i = cf_command(dioctl.cf_ctrl.drvid,
                                            (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
                                            dioctl.cf_ctrl.cfproc,
index c3b1dc3a13a0f998a23e01b81d3b99ede2bc2428..fddae72e3f98ba3ec259e2dee57e12aca0ddd00e 100644 (file)
@@ -16,6 +16,7 @@
 #include "gigaset.h"
 #include <linux/crc-ccitt.h>
 #include <linux/bitrev.h>
+#include <linux/export.h>
 
 /* check if byte must be stuffed/escaped
  * I'm not sure which data should be encoded.
index 658e75f18d052b5a721ff2e6882109c945318d5b..6d5ceeece9f2598b6cd1dedcab65fdc4cac56a80 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/isdn/capilli.h>
 #include <linux/isdn/capicmd.h>
 #include <linux/isdn/capiutil.h>
+#include <linux/export.h>
 
 /* missing from kernelcapi.h */
 #define CapiNcpiNotSupportedByProtocol 0x0001
index bd0b1eaa7572bf785368d7e9fa013c9b93cc10ae..19b1c779d50f22dc3a6a8ea3649e161db4615d95 100644 (file)
@@ -11,6 +11,7 @@
  * =====================================================================
  */
 
+#include <linux/export.h>
 #include "gigaset.h"
 
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
index ba74646cf0e481fd2b6741fc4d012aa1cb5a2fc5..6d12623c1db002db8f935596bc249a9b81a38156 100644 (file)
@@ -13,6 +13,7 @@
  * =====================================================================
  */
 
+#include <linux/export.h>
 #include "gigaset.h"
 
 /* ========================================================== */
index 9bec8b96996466665aee48039508c96303068516..04231cb2f031a6148490e916e93308c0ab391bf2 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "gigaset.h"
 #include <linux/isdnif.h>
+#include <linux/export.h>
 
 #define SBUFSIZE       4096    /* sk_buff payload size */
 #define TRANSBUFSIZE   768     /* bytes per skb for transparent receive */
index e35058bcd7b98e0f1b690f2e359cec96df05140e..ee0a549a933a0176fdf9804e580bcc40557c25ac 100644 (file)
@@ -14,6 +14,7 @@
 #include "gigaset.h"
 #include <linux/gigaset_dev.h>
 #include <linux/tty_flip.h>
+#include <linux/module.h>
 
 /*** our ioctls ***/
 
index d13fa5b119f5f1b15ccb9fb02364223fbef94fe4..7034af28d464f225b424b08c1c7c14345bca9826 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/mISDNhw.h>
+#include <linux/module.h>
 #include "isar.h"
 
 #define ISAR_REV       "2.1"
index 1f73d7f7e0242e4e73d55582935f4ff0a11f6646..2339d7396b9ea305dd845e592d227bd726d3d43b 100644 (file)
@@ -2756,6 +2756,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
                        char *c,
                        *e;
 
+                       if (strnlen(cfg->drvid, sizeof(cfg->drvid)) ==
+                                       sizeof(cfg->drvid))
+                               return -EINVAL;
                        drvidx = -1;
                        chidx = -1;
                        strcpy(drvid, cfg->drvid);
index e5546cb3ac691666048bae0678af98175a26a376..2c26b64ebbea4de6cc0203d35da649c4d41d5bc1 100644 (file)
@@ -750,6 +750,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
  * supplementary service (CAPI 2.0 part III)
  */
 #include <linux/isdn/capicmd.h>
+#include <linux/module.h>
 
 int
 isdn_tty_capi_facility(capi_msg *cm) {
index 1fa629b3b940a94743267c5898ab2ee8876c1e51..7418f2d811d8ff3f4e189db7d8cc6d136173ca10 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/mISDNif.h>
+#include <linux/export.h>
 #include "core.h"
 
 static u_int *debug;
index 9c7c6451bf3db86a95b3309fc06a85b1020b98f2..b8f18bd09e430225ad89e82c125773d94ed41cec 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
+#include <linux/export.h>
 #include "core.h"
 #include "dsp.h"
 
index 621f310070953822a3c782f0c1a73caa91d4fc29..b6c9a5889346418f3f8532b3febd94554c5c3e7f 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/mISDNif.h>
 #include <linux/mISDNdsp.h>
+#include <linux/export.h>
 #include "dsp.h"
 #include "dsp_hwec.h"
 
index 8e325227b4c01153715f396662aeebea5231a219..738ea8dd0adfdd113134eff884dfd6c62cebc494 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/mISDNif.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "core.h"
 
 static u_int   *debug;
index 52590296af33e4a3f3af3b5de975741c3ffb1fc4..e5c57389efd63680af4b028910f8152667844692 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/acpi.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Louis Davis/Jim Dailey");
 MODULE_DESCRIPTION("Dell LED Control Driver");
index 661b692573e7790e7d75a4b815cd7741dfe47c74..6d5628bb060115d6e3f032210f9bc862a0ef397b 100644 (file)
@@ -270,11 +270,8 @@ void led_blink_set(struct led_classdev *led_cdev,
        del_timer_sync(&led_cdev->blink_timer);
 
        if (led_cdev->blink_set &&
-           !led_cdev->blink_set(led_cdev, delay_on, delay_off)) {
-               led_cdev->blink_delay_on = *delay_on;
-               led_cdev->blink_delay_off = *delay_off;
+           !led_cdev->blink_set(led_cdev, delay_on, delay_off))
                return;
-       }
 
        /* blink with 1 Hz as default if nothing specified */
        if (!*delay_on && !*delay_off)
index 0d4c16678ace37a2030f68d141bdf19cfc50d3b3..0810604dc701307973f2967b8fd578f5a9bee997 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/module.h>
 
 #define LED_PWM_SHIFT          (3)
 #define LED_PWM_MASK           (0x1F)
index fbd5d88ccd8f3fc07ef18777f05bbf8fede75994..48d9fe61bdfcdc39e7bd6b1d942bb637f28c00ff 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/mfd/asic3.h>
 #include <linux/mfd/core.h>
+#include <linux/module.h>
 
 /*
  *     The HTC ASIC3 LED GPIOs are inputs, not outputs.
index c941d906bba6e585f750616480ad1cccdcf3b4b9..109c875ea233486fc191a33b938f06f719ad1eaa 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/io.h>
 #include <linux/atmel_pwm.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 
 struct pwmled {
index 438d48384636f2d188e06a1ee648c41c190ce00c..aac1c073fe7bb20b018553c7e5c89e0fe084a8cc 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/export.h>
 
 #define LED_WEB                0x04
 #define LED_POWER_OFF  0x08
index d11d05be0dee3712132a70b50b0a77211aff23b6..49aceffaa5b6b76d0fb4b5fc8e14d6b90012f7fa 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
 
index 504cc26c7e4be9a4ea87ee708e3afd135846b68c..399a86f2013a145f1945f39077d23805bb40213d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 
 #include <asm/gpio.h>
 
index 4dc510fdfa06d8d778ea845d7e4d796f54d359f4..0630e4f4b2866a8829a1731411dfa19afb7e0bae 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/led-lm3530.h>
 #include <linux/types.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 
 #define LM3530_LED_DEV "lcd-backlight"
 #define LM3530_NAME "lm3530-led"
index 1f7c10f6b7f228daf883c1e4dc20a1753b6de0e4..80ba048889d61faa76195805cd622b1dada80d02 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/leds.h>
 
index 2579678f97a6c8e02ca897c363e1b1d107d67715..53f67b8ce55db505bd4ae5127423202e9141bca3 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct lt3593_led_data {
        struct led_classdev cdev;
index 93987a12da494594881dde8c375d94a246cd2254..f117f7326c5b632a356b37661775dc1e96f6a101 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/io.h>
 #include <linux/nsc_gpio.h>
 #include <linux/scx200_gpio.h>
+#include <linux/module.h>
 
 #define DRVNAME "net48xx-led"
 #define NET48XX_ERROR_LED_GPIO 20
index 7e764b8365e60c58e7357da121ae0abbacee1029..0555d4709a7ca413ac31e576eaa520a537f18fe9 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <asm/geode.h>
 
index f77d48d0b3e484bea2d48fd76568f4aa42cce445..37b7d0cfe5867e91ed0c1aa94039dc4985dc79f7 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
+#include <linux/module.h>
 #include <mach/leds-ns2.h>
 
 /*
index a77771dc2e9542fca0bf77cfa5a1466f71fa2e47..29f8b0f0e2c6f880429aea67bcddee59f52f6b91 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/leds.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
index ef5c24140a44deb5890a1620d66e89b071963993..b1eb34c3e81f41d5eafdd00ed112373a5f25c970 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/pdata.h>
 #include <linux/mfd/wm831x/status.h>
+#include <linux/module.h>
 
 
 struct wm831x_status {
index f14edd82cb004475e67fe493f71ee269ee9cd0c7..4a1276578352283544ceb6fda2ff176d0772d887 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mfd/wm8350/pmic.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 /* Microamps */
 static const int isink_cur[] = {
index 2982c86ac4cffb9e93da0a252b232a573c02ac22..6e21e654bb0281ba9e0bca0b5c62731c25c1a8fb 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <asm/io.h>
 #include <linux/scx200_gpio.h>
+#include <linux/module.h>
 
 #define DRVNAME "wrap-led"
 #define WRAP_POWER_LED_GPIO    2
index 5289ffa2e500c77ac3a2c0c1c5cddc1332a07b7b..0dc30ffde5ad7a8defc591c42a251bb9e59c35a9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <asm/io.h>
 #include <asm/paravirt.h>
index f97e625241ad792ea935a77cd3a50afbc165416a..ff4a0bc9904d0b79149d4ace4de5d8bf572b2bb8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/eventfd.h>
 #include <linux/file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "lg.h"
 
 /*L:056
index 817f37a875c9be194c7b7c08736a98acde8d74cb..c9570fcf1cce10fdf06a607aba75d31331011668 100644 (file)
@@ -159,7 +159,7 @@ int macii_init(void)
        err = macii_init_via();
        if (err) goto out;
 
-       err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB",
+       err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB",
                          macii_interrupt);
        if (err) goto out;
 
index 9ab5b0c34f0d0e8ff5f759c1e59dfea3948e674a..34d02a91b29ff70ed3dea3b1ad667da46e2a366a 100644 (file)
@@ -122,8 +122,8 @@ maciisi_init(void)
                return err;
        }
 
-       if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, 
-                       "ADB", maciisi_interrupt)) {
+       if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB",
+                       maciisi_interrupt)) {
                printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
                return -EAGAIN;
        }
index 7878712721bf431a1315f44db1c3b2dcc9486245..b6907118283a627a656fbe408e368da9853ff634 100644 (file)
@@ -1106,10 +1106,12 @@ void bitmap_write_all(struct bitmap *bitmap)
         */
        int i;
 
+       spin_lock_irq(&bitmap->lock);
        for (i = 0; i < bitmap->file_pages; i++)
                set_page_attr(bitmap, bitmap->filemap[i],
                              BITMAP_PAGE_NEEDWRITE);
        bitmap->allclean = 0;
+       spin_unlock_irq(&bitmap->lock);
 }
 
 static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
@@ -1605,7 +1607,9 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
        for (chunk = s; chunk <= e; chunk++) {
                sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap);
                bitmap_set_memory_bits(bitmap, sec, 1);
+               spin_lock_irq(&bitmap->lock);
                bitmap_file_set_bit(bitmap, sec);
+               spin_unlock_irq(&bitmap->lock);
                if (sec < bitmap->mddev->recovery_cp)
                        /* We are asserting that the array is dirty,
                         * so move the recovery_cp address back so
index cb246667dd52b6f7f71595db6db1138c16ea3aa0..0a6806f80ab5cdf40d4dba56c41dc74ad3db772b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/vmalloc.h>
 #include <linux/version.h>
 #include <linux/shrinker.h>
+#include <linux/module.h>
 
 #define DM_MSG_PREFIX "bufio"
 
index 0bdb201c2c2af04ceea2905db5f56c10fe1091df..042e71996569b963a6d9ec1addd4ae5aab97a23c 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #define DM_MSG_PREFIX "snapshot exception stores"
index 8db3862dade5346afa18de58640db51391b7d0fe..9429159d9ee335c78c57f19e023b68d602683acc 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/dm-dirty-log.h>
 #include <linux/device-mapper.h>
 #include <linux/dm-log-userspace.h>
+#include <linux/module.h>
 
 #include "dm-log-userspace-transfer.h"
 
index 42c04f04a0c4c84e28bb1cd05e56a19370d5e565..fa0ccc585cb4cb5ff4551d9bafd8dfd23b6f063c 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/device-mapper.h>
+#include <linux/module.h>
 
 #include "dm-path-selector.h"
 
index 11fa96df4b0614fefa3c00231b5ce98b5c091233..c2907d836e4e563ba50834e2524ae91919ddbd81 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "md.h"
 #include "raid1.h"
index 24752f449bef8834b8ebb0329293491bdf4f07ed..27f1d423b76c0582f77001a1265526fc29db2a47 100644 (file)
@@ -14,6 +14,7 @@
 #include "dm-path-selector.h"
 
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DM_MSG_PREFIX "multipath round-robin"
 
index 9c6c2e47ad625a6a12328d33d3491c7b413ca8f4..59883bd78214b0428a819ee19d397f460bfc6d8b 100644 (file)
@@ -12,6 +12,7 @@
 #include "dm-path-selector.h"
 
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DM_MSG_PREFIX  "multipath service-time"
 #define ST_MIN_IO      1
index d1f1d70171038cf9836832b68c63ad4b1d15297a..3ac415675b6c778b5dd22aaaf4ee6c2dc4ca48eb 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/dm-io.h>
 
index a0898a66a2f848f581ae770a93de74011a9249c8..1ce9a2586e4134a79ec3289808f8229e9aaa2080 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/dm-io.h>
 
index 6b1e3b61b25eacc469fe17e586c45d7f20687dfe..8efe033bab55d0d5b0d92178eeb604100aa60085 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/kobject.h>
 #include <linux/dm-ioctl.h>
+#include <linux/export.h>
 
 #include "dm.h"
 #include "dm-uevent.h"
index 918fb8ac6607b41690d25d50688aea96f680bae6..feb2c3c7bb44ffafcd56b278a099b09b7bc5ad4c 100644 (file)
@@ -63,6 +63,7 @@
 
 #define MaxFault       50
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/raid/md_u.h>
 #include <linux/slab.h>
 #include "md.h"
index a82035867519c944b7e6b93f6aca110d5354a3ff..c3273efd08cb6dce7a19cd8d193e98ff23600bb7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/blkdev.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include "md.h"
 #include "linear.h"
index 2acb32827fde46361e156ee629a6c51cb5edc371..ee981737edfcf3ff674749116d44d89bd45be751 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/hdreg.h>
 #include <linux/proc_fs.h>
 #include <linux/random.h>
+#include <linux/module.h>
 #include <linux/reboot.h>
 #include <linux/file.h>
 #include <linux/compat.h>
@@ -569,7 +570,7 @@ static void mddev_put(struct mddev *mddev)
            mddev->ctime == 0 && !mddev->hold_active) {
                /* Array is not configured at all, and not held active,
                 * so destroy it */
-               list_del(&mddev->all_mddevs);
+               list_del_init(&mddev->all_mddevs);
                bs = mddev->bio_set;
                mddev->bio_set = NULL;
                if (mddev->gendisk) {
@@ -2545,7 +2546,8 @@ state_show(struct md_rdev *rdev, char *page)
                sep = ",";
        }
        if (test_bit(Blocked, &rdev->flags) ||
-           rdev->badblocks.unacked_exist) {
+           (rdev->badblocks.unacked_exist
+            && !test_bit(Faulty, &rdev->flags))) {
                len += sprintf(page+len, "%sblocked", sep);
                sep = ",";
        }
@@ -3787,6 +3789,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
        if (err)
                return err;
        else {
+               if (mddev->hold_active == UNTIL_IOCTL)
+                       mddev->hold_active = 0;
                sysfs_notify_dirent_safe(mddev->sysfs_state);
                return len;
        }
@@ -4486,11 +4490,20 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
        if (!entry->show)
                return -EIO;
+       spin_lock(&all_mddevs_lock);
+       if (list_empty(&mddev->all_mddevs)) {
+               spin_unlock(&all_mddevs_lock);
+               return -EBUSY;
+       }
+       mddev_get(mddev);
+       spin_unlock(&all_mddevs_lock);
+
        rv = mddev_lock(mddev);
        if (!rv) {
                rv = entry->show(mddev, page);
                mddev_unlock(mddev);
        }
+       mddev_put(mddev);
        return rv;
 }
 
@@ -4506,13 +4519,19 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
                return -EIO;
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
+       spin_lock(&all_mddevs_lock);
+       if (list_empty(&mddev->all_mddevs)) {
+               spin_unlock(&all_mddevs_lock);
+               return -EBUSY;
+       }
+       mddev_get(mddev);
+       spin_unlock(&all_mddevs_lock);
        rv = mddev_lock(mddev);
-       if (mddev->hold_active == UNTIL_IOCTL)
-               mddev->hold_active = 0;
        if (!rv) {
                rv = entry->store(mddev, page, length);
                mddev_unlock(mddev);
        }
+       mddev_put(mddev);
        return rv;
 }
 
@@ -7839,6 +7858,7 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors,
                                  s + rdev->data_offset, sectors, acknowledged);
        if (rv) {
                /* Make sure they get written out promptly */
+               sysfs_notify_dirent_safe(rdev->sysfs_state);
                set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags);
                md_wakeup_thread(rdev->mddev->thread);
        }
index ad20a28fbf2aeee9a2df68a41113510fee604686..5899246fa37eccbff362cdc94f205b183c3b35c9 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/raid/md_u.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
index 65fd85ec6514dabcb0d13720cb5f029b861e90a4..023fbc2d389ee086e2edf53168e969a24dba5cad 100644 (file)
@@ -8,7 +8,7 @@
 #include "dm-btree-internal.h"
 #include "dm-transaction-manager.h"
 
-#include <linux/module.h>
+#include <linux/export.h>
 
 /*
  * Removing an entry from a btree
index e0638be53ea4302460d9a47df1cbd7f736d145a7..bd1e7ffbe26c750a26a4b9341d925a98acf632b3 100644 (file)
@@ -8,7 +8,7 @@
 #include "dm-space-map.h"
 #include "dm-transaction-manager.h"
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "btree"
index bb44a937fe635b1f38641ef771b3bd81ce8306d8..50ed53bf4aa2b1efe1136c2520067ece16bb9b35 100644 (file)
@@ -7,6 +7,7 @@
 #include "dm-space-map-checker.h"
 
 #include <linux/device-mapper.h>
+#include <linux/export.h>
 
 #ifdef CONFIG_DM_DEBUG_SPACE_MAPS
 
index aeff7852cf79bf731ab69370fffe9ce0f4c38537..fc469ba9f6277a7c701615a1b3d788a05fa52559 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/list.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "space map disk"
index 728e89a3f97830c3290e282a5daa7788c4fc309c..6f8d38747d7f438294fca80e24a3e3a61441dda1 100644 (file)
@@ -10,7 +10,7 @@
 #include "dm-space-map-metadata.h"
 #include "dm-persistent-data-internal.h"
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/device-mapper.h>
 
index 27e19e2b51d46ca2f30a283128a99ddf9dd944bd..7294bd115e34ec1940a0b1f83c5610f029413289 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include "md.h"
 #include "raid0.h"
index cae874646d9e965719b964b9e7b0539442dbe822..ede2461e79c51e8d3bd1ac04fcac4c7a974bbbbe 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
 #include "md.h"
index dde6dd4b47ec23fb65350904b44a33b59e577b46..685ddf325ee43f4492466c34a50a4a836c766e65 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
 #include "md.h"
index bb1b46143fb6477fcbf4b4acac8abb243cd68a81..31670f8d6b65789c071c1fd8d212c168138e14d8 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/kthread.h>
 #include <linux/raid/pq.h>
 #include <linux/async_tx.h>
+#include <linux/module.h>
 #include <linux/async.h>
 #include <linux/seq_file.h>
 #include <linux/cpu.h>
@@ -3035,6 +3036,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
                if (dev->written)
                        s->written++;
                rdev = rcu_dereference(conf->disks[i].rdev);
+               if (rdev && test_bit(Faulty, &rdev->flags))
+                       rdev = NULL;
                if (rdev) {
                        is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS,
                                             &first_bad, &bad_sectors);
@@ -3062,12 +3065,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
                        }
                } else if (test_bit(In_sync, &rdev->flags))
                        set_bit(R5_Insync, &dev->flags);
-               else if (!test_bit(Faulty, &rdev->flags)) {
+               else {
                        /* in sync if before recovery_offset */
                        if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset)
                                set_bit(R5_Insync, &dev->flags);
                }
-               if (test_bit(R5_WriteError, &dev->flags)) {
+               if (rdev && test_bit(R5_WriteError, &dev->flags)) {
                        clear_bit(R5_Insync, &dev->flags);
                        if (!test_bit(Faulty, &rdev->flags)) {
                                s->handle_bad_blocks = 1;
@@ -3075,7 +3078,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
                        } else
                                clear_bit(R5_WriteError, &dev->flags);
                }
-               if (test_bit(R5_MadeGood, &dev->flags)) {
+               if (rdev && test_bit(R5_MadeGood, &dev->flags)) {
                        if (!test_bit(Faulty, &rdev->flags)) {
                                s->handle_bad_blocks = 1;
                                atomic_inc(&rdev->nr_pending);
@@ -3109,7 +3112,7 @@ static void handle_stripe(struct stripe_head *sh)
        struct r5dev *pdev, *qdev;
 
        clear_bit(STRIPE_HANDLE, &sh->state);
-       if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) {
+       if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {
                /* already being handled, ensure it gets handled
                 * again when current action finishes */
                set_bit(STRIPE_HANDLE, &sh->state);
@@ -3158,10 +3161,14 @@ static void handle_stripe(struct stripe_head *sh)
        /* check if the array has lost more than max_degraded devices and,
         * if so, some requests might need to be failed.
         */
-       if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written)
-               handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
-       if (s.failed > conf->max_degraded && s.syncing)
-               handle_failed_sync(conf, sh, &s);
+       if (s.failed > conf->max_degraded) {
+               sh->check_state = 0;
+               sh->reconstruct_state = 0;
+               if (s.to_read+s.to_write+s.written)
+                       handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
+               if (s.syncing)
+                       handle_failed_sync(conf, sh, &s);
+       }
 
        /*
         * might be able to return some write requests if the parity blocks
@@ -3370,7 +3377,7 @@ finish:
 
        return_io(s.return_bi);
 
-       clear_bit(STRIPE_ACTIVE, &sh->state);
+       clear_bit_unlock(STRIPE_ACTIVE, &sh->state);
 }
 
 static void raid5_activate_delayed(struct r5conf *conf)
index f5d53a2023442fbfe1bb8c9bf77817e0fd051174..d6b1cf66042d196b40a7b99c18241fe186840d1d 100644 (file)
@@ -21,6 +21,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <media/saa7146.h>
+#include <linux/module.h>
 
 LIST_HEAD(saa7146_devices);
 DEFINE_MUTEX(saa7146_devices_lock);
index a92546144eaa30dc33695104374841b73b5b2bda..71f8e018e564818225137d437ecbc369418a5519 100644 (file)
@@ -1,6 +1,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <media/saa7146_vv.h>
+#include <linux/module.h>
 
 /****************************************************************************/
 /* resource management functions, shamelessly stolen from saa7134 driver */
index 79ad73accb27426a058c03ef4481be174988eda0..bc1f545c95cb2b669cae45a7e59bfe268e4d2844 100644 (file)
@@ -1,6 +1,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <media/saa7146_vv.h>
 
 static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
index 384b358d30379dfcdef7a99428bea28c24f7b77f..ce30533fd9724e1f802ecb6f67a6e6f42f998a65 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <media/saa7146_vv.h>
 #include <media/v4l2-chip-ident.h>
+#include <linux/module.h>
 
 static int max_memory = 32;
 
index 94a603a60842d815d6a5ac2b271ce48b14eca974..e13683bab6b3522f3621285b39265ba4ccc7eea6 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <media/tuner.h>
 #include <media/tuner-types.h>
 
index 2e8c288258a95153a97198f8f3d2708d5471d028..34434557ef65934d0652d926df3459d8bbc30c1c 100644 (file)
@@ -398,7 +398,6 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
        u8 i2c_r_data[24];
        u8 i = 0;
        u8 fifo_status = 0;
-       int ret;
        int status = 0;
 
        mxl_i2c("read %d bytes", count);
@@ -418,7 +417,7 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
                i2c_w_data[4+(i*3)] = 0x00;
        }
 
-       ret = mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
+       mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
 
        /* Check for I2C NACK status */
        if (mxl111sf_i2c_check_status(state) == 1) {
index 91dc1fc2825bf8ace4fa88bf33efe9b52ff6bd97..b741b3a7a325d423287512dce40440ad9556505a 100644 (file)
@@ -296,8 +296,7 @@ int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
                goto fail;
 
        ret = mxl111sf_write_reg(state, 0x00, 0x00);
-       if (mxl_fail(ret))
-               goto fail;
+       mxl_fail(ret);
 fail:
        return ret;
 }
@@ -328,11 +327,13 @@ int mxl111sf_idac_config(struct mxl111sf_state *state,
                /* set hysteresis value  reg: 0x0B<5:0> */
                ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
                                         (hysteresis_value & 0x3F));
+               mxl_fail(ret);
        }
 
        ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
+       mxl_fail(ret);
 
-       return val;
+       return ret;
 }
 
 /*
index 774d507b66cc7e841b412efe4c06ea4a6c8c1be5..43be7238311ec513726e8ecaa13d0864c2b622dd 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 
 #include "dibx000_common.h"
 
index af121db88ea002318bf28cb4135c7955ff334927..680c781c8dd61edae199e3bbf572a0f2c97d90ef 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "sms-cards.h"
 #include "smsir.h"
+#include <linux/module.h>
 
 static int sms_dbg;
 module_param_named(cards_dbg, sms_dbg, int, 0644);
index 457b6d02ef856ac1af08f698e34c516ce6b861b7..e2657c2f0109afc8b5a47524f0aec617a5984f85 100644 (file)
@@ -19,6 +19,7 @@
 
  ****************************************************************/
 
+#include <linux/export.h>
 #include <asm/byteorder.h>
 
 #include "smsendian.h"
index e57d38b0197c65e7c2d64e475a9a7c5b56beef43..91f8c8291e2b69eeb4f486667afa75356a6722d6 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
 
 #include "smscoreapi.h"
 #include "sms-cards.h"
index 0c8164a2cc36caf271c34848049290068b4ba855..51c7121b321a9e23cf7b94f4d4680ec442b91438 100644 (file)
@@ -24,6 +24,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <linux/usb.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "smscoreapi.h"
 #include "sms-cards.h"
index 16b70b4412f79a5afa226ec2acd350fb4e2e28df..6edc9ba81203698e9948c066ddfac2370a142b1d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/media.h>
+#include <linux/export.h>
 
 #include <media/media-device.h>
 #include <media/media-devnode.h>
index f17b540d68a5e257662ab82afd1020ebce70872c..3e9209f84e09bb04f46e75e2e517f10f9d37f608 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <media/timb_radio.h>
 
 #define DRIVER_NAME "timb-radio"
index 6d1e4e750f63a08bd88dca3d305014583b01b925..8aa4968d57bc6cf3317669fb3a8b9c27daf074b4 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/mfd/wl1273-core.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
index c9f4a8e65dc45daccc97c70bdaa99c8510fddae1..27aba936fb2bcb95c1fb9faedb7832557abeab42 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
index b93d8cf23b036578cc629d54a6460ce2592ff2f4..4f5c43d2566c887444a91329b64a3960229e5278 100644 (file)
@@ -28,6 +28,8 @@
  *
  */
 
+#include <linux/export.h>
+
 #include "fmdrv.h"
 #include "fmdrv_v4l2.h"
 #include "fmdrv_common.h"
index 624449afaa61744f406b06391946f4e21aa6b33c..035668e27f6b7798000428b4d2351c4908b93acc 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/bitrev.h>
+#include <linux/module.h>
 #include "rc-core-priv.h"
 
 #define JVC_NBITS              16              /* dev(8) + func(8) */
index ec2e67fd236b5f8f4e22be5db3061551b0e443a3..5faba2a2fdd3b87621388c5c8f4254129d4db0ff 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/sched.h>
 #include <linux/wait.h>
+#include <linux/module.h>
 #include <media/lirc.h>
 #include <media/lirc_dev.h>
 #include <media/rc-core.h>
index 63ee722dbd0204ea61860971b1c1d0a37d923dff..17f8db00435ac70269823ae3f029968cebbbd72a 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/bitrev.h>
+#include <linux/module.h>
 #include "rc-core-priv.h"
 
 #define NEC_NBITS              32
index 27808bb59eba3874ee7c1c07f79ba67f82abfd78..2e5cd3100b64476da15ef33508cbd39dd42ded50 100644 (file)
  *  GNU General Public License for more details.
  */
 
+#include <linux/export.h>
 #include <linux/kthread.h>
 #include <linux/mutex.h>
+#include <linux/kmod.h>
 #include <linux/sched.h>
 #include <linux/freezer.h>
 #include "rc-core-priv.h"
index ebdba55399167a78261e4a45d2d4cb64237d4d7c..9ab663a507a4b7e13b216b9604d47f3692840ea5 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "rc-core-priv.h"
+#include <linux/module.h>
 
 #define RC5_NBITS              14
 #define RC5X_NBITS             20
index 90aa8868629adccee354300504fe53fd9f5131ed..ec8d4a2e2c5a1d215920ab69f797c7bc39fa5fce 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "rc-core-priv.h"
+#include <linux/module.h>
 
 #define RC5_SZ_NBITS           15
 #define RC5_UNIT               888888 /* ns */
index 755dafa3871bf1be6f15025f6d775c2be75e6594..140fb67e2f89d9be9ce79a1b475a2fb24a900140 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "rc-core-priv.h"
+#include <linux/module.h>
 
 /*
  * This decoder currently supports:
index a92de80c48db7b4e48b64fead5353a7a9eed6083..d5e2b50aff1f069c5c221332f2d6d9a788118666 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/bitrev.h>
+#include <linux/module.h>
 #include "rc-core-priv.h"
 
 #define SONY_UNIT              600000 /* ns */
index 9a8752fdcca1f0b3f22398b04887206defc07ed6..b0e42df7ff82a27eda82468a51766dbbcb4a5867 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* ADS Tech Instant TV DVB-T PCI Remote */
 
index fe652e928dc0d660b61227d800d647fac854fcf7..4e6ade8e616f4f160f650a9792fbab10705ad724 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* A-Link DTU(m) slim remote, 6 rows, 3 columns. */
 static struct rc_map_table alink_dtu_m[] = {
index 884f1b51a8eea7108412041f10bd9cee302af04f..c735fe10a390663f927622f92e5fe75937cd71f6 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table anysee[] = {
        { 0x0800, KEY_0 },
index 7af188209ff97ec54875f1c1eab54885649ddf05..8c92ff95f94d11eeadd24a38880a387d98ad8b89 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Attila Kondoros <attila.kondoros@chello.hu> */
 
index b2481154491b5d8bb1d5d881b6a79de8e5cb8422..2caf2117759b2be2307faa63d3d6d293975d3b60 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Marc Fargas <telenieko@telenieko.com>
index f766b24b01585d9028637b5ecc7c7b0c5491ed60..2031224a20279c6d0882a40908f6bbcc6cdb299b 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* ATI TV Wonder HD 600 USB
    Devin Heitmueller <devin.heitmueller@gmail.com>
index ec9beeebd4107b798bf939aace91dc4ed944f98a..894939ac17f2c47b8998b9d8b480371b9c130754 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table avermedia_a16d[] = {
        { 0x20, KEY_LIST},
index 22f54d413a352d0a5b5cf15965059ce6a103fb6e..d2aaf5b9e39f074c51d160cfddb0c1bb1a627d1e 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Oldrich Jedlicka <oldium.pro@seznam.cz> */
 
index c25809d4c8138f445cff1ece2a9bf61f6de5e2f6..dc2baf062398e5352e129ffba2574ce1f94b8073 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Matt Jesson <dvb@jesson.eclipse.co.uk */
 
index 3d2cbe4e5e46c1f3739aebd937322cd160938e71..04269d31fa193781f9f817117cba420fc2c903a6 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Avermedia M135A with RM-JX and RM-K6 remote controls
index 8cd7f28808bdad9541c7a4438f5cc5eb1bdd6cde..e83b1a1939bfe49c05908ebef4c5b3d2548154ef 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Avermedia M733A with IR model RM-K6
index 9d68af217d8b0d92f0fee0dd8a123f4fa930c9dd..8344bcc595be5e564cd809d81c6727667788cf35 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Initial keytable is from Jose Alberto Reguero <jareguero@telefonica.net>
    and Felipe Morales Moreno <felipe.morales.moreno@gmail.com> */
index edfa71506d3eecf8d555afae2aa35249f3e3af4b..c6063dfcd507ab46efd726fe7658d2334367b196 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Alex Hermann <gaaf@gmx.net> */
 
index 32e94988dc94ebdacba8369e374c47c7e1bae44c..14f78451e64e2a3bf6c0ed5e477709b0acc875df 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* AVERTV STUDIO 303 Remote */
 
index c3f6d62ac8925d76dfc43cfb19620f5a9de420bc..ea7f2d0f31eb1bfa332acd4323ec4fd1bd4b0b7c 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table azurewave_ad_tu700[] = {
        { 0x0000, KEY_TAB },             /* Tab */
index 8bf058f67f0c7802856c2e31d558c7feac79f4b2..086b4b1f19e1da6f30477301feb53e768552ff9c 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Beholder Intl. Ltd. 2008
  * Dmitry Belimov d.belimov@google.com
index c909a234c77651db350494450e4d64d0202c6d30..0877e348094134ba9e1061ae137ea6580ef03e2c 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Igor Kuznetsov <igk72@ya.ru>
index 2f66e4310d20801e09a5baa3a159ba20a5228786..8311e092c0984ce22a92c7b093fd739963d2fa27 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * From reading the following remotes:
index 284534b67e7d0cdc66f66d895bd756a1e8ca582c..0c87fbaf99ab7752e31cc03cb6332345657496fd 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Cinergy 1400 DVB-T */
 
index cf3a6bfb190c33cc1a4c33a08855ec7fe4ebd68a..309e9e3fb6f30b9d5e2ad3ae9967d84728917bf2 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table cinergy[] = {
        { 0x00, KEY_0 },
index 7a5f5300caf9a0fcab05acbd8febe0acf44035a8..4d13a7f2e5c3bcb64f65dff524d233f85af0d506 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table dib0700_nec_table[] = {
        /* Key codes for the Pixelview SBTVD remote */
index 4af12e45dfbaaaacde6b1906cff036ca8da6027f..ba81d9697cfcaa3b653ee6748df368ec5b6a094e 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table dib0700_rc5_table[] = {
        /* Key codes for the tiny Pinnacle remote*/
index f68b450f5593b871694713da3704394d26d1044c..bed78acb919805589b6df9dc913951d22c1d590c 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table digitalnow_tinytwin[] = {
        { 0x0000, KEY_MUTE },            /* [symbol speaker] */
index 21d49871f2a3cdc8ef53456b0430edcd78cf3dc4..a3b97a1fe223e9853d123c5c39011cdec18e3770 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Digittrade DVB-T USB Stick remote controller. */
 /* Imported from af9015.h.
index d024fbf88bc4079fc7be50686a31c0e5dcd27b7e..67fc9fb0c007ceac45539911c1c51cf8217f07bd 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* DVBWorld remotes
    Igor M. Liplianin <liplianin@me.by>
index 82c0200029afd2c05f9bf8f668dd2c232294b33a..91ea91de91794af1c5fd69ed8ce6628d28ca5271 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* DigitalNow DNTV Live DVB-T Remote */
 
index 015e99de06de2cfe3fdd03f6835d1a4efd40bd06..fd680d4d3eb69a2ecb36693f2b76d7ac7b51a003 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* DigitalNow DNTV Live! DVB-T Pro Remote */
 
index 269d4299da345e7815d40441d7175cb060e97978..d1fcd64c0f90360f344155e6d7ef1b84ecba3109 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table em_terratec[] = {
        { 0x01, KEY_CHANNEL },
index e388698a06976ede300abed52accbc183fce0b51..2fe45e41fe49afad6840e128ef6f08bed2adff60 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Encore ENLTV-FM v5.3
    Mauro Carvalho Chehab <mchehab@infradead.org>
index e56ac6e9670ad299a31f87b25cc8d9f3882d134b..223de75a6d1c7cddc51110eccd96e92d34db3346 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Encore ENLTV-FM  - black plastic, white front cover with white glowing buttons
     Juan Pablo Sormani <sorman@gmail.com> */
index b6264f1bc4c113d13331b066dead373587364786..669cbff22b7e11b7d625e87232474a3c4cf5840e 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Encore ENLTV2-FM  - silver plastic - "Wand Media" written at the botton
     Mauro Carvalho Chehab <mchehab@infradead.org> */
index a2bf24f6dfbb33ac4a4b860eb85cd628e0576a4d..2c647fc2591606195cd9cb21128b4f48b950d191 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* EVGA inDtube
    Devin Heitmueller <devin.heitmueller@gmail.com>
index 1e8e5b2d6e36f72e069f2ad8e50f055546b05c2b..76921445c1d9822ab75aa6bfb8ff5bffa4ecd843 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Alfons Geser <a.geser@cox.net>
  * updates from Job D. R. Borges <jobdrb@ig.com.br> */
index a8b0f66edaa9c15beb69d3fb181548d299292e3d..3a6bba311b08ad0d4b60663a3e9c54b4d50c2a0d 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table flydvb[] = {
        { 0x01, KEY_ZOOM },             /* Full Screen */
index 5bbe683717568300ed2dc182b15dd266ffa622c0..bf9da584643b34da608995ff4ac55b5d56d0bbe3 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table flyvideo[] = {
        { 0x0f, KEY_0 },
index c80b25c65b57fe7286a5c9c689fb00b085cde507..2f0970fe78326710ca541e97d41d700e34d57306 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* DViCO FUSION HDTV MCE remote */
 
index 068c9ead98ddeff0bb6f77b07c3c828581a864ba..0e98ec467c34b47d4b576ec798459b4361c4987d 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* GADMEI UTV330+ RM008Z remote
    Shine Liu <shinel@foxmail.com>
index cdbbed467926092eae7d3c59f85b3e4f7f5c0f99..a2e2faa1d1b3708ec7b454d0eebb9e137a890735 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Remote control for the Genius TVGO A11MCE
index a38bdde8c14021e3c9c4b62016e64935cc9f445f..864614e19314fd7e555392dc17ca7c835ab493b8 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Mike Baikov <mike@baikov.com> */
 
index cd3db7779772140a810e0fe8cca4ce2bf9b82a86..e51c6163378b5e0bece020e4a615da5b0095640c 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Hauppauge:the newer, gray remotes (seems there are multiple
index 0ea2aa190d816af750afeb6688fc422df7aa7140..124c7228ba8cb4e69faf664af4acadad22da111c 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* mce-mode imon mce remote key table */
 static struct rc_map_table imon_mce[] = {
index 75d3843fdc3003924a0bf4965b8905b6dfd7996b..999c6295c70e971f89e7cdd15613e6a198dc5901 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * standard imon remote key table, which isn't really entirely
index 1f59e163f75d43935afbd6d30b92127e4be14d3e..34540dfc3df543d4c94baad09f2cfb87f1e35e00 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* IO-DATA BCTV7E Remote */
 
index f31dc5c1ad9ccb7ce6fb80185a7dd62351c03fb4..4264a787c150d304f4de50454eba753d3e9ed3ec 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Kaiomy TVnPC U2
    Mauro Carvalho Chehab <mchehab@infradead.org>
index 7f33edb4724437625ceb9839d6c1a6ed2d6a2330..e48cd267dda69cf69256a720b6f904065eef42e4 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Kworld 315U
  */
index 7fa17a369f2df467333301d212512ccfb156f70a..32998d6b787d50f260c4e93d82c4a39d87741d95 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Kworld Plus TV Analog Lite PCI IR
    Mauro Carvalho Chehab <mchehab@infradead.org>
index 8faa54ff16e654202d9f39ae540006455b113d21..03d762d986ee181ecd0129b374859fcf8765a3c1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table leadtek_y04g0051[] = {
        { 0x0300, KEY_POWER2 },
index e8e23e233c392373ca92e35176504a03173f779f..fbf08fa6f46e7bee61d165a71ca987e3822415d1 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-core.h>
+#include <linux/module.h>
 
 static struct rc_map_table lirc[] = {
        { },
index 129d3f9a461de94b415b01a6bd1d77cd67da5758..51f18bb50a371b79ffea87850724d900eab48d6f 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 
 static struct rc_map_table lme2510_rc[] = {
index 23b2d04e7a9fde4ae0904fd83759ad85b2f6a4ab..e7038bb71bf6e8207c3dedd2c859c68b033bce47 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Michael Tokarev <mjt@tls.msk.ru>
    keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
index 7b9a01b6e4cfcd9771a4f05bc27812e577125004..c64e9e30045db6c23469dcca884ff2578e83a5e9 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table msi_digivox_ii[] = {
        { 0x0002, KEY_2 },
index ae9d06b39157f28f1f524742f8a8a513c8fd7401..303a0b73175b9c5d3a13f9345c6db0f971546abb 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* MSI DIGIVOX mini III */
 /* Uses NEC extended 0x61d6. */
index 8e9969d1239b252e59974a443210e52ac07eb6a6..c393d8a50bcaad13ad33b8c96dae1c0ab4356e19 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
   Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
index fdd213ff1adf862da69d916e522d381ff9a0b668..a7003d3a3c8ac9c26cca0ab853826e0578aebb2f 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* MSI TV@nywhere MASTER remote */
 
index ddae20e9cd96d11ae78a2c42cb1fad1d12f24cc6..3f0ddd7afd30bb6e804622a8657a293a09534534 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table nebula[] = {
        { 0x00, KEY_0 },
index 26f114c5c0dee70f4469b4fdd8fa604d76714ea3..f3b86c8db67963d4a2e223cfbcaf42261b4ff9e1 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Terratec Cinergy Hybrid T USB XS FM
    Mauro Carvalho Chehab <mchehab@redhat.com>
index f9f2fa2819b808a7bd694bb6571550237758c369..9e65f07157abcb0745bce5c3a21ada596cab51f9 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Norwood Micro (non-Pro) TV Tuner
    By Peter Naulls <peter@chocky.org>
index 4aa588bf6d6917f79ff9f0ad77360ad50064230a..65d0cfc3c33b62be70040f11691d1d28a1410343 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table npgtech[] = {
        { 0x1d, KEY_SWITCHVIDEOMODE },  /* switch inputs */
index 7cdef6e6cc0f5123573c11a56625163daac74e00..bf2cbdfe2e32f7c9645d8ff7fd26099f21c269a4 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Mapping for the 28 key remote control as seen at
    http://www.sednacomputer.com/photo/cardbus-tv.jpg
index 23b8c505c6aac89db53be24a93f3dff3e4948844..b46cd8fe64383d7216ffc8901234f2b1eff2ab77 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table pinnacle_color[] = {
        { 0x59, KEY_MUTE },
index 6ba8c368d10a6ba5e0cf6ca55e6e4b12a1c6269b..d525df9ad868b9b9a6f6143b4f300897219ecc50 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table pinnacle_grey[] = {
        { 0x3a, KEY_0 },
index 31fc64cd17ba94da435e16561ab8159525a9e4fe..a4603d035374e31ff58e3e892118a647904f3036 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Pinnacle PCTV HD 800i mini remote */
 
index e5ab071f635a4a15bef075a868e5c96599b9f39e..33eb64333c6f738fdc4673cb6b85b3ca4eebde02 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Keytable for 002-T IR remote provided together with Pixelview
index 125fc3949c15f6470b3058bf7a72e6efe9186239..21f4dd25c2ec872c4bb6be49cdca4ea8e88d7089 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Keytable for MK-F12 IR remote provided together with Pixelview
index bd78d6ac1e16f1c55caea1cd151c6c61cf00eea2..f944ad2cac2b8697bd33e8acc5aa17c129c46773 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
    Mauro Carvalho Chehab <mchehab@infradead.org>
index 06187e7db4467856de66c77f149311d99f6fdfe6..a6020eea7b951b9e091433ba238616dd66e492bf 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table pixelview[] = {
 
index 5f9d546a86c499f6d129bb74eb13a187d8be8882..e74c571a5e44a34f46d7fe832b75a35c22e7621c 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Remote control for Powercolor Real Angel 330
index 8a3a643879d43b0fab91709a6191d169932df471..adee8035ce9624c102ca9f6c893ba85eced8d9a1 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Michal Majchrowicz <mmajchrowicz@gmail.com> */
 
index ef90296bfd6855502d4cd26dd7ccdea70c812897..722597a20e4ac708a9e2b8d8aa56f6ebae32a605 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table purpletv[] = {
        { 0x03, KEY_POWER },
index 5e8beee94de4ec6b05169411e5fe3042a3658532..0105d63c07a90bb02e6e45d09b91d66a685aecc4 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Mark Phalan <phalanm@o2.ie> */
 
index c3907e211d397bd7dadb36b46ec184d3b29d1884..753e43ec787ba10d09f35fbd4d5a33457319477a 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table rc6_mce[] = {
 
index 6813d1102118357f86ad0d1c146ad2fcb905eead..073694d50f49e6e6faa2874e3a8733ba0a210983 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Zogis Real Audio 220 - 32 keys IR */
 
index 92cc10d2f9cdc8e0c7ccbf30bc6c7c0ece561e2c..f9a07578d985957da91ed5324b4bf8393d6d75ea 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table streamzap[] = {
 /*
index 7242ee66f6e07729dffc94d2946d7c4f2ffd05a8..5039be782bc595068f66cd5c16b814f48f178718 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table tbs_nec[] = {
        { 0x84, KEY_POWER2},            /* power */
index 4afe5774f1925d6f0d0e2235e2ebcb6fdbd46d71..f9733bb289d63441c7d2f249ebc30f69c960c84c 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table technisat_usb2[] = {
        {0x0a0c, KEY_POWER},
index bc38e34b9fda1cd892ac2fc818f485c2bc5371a1..53629fb0151f98293de5044f13537c13487581b8 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Terratec Cinergy Hybrid T USB XS
    Devin Heitmueller <dheitmueller@linuxtv.org>
index 44093918cf03fa5caa56997945ab17504fb72d42..4c149ef712dcf6300ae8d493cabcc73abf326715 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * TerraTec slim remote, 6 rows, 3 columns.
index 1abafa5fd303587d719d5551750180505131750e..3d8a19cdb5a24e4584f04933fdbefd6e15e47534 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* TerraTec slim remote, 7 rows, 4 columns. */
 /* Uses NEC extended 0x02bd. */
index ef5ba3f3273543a28d4c04d4c4755d870687e5cd..f2c3b75d85800e1cca63bd50bcaaa34167f6178a 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table tevii_nec[] = {
        { 0x0a, KEY_POWER2},
index 98ad085531fdf4a25c035d036680caa751fb8aa8..454e062956925ee6b82ad195f10ca6bca82d4516 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /*
  * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
index 20ac4e19fb3f6a4974a29d244e41357823e63415..5b9f9ec13680fddf69f0c985fa5b3c092c0e72b6 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Uses NEC extended 0x02bd */
 static struct rc_map_table total_media_in_hand[] = {
index f8190ead2e326e08406ac372fce25a9db1054988..f9a2e0fabb9f8c4e6bdc03ae0de0ceba3947607b 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* TrekStor DVB-T USB Stick remote controller. */
 /* Imported from af9015.h.
index 295f3738e301d3a917c3f42c5d0a623a781c91d4..caeff85603e3c71fb4182ae8822aff4734df801f 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* for the Technotrend 1500 bundled remotes (grey and black): */
 
index 8bf8df64b081d5dfe4d83580888d8271fd5b9921..509299b90c903b7e6b799ebcd1dcc31c2172d208 100644 (file)
@@ -1,4 +1,5 @@
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table twinhan_vp1027[] = {
        { 0x16, KEY_POWER2 },
index 4994d405c0a1a1ebb07ae9c9a9d15ef9f56c8a85..3bd1de1f585c198d54c73ae16b018c6471ce8e35 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table videomate_m1f[] = {
        { 0x01, KEY_POWER },
index 9e474a6024e5acaf3b8a2c829d8bede5aa75fb70..8bfc3e8d909d61e2abda64dc58dea019e719de9a 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table videomate_s350[] = {
        { 0x00, KEY_TV},
index 5f2a46e1f8f6b0ecfb54d75e39ac41beb29b669d..390ce9431b35aa43ac676d6765e5c0282dbe8a10 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 static struct rc_map_table videomate_tv_pvr[] = {
        { 0x14, KEY_MUTE },
index bd8d021f40aa447ee153fae7c4b1786a41c67bf4..2852bf705064f8cfd794a35aece5baf5c1d3d616 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Leadtek Winfast TV USB II Deluxe remote
    Magnus Alm <magnus.alm@gmail.com>
index d8a34c14676ad4ae660d755c2ab492f35bc9798d..2df1cba236002c601a18c89357f1f2fc2f1f9333 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <media/rc-map.h>
+#include <linux/module.h>
 
 /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
 
index 666d4bb5b1fb17b611c8fba37517494db746ead8..29f900065d8ad7c74f252cb8b8a3479b0c456838 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include "rc-core-priv.h"
 
 /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
index 5914390211ff2ac6f087ec5693c08234ec55bd7d..12eedf4d515aa86dcf60107de69158895ae04795 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index b388654d48cd6bce3859ff7601e7a7ab1abffc82..53c496c00fb6b76fd03f151ad04cd9106b79c1c3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/ak881x.h>
 #include <media/v4l2-chip-ident.h>
index dc5b07a20f693a50a4af0cdc7a2b93fb5ff3c2f7..59c797c1527787df1187ca59bff16fd8a4d5c743 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 
 #include "cpia2.h"
 
index b718a3a4bed359ecfa3b7b178ce56508c79a920c..13c380ebb5621571bf43fc546acaa1aaf07b6029 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/slab.h>
 #include <linux/kfifo.h>
+#include <linux/module.h>
 #include <media/cx25840.h>
 #include <media/rc-core.h>
 
index c29ac88ffd787760cc8c1ccee74308afcee9559b..bd443ee76fff2a342b5c7633969affdbadfa480e 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/videodev2.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/module.h>
 
 #include <media/davinci/dm355_ccdc.h>
 #include <media/davinci/vpss.h>
index c8b32c1c7386168a60aa5e6f82cb51ebf294385d..8051c2956478d9ff826839874b34338ca675dcc8 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/gfp.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/module.h>
 
 #include <media/davinci/dm644x_ccdc.h>
 #include <media/davinci/vpss.h>
index 2a1ac287591db29fa94d87fdd9fd08b44e0decaf..82e819fa91c0814047074b867ae2bca713570b75 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "hdpvr.h"
 
index 9cb039e593dbc78140d7f801e31dfbd9a30ddc9f..a62322d5c0d87fd6346982acd9db4897c2e688f0 100644 (file)
@@ -26,6 +26,7 @@
 #define DEBUG_VARIABLE debug
 
 #include <media/saa7146_vv.h>
+#include <linux/module.h>
 
 static int debug;
 module_param(debug, int, 0);
index 74861a4b601aff51589e96fabb61167b51fa993f..23debc967d946c3932a86eec0247e04fb90fdb97 100644 (file)
@@ -26,6 +26,7 @@
 #define DEBUG_VARIABLE debug
 
 #include <media/saa7146_vv.h>
+#include <linux/module.h>
 
 static int debug;
 module_param(debug, int, 0);
index 8775e262bb6e8b9f42f19a467ed37ec806ff79e4..eec75bb57203f4c044ce8072616f625094a78385 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/v4l2-mediabus.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-subdev.h>
index 5d21d056d6a3523dbd440bc77ea78a8f8df2eee6..05ab3700647e286acf9b01ee994a07cd56eb8014 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
index 63ae5c61c9bf9af4f63c32f0ed6ed3e513206d1a..e2b1029b16cdd24552123d67dfc4a44ef51a6359 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
index f023cc092c2b8ea6d435daaf77e802ae74ef0ad3..cf2c0fb95f2f47d96121e55a4e4d87a07c076bcf 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/v4l2-mediabus.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-common.h>
index 7ee84cc578b9d2d018358bb6d1a44b7415fdb994..0e78477452ffb81bf5a09a781d9b68326b61e345 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
index 893a8b8f514134a4aa68645e8029166e75e16c02..db74dd27c722d987b07a4e625499d86061c3b4e2 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <asm/div64.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index b6a29f7de82cf60ff6cbf21c878db52f43afbd78..690ee0d42eebbcbb8aaf7374ca49a7302716180f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
index c64e1dc4cb4e52585f3518564cf334d2b2bf55ba..f080c162123f3ee0de1d0b532fc74a96d760b846 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/v4l2-mediabus.h>
+#include <linux/module.h>
 
 #include <media/mt9v032.h>
 #include <media/v4l2-ctrls.h>
index f0c3968ac7ebf68098f510d5604a82cfd7c01745..2e4131748438d158ff7127a1469629221700ff67 100644 (file)
@@ -29,6 +29,7 @@
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/saa7115.h>
+#include <linux/module.h>
 
 #include "mxb.h"
 #include "tea6415c.h"
index 6cd21cf91b44b8667015034dc5734882c91c5b4e..50838bf8420483dae1df53455edc9deedae0945d 100644 (file)
@@ -21,6 +21,7 @@
 #include <media/noon010pc30.h>
 #include <media/v4l2-chip-ident.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mediabus.h>
index eb97bff7116f644bbe66c5bd570d6a059f1a852b..45522e603185f45dbc5bac41c3c99032f06da6ca 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index d5b057207a7b969b330d20e02161ac7a0bf7c245..9f2d26b1d4cb8e2af6a48ccdc9c3f66c4bc87715 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/v4l2-mediabus.h>
+#include <linux/module.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
index e799331389b1b7dc3e92af6a15e8ef7469d5a89e..c6da8f77e1a29dd251de6a81dce727f67ddeabc9 100644 (file)
@@ -28,6 +28,7 @@ pvr2_device_desc structures.
 
 #include "pvrusb2-devattr.h"
 #include <linux/usb.h>
+#include <linux/module.h>
 /* This is needed in order to pull in tuner type ids... */
 #include <linux/i2c.h>
 #include <media/tuner.h>
index 5a6f24d1246d459edbd69cefde0a690048ff8e16..122b45760f0d9103306502e09e08c9d0b03002ae 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
index e72d5103e778c7d774eb4214e17950df5f0a8656..885ce11f222d779e5320e2dc43494bc6b7011cd0 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <media/ir-kbd-i2c.h>
 #include "pvrusb2-i2c-core.h"
 #include "pvrusb2-hdw-internal.h"
index ce7ac4595276b8a86da9e8a4641f5b1207e31bc6..6d666174dbb4491aff05b5f2c39c065f15b00b78 100644 (file)
@@ -29,6 +29,7 @@
 #include "pvrusb2-v4l2.h"
 #include "pvrusb2-ioread.h"
 #include <linux/videodev2.h>
+#include <linux/module.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index 6afc6168954926cb0f4715150798ea217255ca79..9937386a3baef7e0bf252eb82d75a2283b89b97a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
index 2446736b787115cb6e51f3e4fc32c2960a27694c..0df7f2a418140420c370e514e3c54a2da912820d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/media.h>
+#include <linux/module.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
index 725634d9736d5de28e1dd9f35719515abf6e5508..844a4d7797bc0be85ff01eae08837d5d49dbee69 100644 (file)
@@ -220,8 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv,
        strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
        cap->bus_info[0] = 0;
        cap->version = KERNEL_VERSION(1, 0, 0);
-       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
-                                                   | V4L2_CAP_STREAMING;
+       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+                       V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING;
        return 0;
 }
 
index ecef127dbc66faf3a949360882a424d4c1c49182..1e8cdb77d4b8540a991bb55d98ef35225596c98f 100644 (file)
@@ -785,8 +785,8 @@ static int vidioc_querycap(struct file *file, void *priv,
        strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
        cap->bus_info[0] = 0;
        cap->version = KERNEL_VERSION(1, 0, 0);
-       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
-                         | V4L2_CAP_VIDEO_OUTPUT
+       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE
+                         | V4L2_CAP_VIDEO_OUTPUT_MPLANE
                          | V4L2_CAP_STREAMING;
        return 0;
 }
index 37706eb81f25efefa89669f79f3abfbbad09e452..ea4f0473ed3be5c35c076c78e8f370e224175821 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/sh_mobile_ceu.h>
 #include <media/sh_mobile_csi2.h>
index 6a729879d89e66b684d675839aa0fdf1b2c923ce..9644bd861abc97290560a09f569bdf420578cfcd 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/sh_vou.h>
 #include <media/v4l2-common.h>
index 10aff3f943a88a23c4fd88ceb67837b92684da32..d1b07aceaf9465b0d46eb65ab9db8e2df7f7ec98 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
index b6ee1bd342dc10bf4134f4bc4bc8495f9de6e687..462caa44ae001c1a802fe8ca48f46052bcd59917 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <media/v4l2-int-device.h>
 
 #include "tcm825x.h"
index 84cd1b65b765afd19b628daede13dca6354469da..a0895bf07487847c921505e7d119dfa434c40037 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/videobuf-dma-contig.h>
index 9b3e828b0775fc6e4bd1f1b3077128d49f40545f..926f03931156541f98937ac9a3b0040c7a0f6a12 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
index e927d25e0d35b431a38140340cfcfac7dd57f572..6abaa16ae136b950657e1086fee643a0f6cc8b50 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
 #include <media/v4l2-chip-ident.h>
index 2e6059a52e9f4e5cdb38f1999f346d5921ff8254..7875e80cb2ff277bdd555e55f52cdb0d87f666d0 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
+#include <linux/module.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
index 8f5266157f15a037d09757e797e4713250dc599c..3103d0d020e814e70a82d38a0f9d1b3fa12341c3 100644 (file)
@@ -24,6 +24,7 @@
 
 
 #include <linux/list.h>
+#include <linux/module.h>
 #include <media/v4l2-dev.h>
 #include <media/tuner.h>
 #include "usbvision.h"
index 10c2364f3e8a56624babb71ac2f1d59f2c4c37f1..254d32688843bdc3f0a38a782e13fef2ec8d5a18 100644 (file)
@@ -1016,7 +1016,8 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
 
        menu_info = &mapping->menu_info[query_menu->index];
 
-       if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+       if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
+           (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
                s32 bitmap;
 
                if (!ctrl->cached) {
@@ -1225,7 +1226,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
                /* Valid menu indices are reported by the GET_RES request for
                 * UVC controls that support it.
                 */
-               if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+               if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
+                   (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
                        if (!ctrl->cached) {
                                ret = uvc_ctrl_populate_cache(chain, ctrl);
                                if (ret < 0)
index 5552f8137571e640bfdcec380b9d3c3773a917df..0f415dade05ae4bec936b2300f9c81e93fa535eb 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/ctype.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -820,8 +821,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
        fill_event(&ev, ctrl, changes);
 
        list_for_each_entry(sev, &ctrl->ev_subs, node)
-               if (sev->fh && (sev->fh != fh ||
-                               (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)))
+               if (sev->fh != fh ||
+                   (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))
                        v4l2_event_queue_fh(sev->fh, &ev);
 }
 
@@ -946,6 +947,7 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
                        if (ctrl->cluster[0]->has_volatiles)
                                ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
                }
+               fh = NULL;
        }
        if (changed || update_inactive) {
                /* If a control was changed that was not one of the controls
index 9fc0ae8a526a4958995dd76fbedefd630d736879..0edd618b9ddf17c1a117b157428df48ceccca1ae 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
+#include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #if defined(CONFIG_SPI)
index 53b190cf225e734e71a0ddaacfa1c66b69644b67..c26ad9637143bcc82bc0bb5618b207ccc07277ba 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 static unsigned sev_pos(const struct v4l2_subscribed_event *sev, unsigned idx)
 {
@@ -215,6 +216,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
        unsigned long flags;
        unsigned i;
 
+       if (sub->type == V4L2_EVENT_ALL)
+               return -EINVAL;
+
        if (elems < 1)
                elems = 1;
        if (sub->type == V4L2_EVENT_CTRL) {
@@ -282,6 +286,7 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 {
        struct v4l2_subscribed_event *sev;
        unsigned long flags;
+       int i;
 
        if (sub->type == V4L2_EVENT_ALL) {
                v4l2_event_unsubscribe_all(fh);
@@ -292,8 +297,12 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh,
 
        sev = v4l2_event_subscribed(fh, sub->type, sub->id);
        if (sev != NULL) {
+               /* Remove any pending events for this subscription */
+               for (i = 0; i < sev->in_use; i++) {
+                       list_del(&sev->events[sev_pos(sev, i)].list);
+                       fh->navailable--;
+               }
                list_del(&sev->list);
-               sev->fh = NULL;
        }
 
        spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
index 122822d2b8b2ccb1a1869833f44ea77ddec33999..9e3fc040ea20303056fcffcaa0b6f0f318deffb4 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/bitops.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
index a935bae538ef26f4455cea5f58e0bf1da2b7c159..f4473494af7aef3e9db95729905c610aef4b8f40 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/list.h>
 #include <linux/sort.h>
 #include <linux/string.h>
+#include <linux/module.h>
 
 #include <media/v4l2-int-device.h>
 
index 179e20e23fc4b58673f23c7fb37688a506589d83..65ade5f03c2ef56efa5331c58a44391caa30f2ac 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/videodev2.h>
+#include <linux/export.h>
 
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
index 979e544388cbfbdea4efa2ea1c1bb321e1d37897..95a3f5e82aef14c74a81045baa26874eb008e7c1 100644 (file)
@@ -131,6 +131,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n)
                        continue;
 
                for (plane = 0; plane < vb->num_planes; ++plane) {
+                       vb->v4l2_planes[plane].length = q->plane_sizes[plane];
                        vb->v4l2_planes[plane].m.mem_offset = off;
 
                        dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
@@ -264,6 +265,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
        q->num_buffers -= buffers;
        if (!q->num_buffers)
                q->memory = 0;
+       INIT_LIST_HEAD(&q->queued_list);
 }
 
 /**
@@ -296,14 +298,14 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
 {
        unsigned int plane;
        for (plane = 0; plane < vb->num_planes; ++plane) {
+               void *mem_priv = vb->planes[plane].mem_priv;
                /*
                 * If num_users() has not been provided, call_memop
                 * will return 0, apparently nobody cares about this
                 * case anyway. If num_users() returns more than 1,
                 * we are not the only user of the plane's memory.
                 */
-               if (call_memop(q, plane, num_users,
-                               vb->planes[plane].mem_priv) > 1)
+               if (mem_priv && call_memop(q, plane, num_users, mem_priv) > 1)
                        return true;
        }
        return false;
index 8c1d85e27be4bcecb8862fdce7eeb36157cfc209..56ff19cdc2ad81ca015b9e9364318609921dcace 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "memstick"
 
index 4a1909a32b6021827a46e9b9db87467ae9c545c5..9729b92fbfdd3150280328a2be3d5872beacd618 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/memstick.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "mspro_block"
 
index d89d925caecf39a8d2f2feb3e6f58361eee14682..6ce70e9615d342660f7da9e71339ffad4c3087a3 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/memstick.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "jmb38x_ms"
 
index 03f71a431c8207f403fcf1924ffe3b9f3ce36659..b7aacf47703a33c1609f51ddfb5c7ec56a91a1de 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
+#include <linux/module.h>
 #include <asm/io.h>
 
 #define DRIVER_NAME "tifm_ms"
index 73e4658af53c5216b27c029cdc078ee0d379148e..7190d5239b4fa0e5725169a134ed620b776e25d4 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/i2o.h>
+#include <linux/module.h>
 #include "core.h"
 
 #define OSM_DESCRIPTION        "I2O-subsystem"
index 4f5725508ac0eb47ed09396998343d5c41df7ad9..60107ee166fc4852da4bd63835913fca96becac6 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/notifier.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
index 4175544b491b51917c0c309194ba82de67327ec1..ec10629a0b0b151b5235432dc08bb238f4783b22 100644 (file)
@@ -13,6 +13,7 @@
  * TODO: Event handling with irq_chip. Waiting for PRCMU fw support.
  */
 
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
index 6be1fe6b5f9ac70c8ef31df1a3d546a3dc695707..43c0ebb81956188b22f7ce2953eddc936f39ae3a 100644 (file)
@@ -4,6 +4,7 @@
  * Debugfs support for the AB5500 MFD driver
  */
 
+#include <linux/export.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/mfd/ab5500/ab5500.h>
index 64bdeeb1c11a4c18f236a764e2e863cd4c1920c4..dedb7f65cea600a205f83fc2e81e385649cf74ee 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/fs.h>
+#include <linux/module.h>
 #include <linux/debugfs.h>
 #include <linux/platform_device.h>
 
index 392185965b39f14ad57a63fb1db5b8340b3abff6..f20feefac19020969dc55a24bb8a8d162934adb5 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ab8500.h>
 #include <linux/mfd/abx500.h>
index f12720dbe1262a5a78ce99154c0ca8549552c448..7ce65f49480f1bfb4b68d7c693a27451e797e27b 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/mfd/abx500.h>
 
 static LIST_HEAD(abx500_list);
index 3bd85bddf6e31e51096937abdb60ff170779e1c3..b85bbd7f0d1980f16e78a49cae46658b1158627b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
index 3d4a861976ca9ea60477382e5ad52909734161eb..8ad88da647b9abfd201c659eb92ec12072b03a60 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
index dc58750bb71bbfc52c45fd8afe93be1d5d288be7..5be53ae9b61cf2a6d6c318c881e43605b3dee526 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8997.h>
index 0902523af62d47e33e139c1feab75e5b0ef2a49c..0f5922812bffdee8e3e892cab978052548d92114 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mfd/core.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 int mfd_cell_enable(struct platform_device *pdev)
 {
index 1b0192f1efffee1214c9b36e407b060ef8c315db..048a3b903b013bcb5a0efb62c303e76c02ab1056 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include <linux/mfd/pcf50633/core.h>
index eddc19ae464becb8887c479945368183e328af84..83af78c1b0ebede74c588e6913e62a6f321dfb59 100644 (file)
@@ -6,6 +6,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/export.h>
 #include <linux/mfd/tmio.h>
 
 int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
index b8eef462737a42222e48c80da56a576960384171..bfbd66021afd383703fad96e890975853c2bf063 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
index deec3ec858bf8125af6e76e282157df5ff5e3826..3eee45ffb096e337d1e1aa67040532a14ff0b670 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kthread.h>
index d97a86945174519a6d333bf0527875b63537384d..f39b756df561dcfd5fee7fa310222bb27748d708 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/mfd/wl1273-core.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRIVER_DESC "WL1273 FM Radio Core"
 
index e06ba9440cdbea2c7143b7dcbe9f752e9d47936c..62b4626f4561029102ece804a7de96708186b2cb 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <linux/bug.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
index d593878d66d054e76f75860aec7176b9c012a5cf..5664696f2d3a8512c6ef96aca461dde22e5d486f 100644 (file)
@@ -472,7 +472,7 @@ config BMP085
          module will be called bmp085.
 
 config PCH_PHUB
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
+       tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
        depends on PCI
        help
          This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
@@ -480,12 +480,13 @@ config PCH_PHUB
          processor. The Topcliff has MAC address and Option ROM data in SROM.
          This driver can access MAC address and Option ROM data in SROM.
 
-         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7213 and ML7223.
-         ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
-         for MP(Media Phone) use.
-         ML7213/ML7223 is companion chip for Intel Atom E6xx series.
-         ML7213/ML7223 is completely compatible for Intel EG20T PCH.
+         This driver also can be used for LAPIS Semiconductor's IOH,
+         ML7213/ML7223/ML7831.
+         ML7213 which is for IVI(In-Vehicle Infotainment) use.
+         ML7223 IOH is for MP(Media Phone) use.
+         ML7831 IOH is for general purpose use.
+         ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
 
          To compile this driver as a module, choose M here: the module will
          be called pch_phub.
index 35903154ca2ee0e5c2adaa7971c0370aac8f19cc..2208a9d526222a9ebb30a0f2538553029e6f4e19 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/pwm.h>
 #include <linux/mfd/ab8500.h>
 #include <linux/mfd/abx500.h>
+#include <linux/module.h>
 
 /*
  * PWM Out generators
index a662f5987b6892591008291e3b5b05506918ed9e..82b2cb77ae197b2124ede9131dc4cbe0902ce0e8 100644 (file)
@@ -100,7 +100,7 @@ enum dpot_devid {
        AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27),
        AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
                        BRDAC0, 7, 28),
-       AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
+       AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
                        BRDAC0, 8, 29),
        AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
                        BRDAC0 | BRDAC1, 8, 30),
index 769a4e8e10dc17a0a10e8e206b24567a2ba6747f..5bb1877810749da2581aff03c6d7d50c18b875c3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/spinlock.h>
 #include <linux/atmel-ssc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 /* Serialize access to ssc_list and user count */
 static DEFINE_SPINLOCK(user_lock);
index a844810b50f68a6a88e12ed7a427862a044efc48..4bcfc375973429a07dbcccf2558ef40237e20f00 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 /* Number of bytes to reserve for the iomem resource */
 #define ATMEL_TC_IOMEM_SIZE    256
index 82fe2d067827b43f3e89ade1afdb9827e2982133..bfeea9ba702e4ecae54d782b1adfde71a3c5dfe9 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #define BH1780_REG_CONTROL     0x80
 #define BH1780_REG_PARTID      0x8A
index 7ce6065dc20e806a06845f08bcec084adbb4418d..eb5cd28bc6d8d7a1917f7f15d82b267b692315f8 100644 (file)
@@ -945,8 +945,7 @@ static int fpga_of_remove(struct platform_device *op)
 /* CTL-CPLD Version Register */
 #define CTL_CPLD_VERSION       0x2000
 
-static int fpga_of_probe(struct platform_device *op,
-                        const struct of_device_id *match)
+static int fpga_of_probe(struct platform_device *op)
 {
        struct device_node *of_node = op->dev.of_node;
        struct device *this_device;
@@ -1107,7 +1106,7 @@ static struct of_device_id fpga_of_match[] = {
        {},
 };
 
-static struct of_platform_driver fpga_of_driver = {
+static struct platform_driver fpga_of_driver = {
        .probe          = fpga_of_probe,
        .remove         = fpga_of_remove,
        .driver         = {
@@ -1124,12 +1123,12 @@ static struct of_platform_driver fpga_of_driver = {
 static int __init fpga_init(void)
 {
        led_trigger_register_simple("fpga", &ledtrig_fpga);
-       return of_register_platform_driver(&fpga_of_driver);
+       return platform_driver_register(&fpga_of_driver);
 }
 
 static void __exit fpga_exit(void)
 {
-       of_unregister_platform_driver(&fpga_of_driver);
+       platform_driver_unregister(&fpga_of_driver);
        led_trigger_unregister_simple(ledtrig_fpga);
 }
 
index 3965821fef174c308ac73e37072d552287985d91..14e974b2a7812452d14ad2d92979e8d84483da7e 100644 (file)
@@ -1249,8 +1249,7 @@ static bool dma_filter(struct dma_chan *chan, void *data)
        return true;
 }
 
-static int data_of_probe(struct platform_device *op,
-                        const struct of_device_id *match)
+static int data_of_probe(struct platform_device *op)
 {
        struct device_node *of_node = op->dev.of_node;
        struct device *this_device;
@@ -1401,7 +1400,7 @@ static struct of_device_id data_of_match[] = {
        {},
 };
 
-static struct of_platform_driver data_of_driver = {
+static struct platform_driver data_of_driver = {
        .probe          = data_of_probe,
        .remove         = data_of_remove,
        .driver         = {
@@ -1417,12 +1416,12 @@ static struct of_platform_driver data_of_driver = {
 
 static int __init data_init(void)
 {
-       return of_register_platform_driver(&data_of_driver);
+       return platform_driver_register(&data_of_driver);
 }
 
 static void __exit data_exit(void)
 {
-       of_unregister_platform_driver(&data_of_driver);
+       platform_driver_unregister(&data_of_driver);
 }
 
 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
index 26cf12ca7f503e5d2babb111ab6eaf132cf5c5a2..701edf6589705cb42f290a04c233239f7248760a 100644 (file)
@@ -85,7 +85,7 @@ config EEPROM_93XX46
 
 config EEPROM_DIGSY_MTC_CFG
        bool "DigsyMTC display configuration EEPROMs device"
-       depends on PPC_MPC5200_GPIO && GPIOLIB && SPI_GPIO
+       depends on GPIO_MPC5200 && SPI_GPIO
        help
          This option enables access to display configuration EEPROMs
          on digsy_mtc board. You have to additionally select Microwire
index 8cebec5e85eeb3d3c80bd998815a3e07f1a913ad..3f7ad83ed740bc0f008ca50ec8efdc125369d644 100644 (file)
 #include <linux/nmi.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/module.h>
 
 #define v1printk(a...) do { \
        if (verbose) \
index dee33addcaebf82c2652e089830fff7d442a8ed2..10fc4785dba7dd65330a7008db87a4423a0bedd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
                                              (Intel EG20T PCH)*/
 #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
-                                               offset(OKI SEMICONDUCTOR ML7213)
+                                               offset(LAPIS Semicon ML7213)
                                              */
 #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
-                                               offset(OKI SEMICONDUCTOR ML7223)
+                                               offset(LAPIS Semicon ML7223)
                                              */
 
 /* MAX number of INT_REDUCE_CONTROL registers */
@@ -73,6 +73,9 @@
 #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB        0x8012 /* for Bus-m */
 #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB        0x8002 /* for Bus-n */
 
+/* Macros for ML7831 */
+#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
+
 /* SROM ACCESS Macro */
 #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
 
  * @pch_mac_start_address:             MAC address area start address
  * @pch_opt_rom_start_address:         Option ROM start address
  * @ioh_type:                          Save IOH type
+ * @pdev:                              pointer to pci device struct
  */
 struct pch_phub_reg {
        u32 phub_id_reg;
@@ -136,6 +140,7 @@ struct pch_phub_reg {
        u32 pch_mac_start_address;
        u32 pch_opt_rom_start_address;
        int ioh_type;
+       struct pci_dev *pdev;
 };
 
 /* SROM SPEC for MAC address assignment offset */
@@ -471,7 +476,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
        int retval;
        int i;
 
-       if (chip->ioh_type == 1) /* EG20T */
+       if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
                retval = pch_phub_gbe_serial_rom_conf(chip);
        else    /* ML7223 */
                retval = pch_phub_gbe_serial_rom_conf_mp(chip);
@@ -498,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
        unsigned int orom_size;
        int ret;
        int err;
+       ssize_t rom_size;
 
        struct pch_phub_reg *chip =
                dev_get_drvdata(container_of(kobj, struct device, kobj));
@@ -509,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
        }
 
        /* Get Rom signature */
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               goto exrom_map_err;
+
        pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
                                (unsigned char *)&rom_signature);
        rom_signature &= 0xff;
@@ -539,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
                goto return_err;
        }
 return_ok:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
        mutex_unlock(&pch_phub_mutex);
        return addr_offset;
 
 return_err:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
+exrom_map_err:
        mutex_unlock(&pch_phub_mutex);
 return_err_nomutex:
        return err;
@@ -555,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
        int err;
        unsigned int addr_offset;
        int ret;
+       ssize_t rom_size;
        struct pch_phub_reg *chip =
                dev_get_drvdata(container_of(kobj, struct device, kobj));
 
@@ -571,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
                goto return_ok;
        }
 
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address) {
+               err = -ENOMEM;
+               goto exrom_map_err;
+       }
+
        for (addr_offset = 0; addr_offset < count; addr_offset++) {
                if (PCH_PHUB_OROM_SIZE < off + addr_offset)
                        goto return_ok;
@@ -585,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
        }
 
 return_ok:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
        mutex_unlock(&pch_phub_mutex);
        return addr_offset;
 
 return_err:
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
+
+exrom_map_err:
        mutex_unlock(&pch_phub_mutex);
        return err;
 }
@@ -598,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
 {
        u8 mac[8];
        struct pch_phub_reg *chip = dev_get_drvdata(dev);
+       ssize_t rom_size;
+
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               return -ENOMEM;
 
        pch_phub_read_gbe_mac_addr(chip, mac);
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
 
        return sprintf(buf, "%pM\n", mac);
 }
@@ -608,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
                             const char *buf, size_t count)
 {
        u8 mac[6];
+       ssize_t rom_size;
        struct pch_phub_reg *chip = dev_get_drvdata(dev);
 
        if (count != 18)
@@ -617,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
                (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
                (u32 *)&mac[4], (u32 *)&mac[5]);
 
+       chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
+       if (!chip->pch_phub_extrom_base_address)
+               return -ENOMEM;
+
        pch_phub_write_gbe_mac_addr(chip, mac);
+       pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
 
        return count;
 }
@@ -640,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
        int retval;
 
        int ret;
-       ssize_t rom_size;
        struct pch_phub_reg *chip;
 
        chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
@@ -677,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
                "in pch_phub_base_address variable is %p\n", __func__,
                chip->pch_phub_base_address);
 
-       if (id->driver_data != 3) {
-               chip->pch_phub_extrom_base_address =\
-                                                  pci_map_rom(pdev, &rom_size);
-               if (chip->pch_phub_extrom_base_address == 0) {
-                       dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
-                       ret = -ENOMEM;
-                       goto err_pci_map;
-               }
-               dev_dbg(&pdev->dev, "%s : "
-                       "pci_map_rom SUCCESS and value in "
-                       "pch_phub_extrom_base_address variable is %p\n",
-                       __func__, chip->pch_phub_extrom_base_address);
-       }
+       chip->pdev = pdev; /* Save pci device struct */
 
        if (id->driver_data == 1) { /* EG20T PCH */
                const char *board_name;
@@ -763,6 +786,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
                chip->pch_opt_rom_start_address =\
                                                 PCH_PHUB_ROM_START_ADDR_ML7223;
                chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
+       } else if (id->driver_data == 5) { /* ML7831 */
+               retval = sysfs_create_file(&pdev->dev.kobj,
+                                          &dev_attr_pch_mac.attr);
+               if (retval)
+                       goto err_sysfs_create;
+
+               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+               if (retval)
+                       goto exit_bin_attr;
+
+               /* set the prefech value */
+               iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
+               /* set the interrupt delay value */
+               iowrite32(0x25, chip->pch_phub_base_address + 0x44);
+               chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
+               chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
        }
 
        chip->ioh_type = id->driver_data;
@@ -773,8 +812,6 @@ exit_bin_attr:
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
 
 err_sysfs_create:
-       pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
-err_pci_map:
        pci_iounmap(pdev, chip->pch_phub_base_address);
 err_pci_iomap:
        pci_release_regions(pdev);
@@ -792,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)
 
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
        sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-       pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
        pci_iounmap(pdev, chip->pch_phub_base_address);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -847,6 +883,7 @@ static struct pci_device_id pch_phub_pcidev_id[] = {
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },
        { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  },
+       { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5,  },
        { }
 };
 MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
@@ -873,5 +910,5 @@ static void __exit pch_phub_pci_exit(void)
 module_init(pch_phub_pci_init);
 module_exit(pch_phub_pci_exit);
 
-MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
+MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
 MODULE_LICENSE("GPL");
index 9e9bddaa95ae50a7e8440a73d4ae582cf70bb9be..913de07e577c752fc338ce8b30b39a58290763d0 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <asm/io_apic.h>
 #include "gru.h"
 #include "grulib.h"
index cfbddbef11de3b67c54be85797dd124843ca8596..43d073bc1d9c5fef61a1cb3a1e741a6cd6b6e0f9 100644 (file)
@@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void)
 }
 module_exit(spear_pcie_gadget_exit);
 
-MODULE_ALIAS("pcie-gadget-spear");
+MODULE_ALIAS("platform:pcie-gadget-spear");
 MODULE_AUTHOR("Pratyush Anand");
 MODULE_LICENSE("GPL");
index 3a3580566dfca39fa5e2882f1658418665a9e72d..43ef8d162f2d6b3f657359ee9be3e1100dbc2232 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/skbuff.h>
 #include <linux/ti_wilink_st.h>
+#include <linux/module.h>
 
 
 #define MAX_ST_DEVICES 3       /* Imagine 1 on each UART for now */
index a6ef18259da033ea7a9d6426f53575de1a35e027..ba2479022670b65d7a1326b2ba39a20550aabbaf 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/tifm.h>
 #include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "tifm_7xx1"
 #define DRIVER_VERSION "0.8"
index 44d4475a09ddd5a23947debf1a53fa3a37739dcf..0bd5349b04228ca0b784c44d4ea5dd6770450472 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/idr.h>
+#include <linux/module.h>
 
 #define DRIVER_NAME "tifm_core"
 #define DRIVER_VERSION "0.8"
index 46b6e84d953e3f29697fbdb4d275edc778783988..6be49249895a21bab3c06cd4bc658f347ed99124 100644 (file)
  *  MMC card bus driver model
  */
 
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/pm_runtime.h>
 
 #include <linux/mmc/card.h>
index 6045ea469362ebf3875f57af34c13451d9c665ad..3923880118b64d0519d7eb00d084e9709b271b59 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/moduleparam.h>
+#include <linux/export.h>
 #include <linux/debugfs.h>
 #include <linux/fs.h>
 #include <linux/seq_file.h>
index ca2e4f50f61580f65b213159af86647272fbea2d..e8a5eb38748be34a002aa24a5ba28af9c472c182 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/pagemap.h>
+#include <linux/export.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
index 36270449dd9d24c20167484bfbeb70b7b9f4e6d4..dbf421a6279c702d91baeede5bb5f1e55dcb6fcd 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
index 007863eea4fb73ba72ad3bc052b0cc139c137456..4d41fa984c9344d007a1df43898f25a18c0a4e91 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/scatterlist.h>
 
index 6c3cf98a62eb6d04825afb1b792e5d4e1c3ade55..06ee1aeaacec2693fd8f4a36b564902b1e738234 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mmc/card.h>
 
 #ifndef SDIO_VENDOR_ID_TI
index a230e7f9d77a5c79c2f1b9f52606f5d9b53dce8c..f2a05ea40f2a3ed705e220fd5216d508d538b033 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
index 46a785419fab59c6cdfced8e082e60f2af4371f6..274ef00b44639149c3d43c24effffd400fa5ba69 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/export.h>
 #include <linux/scatterlist.h>
 
 #include <linux/mmc/host.h>
index c643b2f78bf1f95a66ad822d4cc559c41b1fdcfd..40989e6bb53a588a8afa1e4281c1cd320999f117 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 
index 0f687cdeb064ac917d778a35f9bc5c756f1da89e..b1f3168f791b5fcbabe144faf9c6f23243957c5d 100644 (file)
@@ -9,6 +9,7 @@
  * your option) any later version.
  */
 
+#include <linux/export.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio.h>
index b644dd59c16eee8337e45e59c8b4d61f76d3e2ee..68f81b9ee0fbe4eb10c962b0ddb088ee11f8e213 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
+#include <linux/export.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
 
index ae57769ba50d53c129bc1b6399b92db37c9bc010..4b976f00ea85137913a2b54e7dce63e590b809ac 100644 (file)
@@ -32,6 +32,7 @@
 /* VENDOR SPEC register */
 #define SDHCI_VENDOR_SPEC              0xC0
 #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK  0x00000002
+#define SDHCI_WTMK_LVL                 0x44
 #define SDHCI_MIX_CTRL                 0x48
 
 /*
@@ -476,6 +477,13 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
        if (is_imx53_esdhc(imx_data))
                imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
 
+       /*
+        * The imx6q ROM code will change the default watermark level setting
+        * to something insane.  Change it back here.
+        */
+       if (is_imx6q_usdhc(imx_data))
+               writel(0x08100810, host->ioaddr + SDHCI_WTMK_LVL);
+
        boarddata = &imx_data->boarddata;
        if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
                if (!host->mmc->parent->platform_data) {
index 067a4cded9cf7b592938aa24b306679c5038141a..89699e861fc1c90c8c127ac798a3e208dd2d839e 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
index 66b616ebe536d512bf534d28ea48cf9db284d286..318a869286ab09581e761a391e57539faa7b5c77 100644 (file)
@@ -12,27 +12,17 @@ menuconfig MTD
 
 if MTD
 
-config MTD_DEBUG
-       bool "Debugging"
-       help
-         This turns on low-level debugging for the entire MTD sub-system.
-         Normally, you should say 'N'.
-
-config MTD_DEBUG_VERBOSE
-       int "Debugging verbosity (0 = quiet, 3 = noisy)"
-       depends on MTD_DEBUG
-       default "0"
-       help
-         Determines the verbosity level of the MTD debugging messages.
-
 config MTD_TESTS
-       tristate "MTD tests support"
+       tristate "MTD tests support (DANGEROUS)"
        depends on m
        help
          This option includes various MTD tests into compilation. The tests
          should normally be compiled as kernel modules. The modules perform
          various checks and verifications when loaded.
 
+         WARNING: some of the tests will ERASE entire MTD device which they
+         test. Do not use these tests unless you really know what you do.
+
 config MTD_REDBOOT_PARTS
        tristate "RedBoot partition table parsing"
        ---help---
@@ -137,7 +127,8 @@ config MTD_AFS_PARTS
          'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
 
 config MTD_OF_PARTS
-       def_bool y
+       tristate "OpenFirmware partitioning information support"
+       default Y
        depends on OF
        help
          This provides a partition parsing function which derives
index 39664c4229ff5139293dc63d27e09837d2a7696b..9aaac3ac89f3f55e64adb4d72f1e94c8c3967e16 100644 (file)
@@ -5,8 +5,8 @@
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
 mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
-mtd-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 
+obj-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
 obj-$(CONFIG_MTD_AFS_PARTS)    += afs.o
index 302372c08b566cf61b7f0022aa059779bc123208..89a02f6f65dc1ae4c2752e6d941602c6a7295709 100644 (file)
@@ -162,8 +162,8 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
 }
 
 static int parse_afs_partitions(struct mtd_info *mtd,
-                         struct mtd_partition **pparts,
-                         unsigned long origin)
+                               struct mtd_partition **pparts,
+                               struct mtd_part_parser_data *data)
 {
        struct mtd_partition *parts;
        u_int mask, off, idx, sz;
index 6697a1ec72d067ec07a42c15986740ea33169095..f40ea4547554d93def59fb55f1aac233fb12528f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/bootmem.h>
 #include <linux/magic.h>
+#include <linux/module.h>
 
 #define AR7_PARTS      4
 #define ROOT_OFFSET    0xe0000
@@ -46,7 +47,7 @@ struct ar7_bin_rec {
 
 static int create_mtd_partitions(struct mtd_info *master,
                                 struct mtd_partition **pparts,
-                                unsigned long origin)
+                                struct mtd_part_parser_data *data)
 {
        struct ar7_bin_rec header;
        unsigned int offset;
index 23175edd5634ff16190b4d7be6ca74d3392e5e80..8d70895a58d6b424d34563e7f43a2a13df57ddfb 100644 (file)
@@ -145,8 +145,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
        if (((major << 8) | minor) < 0x3131) {
                /* CFI version 1.0 => don't trust bootloc */
 
-               DEBUG(MTD_DEBUG_LEVEL1,
-                       "%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
+               pr_debug("%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
                        map->name, cfi->mfr, cfi->id);
 
                /* AFAICS all 29LV400 with a bottom boot block have a device ID
@@ -166,8 +165,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
                         * the 8-bit device ID.
                         */
                        (cfi->mfr == CFI_MFR_MACRONIX)) {
-                       DEBUG(MTD_DEBUG_LEVEL1,
-                               "%s: Macronix MX29LV400C with bottom boot block"
+                       pr_debug("%s: Macronix MX29LV400C with bottom boot block"
                                " detected\n", map->name);
                        extp->TopBottom = 2;    /* bottom boot */
                } else
@@ -178,8 +176,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd)
                        extp->TopBottom = 2;    /* bottom boot */
                }
 
-               DEBUG(MTD_DEBUG_LEVEL1,
-                       "%s: AMD CFI PRI V%c.%c has no boot block field;"
+               pr_debug("%s: AMD CFI PRI V%c.%c has no boot block field;"
                        " deduced %s from Device ID\n", map->name, major, minor,
                        extp->TopBottom == 2 ? "bottom" : "top");
        }
@@ -191,7 +188,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
        if (cfi->cfiq->BufWriteTimeoutTyp) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
+               pr_debug("Using buffer write method\n" );
                mtd->write = cfi_amdstd_write_buffers;
        }
 }
@@ -443,8 +440,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
        mtd->writesize = 1;
        mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): write buffer size %d\n",
-               __func__, mtd->writebufsize);
+       pr_debug("MTD %s(): write buffer size %d\n", __func__,
+                       mtd->writebufsize);
 
        mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
 
@@ -1163,7 +1160,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+       pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
               __func__, adr, datum.x[0] );
 
        /*
@@ -1174,7 +1171,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
         */
        oldd = map_read(map, adr);
        if (map_word_equal(map, oldd, datum)) {
-               DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP\n",
+               pr_debug("MTD %s(): NOP\n",
                       __func__);
                goto op_done;
        }
@@ -1400,7 +1397,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 
        datum = map_word_load(map, buf);
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
+       pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
               __func__, adr, datum.x[0] );
 
        XIP_INVAL_CACHED_RANGE(map, adr, len);
@@ -1587,7 +1584,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
+       pr_debug("MTD %s(): ERASE 0x%.8lx\n",
               __func__, chip->start );
 
        XIP_INVAL_CACHED_RANGE(map, adr, map->size);
@@ -1675,7 +1672,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
                return ret;
        }
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
+       pr_debug("MTD %s(): ERASE 0x%.8lx\n",
               __func__, adr );
 
        XIP_INVAL_CACHED_RANGE(map, adr, len);
@@ -1801,8 +1798,7 @@ static int do_atmel_lock(struct map_info *map, struct flchip *chip,
                goto out_unlock;
        chip->state = FL_LOCKING;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
-             __func__, adr, len);
+       pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
 
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
                         cfi->device_type, NULL);
@@ -1837,8 +1833,7 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
                goto out_unlock;
        chip->state = FL_UNLOCKING;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
-             __func__, adr, len);
+       pr_debug("MTD %s(): LOCK 0x%08lx len %d\n", __func__, adr, len);
 
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
                         cfi->device_type, NULL);
index 5e3cc80128aa90beec305b168b02c50f56f3b6f8..89c6595454a508925fe6c5accf0fbd44d1af56f9 100644 (file)
@@ -34,8 +34,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
 
        /* Refuse the operation if the we cannot look behind the chip */
        if (chip->start < 0x400000) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                       "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
+               pr_debug( "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
                        __func__, chip->start );
                return -EIO;
        }
index ea832ea0e4aacac6840dbfcfa73a9f7e0262667e..c443f527a53a5d9dae069701c9b1e0c497e63999 100644 (file)
@@ -1914,11 +1914,10 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi)
         * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
         * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
         * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
-        * as they will ignore the writes and dont care what address
+        * as they will ignore the writes and don't care what address
         * the F0 is written to */
        if (cfi->addr_unlock1) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "reset unlock called %x %x \n",
+               pr_debug( "reset unlock called %x %x \n",
                       cfi->addr_unlock1,cfi->addr_unlock2);
                cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
                cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@@ -1941,7 +1940,7 @@ static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int in
        uint8_t uaddr;
 
        if (!(jedec_table[index].devtypes & cfi->device_type)) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n",
+               pr_debug("Rejecting potential %s with incompatible %d-bit device type\n",
                      jedec_table[index].name, 4 * (1<<cfi->device_type));
                return 0;
        }
@@ -2021,7 +2020,7 @@ static inline int jedec_match( uint32_t base,
                 * there aren't.
                 */
                if (finfo->dev_id > 0xff) {
-                       DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
+                       pr_debug("%s(): ID is not 8bit\n",
                               __func__);
                        goto match_done;
                }
@@ -2045,12 +2044,10 @@ static inline int jedec_match( uint32_t base,
        }
 
        /* the part size must fit in the memory window */
-       DEBUG( MTD_DEBUG_LEVEL3,
-              "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
+       pr_debug("MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
               __func__, base, 1 << finfo->dev_size, base + (1 << finfo->dev_size) );
        if ( base + cfi_interleave(cfi) * ( 1 << finfo->dev_size ) > map->size ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
+               pr_debug("MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
                       __func__, finfo->mfr_id, finfo->dev_id,
                       1 << finfo->dev_size );
                goto match_done;
@@ -2061,13 +2058,12 @@ static inline int jedec_match( uint32_t base,
 
        uaddr = finfo->uaddr;
 
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
+       pr_debug("MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
               __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
        if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
             && ( unlock_addrs[uaddr].addr1 / cfi->device_type != cfi->addr_unlock1 ||
                  unlock_addrs[uaddr].addr2 / cfi->device_type != cfi->addr_unlock2 ) ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                       "MTD %s(): 0x%.4x 0x%.4x did not match\n",
+               pr_debug("MTD %s(): 0x%.4x 0x%.4x did not match\n",
                        __func__,
                        unlock_addrs[uaddr].addr1,
                        unlock_addrs[uaddr].addr2);
@@ -2083,15 +2079,13 @@ static inline int jedec_match( uint32_t base,
         * FIXME - write a driver that takes all of the chip info as
         * module parameters, doesn't probe but forces a load.
         */
-       DEBUG( MTD_DEBUG_LEVEL3,
-              "MTD %s(): check ID's disappear when not in ID mode\n",
+       pr_debug("MTD %s(): check ID's disappear when not in ID mode\n",
               __func__ );
        jedec_reset( base, map, cfi );
        mfr = jedec_read_mfr( map, base, cfi );
        id = jedec_read_id( map, base, cfi );
        if ( mfr == cfi->mfr && id == cfi->id ) {
-               DEBUG( MTD_DEBUG_LEVEL3,
-                      "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
+               pr_debug("MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
                       "You might need to manually specify JEDEC parameters.\n",
                        __func__, cfi->mfr, cfi->id );
                goto match_done;
@@ -2104,7 +2098,7 @@ static inline int jedec_match( uint32_t base,
         * Put the device back in ID mode - only need to do this if we
         * were truly frobbing a real device.
         */
-       DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
+       pr_debug("MTD %s(): return to ID mode\n", __func__ );
        if (cfi->addr_unlock1) {
                cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
                cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
@@ -2167,13 +2161,11 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
 
                cfi->mfr = jedec_read_mfr(map, base, cfi);
                cfi->id = jedec_read_id(map, base, cfi);
-               DEBUG(MTD_DEBUG_LEVEL3,
-                     "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
+               pr_debug("Search for id:(%02x %02x) interleave(%d) type(%d)\n",
                        cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
                for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
                        if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
-                               DEBUG( MTD_DEBUG_LEVEL3,
-                                      "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
+                               pr_debug("MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
                                       __func__, cfi->mfr, cfi->id,
                                       cfi->addr_unlock1, cfi->addr_unlock2 );
                                if (!cfi_jedec_setup(map, cfi, i))
index e790f38893b00b2f0c0c645b3d66fd1b6a90651b..ddf9ec6d9168ed3848fdd249a67c2c2053b43444 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/bootmem.h>
+#include <linux/module.h>
 
 /* error message prefix */
 #define ERRP "mtd: "
@@ -188,10 +189,7 @@ static struct mtd_partition * newpart(char *s,
                             extra_mem_size;
                parts = kzalloc(alloc_size, GFP_KERNEL);
                if (!parts)
-               {
-                       printk(KERN_ERR ERRP "out of memory\n");
                        return NULL;
-               }
                extra_mem = (unsigned char *)(parts + *num_parts);
        }
        /* enter this partition (offset will be calculated later if it is zero at this point) */
@@ -316,8 +314,8 @@ static int mtdpart_setup_real(char *s)
  * the first one in the chain if a NULL mtd_id is passed in.
  */
 static int parse_cmdline_partitions(struct mtd_info *master,
-                             struct mtd_partition **pparts,
-                             unsigned long origin)
+                                   struct mtd_partition **pparts,
+                                   struct mtd_part_parser_data *data)
 {
        unsigned long offset;
        int i;
index 35081ce77fbdd0bd4260fd9a812ee6cae8dd08ca..283d887f78251168f40255fe80b788f6fba0b0fc 100644 (file)
@@ -249,6 +249,16 @@ config MTD_DOC2001PLUS
          under "NAND Flash Device Drivers" (currently that driver does not
          support all Millennium Plus devices).
 
+config MTD_DOCG3
+       tristate "M-Systems Disk-On-Chip G3"
+       ---help---
+         This provides an MTD device driver for the M-Systems DiskOnChip
+         G3 devices.
+
+         The driver provides access to G3 DiskOnChip, distributed by
+         M-Systems and now Sandisk. The support is very experimental,
+         and doesn't give access to any write operations.
+
 config MTD_DOCPROBE
        tristate
        select MTD_DOCECC
@@ -268,8 +278,7 @@ config MTD_DOCPROBE_ADVANCED
 config MTD_DOCPROBE_ADDRESS
        hex "Physical address of DiskOnChip" if MTD_DOCPROBE_ADVANCED
        depends on MTD_DOCPROBE
-       default "0x0000" if MTD_DOCPROBE_ADVANCED
-       default "0" if !MTD_DOCPROBE_ADVANCED
+       default "0x0"
        ---help---
          By default, the probe for DiskOnChip devices will look for a
          DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
index f3226b1d38fca15cbb9ace95a06e10dd9a6b2b8e..56c7cd462f11e33b191d73a6c3a7fe7d07e644b5 100644 (file)
@@ -5,6 +5,7 @@
 obj-$(CONFIG_MTD_DOC2000)      += doc2000.o
 obj-$(CONFIG_MTD_DOC2001)      += doc2001.o
 obj-$(CONFIG_MTD_DOC2001PLUS)  += doc2001plus.o
+obj-$(CONFIG_MTD_DOCG3)                += docg3.o
 obj-$(CONFIG_MTD_DOCPROBE)     += docprobe.o
 obj-$(CONFIG_MTD_DOCECC)       += docecc.o
 obj-$(CONFIG_MTD_SLRAM)                += slram.o
@@ -17,3 +18,5 @@ obj-$(CONFIG_MTD_BLOCK2MTD)   += block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)    += mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)       += m25p80.o
 obj-$(CONFIG_MTD_SST25L)       += sst25l.o
+
+CFLAGS_docg3.o                 += -I$(src)
\ No newline at end of file
index f7fbf6025ef286de5f7fc61c1d3eada86695073f..e9fad915121924e636c32480b7b699bd6f76379f 100644 (file)
@@ -82,8 +82,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
        void __iomem *docptr = doc->virtadr;
        unsigned long timeo = jiffies + (HZ * 10);
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
@@ -92,7 +91,7 @@ static int _DoC_WaitReady(struct DiskOnChip *doc)
                DoC_Delay(doc, 2);
 
                if (time_after(jiffies, timeo)) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+                       pr_debug("_DoC_WaitReady timed out.\n");
                        return -EIO;
                }
                udelay(1);
@@ -323,8 +322,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
 
        /* Reset the chip */
        if (DoC_Command(doc, NAND_CMD_RESET, CDSN_CTRL_WP)) {
-               DEBUG(MTD_DEBUG_LEVEL2,
-                     "DoC_Command (reset) for %d,%d returned true\n",
+               pr_debug("DoC_Command (reset) for %d,%d returned true\n",
                      floor, chip);
                return 0;
        }
@@ -332,8 +330,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
 
        /* Read the NAND chip ID: 1. Send ReadID command */
        if (DoC_Command(doc, NAND_CMD_READID, CDSN_CTRL_WP)) {
-               DEBUG(MTD_DEBUG_LEVEL2,
-                     "DoC_Command (ReadID) for %d,%d returned true\n",
+               pr_debug("DoC_Command (ReadID) for %d,%d returned true\n",
                      floor, chip);
                return 0;
        }
@@ -699,7 +696,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                        printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-                       /* Read the ECC syndrom through the DiskOnChip ECC
+                       /* Read the ECC syndrome through the DiskOnChip ECC
                           logic.  These syndrome will be all ZERO when there
                           is no error */
                        for (i = 0; i < 6; i++) {
@@ -930,7 +927,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
        uint8_t *buf = ops->oobbuf;
        size_t len = ops->len;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        ofs += ops->ooboffs;
 
@@ -1094,7 +1091,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
        struct DiskOnChip *this = mtd->priv;
        int ret;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        mutex_lock(&this->lock);
        ret = doc_write_oob_nolock(mtd, ofs + ops->ooboffs, ops->len,
index 241192f05bc8d2cb8bcc601f2c61b06cd815274e..a3f7a27499be86a711b4c57018b8e8b958671969 100644 (file)
@@ -55,15 +55,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
 {
        unsigned short c = 0xffff;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
                ;
 
        if (c == 0)
-               DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+               pr_debug("_DoC_WaitReady timed out.\n");
 
        return (c == 0);
 }
@@ -464,7 +463,7 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-               /* Read the ECC syndrom through the DiskOnChip ECC logic.
+               /* Read the ECC syndrome through the DiskOnChip ECC logic.
                   These syndrome will be all ZERO when there is no error */
                for (i = 0; i < 6; i++) {
                        syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
@@ -632,7 +631,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
        uint8_t *buf = ops->oobbuf;
        size_t len = ops->len;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        ofs += ops->ooboffs;
 
@@ -690,7 +689,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
        uint8_t *buf = ops->oobbuf;
        size_t len = ops->len;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        ofs += ops->ooboffs;
 
index 09ae0adc3ad07be984d9b936d9eda7fe24e0e86d..99351bc3e0ed32207ecf294ff03bad1b322ea74c 100644 (file)
@@ -61,15 +61,14 @@ static int _DoC_WaitReady(void __iomem * docptr)
 {
        unsigned int c = 0xffff;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "_DoC_WaitReady called for out-of-line wait\n");
+       pr_debug("_DoC_WaitReady called for out-of-line wait\n");
 
        /* Out-of-line routine to wait for chip response */
        while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
                ;
 
        if (c == 0)
-               DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+               pr_debug("_DoC_WaitReady timed out.\n");
 
        return (c == 0);
 }
@@ -655,7 +654,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 #ifdef ECC_DEBUG
                printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
-               /* Read the ECC syndrom through the DiskOnChip ECC logic.
+               /* Read the ECC syndrome through the DiskOnChip ECC logic.
                   These syndrome will be all ZERO when there is no error */
                for (i = 0; i < 6; i++)
                        syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
@@ -835,7 +834,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
        uint8_t *buf = ops->oobbuf;
        size_t len = ops->len;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        ofs += ops->ooboffs;
 
@@ -920,7 +919,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
        uint8_t *buf = ops->oobbuf;
        size_t len = ops->len;
 
-       BUG_ON(ops->mode != MTD_OOB_PLACE);
+       BUG_ON(ops->mode != MTD_OPS_PLACE_OOB);
 
        ofs += ops->ooboffs;
 
index 37ef29a73ee43993ded8414fb8dcbaafdbf1c20a..4a1c39b6f37df4276b2fb27749aadcd37995d235 100644 (file)
@@ -2,7 +2,7 @@
  * ECC algorithm for M-systems disk on chip. We use the excellent Reed
  * Solmon code of Phil Karn (karn@ka9q.ampr.org) available under the
  * GNU GPL License. The rest is simply to convert the disk on chip
- * syndrom into a standard syndom.
+ * syndrome into a standard syndome.
  *
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
  * Copyright (C) 2000 Netgem S.A.
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
new file mode 100644 (file)
index 0000000..bdcf5df
--- /dev/null
@@ -0,0 +1,1114 @@
+/*
+ * Handles the M-Systems DiskOnChip G3 chip
+ *
+ * Copyright (C) 2011 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define CREATE_TRACE_POINTS
+#include "docg3.h"
+
+/*
+ * This driver handles the DiskOnChip G3 flash memory.
+ *
+ * As no specification is available from M-Systems/Sandisk, this drivers lacks
+ * several functions available on the chip, as :
+ *  - block erase
+ *  - page write
+ *  - IPL write
+ *  - ECC fixing (lack of BCH algorith understanding)
+ *  - powerdown / powerup
+ *
+ * The bus data width (8bits versus 16bits) is not handled (if_cfg flag), and
+ * the driver assumes a 16bits data bus.
+ *
+ * DocG3 relies on 2 ECC algorithms, which are handled in hardware :
+ *  - a 1 byte Hamming code stored in the OOB for each page
+ *  - a 7 bytes BCH code stored in the OOB for each page
+ * The BCH part is only used for check purpose, no correction is available as
+ * some information is missing. What is known is that :
+ *  - BCH is in GF(2^14)
+ *  - BCH is over data of 520 bytes (512 page + 7 page_info bytes
+ *                                   + 1 hamming byte)
+ *  - BCH can correct up to 4 bits (t = 4)
+ *  - BCH syndroms are calculated in hardware, and checked in hardware as well
+ *
+ */
+
+static inline u8 doc_readb(struct docg3 *docg3, u16 reg)
+{
+       u8 val = readb(docg3->base + reg);
+
+       trace_docg3_io(0, 8, reg, (int)val);
+       return val;
+}
+
+static inline u16 doc_readw(struct docg3 *docg3, u16 reg)
+{
+       u16 val = readw(docg3->base + reg);
+
+       trace_docg3_io(0, 16, reg, (int)val);
+       return val;
+}
+
+static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg)
+{
+       writeb(val, docg3->base + reg);
+       trace_docg3_io(1, 16, reg, val);
+}
+
+static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg)
+{
+       writew(val, docg3->base + reg);
+       trace_docg3_io(1, 16, reg, val);
+}
+
+static inline void doc_flash_command(struct docg3 *docg3, u8 cmd)
+{
+       doc_writeb(docg3, cmd, DOC_FLASHCOMMAND);
+}
+
+static inline void doc_flash_sequence(struct docg3 *docg3, u8 seq)
+{
+       doc_writeb(docg3, seq, DOC_FLASHSEQUENCE);
+}
+
+static inline void doc_flash_address(struct docg3 *docg3, u8 addr)
+{
+       doc_writeb(docg3, addr, DOC_FLASHADDRESS);
+}
+
+static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL };
+
+static int doc_register_readb(struct docg3 *docg3, int reg)
+{
+       u8 val;
+
+       doc_writew(docg3, reg, DOC_READADDRESS);
+       val = doc_readb(docg3, reg);
+       doc_vdbg("Read register %04x : %02x\n", reg, val);
+       return val;
+}
+
+static int doc_register_readw(struct docg3 *docg3, int reg)
+{
+       u16 val;
+
+       doc_writew(docg3, reg, DOC_READADDRESS);
+       val = doc_readw(docg3, reg);
+       doc_vdbg("Read register %04x : %04x\n", reg, val);
+       return val;
+}
+
+/**
+ * doc_delay - delay docg3 operations
+ * @docg3: the device
+ * @nbNOPs: the number of NOPs to issue
+ *
+ * As no specification is available, the right timings between chip commands are
+ * unknown. The only available piece of information are the observed nops on a
+ * working docg3 chip.
+ * Therefore, doc_delay relies on a busy loop of NOPs, instead of scheduler
+ * friendlier msleep() functions or blocking mdelay().
+ */
+static void doc_delay(struct docg3 *docg3, int nbNOPs)
+{
+       int i;
+
+       doc_dbg("NOP x %d\n", nbNOPs);
+       for (i = 0; i < nbNOPs; i++)
+               doc_writeb(docg3, 0, DOC_NOP);
+}
+
+static int is_prot_seq_error(struct docg3 *docg3)
+{
+       int ctrl;
+
+       ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
+       return ctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR);
+}
+
+static int doc_is_ready(struct docg3 *docg3)
+{
+       int ctrl;
+
+       ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
+       return ctrl & DOC_CTRL_FLASHREADY;
+}
+
+static int doc_wait_ready(struct docg3 *docg3)
+{
+       int maxWaitCycles = 100;
+
+       do {
+               doc_delay(docg3, 4);
+               cpu_relax();
+       } while (!doc_is_ready(docg3) && maxWaitCycles--);
+       doc_delay(docg3, 2);
+       if (maxWaitCycles > 0)
+               return 0;
+       else
+               return -EIO;
+}
+
+static int doc_reset_seq(struct docg3 *docg3)
+{
+       int ret;
+
+       doc_writeb(docg3, 0x10, DOC_FLASHCONTROL);
+       doc_flash_sequence(docg3, DOC_SEQ_RESET);
+       doc_flash_command(docg3, DOC_CMD_RESET);
+       doc_delay(docg3, 2);
+       ret = doc_wait_ready(docg3);
+
+       doc_dbg("doc_reset_seq() -> isReady=%s\n", ret ? "false" : "true");
+       return ret;
+}
+
+/**
+ * doc_read_data_area - Read data from data area
+ * @docg3: the device
+ * @buf: the buffer to fill in
+ * @len: the lenght to read
+ * @first: first time read, DOC_READADDRESS should be set
+ *
+ * Reads bytes from flash data. Handles the single byte / even bytes reads.
+ */
+static void doc_read_data_area(struct docg3 *docg3, void *buf, int len,
+                              int first)
+{
+       int i, cdr, len4;
+       u16 data16, *dst16;
+       u8 data8, *dst8;
+
+       doc_dbg("doc_read_data_area(buf=%p, len=%d)\n", buf, len);
+       cdr = len & 0x3;
+       len4 = len - cdr;
+
+       if (first)
+               doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS);
+       dst16 = buf;
+       for (i = 0; i < len4; i += 2) {
+               data16 = doc_readw(docg3, DOC_IOSPACE_DATA);
+               *dst16 = data16;
+               dst16++;
+       }
+
+       if (cdr) {
+               doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE,
+                          DOC_READADDRESS);
+               doc_delay(docg3, 1);
+               dst8 = (u8 *)dst16;
+               for (i = 0; i < cdr; i++) {
+                       data8 = doc_readb(docg3, DOC_IOSPACE_DATA);
+                       *dst8 = data8;
+                       dst8++;
+               }
+       }
+}
+
+/**
+ * doc_set_data_mode - Sets the flash to reliable data mode
+ * @docg3: the device
+ *
+ * The reliable data mode is a bit slower than the fast mode, but less errors
+ * occur.  Entering the reliable mode cannot be done without entering the fast
+ * mode first.
+ */
+static void doc_set_reliable_mode(struct docg3 *docg3)
+{
+       doc_dbg("doc_set_reliable_mode()\n");
+       doc_flash_sequence(docg3, DOC_SEQ_SET_MODE);
+       doc_flash_command(docg3, DOC_CMD_FAST_MODE);
+       doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE);
+       doc_delay(docg3, 2);
+}
+
+/**
+ * doc_set_asic_mode - Set the ASIC mode
+ * @docg3: the device
+ * @mode: the mode
+ *
+ * The ASIC can work in 3 modes :
+ *  - RESET: all registers are zeroed
+ *  - NORMAL: receives and handles commands
+ *  - POWERDOWN: minimal poweruse, flash parts shut off
+ */
+static void doc_set_asic_mode(struct docg3 *docg3, u8 mode)
+{
+       int i;
+
+       for (i = 0; i < 12; i++)
+               doc_readb(docg3, DOC_IOSPACE_IPL);
+
+       mode |= DOC_ASICMODE_MDWREN;
+       doc_dbg("doc_set_asic_mode(%02x)\n", mode);
+       doc_writeb(docg3, mode, DOC_ASICMODE);
+       doc_writeb(docg3, ~mode, DOC_ASICMODECONFIRM);
+       doc_delay(docg3, 1);
+}
+
+/**
+ * doc_set_device_id - Sets the devices id for cascaded G3 chips
+ * @docg3: the device
+ * @id: the chip to select (amongst 0, 1, 2, 3)
+ *
+ * There can be 4 cascaded G3 chips. This function selects the one which will
+ * should be the active one.
+ */
+static void doc_set_device_id(struct docg3 *docg3, int id)
+{
+       u8 ctrl;
+
+       doc_dbg("doc_set_device_id(%d)\n", id);
+       doc_writeb(docg3, id, DOC_DEVICESELECT);
+       ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
+
+       ctrl &= ~DOC_CTRL_VIOLATION;
+       ctrl |= DOC_CTRL_CE;
+       doc_writeb(docg3, ctrl, DOC_FLASHCONTROL);
+}
+
+/**
+ * doc_set_extra_page_mode - Change flash page layout
+ * @docg3: the device
+ *
+ * Normally, the flash page is split into the data (512 bytes) and the out of
+ * band data (16 bytes). For each, 4 more bytes can be accessed, where the wear
+ * leveling counters are stored.  To access this last area of 4 bytes, a special
+ * mode must be input to the flash ASIC.
+ *
+ * Returns 0 if no error occured, -EIO else.
+ */
+static int doc_set_extra_page_mode(struct docg3 *docg3)
+{
+       int fctrl;
+
+       doc_dbg("doc_set_extra_page_mode()\n");
+       doc_flash_sequence(docg3, DOC_SEQ_PAGE_SIZE_532);
+       doc_flash_command(docg3, DOC_CMD_PAGE_SIZE_532);
+       doc_delay(docg3, 2);
+
+       fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
+       if (fctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR))
+               return -EIO;
+       else
+               return 0;
+}
+
+/**
+ * doc_seek - Set both flash planes to the specified block, page for reading
+ * @docg3: the device
+ * @block0: the first plane block index
+ * @block1: the second plane block index
+ * @page: the page index within the block
+ * @wear: if true, read will occur on the 4 extra bytes of the wear area
+ * @ofs: offset in page to read
+ *
+ * Programs the flash even and odd planes to the specific block and page.
+ * Alternatively, programs the flash to the wear area of the specified page.
+ */
+static int doc_read_seek(struct docg3 *docg3, int block0, int block1, int page,
+                        int wear, int ofs)
+{
+       int sector, ret = 0;
+
+       doc_dbg("doc_seek(blocks=(%d,%d), page=%d, ofs=%d, wear=%d)\n",
+               block0, block1, page, ofs, wear);
+
+       if (!wear && (ofs < 2 * DOC_LAYOUT_PAGE_SIZE)) {
+               doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1);
+               doc_flash_command(docg3, DOC_CMD_READ_PLANE1);
+               doc_delay(docg3, 2);
+       } else {
+               doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2);
+               doc_flash_command(docg3, DOC_CMD_READ_PLANE2);
+               doc_delay(docg3, 2);
+       }
+
+       doc_set_reliable_mode(docg3);
+       if (wear)
+               ret = doc_set_extra_page_mode(docg3);
+       if (ret)
+               goto out;
+
+       sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK);
+       doc_flash_sequence(docg3, DOC_SEQ_READ);
+       doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR);
+       doc_delay(docg3, 1);
+       doc_flash_address(docg3, sector & 0xff);
+       doc_flash_address(docg3, (sector >> 8) & 0xff);
+       doc_flash_address(docg3, (sector >> 16) & 0xff);
+       doc_delay(docg3, 1);
+
+       sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK);
+       doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR);
+       doc_delay(docg3, 1);
+       doc_flash_address(docg3, sector & 0xff);
+       doc_flash_address(docg3, (sector >> 8) & 0xff);
+       doc_flash_address(docg3, (sector >> 16) & 0xff);
+       doc_delay(docg3, 2);
+
+out:
+       return ret;
+}
+
+/**
+ * doc_read_page_ecc_init - Initialize hardware ECC engine
+ * @docg3: the device
+ * @len: the number of bytes covered by the ECC (BCH covered)
+ *
+ * The function does initialize the hardware ECC engine to compute the Hamming
+ * ECC (on 1 byte) and the BCH Syndroms (on 7 bytes).
+ *
+ * Return 0 if succeeded, -EIO on error
+ */
+static int doc_read_page_ecc_init(struct docg3 *docg3, int len)
+{
+       doc_writew(docg3, DOC_ECCCONF0_READ_MODE
+                  | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE
+                  | (len & DOC_ECCCONF0_DATA_BYTES_MASK),
+                  DOC_ECCCONF0);
+       doc_delay(docg3, 4);
+       doc_register_readb(docg3, DOC_FLASHCONTROL);
+       return doc_wait_ready(docg3);
+}
+
+/**
+ * doc_read_page_prepare - Prepares reading data from a flash page
+ * @docg3: the device
+ * @block0: the first plane block index on flash memory
+ * @block1: the second plane block index on flash memory
+ * @page: the page index in the block
+ * @offset: the offset in the page (must be a multiple of 4)
+ *
+ * Prepares the page to be read in the flash memory :
+ *   - tell ASIC to map the flash pages
+ *   - tell ASIC to be in read mode
+ *
+ * After a call to this method, a call to doc_read_page_finish is mandatory,
+ * to end the read cycle of the flash.
+ *
+ * Read data from a flash page. The length to be read must be between 0 and
+ * (page_size + oob_size + wear_size), ie. 532, and a multiple of 4 (because
+ * the extra bytes reading is not implemented).
+ *
+ * As pages are grouped by 2 (in 2 planes), reading from a page must be done
+ * in two steps:
+ *  - one read of 512 bytes at offset 0
+ *  - one read of 512 bytes at offset 512 + 16
+ *
+ * Returns 0 if successful, -EIO if a read error occured.
+ */
+static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1,
+                                int page, int offset)
+{
+       int wear_area = 0, ret = 0;
+
+       doc_dbg("doc_read_page_prepare(blocks=(%d,%d), page=%d, ofsInPage=%d)\n",
+               block0, block1, page, offset);
+       if (offset >= DOC_LAYOUT_WEAR_OFFSET)
+               wear_area = 1;
+       if (!wear_area && offset > (DOC_LAYOUT_PAGE_OOB_SIZE * 2))
+               return -EINVAL;
+
+       doc_set_device_id(docg3, docg3->device_id);
+       ret = doc_reset_seq(docg3);
+       if (ret)
+               goto err;
+
+       /* Program the flash address block and page */
+       ret = doc_read_seek(docg3, block0, block1, page, wear_area, offset);
+       if (ret)
+               goto err;
+
+       doc_flash_command(docg3, DOC_CMD_READ_ALL_PLANES);
+       doc_delay(docg3, 2);
+       doc_wait_ready(docg3);
+
+       doc_flash_command(docg3, DOC_CMD_SET_ADDR_READ);
+       doc_delay(docg3, 1);
+       if (offset >= DOC_LAYOUT_PAGE_SIZE * 2)
+               offset -= 2 * DOC_LAYOUT_PAGE_SIZE;
+       doc_flash_address(docg3, offset >> 2);
+       doc_delay(docg3, 1);
+       doc_wait_ready(docg3);
+
+       doc_flash_command(docg3, DOC_CMD_READ_FLASH);
+
+       return 0;
+err:
+       doc_writeb(docg3, 0, DOC_DATAEND);
+       doc_delay(docg3, 2);
+       return -EIO;
+}
+
+/**
+ * doc_read_page_getbytes - Reads bytes from a prepared page
+ * @docg3: the device
+ * @len: the number of bytes to be read (must be a multiple of 4)
+ * @buf: the buffer to be filled in
+ * @first: 1 if first time read, DOC_READADDRESS should be set
+ *
+ */
+static int doc_read_page_getbytes(struct docg3 *docg3, int len, u_char *buf,
+                                 int first)
+{
+       doc_read_data_area(docg3, buf, len, first);
+       doc_delay(docg3, 2);
+       return len;
+}
+
+/**
+ * doc_get_hw_bch_syndroms - Get hardware calculated BCH syndroms
+ * @docg3: the device
+ * @syns:  the array of 7 integers where the syndroms will be stored
+ */
+static void doc_get_hw_bch_syndroms(struct docg3 *docg3, int *syns)
+{
+       int i;
+
+       for (i = 0; i < DOC_ECC_BCH_SIZE; i++)
+               syns[i] = doc_register_readb(docg3, DOC_BCH_SYNDROM(i));
+}
+
+/**
+ * doc_read_page_finish - Ends reading of a flash page
+ * @docg3: the device
+ *
+ * As a side effect, resets the chip selector to 0. This ensures that after each
+ * read operation, the floor 0 is selected. Therefore, if the systems halts, the
+ * reboot will boot on floor 0, where the IPL is.
+ */
+static void doc_read_page_finish(struct docg3 *docg3)
+{
+       doc_writeb(docg3, 0, DOC_DATAEND);
+       doc_delay(docg3, 2);
+       doc_set_device_id(docg3, 0);
+}
+
+/**
+ * calc_block_sector - Calculate blocks, pages and ofs.
+
+ * @from: offset in flash
+ * @block0: first plane block index calculated
+ * @block1: second plane block index calculated
+ * @page: page calculated
+ * @ofs: offset in page
+ */
+static void calc_block_sector(loff_t from, int *block0, int *block1, int *page,
+                             int *ofs)
+{
+       uint sector;
+
+       sector = from / DOC_LAYOUT_PAGE_SIZE;
+       *block0 = sector / (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES)
+               * DOC_LAYOUT_NBPLANES;
+       *block1 = *block0 + 1;
+       *page = sector % (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES);
+       *page /= DOC_LAYOUT_NBPLANES;
+       if (sector % 2)
+               *ofs = DOC_LAYOUT_PAGE_OOB_SIZE;
+       else
+               *ofs = 0;
+}
+
+/**
+ * doc_read - Read bytes from flash
+ * @mtd: the device
+ * @from: the offset from first block and first page, in bytes, aligned on page
+ *        size
+ * @len: the number of bytes to read (must be a multiple of 4)
+ * @retlen: the number of bytes actually read
+ * @buf: the filled in buffer
+ *
+ * Reads flash memory pages. This function does not read the OOB chunk, but only
+ * the page data.
+ *
+ * Returns 0 if read successfull, of -EIO, -EINVAL if an error occured
+ */
+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
+            size_t *retlen, u_char *buf)
+{
+       struct docg3 *docg3 = mtd->priv;
+       int block0, block1, page, readlen, ret, ofs = 0;
+       int syn[DOC_ECC_BCH_SIZE], eccconf1;
+       u8 oob[DOC_LAYOUT_OOB_SIZE];
+
+       ret = -EINVAL;
+       doc_dbg("doc_read(from=%lld, len=%zu, buf=%p)\n", from, len, buf);
+       if (from % DOC_LAYOUT_PAGE_SIZE)
+               goto err;
+       if (len % 4)
+               goto err;
+       calc_block_sector(from, &block0, &block1, &page, &ofs);
+       if (block1 > docg3->max_block)
+               goto err;
+
+       *retlen = 0;
+       ret = 0;
+       readlen = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
+       while (!ret && len > 0) {
+               readlen = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE);
+               ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
+               if (ret < 0)
+                       goto err;
+               ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_COVERED_BYTES);
+               if (ret < 0)
+                       goto err_in_read;
+               ret = doc_read_page_getbytes(docg3, readlen, buf, 1);
+               if (ret < readlen)
+                       goto err_in_read;
+               ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE,
+                                            oob, 0);
+               if (ret < DOC_LAYOUT_OOB_SIZE)
+                       goto err_in_read;
+
+               *retlen += readlen;
+               buf += readlen;
+               len -= readlen;
+
+               ofs ^= DOC_LAYOUT_PAGE_OOB_SIZE;
+               if (ofs == 0)
+                       page += 2;
+               if (page > DOC_ADDR_PAGE_MASK) {
+                       page = 0;
+                       block0 += 2;
+                       block1 += 2;
+               }
+
+               /*
+                * There should be a BCH bitstream fixing algorithm here ...
+                * By now, a page read failure is triggered by BCH error
+                */
+               doc_get_hw_bch_syndroms(docg3, syn);
+               eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1);
+
+               doc_dbg("OOB - INFO: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                        oob[0], oob[1], oob[2], oob[3], oob[4],
+                        oob[5], oob[6]);
+               doc_dbg("OOB - HAMMING: %02x\n", oob[7]);
+               doc_dbg("OOB - BCH_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                        oob[8], oob[9], oob[10], oob[11], oob[12],
+                        oob[13], oob[14]);
+               doc_dbg("OOB - UNUSED: %02x\n", oob[15]);
+               doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1);
+               doc_dbg("ECC BCH syndrom: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                       syn[0], syn[1], syn[2], syn[3], syn[4], syn[5], syn[6]);
+
+               ret = -EBADMSG;
+               if (block0 >= DOC_LAYOUT_BLOCK_FIRST_DATA) {
+                       if (eccconf1 & DOC_ECCCONF1_BCH_SYNDROM_ERR)
+                               goto err_in_read;
+                       if (is_prot_seq_error(docg3))
+                               goto err_in_read;
+               }
+               doc_read_page_finish(docg3);
+       }
+
+       return 0;
+err_in_read:
+       doc_read_page_finish(docg3);
+err:
+       return ret;
+}
+
+/**
+ * doc_read_oob - Read out of band bytes from flash
+ * @mtd: the device
+ * @from: the offset from first block and first page, in bytes, aligned on page
+ *        size
+ * @ops: the mtd oob structure
+ *
+ * Reads flash memory OOB area of pages.
+ *
+ * Returns 0 if read successfull, of -EIO, -EINVAL if an error occured
+ */
+static int doc_read_oob(struct mtd_info *mtd, loff_t from,
+                       struct mtd_oob_ops *ops)
+{
+       struct docg3 *docg3 = mtd->priv;
+       int block0, block1, page, ofs, ret;
+       u8 *buf = ops->oobbuf;
+       size_t len = ops->ooblen;
+
+       doc_dbg("doc_read_oob(from=%lld, buf=%p, len=%zu)\n", from, buf, len);
+       if (len != DOC_LAYOUT_OOB_SIZE)
+               return -EINVAL;
+
+       switch (ops->mode) {
+       case MTD_OPS_PLACE_OOB:
+               buf += ops->ooboffs;
+               break;
+       default:
+               break;
+       }
+
+       calc_block_sector(from, &block0, &block1, &page, &ofs);
+       if (block1 > docg3->max_block)
+               return -EINVAL;
+
+       ret = doc_read_page_prepare(docg3, block0, block1, page,
+                                   ofs + DOC_LAYOUT_PAGE_SIZE);
+       if (!ret)
+               ret = doc_read_page_ecc_init(docg3, DOC_LAYOUT_OOB_SIZE);
+       if (!ret)
+               ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE,
+                                            buf, 1);
+       doc_read_page_finish(docg3);
+
+       if (ret > 0)
+               ops->oobretlen = ret;
+       else
+               ops->oobretlen = 0;
+       return (ret > 0) ? 0 : ret;
+}
+
+static int doc_reload_bbt(struct docg3 *docg3)
+{
+       int block = DOC_LAYOUT_BLOCK_BBT;
+       int ret = 0, nbpages, page;
+       u_char *buf = docg3->bbt;
+
+       nbpages = DIV_ROUND_UP(docg3->max_block + 1, 8 * DOC_LAYOUT_PAGE_SIZE);
+       for (page = 0; !ret && (page < nbpages); page++) {
+               ret = doc_read_page_prepare(docg3, block, block + 1,
+                                           page + DOC_LAYOUT_PAGE_BBT, 0);
+               if (!ret)
+                       ret = doc_read_page_ecc_init(docg3,
+                                                    DOC_LAYOUT_PAGE_SIZE);
+               if (!ret)
+                       doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE,
+                                              buf, 1);
+               buf += DOC_LAYOUT_PAGE_SIZE;
+       }
+       doc_read_page_finish(docg3);
+       return ret;
+}
+
+/**
+ * doc_block_isbad - Checks whether a block is good or not
+ * @mtd: the device
+ * @from: the offset to find the correct block
+ *
+ * Returns 1 if block is bad, 0 if block is good
+ */
+static int doc_block_isbad(struct mtd_info *mtd, loff_t from)
+{
+       struct docg3 *docg3 = mtd->priv;
+       int block0, block1, page, ofs, is_good;
+
+       calc_block_sector(from, &block0, &block1, &page, &ofs);
+       doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n",
+               from, block0, block1, page, ofs);
+
+       if (block0 < DOC_LAYOUT_BLOCK_FIRST_DATA)
+               return 0;
+       if (block1 > docg3->max_block)
+               return -EINVAL;
+
+       is_good = docg3->bbt[block0 >> 3] & (1 << (block0 & 0x7));
+       return !is_good;
+}
+
+/**
+ * doc_get_erase_count - Get block erase count
+ * @docg3: the device
+ * @from: the offset in which the block is.
+ *
+ * Get the number of times a block was erased. The number is the maximum of
+ * erase times between first and second plane (which should be equal normally).
+ *
+ * Returns The number of erases, or -EINVAL or -EIO on error.
+ */
+static int doc_get_erase_count(struct docg3 *docg3, loff_t from)
+{
+       u8 buf[DOC_LAYOUT_WEAR_SIZE];
+       int ret, plane1_erase_count, plane2_erase_count;
+       int block0, block1, page, ofs;
+
+       doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf);
+       if (from % DOC_LAYOUT_PAGE_SIZE)
+               return -EINVAL;
+       calc_block_sector(from, &block0, &block1, &page, &ofs);
+       if (block1 > docg3->max_block)
+               return -EINVAL;
+
+       ret = doc_reset_seq(docg3);
+       if (!ret)
+               ret = doc_read_page_prepare(docg3, block0, block1, page,
+                                           ofs + DOC_LAYOUT_WEAR_OFFSET);
+       if (!ret)
+               ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_WEAR_SIZE,
+                                            buf, 1);
+       doc_read_page_finish(docg3);
+
+       if (ret || (buf[0] != DOC_ERASE_MARK) || (buf[2] != DOC_ERASE_MARK))
+               return -EIO;
+       plane1_erase_count = (u8)(~buf[1]) | ((u8)(~buf[4]) << 8)
+               | ((u8)(~buf[5]) << 16);
+       plane2_erase_count = (u8)(~buf[3]) | ((u8)(~buf[6]) << 8)
+               | ((u8)(~buf[7]) << 16);
+
+       return max(plane1_erase_count, plane2_erase_count);
+}
+
+/*
+ * Debug sysfs entries
+ */
+static int dbg_flashctrl_show(struct seq_file *s, void *p)
+{
+       struct docg3 *docg3 = (struct docg3 *)s->private;
+
+       int pos = 0;
+       u8 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL);
+
+       pos += seq_printf(s,
+                "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n",
+                fctrl,
+                fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-",
+                fctrl & DOC_CTRL_CE ? "active" : "inactive",
+                fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-",
+                fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-",
+                fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready");
+       return pos;
+}
+DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show);
+
+static int dbg_asicmode_show(struct seq_file *s, void *p)
+{
+       struct docg3 *docg3 = (struct docg3 *)s->private;
+
+       int pos = 0;
+       int pctrl = doc_register_readb(docg3, DOC_ASICMODE);
+       int mode = pctrl & 0x03;
+
+       pos += seq_printf(s,
+                        "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (",
+                        pctrl,
+                        pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0,
+                        pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0,
+                        pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0,
+                        pctrl & DOC_ASICMODE_MDWREN ? 1 : 0,
+                        pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0,
+                        mode >> 1, mode & 0x1);
+
+       switch (mode) {
+       case DOC_ASICMODE_RESET:
+               pos += seq_printf(s, "reset");
+               break;
+       case DOC_ASICMODE_NORMAL:
+               pos += seq_printf(s, "normal");
+               break;
+       case DOC_ASICMODE_POWERDOWN:
+               pos += seq_printf(s, "powerdown");
+               break;
+       }
+       pos += seq_printf(s, ")\n");
+       return pos;
+}
+DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show);
+
+static int dbg_device_id_show(struct seq_file *s, void *p)
+{
+       struct docg3 *docg3 = (struct docg3 *)s->private;
+       int pos = 0;
+       int id = doc_register_readb(docg3, DOC_DEVICESELECT);
+
+       pos += seq_printf(s, "DeviceId = %d\n", id);
+       return pos;
+}
+DEBUGFS_RO_ATTR(device_id, dbg_device_id_show);
+
+static int dbg_protection_show(struct seq_file *s, void *p)
+{
+       struct docg3 *docg3 = (struct docg3 *)s->private;
+       int pos = 0;
+       int protect = doc_register_readb(docg3, DOC_PROTECTION);
+       int dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS);
+       int dps0_low = doc_register_readb(docg3, DOC_DPS0_ADDRLOW);
+       int dps0_high = doc_register_readb(docg3, DOC_DPS0_ADDRHIGH);
+       int dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS);
+       int dps1_low = doc_register_readb(docg3, DOC_DPS1_ADDRLOW);
+       int dps1_high = doc_register_readb(docg3, DOC_DPS1_ADDRHIGH);
+
+       pos += seq_printf(s, "Protection = 0x%02x (",
+                        protect);
+       if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK)
+               pos += seq_printf(s, "FOUNDRY_OTP_LOCK,");
+       if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK)
+               pos += seq_printf(s, "CUSTOMER_OTP_LOCK,");
+       if (protect & DOC_PROTECT_LOCK_INPUT)
+               pos += seq_printf(s, "LOCK_INPUT,");
+       if (protect & DOC_PROTECT_STICKY_LOCK)
+               pos += seq_printf(s, "STICKY_LOCK,");
+       if (protect & DOC_PROTECT_PROTECTION_ENABLED)
+               pos += seq_printf(s, "PROTECTION ON,");
+       if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK)
+               pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,");
+       if (protect & DOC_PROTECT_PROTECTION_ERROR)
+               pos += seq_printf(s, "PROTECT_ERR,");
+       else
+               pos += seq_printf(s, "NO_PROTECT_ERR");
+       pos += seq_printf(s, ")\n");
+
+       pos += seq_printf(s, "DPS0 = 0x%02x : "
+                        "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, "
+                        "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n",
+                        dps0, dps0_low, dps0_high,
+                        !!(dps0 & DOC_DPS_OTP_PROTECTED),
+                        !!(dps0 & DOC_DPS_READ_PROTECTED),
+                        !!(dps0 & DOC_DPS_WRITE_PROTECTED),
+                        !!(dps0 & DOC_DPS_HW_LOCK_ENABLED),
+                        !!(dps0 & DOC_DPS_KEY_OK));
+       pos += seq_printf(s, "DPS1 = 0x%02x : "
+                        "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, "
+                        "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n",
+                        dps1, dps1_low, dps1_high,
+                        !!(dps1 & DOC_DPS_OTP_PROTECTED),
+                        !!(dps1 & DOC_DPS_READ_PROTECTED),
+                        !!(dps1 & DOC_DPS_WRITE_PROTECTED),
+                        !!(dps1 & DOC_DPS_HW_LOCK_ENABLED),
+                        !!(dps1 & DOC_DPS_KEY_OK));
+       return pos;
+}
+DEBUGFS_RO_ATTR(protection, dbg_protection_show);
+
+static int __init doc_dbg_register(struct docg3 *docg3)
+{
+       struct dentry *root, *entry;
+
+       root = debugfs_create_dir("docg3", NULL);
+       if (!root)
+               return -ENOMEM;
+
+       entry = debugfs_create_file("flashcontrol", S_IRUSR, root, docg3,
+                                 &flashcontrol_fops);
+       if (entry)
+               entry = debugfs_create_file("asic_mode", S_IRUSR, root,
+                                           docg3, &asic_mode_fops);
+       if (entry)
+               entry = debugfs_create_file("device_id", S_IRUSR, root,
+                                           docg3, &device_id_fops);
+       if (entry)
+               entry = debugfs_create_file("protection", S_IRUSR, root,
+                                           docg3, &protection_fops);
+       if (entry) {
+               docg3->debugfs_root = root;
+               return 0;
+       } else {
+               debugfs_remove_recursive(root);
+               return -ENOMEM;
+       }
+}
+
+static void __exit doc_dbg_unregister(struct docg3 *docg3)
+{
+       debugfs_remove_recursive(docg3->debugfs_root);
+}
+
+/**
+ * doc_set_driver_info - Fill the mtd_info structure and docg3 structure
+ * @chip_id: The chip ID of the supported chip
+ * @mtd: The structure to fill
+ */
+static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
+{
+       struct docg3 *docg3 = mtd->priv;
+       int cfg;
+
+       cfg = doc_register_readb(docg3, DOC_CONFIGURATION);
+       docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0);
+
+       switch (chip_id) {
+       case DOC_CHIPID_G3:
+               mtd->name = "DiskOnChip G3";
+               docg3->max_block = 2047;
+               break;
+       }
+       mtd->type = MTD_NANDFLASH;
+       /*
+        * Once write methods are added, the correct flags will be set.
+        * mtd->flags = MTD_CAP_NANDFLASH;
+        */
+       mtd->flags = MTD_CAP_ROM;
+       mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE;
+       mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
+       mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
+       mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
+       mtd->owner = THIS_MODULE;
+       mtd->erase = NULL;
+       mtd->point = NULL;
+       mtd->unpoint = NULL;
+       mtd->read = doc_read;
+       mtd->write = NULL;
+       mtd->read_oob = doc_read_oob;
+       mtd->write_oob = NULL;
+       mtd->sync = NULL;
+       mtd->block_isbad = doc_block_isbad;
+}
+
+/**
+ * doc_probe - Probe the IO space for a DiskOnChip G3 chip
+ * @pdev: platform device
+ *
+ * Probes for a G3 chip at the specified IO space in the platform data
+ * ressources.
+ *
+ * Returns 0 on success, -ENOMEM, -ENXIO on error
+ */
+static int __init docg3_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct docg3 *docg3;
+       struct mtd_info *mtd;
+       struct resource *ress;
+       int ret, bbt_nbpages;
+       u16 chip_id, chip_id_inv;
+
+       ret = -ENOMEM;
+       docg3 = kzalloc(sizeof(struct docg3), GFP_KERNEL);
+       if (!docg3)
+               goto nomem1;
+       mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
+       if (!mtd)
+               goto nomem2;
+       mtd->priv = docg3;
+
+       ret = -ENXIO;
+       ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!ress) {
+               dev_err(dev, "No I/O memory resource defined\n");
+               goto noress;
+       }
+       docg3->base = ioremap(ress->start, DOC_IOSPACE_SIZE);
+
+       docg3->dev = &pdev->dev;
+       docg3->device_id = 0;
+       doc_set_device_id(docg3, docg3->device_id);
+       doc_set_asic_mode(docg3, DOC_ASICMODE_RESET);
+       doc_set_asic_mode(docg3, DOC_ASICMODE_NORMAL);
+
+       chip_id = doc_register_readw(docg3, DOC_CHIPID);
+       chip_id_inv = doc_register_readw(docg3, DOC_CHIPID_INV);
+
+       ret = -ENODEV;
+       if (chip_id != (u16)(~chip_id_inv)) {
+               doc_info("No device found at IO addr %p\n",
+                        (void *)ress->start);
+               goto nochipfound;
+       }
+
+       switch (chip_id) {
+       case DOC_CHIPID_G3:
+               doc_info("Found a G3 DiskOnChip at addr %p\n",
+                        (void *)ress->start);
+               break;
+       default:
+               doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id);
+               goto nochipfound;
+       }
+
+       doc_set_driver_info(chip_id, mtd);
+       platform_set_drvdata(pdev, mtd);
+
+       ret = -ENOMEM;
+       bbt_nbpages = DIV_ROUND_UP(docg3->max_block + 1,
+                                  8 * DOC_LAYOUT_PAGE_SIZE);
+       docg3->bbt = kzalloc(bbt_nbpages * DOC_LAYOUT_PAGE_SIZE, GFP_KERNEL);
+       if (!docg3->bbt)
+               goto nochipfound;
+       doc_reload_bbt(docg3);
+
+       ret = mtd_device_parse_register(mtd, part_probes,
+                                       NULL, NULL, 0);
+       if (ret)
+               goto register_error;
+
+       doc_dbg_register(docg3);
+       return 0;
+
+register_error:
+       kfree(docg3->bbt);
+nochipfound:
+       iounmap(docg3->base);
+noress:
+       kfree(mtd);
+nomem2:
+       kfree(docg3);
+nomem1:
+       return ret;
+}
+
+/**
+ * docg3_release - Release the driver
+ * @pdev: the platform device
+ *
+ * Returns 0
+ */
+static int __exit docg3_release(struct platform_device *pdev)
+{
+       struct mtd_info *mtd = platform_get_drvdata(pdev);
+       struct docg3 *docg3 = mtd->priv;
+
+       doc_dbg_unregister(docg3);
+       mtd_device_unregister(mtd);
+       iounmap(docg3->base);
+       kfree(docg3->bbt);
+       kfree(docg3);
+       kfree(mtd);
+       return 0;
+}
+
+static struct platform_driver g3_driver = {
+       .driver         = {
+               .name   = "docg3",
+               .owner  = THIS_MODULE,
+       },
+       .remove         = __exit_p(docg3_release),
+};
+
+static int __init docg3_init(void)
+{
+       return platform_driver_probe(&g3_driver, docg3_probe);
+}
+module_init(docg3_init);
+
+
+static void __exit docg3_exit(void)
+{
+       platform_driver_unregister(&g3_driver);
+}
+module_exit(docg3_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
+MODULE_DESCRIPTION("MTD driver for DiskOnChip G3");
diff --git a/drivers/mtd/devices/docg3.h b/drivers/mtd/devices/docg3.h
new file mode 100644 (file)
index 0000000..0d407be
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Handles the M-Systems DiskOnChip G3 chip
+ *
+ * Copyright (C) 2011 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _MTD_DOCG3_H
+#define _MTD_DOCG3_H
+
+/*
+ * Flash memory areas :
+ *   - 0x0000 .. 0x07ff : IPL
+ *   - 0x0800 .. 0x0fff : Data area
+ *   - 0x1000 .. 0x17ff : Registers
+ *   - 0x1800 .. 0x1fff : Unknown
+ */
+#define DOC_IOSPACE_IPL                        0x0000
+#define DOC_IOSPACE_DATA               0x0800
+#define DOC_IOSPACE_SIZE               0x2000
+
+/*
+ * DOC G3 layout and adressing scheme
+ *   A page address for the block "b", plane "P" and page "p":
+ *   address = [bbbb bPpp pppp]
+ */
+
+#define DOC_ADDR_PAGE_MASK             0x3f
+#define DOC_ADDR_BLOCK_SHIFT           6
+#define DOC_LAYOUT_NBPLANES            2
+#define DOC_LAYOUT_PAGES_PER_BLOCK     64
+#define DOC_LAYOUT_PAGE_SIZE           512
+#define DOC_LAYOUT_OOB_SIZE            16
+#define DOC_LAYOUT_WEAR_SIZE           8
+#define DOC_LAYOUT_PAGE_OOB_SIZE                               \
+       (DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_SIZE)
+#define DOC_LAYOUT_WEAR_OFFSET         (DOC_LAYOUT_PAGE_OOB_SIZE * 2)
+#define DOC_LAYOUT_BLOCK_SIZE                                  \
+       (DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_PAGE_SIZE)
+#define DOC_ECC_BCH_SIZE               7
+#define DOC_ECC_BCH_COVERED_BYTES                              \
+       (DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_PAGEINFO_SZ +    \
+        DOC_LAYOUT_OOB_HAMMING_SZ + DOC_LAYOUT_OOB_BCH_SZ)
+
+/*
+ * Blocks distribution
+ */
+#define DOC_LAYOUT_BLOCK_BBT           0
+#define DOC_LAYOUT_BLOCK_OTP           0
+#define DOC_LAYOUT_BLOCK_FIRST_DATA    6
+
+#define DOC_LAYOUT_PAGE_BBT            4
+
+/*
+ * Extra page OOB (16 bytes wide) layout
+ */
+#define DOC_LAYOUT_OOB_PAGEINFO_OFS    0
+#define DOC_LAYOUT_OOB_HAMMING_OFS     7
+#define DOC_LAYOUT_OOB_BCH_OFS         8
+#define DOC_LAYOUT_OOB_UNUSED_OFS      15
+#define DOC_LAYOUT_OOB_PAGEINFO_SZ     7
+#define DOC_LAYOUT_OOB_HAMMING_SZ      1
+#define DOC_LAYOUT_OOB_BCH_SZ          7
+#define DOC_LAYOUT_OOB_UNUSED_SZ       1
+
+
+#define DOC_CHIPID_G3                  0x200
+#define DOC_ERASE_MARK                 0xaa
+/*
+ * Flash registers
+ */
+#define DOC_CHIPID                     0x1000
+#define DOC_TEST                       0x1004
+#define DOC_BUSLOCK                    0x1006
+#define DOC_ENDIANCONTROL              0x1008
+#define DOC_DEVICESELECT               0x100a
+#define DOC_ASICMODE                   0x100c
+#define DOC_CONFIGURATION              0x100e
+#define DOC_INTERRUPTCONTROL           0x1010
+#define DOC_READADDRESS                        0x101a
+#define DOC_DATAEND                    0x101e
+#define DOC_INTERRUPTSTATUS            0x1020
+
+#define DOC_FLASHSEQUENCE              0x1032
+#define DOC_FLASHCOMMAND               0x1034
+#define DOC_FLASHADDRESS               0x1036
+#define DOC_FLASHCONTROL               0x1038
+#define DOC_NOP                                0x103e
+
+#define DOC_ECCCONF0                   0x1040
+#define DOC_ECCCONF1                   0x1042
+#define DOC_ECCPRESET                  0x1044
+#define DOC_HAMMINGPARITY              0x1046
+#define DOC_BCH_SYNDROM(idx)           (0x1048 + (idx << 1))
+
+#define DOC_PROTECTION                 0x1056
+#define DOC_DPS0_ADDRLOW               0x1060
+#define DOC_DPS0_ADDRHIGH              0x1062
+#define DOC_DPS1_ADDRLOW               0x1064
+#define DOC_DPS1_ADDRHIGH              0x1066
+#define DOC_DPS0_STATUS                        0x106c
+#define DOC_DPS1_STATUS                        0x106e
+
+#define DOC_ASICMODECONFIRM            0x1072
+#define DOC_CHIPID_INV                 0x1074
+
+/*
+ * Flash sequences
+ * A sequence is preset before one or more commands are input to the chip.
+ */
+#define DOC_SEQ_RESET                  0x00
+#define DOC_SEQ_PAGE_SIZE_532          0x03
+#define DOC_SEQ_SET_MODE               0x09
+#define DOC_SEQ_READ                   0x12
+#define DOC_SEQ_SET_PLANE1             0x0e
+#define DOC_SEQ_SET_PLANE2             0x10
+#define DOC_SEQ_PAGE_SETUP             0x1d
+
+/*
+ * Flash commands
+ */
+#define DOC_CMD_READ_PLANE1            0x00
+#define DOC_CMD_SET_ADDR_READ          0x05
+#define DOC_CMD_READ_ALL_PLANES                0x30
+#define DOC_CMD_READ_PLANE2            0x50
+#define DOC_CMD_READ_FLASH             0xe0
+#define DOC_CMD_PAGE_SIZE_532          0x3c
+
+#define DOC_CMD_PROG_BLOCK_ADDR                0x60
+#define DOC_CMD_PROG_CYCLE1            0x80
+#define DOC_CMD_PROG_CYCLE2            0x10
+#define DOC_CMD_ERASECYCLE2            0xd0
+
+#define DOC_CMD_RELIABLE_MODE          0x22
+#define DOC_CMD_FAST_MODE              0xa2
+
+#define DOC_CMD_RESET                  0xff
+
+/*
+ * Flash register : DOC_FLASHCONTROL
+ */
+#define DOC_CTRL_VIOLATION             0x20
+#define DOC_CTRL_CE                    0x10
+#define DOC_CTRL_UNKNOWN_BITS          0x08
+#define DOC_CTRL_PROTECTION_ERROR      0x04
+#define DOC_CTRL_SEQUENCE_ERROR                0x02
+#define DOC_CTRL_FLASHREADY            0x01
+
+/*
+ * Flash register : DOC_ASICMODE
+ */
+#define DOC_ASICMODE_RESET             0x00
+#define DOC_ASICMODE_NORMAL            0x01
+#define DOC_ASICMODE_POWERDOWN         0x02
+#define DOC_ASICMODE_MDWREN            0x04
+#define DOC_ASICMODE_BDETCT_RESET      0x08
+#define DOC_ASICMODE_RSTIN_RESET       0x10
+#define DOC_ASICMODE_RAM_WE            0x20
+
+/*
+ * Flash register : DOC_ECCCONF0
+ */
+#define DOC_ECCCONF0_READ_MODE         0x8000
+#define DOC_ECCCONF0_AUTO_ECC_ENABLE   0x4000
+#define DOC_ECCCONF0_HAMMING_ENABLE    0x1000
+#define DOC_ECCCONF0_BCH_ENABLE                0x0800
+#define DOC_ECCCONF0_DATA_BYTES_MASK   0x07ff
+
+/*
+ * Flash register : DOC_ECCCONF1
+ */
+#define DOC_ECCCONF1_BCH_SYNDROM_ERR   0x80
+#define DOC_ECCCONF1_UNKOWN1           0x40
+#define DOC_ECCCONF1_UNKOWN2           0x20
+#define DOC_ECCCONF1_UNKOWN3           0x10
+#define DOC_ECCCONF1_HAMMING_BITS_MASK 0x0f
+
+/*
+ * Flash register : DOC_PROTECTION
+ */
+#define DOC_PROTECT_FOUNDRY_OTP_LOCK   0x01
+#define DOC_PROTECT_CUSTOMER_OTP_LOCK  0x02
+#define DOC_PROTECT_LOCK_INPUT         0x04
+#define DOC_PROTECT_STICKY_LOCK                0x08
+#define DOC_PROTECT_PROTECTION_ENABLED 0x10
+#define DOC_PROTECT_IPL_DOWNLOAD_LOCK  0x20
+#define DOC_PROTECT_PROTECTION_ERROR   0x80
+
+/*
+ * Flash register : DOC_DPS0_STATUS and DOC_DPS1_STATUS
+ */
+#define DOC_DPS_OTP_PROTECTED          0x01
+#define DOC_DPS_READ_PROTECTED         0x02
+#define DOC_DPS_WRITE_PROTECTED                0x04
+#define DOC_DPS_HW_LOCK_ENABLED                0x08
+#define DOC_DPS_KEY_OK                 0x80
+
+/*
+ * Flash register : DOC_CONFIGURATION
+ */
+#define DOC_CONF_IF_CFG                        0x80
+#define DOC_CONF_MAX_ID_MASK           0x30
+#define DOC_CONF_VCCQ_3V               0x01
+
+/*
+ * Flash register : DOC_READADDRESS
+ */
+#define DOC_READADDR_INC               0x8000
+#define DOC_READADDR_ONE_BYTE          0x4000
+#define DOC_READADDR_ADDR_MASK         0x1fff
+
+/**
+ * struct docg3 - DiskOnChip driver private data
+ * @dev: the device currently under control
+ * @base: mapped IO space
+ * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
+ * @if_cfg: if true, reads are on 16bits, else reads are on 8bits
+ * @bbt: bad block table cache
+ * @debugfs_root: debugfs root node
+ */
+struct docg3 {
+       struct device *dev;
+       void __iomem *base;
+       unsigned int device_id:4;
+       unsigned int if_cfg:1;
+       int max_block;
+       u8 *bbt;
+       struct dentry *debugfs_root;
+};
+
+#define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg)
+#define doc_info(fmt, arg...) dev_info(docg3->dev, (fmt), ## arg)
+#define doc_dbg(fmt, arg...) dev_dbg(docg3->dev, (fmt), ## arg)
+#define doc_vdbg(fmt, arg...) dev_vdbg(docg3->dev, (fmt), ## arg)
+
+#define DEBUGFS_RO_ATTR(name, show_fct) \
+       static int name##_open(struct inode *inode, struct file *file) \
+       { return single_open(file, show_fct, inode->i_private); }      \
+       static const struct file_operations name##_fops = { \
+               .owner = THIS_MODULE, \
+               .open = name##_open, \
+               .llseek = seq_lseek, \
+               .read = seq_read, \
+               .release = single_release \
+       };
+#endif
+
+/*
+ * Trace events part
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM docg3
+
+#if !defined(_MTD_DOCG3_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define _MTD_DOCG3_TRACE
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(docg3_io,
+           TP_PROTO(int op, int width, u16 reg, int val),
+           TP_ARGS(op, width, reg, val),
+           TP_STRUCT__entry(
+                   __field(int, op)
+                   __field(unsigned char, width)
+                   __field(u16, reg)
+                   __field(int, val)),
+           TP_fast_assign(
+                   __entry->op = op;
+                   __entry->width = width;
+                   __entry->reg = reg;
+                   __entry->val = val;),
+           TP_printk("docg3: %s%02d reg=%04x, val=%04x",
+                     __entry->op ? "write" : "read", __entry->width,
+                     __entry->reg, __entry->val)
+       );
+#endif
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE docg3
+#include <trace/define_trace.h>
index d374603493a7da77c6f0004643809e0ac5862374..45116bb302972ba5cbde40719778aa4cb065635e 100644 (file)
 #include <linux/mtd/nand.h>
 #include <linux/mtd/doc2000.h>
 
-/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-#define CONFIG_MTD_DOCPROBE_ADDRESS 0
-#endif
-
 
 static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
 module_param(doc_config_location, ulong, 0);
index 772a0ff89e0f7e316279d82632d0893ad89b0f64..3a11ea628e58a2249bbe1d54939a77d2003690cb 100644 (file)
@@ -34,9 +34,6 @@
 /* debugging */
 //#define LART_DEBUG
 
-/* partition support */
-#define HAVE_PARTITIONS
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -44,9 +41,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mtd/mtd.h>
-#ifdef HAVE_PARTITIONS
 #include <linux/mtd/partitions.h>
-#endif
 
 #ifndef CONFIG_SA1100_LART
 #error This is for LART architecture only
@@ -598,7 +593,6 @@ static struct mtd_erase_region_info erase_regions[] = {
        }
 };
 
-#ifdef HAVE_PARTITIONS
 static struct mtd_partition lart_partitions[] = {
        /* blob */
        {
@@ -619,7 +613,7 @@ static struct mtd_partition lart_partitions[] = {
                .size   = INITRD_LEN,           /* MTDPART_SIZ_FULL */
        }
 };
-#endif
+#define NUM_PARTITIONS ARRAY_SIZE(lart_partitions)
 
 static int __init lart_flash_init (void)
 {
@@ -668,7 +662,6 @@ static int __init lart_flash_init (void)
                           result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
                           result,mtd.eraseregions[result].numblocks);
 
-#ifdef HAVE_PARTITIONS
    printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions));
 
    for (result = 0; result < ARRAY_SIZE(lart_partitions); result++)
@@ -681,25 +674,16 @@ static int __init lart_flash_init (void)
                         result,lart_partitions[result].offset,
                         result,lart_partitions[result].size,lart_partitions[result].size / 1024);
 #endif
-#endif
 
-#ifndef HAVE_PARTITIONS
-   result = mtd_device_register(&mtd, NULL, 0);
-#else
    result = mtd_device_register(&mtd, lart_partitions,
                                 ARRAY_SIZE(lart_partitions));
-#endif
 
    return (result);
 }
 
 static void __exit lart_flash_exit (void)
 {
-#ifndef HAVE_PARTITIONS
-   mtd_device_unregister(&mtd);
-#else
    mtd_device_unregister(&mtd);
-#endif
 }
 
 module_init (lart_flash_init);
index 35180e475c4c565fded31dc91d6fe05c91aec805..884904d3f9d2deda9088046f8666e2f14b2aa664 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
@@ -88,7 +89,6 @@ struct m25p {
        struct spi_device       *spi;
        struct mutex            lock;
        struct mtd_info         mtd;
-       unsigned                partitioned:1;
        u16                     page_size;
        u16                     addr_width;
        u8                      erase_opcode;
@@ -209,9 +209,8 @@ static int wait_till_ready(struct m25p *flash)
  */
 static int erase_chip(struct m25p *flash)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
-             dev_name(&flash->spi->dev), __func__,
-             (long long)(flash->mtd.size >> 10));
+       pr_debug("%s: %s %lldKiB\n", dev_name(&flash->spi->dev), __func__,
+                       (long long)(flash->mtd.size >> 10));
 
        /* Wait until finished previous write command. */
        if (wait_till_ready(flash))
@@ -250,9 +249,8 @@ static int m25p_cmdsz(struct m25p *flash)
  */
 static int erase_sector(struct m25p *flash, u32 offset)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
-                       dev_name(&flash->spi->dev), __func__,
-                       flash->mtd.erasesize / 1024, offset);
+       pr_debug("%s: %s %dKiB at 0x%08x\n", dev_name(&flash->spi->dev),
+                       __func__, flash->mtd.erasesize / 1024, offset);
 
        /* Wait until finished previous write command. */
        if (wait_till_ready(flash))
@@ -286,9 +284,9 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
        u32 addr,len;
        uint32_t rem;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%llx, len %lld\n",
-             dev_name(&flash->spi->dev), __func__, "at",
-             (long long)instr->addr, (long long)instr->len);
+       pr_debug("%s: %s at 0x%llx, len %lld\n", dev_name(&flash->spi->dev),
+                       __func__, (long long)instr->addr,
+                       (long long)instr->len);
 
        /* sanity checks */
        if (instr->addr + instr->len > flash->mtd.size)
@@ -348,9 +346,8 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
        struct spi_transfer t[2];
        struct spi_message m;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "from",
-                       (u32)from, len);
+       pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)from, len);
 
        /* sanity checks */
        if (!len)
@@ -417,9 +414,8 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
        struct spi_transfer t[2];
        struct spi_message m;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "to",
-                       (u32)to, len);
+       pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)to, len);
 
        *retlen = 0;
 
@@ -510,9 +506,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
        size_t actual;
        int cmd_sz, ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
-                       dev_name(&flash->spi->dev), __func__, "to",
-                       (u32)to, len);
+       pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+                       __func__, (u32)to, len);
 
        *retlen = 0;
 
@@ -661,6 +656,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
 
        { "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
+       { "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
        { "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
 
        { "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
@@ -671,6 +667,7 @@ static const struct spi_device_id m25p_ids[] = {
        /* EON -- en25xxx */
        { "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
        { "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
+       { "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
        { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
 
        /* Intel/Numonyx -- xxxs33b */
@@ -788,8 +785,8 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
         */
        tmp = spi_write_then_read(spi, &code, 1, id, 5);
        if (tmp < 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
-                       dev_name(&spi->dev), tmp);
+               pr_debug("%s: error %d reading JEDEC ID\n",
+                               dev_name(&spi->dev), tmp);
                return ERR_PTR(tmp);
        }
        jedec = id[0];
@@ -825,8 +822,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
        struct m25p                     *flash;
        struct flash_info               *info;
        unsigned                        i;
-       struct mtd_partition            *parts = NULL;
-       int                             nr_parts = 0;
+       struct mtd_part_parser_data     ppdata;
+
+#ifdef CONFIG_MTD_OF_PARTS
+       if (!of_device_is_available(spi->dev.of_node))
+               return -ENODEV;
+#endif
 
        /* Platform data helps sort out which chip type we have, as
         * well as how this board partitions it.  If we don't have
@@ -928,6 +929,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        if (info->flags & M25P_NO_ERASE)
                flash->mtd.flags |= MTD_NO_ERASE;
 
+       ppdata.of_node = spi->dev.of_node;
        flash->mtd.dev.parent = &spi->dev;
        flash->page_size = info->page_size;
 
@@ -945,8 +947,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
        dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name,
                        (long long)flash->mtd.size >> 10);
 
-       DEBUG(MTD_DEBUG_LEVEL2,
-               "mtd .name = %s, .size = 0x%llx (%lldMiB) "
+       pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
                        ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
                flash->mtd.name,
                (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@@ -955,8 +956,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
 
        if (flash->mtd.numeraseregions)
                for (i = 0; i < flash->mtd.numeraseregions; i++)
-                       DEBUG(MTD_DEBUG_LEVEL2,
-                               "mtd.eraseregions[%d] = { .offset = 0x%llx, "
+                       pr_debug("mtd.eraseregions[%d] = { .offset = 0x%llx, "
                                ".erasesize = 0x%.8x (%uKiB), "
                                ".numblocks = %d }\n",
                                i, (long long)flash->mtd.eraseregions[i].offset,
@@ -968,41 +968,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
        /* partitions should match sector boundaries; and it may be good to
         * use readonly partitions for writeprotected sectors (BP2..BP0).
         */
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[]
-                       = { "cmdlinepart", NULL, };
-
-               nr_parts = parse_mtd_partitions(&flash->mtd,
-                                               part_probes, &parts, 0);
-       }
-
-       if (nr_parts <= 0 && data && data->parts) {
-               parts = data->parts;
-               nr_parts = data->nr_parts;
-       }
-
-#ifdef CONFIG_MTD_OF_PARTS
-       if (nr_parts <= 0 && spi->dev.of_node) {
-               nr_parts = of_mtd_parse_partitions(&spi->dev,
-                                                  spi->dev.of_node, &parts);
-       }
-#endif
-
-       if (nr_parts > 0) {
-               for (i = 0; i < nr_parts; i++) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-                             "{.name = %s, .offset = 0x%llx, "
-                             ".size = 0x%llx (%lldKiB) }\n",
-                             i, parts[i].name,
-                             (long long)parts[i].offset,
-                             (long long)parts[i].size,
-                             (long long)(parts[i].size >> 10));
-               }
-               flash->partitioned = 1;
-       }
-
-       return mtd_device_register(&flash->mtd, parts, nr_parts) == 1 ?
-               -ENODEV : 0;
+       return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
+                       data ? data->parts : NULL,
+                       data ? data->nr_parts : 0);
 }
 
 
index 13749d458a313297fed127f39399b3432e3be1ff..d75c7af18a638d9f94588565e2d6b3271c95b05d 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/mutex.h>
 #include <linux/err.h>
 #include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
@@ -24,7 +26,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
-
 /*
  * DataFlash is a kind of SPI flash.  Most AT45 chips have two buffers in
  * each chip, which may be used for double buffered I/O; but this driver
@@ -98,6 +99,16 @@ struct dataflash {
        struct mtd_info         mtd;
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id dataflash_dt_ids[] = {
+       { .compatible = "atmel,at45", },
+       { .compatible = "atmel,dataflash", },
+       { /* sentinel */ }
+};
+#else
+#define dataflash_dt_ids NULL
+#endif
+
 /* ......................................................................... */
 
 /*
@@ -122,7 +133,7 @@ static int dataflash_waitready(struct spi_device *spi)
        for (;;) {
                status = dataflash_status(spi);
                if (status < 0) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n",
+                       pr_debug("%s: status %d?\n",
                                        dev_name(&spi->dev), status);
                        status = 0;
                }
@@ -149,7 +160,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
        uint8_t                 *command;
        uint32_t                rem;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n",
+       pr_debug("%s: erase addr=0x%llx len 0x%llx\n",
              dev_name(&spi->dev), (long long)instr->addr,
              (long long)instr->len);
 
@@ -187,7 +198,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
                command[2] = (uint8_t)(pageaddr >> 8);
                command[3] = 0;
 
-               DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n",
+               pr_debug("ERASE %s: (%x) %x %x %x [%i]\n",
                        do_block ? "block" : "page",
                        command[0], command[1], command[2], command[3],
                        pageaddr);
@@ -238,8 +249,8 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
        uint8_t                 *command;
        int                     status;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n",
-               dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len));
+       pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
+                       (unsigned)from, (unsigned)(from + len));
 
        *retlen = 0;
 
@@ -255,7 +266,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        command = priv->command;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
+       pr_debug("READ: (%x) %x %x %x\n",
                command[0], command[1], command[2], command[3]);
 
        spi_message_init(&msg);
@@ -287,7 +298,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
                *retlen = msg.actual_length - 8;
                status = 0;
        } else
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n",
+               pr_debug("%s: read %x..%x --> %d\n",
                        dev_name(&priv->spi->dev),
                        (unsigned)from, (unsigned)(from + len),
                        status);
@@ -314,7 +325,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
        int                     status = -EINVAL;
        uint8_t                 *command;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n",
+       pr_debug("%s: write 0x%x..0x%x\n",
                dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));
 
        *retlen = 0;
@@ -340,7 +351,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 
        mutex_lock(&priv->lock);
        while (remaining > 0) {
-               DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
+               pr_debug("write @ %i:%i len=%i\n",
                        pageaddr, offset, writelen);
 
                /* REVISIT:
@@ -368,12 +379,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                        command[2] = (addr & 0x0000FF00) >> 8;
                        command[3] = 0;
 
-                       DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
+                       pr_debug("TRANSFER: (%x) %x %x %x\n",
                                command[0], command[1], command[2], command[3]);
 
                        status = spi_sync(spi, &msg);
                        if (status < 0)
-                               DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
+                               pr_debug("%s: xfer %u -> %d\n",
                                        dev_name(&spi->dev), addr, status);
 
                        (void) dataflash_waitready(priv->spi);
@@ -386,7 +397,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                command[2] = (addr & 0x0000FF00) >> 8;
                command[3] = (addr & 0x000000FF);
 
-               DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n",
+               pr_debug("PROGRAM: (%x) %x %x %x\n",
                        command[0], command[1], command[2], command[3]);
 
                x[1].tx_buf = writebuf;
@@ -395,7 +406,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                status = spi_sync(spi, &msg);
                spi_transfer_del(x + 1);
                if (status < 0)
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
+                       pr_debug("%s: pgm %u/%u -> %d\n",
                                dev_name(&spi->dev), addr, writelen, status);
 
                (void) dataflash_waitready(priv->spi);
@@ -410,12 +421,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
                command[2] = (addr & 0x0000FF00) >> 8;
                command[3] = 0;
 
-               DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
+               pr_debug("COMPARE: (%x) %x %x %x\n",
                        command[0], command[1], command[2], command[3]);
 
                status = spi_sync(spi, &msg);
                if (status < 0)
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",
+                       pr_debug("%s: compare %u -> %d\n",
                                dev_name(&spi->dev), addr, status);
 
                status = dataflash_waitready(priv->spi);
@@ -634,11 +645,10 @@ add_dataflash_otp(struct spi_device *spi, char *name,
 {
        struct dataflash                *priv;
        struct mtd_info                 *device;
+       struct mtd_part_parser_data     ppdata;
        struct flash_platform_data      *pdata = spi->dev.platform_data;
        char                            *otp_tag = "";
        int                             err = 0;
-       struct mtd_partition            *parts;
-       int                             nr_parts = 0;
 
        priv = kzalloc(sizeof *priv, GFP_KERNEL);
        if (!priv)
@@ -677,28 +687,11 @@ add_dataflash_otp(struct spi_device *spi, char *name,
                        pagesize, otp_tag);
        dev_set_drvdata(&spi->dev, priv);
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[] = { "cmdlinepart", NULL, };
-
-               nr_parts = parse_mtd_partitions(device, part_probes, &parts,
-                                               0);
-       }
+       ppdata.of_node = spi->dev.of_node;
+       err = mtd_device_parse_register(device, NULL, &ppdata,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
 
-       if (nr_parts <= 0 && pdata && pdata->parts) {
-               parts = pdata->parts;
-               nr_parts = pdata->nr_parts;
-       }
-
-       if (nr_parts > 0) {
-               priv->partitioned = 1;
-               err = mtd_device_register(device, parts, nr_parts);
-               goto out;
-       }
-
-       if (mtd_device_register(device, NULL, 0) == 1)
-               err = -ENODEV;
-
-out:
        if (!err)
                return 0;
 
@@ -787,7 +780,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
         */
        tmp = spi_write_then_read(spi, &code, 1, id, 3);
        if (tmp < 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
+               pr_debug("%s: error %d reading JEDEC ID\n",
                        dev_name(&spi->dev), tmp);
                return ERR_PTR(tmp);
        }
@@ -804,7 +797,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
                        tmp < ARRAY_SIZE(dataflash_data);
                        tmp++, info++) {
                if (info->jedec_id == jedec) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "%s: OTP, sector protect%s\n",
+                       pr_debug("%s: OTP, sector protect%s\n",
                                dev_name(&spi->dev),
                                (info->flags & SUP_POW2PS)
                                        ? ", binary pagesize" : ""
@@ -812,8 +805,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
                        if (info->flags & SUP_POW2PS) {
                                status = dataflash_status(spi);
                                if (status < 0) {
-                                       DEBUG(MTD_DEBUG_LEVEL1,
-                                               "%s: status error %d\n",
+                                       pr_debug("%s: status error %d\n",
                                                dev_name(&spi->dev), status);
                                        return ERR_PTR(status);
                                }
@@ -878,7 +870,7 @@ static int __devinit dataflash_probe(struct spi_device *spi)
         */
        status = dataflash_status(spi);
        if (status <= 0 || status == 0xff) {
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n",
+               pr_debug("%s: status error %d\n",
                                dev_name(&spi->dev), status);
                if (status == 0 || status == 0xff)
                        status = -ENODEV;
@@ -914,14 +906,14 @@ static int __devinit dataflash_probe(struct spi_device *spi)
                break;
        /* obsolete AT45DB1282 not (yet?) supported */
        default:
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n",
-                               dev_name(&spi->dev), status & 0x3c);
+               pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev),
+                               status & 0x3c);
                status = -ENODEV;
        }
 
        if (status < 0)
-               DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n",
-                               dev_name(&spi->dev), status);
+               pr_debug("%s: add_dataflash --> %d\n", dev_name(&spi->dev),
+                               status);
 
        return status;
 }
@@ -931,7 +923,7 @@ static int __devexit dataflash_remove(struct spi_device *spi)
        struct dataflash        *flash = dev_get_drvdata(&spi->dev);
        int                     status;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev));
+       pr_debug("%s: remove\n", dev_name(&spi->dev));
 
        status = mtd_device_unregister(&flash->mtd);
        if (status == 0) {
@@ -946,6 +938,7 @@ static struct spi_driver dataflash_driver = {
                .name           = "mtd_dataflash",
                .bus            = &spi_bus_type,
                .owner          = THIS_MODULE,
+               .of_match_table = dataflash_dt_ids,
        },
 
        .probe          = dataflash_probe,
index 83e80c65d6e70ce9b508591ff814eab6150c9d08..d38ef3bffe8d0723806835df2d1093a017757380 100644 (file)
@@ -52,8 +52,6 @@ struct sst25l_flash {
        struct spi_device       *spi;
        struct mutex            lock;
        struct mtd_info         mtd;
-
-       int                     partitioned;
 };
 
 struct flash_info {
@@ -381,8 +379,6 @@ static int __devinit sst25l_probe(struct spi_device *spi)
        struct sst25l_flash *flash;
        struct flash_platform_data *data;
        int ret, i;
-       struct mtd_partition *parts = NULL;
-       int nr_parts = 0;
 
        flash_info = sst25l_match_device(spi);
        if (!flash_info)
@@ -414,8 +410,7 @@ static int __devinit sst25l_probe(struct spi_device *spi)
        dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
                 (long long)flash->mtd.size >> 10);
 
-       DEBUG(MTD_DEBUG_LEVEL2,
-             "mtd .name = %s, .size = 0x%llx (%lldMiB) "
+       pr_debug("mtd .name = %s, .size = 0x%llx (%lldMiB) "
              ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
              flash->mtd.name,
              (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
@@ -423,37 +418,10 @@ static int __devinit sst25l_probe(struct spi_device *spi)
              flash->mtd.numeraseregions);
 
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *part_probes[] = {"cmdlinepart", NULL};
-
-               nr_parts = parse_mtd_partitions(&flash->mtd,
-                                               part_probes,
-                                               &parts, 0);
-       }
-
-       if (nr_parts <= 0 && data && data->parts) {
-               parts = data->parts;
-               nr_parts = data->nr_parts;
-       }
-
-       if (nr_parts > 0) {
-               for (i = 0; i < nr_parts; i++) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-                             "{.name = %s, .offset = 0x%llx, "
-                             ".size = 0x%llx (%lldKiB) }\n",
-                             i, parts[i].name,
-                             (long long)parts[i].offset,
-                             (long long)parts[i].size,
-                             (long long)(parts[i].size >> 10));
-               }
-
-               flash->partitioned = 1;
-               return mtd_device_register(&flash->mtd, parts,
-                                          nr_parts);
-       }
-
-       ret = mtd_device_register(&flash->mtd, NULL, 0);
-       if (ret == 1) {
+       ret = mtd_device_parse_register(&flash->mtd, NULL, 0,
+                       data ? data->parts : NULL,
+                       data ? data->nr_parts : 0);
+       if (ret) {
                kfree(flash);
                dev_set_drvdata(&spi->dev, NULL);
                return -ENODEV;
index 037b399df3f1a384dbdc45b9c6d9dbf0d3c8abaf..c7382bb686c679efef42dd5218cce645002512eb 100644 (file)
@@ -339,7 +339,7 @@ static int erase_xfer(partition_t *part,
     struct erase_info *erase;
 
     xfer = &part->XferInfo[xfernum];
-    DEBUG(1, "ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
+    pr_debug("ftl_cs: erasing xfer unit at 0x%x\n", xfer->Offset);
     xfer->state = XFER_ERASING;
 
     /* Is there a free erase slot? Always in MTD. */
@@ -415,7 +415,7 @@ static int prepare_xfer(partition_t *part, int i)
     xfer = &part->XferInfo[i];
     xfer->state = XFER_FAILED;
 
-    DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
+    pr_debug("ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
 
     /* Write the transfer unit header */
     header = part->header;
@@ -476,7 +476,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
 
     eun = &part->EUNInfo[srcunit];
     xfer = &part->XferInfo[xferunit];
-    DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
+    pr_debug("ftl_cs: copying block 0x%x to 0x%x\n",
          eun->Offset, xfer->Offset);
 
 
@@ -598,7 +598,7 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit,
     unit with the fewest erases, and usually pick the data unit with
     the most deleted blocks.  But with a small probability, pick the
     oldest data unit instead.  This means that we generally postpone
-    the next reclaimation as long as possible, but shuffle static
+    the next reclamation as long as possible, but shuffle static
     stuff around a bit for wear leveling.
 
 ======================================================================*/
@@ -609,8 +609,8 @@ static int reclaim_block(partition_t *part)
     uint32_t best;
     int queued, ret;
 
-    DEBUG(0, "ftl_cs: reclaiming space...\n");
-    DEBUG(3, "NumTransferUnits == %x\n", part->header.NumTransferUnits);
+    pr_debug("ftl_cs: reclaiming space...\n");
+    pr_debug("NumTransferUnits == %x\n", part->header.NumTransferUnits);
     /* Pick the least erased transfer unit */
     best = 0xffffffff; xfer = 0xffff;
     do {
@@ -618,22 +618,22 @@ static int reclaim_block(partition_t *part)
        for (i = 0; i < part->header.NumTransferUnits; i++) {
            int n=0;
            if (part->XferInfo[i].state == XFER_UNKNOWN) {
-               DEBUG(3,"XferInfo[%d].state == XFER_UNKNOWN\n",i);
+               pr_debug("XferInfo[%d].state == XFER_UNKNOWN\n",i);
                n=1;
                erase_xfer(part, i);
            }
            if (part->XferInfo[i].state == XFER_ERASING) {
-               DEBUG(3,"XferInfo[%d].state == XFER_ERASING\n",i);
+               pr_debug("XferInfo[%d].state == XFER_ERASING\n",i);
                n=1;
                queued = 1;
            }
            else if (part->XferInfo[i].state == XFER_ERASED) {
-               DEBUG(3,"XferInfo[%d].state == XFER_ERASED\n",i);
+               pr_debug("XferInfo[%d].state == XFER_ERASED\n",i);
                n=1;
                prepare_xfer(part, i);
            }
            if (part->XferInfo[i].state == XFER_PREPARED) {
-               DEBUG(3,"XferInfo[%d].state == XFER_PREPARED\n",i);
+               pr_debug("XferInfo[%d].state == XFER_PREPARED\n",i);
                n=1;
                if (part->XferInfo[i].EraseCount <= best) {
                    best = part->XferInfo[i].EraseCount;
@@ -641,12 +641,12 @@ static int reclaim_block(partition_t *part)
                }
            }
                if (!n)
-                   DEBUG(3,"XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
+                   pr_debug("XferInfo[%d].state == %x\n",i, part->XferInfo[i].state);
 
        }
        if (xfer == 0xffff) {
            if (queued) {
-               DEBUG(1, "ftl_cs: waiting for transfer "
+               pr_debug("ftl_cs: waiting for transfer "
                      "unit to be prepared...\n");
                if (part->mbd.mtd->sync)
                        part->mbd.mtd->sync(part->mbd.mtd);
@@ -656,7 +656,7 @@ static int reclaim_block(partition_t *part)
                    printk(KERN_NOTICE "ftl_cs: reclaim failed: no "
                           "suitable transfer units!\n");
                else
-                   DEBUG(1, "ftl_cs: reclaim failed: no "
+                   pr_debug("ftl_cs: reclaim failed: no "
                          "suitable transfer units!\n");
 
                return -EIO;
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
 
     eun = 0;
     if ((jiffies % shuffle_freq) == 0) {
-       DEBUG(1, "ftl_cs: recycling freshest block...\n");
+       pr_debug("ftl_cs: recycling freshest block...\n");
        best = 0xffffffff;
        for (i = 0; i < part->DataUnits; i++)
            if (part->EUNInfo[i].EraseCount <= best) {
@@ -686,7 +686,7 @@ static int reclaim_block(partition_t *part)
                printk(KERN_NOTICE "ftl_cs: reclaim failed: "
                       "no free blocks!\n");
            else
-               DEBUG(1,"ftl_cs: reclaim failed: "
+               pr_debug("ftl_cs: reclaim failed: "
                       "no free blocks!\n");
 
            return -EIO;
@@ -771,7 +771,7 @@ static uint32_t find_free(partition_t *part)
        printk(KERN_NOTICE "ftl_cs: bad free list!\n");
        return 0;
     }
-    DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
+    pr_debug("ftl_cs: found free block at %d in %d\n", blk, eun);
     return blk;
 
 } /* find_free */
@@ -791,7 +791,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
     int ret;
     size_t offset, retlen;
 
-    DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
+    pr_debug("ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
          part, sector, nblocks);
     if (!(part->state & FTL_FORMATTED)) {
        printk(KERN_NOTICE "ftl_cs: bad partition\n");
@@ -840,7 +840,7 @@ static int set_bam_entry(partition_t *part, uint32_t log_addr,
     int ret;
     size_t retlen, offset;
 
-    DEBUG(2, "ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
+    pr_debug("ftl_cs: set_bam_entry(0x%p, 0x%x, 0x%x)\n",
          part, log_addr, virt_addr);
     bsize = 1 << part->header.EraseUnitSize;
     eun = log_addr / bsize;
@@ -905,7 +905,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
     int ret;
     size_t retlen, offset;
 
-    DEBUG(2, "ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
+    pr_debug("ftl_cs: ftl_write(0x%p, %ld, %ld)\n",
          part, sector, nblocks);
     if (!(part->state & FTL_FORMATTED)) {
        printk(KERN_NOTICE "ftl_cs: bad partition\n");
@@ -1011,7 +1011,7 @@ static int ftl_discardsect(struct mtd_blktrans_dev *dev,
        partition_t *part = (void *)dev;
        uint32_t bsize = 1 << part->header.EraseUnitSize;
 
-       DEBUG(1, "FTL erase sector %ld for %d sectors\n",
+       pr_debug("FTL erase sector %ld for %d sectors\n",
              sector, nr_sects);
 
        while (nr_sects) {
index d7592e67d04861cfc2a952112445ef0601dd58ce..dd034efd18751c8aaded3779f8ba85df06110bc5 100644 (file)
@@ -63,14 +63,12 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
        }
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name);
+       pr_debug("INFTL: add_mtd for %s\n", mtd->name);
 
        inftl = kzalloc(sizeof(*inftl), GFP_KERNEL);
 
-       if (!inftl) {
-               printk(KERN_WARNING "INFTL: Out of memory for data structures\n");
+       if (!inftl)
                return;
-       }
 
        inftl->mbd.mtd = mtd;
        inftl->mbd.devnum = -1;
@@ -133,7 +131,7 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct INFTLrecord *inftl = (void *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("INFTL: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
 
@@ -154,7 +152,7 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs & (mtd->writesize - 1);
        ops.ooblen = len;
        ops.oobbuf = buf;
@@ -174,7 +172,7 @@ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs & (mtd->writesize - 1);
        ops.ooblen = len;
        ops.oobbuf = buf;
@@ -194,7 +192,7 @@ static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs;
        ops.ooblen = mtd->oobsize;
        ops.oobbuf = oob;
@@ -215,16 +213,16 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
        u16 pot = inftl->LastFreeEUN;
        int silly = inftl->nb_blocks;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=%p,"
-               "desperate=%d)\n", inftl, desperate);
+       pr_debug("INFTL: INFTL_findfreeblock(inftl=%p,desperate=%d)\n",
+                       inftl, desperate);
 
        /*
         * Normally, we force a fold to happen before we run out of free
         * blocks completely.
         */
        if (!desperate && inftl->numfreeEUNs < 2) {
-               DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
-                       "EUNs (%d)\n", inftl->numfreeEUNs);
+               pr_debug("INFTL: there are too few free EUNs (%d)\n",
+                               inftl->numfreeEUNs);
                return BLOCK_NIL;
        }
 
@@ -259,8 +257,8 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
        struct inftl_oob oob;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,"
-               "pending=%d)\n", inftl, thisVUC, pendingblock);
+       pr_debug("INFTL: INFTL_foldchain(inftl=%p,thisVUC=%d,pending=%d)\n",
+                       inftl, thisVUC, pendingblock);
 
        memset(BlockMap, 0xff, sizeof(BlockMap));
        memset(BlockDeleted, 0, sizeof(BlockDeleted));
@@ -323,8 +321,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
         * Chain, and the Erase Unit into which we are supposed to be copying.
         * Go for it.
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
-               thisVUC, targetEUN);
+       pr_debug("INFTL: folding chain %d into unit %d\n", thisVUC, targetEUN);
 
        for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
                unsigned char movebuf[SECTORSIZE];
@@ -349,14 +346,13 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
                ret = mtd->read(mtd, (inftl->EraseSize * BlockMap[block]) +
                                (block * SECTORSIZE), SECTORSIZE, &retlen,
                                movebuf);
-               if (ret < 0 && ret != -EUCLEAN) {
+               if (ret < 0 && !mtd_is_bitflip(ret)) {
                        ret = mtd->read(mtd,
                                        (inftl->EraseSize * BlockMap[block]) +
                                        (block * SECTORSIZE), SECTORSIZE,
                                        &retlen, movebuf);
                        if (ret != -EIO)
-                               DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
-                                     "away on retry?\n");
+                               pr_debug("INFTL: error went away on retry?\n");
                }
                memset(&oob, 0xff, sizeof(struct inftl_oob));
                oob.b.Status = oob.b.Status1 = SECTOR_USED;
@@ -372,8 +368,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
         * is important, by doing oldest first if we crash/reboot then it
         * it is relatively simple to clean up the mess).
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
-               thisVUC);
+       pr_debug("INFTL: want to erase virtual chain %d\n", thisVUC);
 
        for (;;) {
                /* Find oldest unit in chain. */
@@ -421,7 +416,7 @@ static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
        u16 ChainLength = 0, thislen;
        u16 chain, EUN;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=%p,"
+       pr_debug("INFTL: INFTL_makefreeblock(inftl=%p,"
                "pending=%d)\n", inftl, pendingblock);
 
        for (chain = 0; chain < inftl->nb_blocks; chain++) {
@@ -484,8 +479,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
        size_t retlen;
        int silly, silly2 = 3;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=%p,"
-               "block=%d)\n", inftl, block);
+       pr_debug("INFTL: INFTL_findwriteunit(inftl=%p,block=%d)\n",
+                       inftl, block);
 
        do {
                /*
@@ -501,8 +496,8 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
                                       blockofs, 8, &retlen, (char *)&bci);
 
                        status = bci.Status | bci.Status1;
-                       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
-                               "EUN %d is %x\n", block , writeEUN, status);
+                       pr_debug("INFTL: status of block %d in EUN %d is %x\n",
+                                       block , writeEUN, status);
 
                        switch(status) {
                        case SECTOR_FREE:
@@ -555,9 +550,9 @@ hitused:
                         * Hopefully we free something, lets try again.
                         * This time we are desperate...
                         */
-                       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
-                               "to find free EUN to accommodate write to "
-                               "VUC %d\n", thisVUC);
+                       pr_debug("INFTL: using desperate==1 to find free EUN "
+                                       "to accommodate write to VUC %d\n",
+                                       thisVUC);
                        writeEUN = INFTL_findfreeblock(inftl, 1);
                        if (writeEUN == BLOCK_NIL) {
                                /*
@@ -647,7 +642,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
        struct inftl_bci bci;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=%p,"
+       pr_debug("INFTL: INFTL_trydeletechain(inftl=%p,"
                "thisVUC=%d)\n", inftl, thisVUC);
 
        memset(BlockUsed, 0, sizeof(BlockUsed));
@@ -711,7 +706,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
         * For each block in the chain free it and make it available
         * for future use. Erase from the oldest unit first.
         */
-       DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
+       pr_debug("INFTL: deleting empty VUC %d\n", thisVUC);
 
        for (;;) {
                u16 *prevEUN = &inftl->VUtable[thisVUC];
@@ -719,7 +714,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
 
                /* If the chain is all gone already, we're done */
                if (thisEUN == BLOCK_NIL) {
-                       DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
+                       pr_debug("INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
                        return;
                }
 
@@ -731,7 +726,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
                        thisEUN = *prevEUN;
                }
 
-               DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
+               pr_debug("Deleting EUN %d from VUC %d\n",
                      thisEUN, thisVUC);
 
                if (INFTL_formatblock(inftl, thisEUN) < 0) {
@@ -767,7 +762,7 @@ static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
        size_t retlen;
        struct inftl_bci bci;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=%p,"
+       pr_debug("INFTL: INFTL_deleteblock(inftl=%p,"
                "block=%d)\n", inftl, block);
 
        while (thisEUN < inftl->nb_blocks) {
@@ -826,7 +821,7 @@ static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
        struct inftl_oob oob;
        char *p, *pend;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=%p,block=%ld,"
+       pr_debug("INFTL: inftl_writeblock(inftl=%p,block=%ld,"
                "buffer=%p)\n", inftl, block, buffer);
 
        /* Is block all zero? */
@@ -876,7 +871,7 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
        struct inftl_bci bci;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=%p,block=%ld,"
+       pr_debug("INFTL: inftl_readblock(inftl=%p,block=%ld,"
                "buffer=%p)\n", inftl, block, buffer);
 
        while (thisEUN < inftl->nb_blocks) {
@@ -922,7 +917,7 @@ foundit:
                int ret = mtd->read(mtd, ptr, SECTORSIZE, &retlen, buffer);
 
                /* Handle corrected bit flips gracefully */
-               if (ret < 0 && ret != -EUCLEAN)
+               if (ret < 0 && !mtd_is_bitflip(ret))
                        return -EIO;
        }
        return 0;
index 104052e774b06a33ce56191f62077d29b8af57e6..2ff601f816cebd12b4210b199e85fbcbdfb424cf 100644 (file)
@@ -53,7 +53,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
        struct INFTLPartition *ip;
        size_t retlen;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=%p)\n", inftl);
+       pr_debug("INFTL: find_boot_record(inftl=%p)\n", inftl);
 
         /*
         * Assume logical EraseSize == physical erasesize for starting the
@@ -139,24 +139,20 @@ static int find_boot_record(struct INFTLrecord *inftl)
                mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
                mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-               if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-                       printk("INFTL: Media Header ->\n"
-                               "    bootRecordID          = %s\n"
-                               "    NoOfBootImageBlocks   = %d\n"
-                               "    NoOfBinaryPartitions  = %d\n"
-                               "    NoOfBDTLPartitions    = %d\n"
-                               "    BlockMultiplerBits    = %d\n"
-                               "    FormatFlgs            = %d\n"
-                               "    OsakVersion           = 0x%x\n"
-                               "    PercentUsed           = %d\n",
-                               mh->bootRecordID, mh->NoOfBootImageBlocks,
-                               mh->NoOfBinaryPartitions,
-                               mh->NoOfBDTLPartitions,
-                               mh->BlockMultiplierBits, mh->FormatFlags,
-                               mh->OsakVersion, mh->PercentUsed);
-               }
-#endif
+               pr_debug("INFTL: Media Header ->\n"
+                        "    bootRecordID          = %s\n"
+                        "    NoOfBootImageBlocks   = %d\n"
+                        "    NoOfBinaryPartitions  = %d\n"
+                        "    NoOfBDTLPartitions    = %d\n"
+                        "    BlockMultiplerBits    = %d\n"
+                        "    FormatFlgs            = %d\n"
+                        "    OsakVersion           = 0x%x\n"
+                        "    PercentUsed           = %d\n",
+                        mh->bootRecordID, mh->NoOfBootImageBlocks,
+                        mh->NoOfBinaryPartitions,
+                        mh->NoOfBDTLPartitions,
+                        mh->BlockMultiplierBits, mh->FormatFlags,
+                        mh->OsakVersion, mh->PercentUsed);
 
                if (mh->NoOfBDTLPartitions == 0) {
                        printk(KERN_WARNING "INFTL: Media Header sanity check "
@@ -200,19 +196,15 @@ static int find_boot_record(struct INFTLrecord *inftl)
                        ip->spareUnits = le32_to_cpu(ip->spareUnits);
                        ip->Reserved0 = le32_to_cpu(ip->Reserved0);
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-                       if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-                               printk("    PARTITION[%d] ->\n"
-                                       "        virtualUnits    = %d\n"
-                                       "        firstUnit       = %d\n"
-                                       "        lastUnit        = %d\n"
-                                       "        flags           = 0x%x\n"
-                                       "        spareUnits      = %d\n",
-                                       i, ip->virtualUnits, ip->firstUnit,
-                                       ip->lastUnit, ip->flags,
-                                       ip->spareUnits);
-                       }
-#endif
+                       pr_debug("    PARTITION[%d] ->\n"
+                                "        virtualUnits    = %d\n"
+                                "        firstUnit       = %d\n"
+                                "        lastUnit        = %d\n"
+                                "        flags           = 0x%x\n"
+                                "        spareUnits      = %d\n",
+                                i, ip->virtualUnits, ip->firstUnit,
+                                ip->lastUnit, ip->flags,
+                                ip->spareUnits);
 
                        if (ip->Reserved0 != ip->firstUnit) {
                                struct erase_info *instr = &inftl->instr;
@@ -375,7 +367,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
  *
  * Return: 0 when succeed, -1 on error.
  *
- * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ * ToDo: 1. Is it necessary to check_free_sector after erasing ??
  */
 int INFTL_formatblock(struct INFTLrecord *inftl, int block)
 {
@@ -385,8 +377,7 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
        struct mtd_info *mtd = inftl->mbd.mtd;
        int physblock;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=%p,"
-               "block=%d)\n", inftl, block);
+       pr_debug("INFTL: INFTL_formatblock(inftl=%p,block=%d)\n", inftl, block);
 
        memset(instr, 0, sizeof(struct erase_info));
 
@@ -476,30 +467,30 @@ void INFTL_dumptables(struct INFTLrecord *s)
 {
        int i;
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 
-       printk("VUtable[%d] ->", s->nb_blocks);
+       pr_debug("VUtable[%d] ->", s->nb_blocks);
        for (i = 0; i < s->nb_blocks; i++) {
                if ((i % 8) == 0)
-                       printk("\n%04x: ", i);
-               printk("%04x ", s->VUtable[i]);
+                       pr_debug("\n%04x: ", i);
+               pr_debug("%04x ", s->VUtable[i]);
        }
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 
-       printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
+       pr_debug("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
        for (i = 0; i <= s->lastEUN; i++) {
                if ((i % 8) == 0)
-                       printk("\n%04x: ", i);
-               printk("%04x ", s->PUtable[i]);
+                       pr_debug("\n%04x: ", i);
+               pr_debug("%04x ", s->PUtable[i]);
        }
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 
-       printk("INFTL ->\n"
+       pr_debug("INFTL ->\n"
                "  EraseSize       = %d\n"
                "  h/s/c           = %d/%d/%d\n"
                "  numvunits       = %d\n"
@@ -513,7 +504,7 @@ void INFTL_dumptables(struct INFTLrecord *s)
                s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
                s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
 
-       printk("\n-------------------------------------------"
+       pr_debug("\n-------------------------------------------"
                "----------------------------------\n");
 }
 
@@ -521,25 +512,25 @@ void INFTL_dumpVUchains(struct INFTLrecord *s)
 {
        int logical, block, i;
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 
-       printk("INFTL Virtual Unit Chains:\n");
+       pr_debug("INFTL Virtual Unit Chains:\n");
        for (logical = 0; logical < s->nb_blocks; logical++) {
                block = s->VUtable[logical];
                if (block > s->nb_blocks)
                        continue;
-               printk("  LOGICAL %d --> %d ", logical, block);
+               pr_debug("  LOGICAL %d --> %d ", logical, block);
                for (i = 0; i < s->nb_blocks; i++) {
                        if (s->PUtable[block] == BLOCK_NIL)
                                break;
                        block = s->PUtable[block];
-                       printk("%d ", block);
+                       pr_debug("%d ", block);
                }
-               printk("\n");
+               pr_debug("\n");
        }
 
-       printk("-------------------------------------------"
+       pr_debug("-------------------------------------------"
                "----------------------------------\n");
 }
 
@@ -555,7 +546,7 @@ int INFTL_mount(struct INFTLrecord *s)
        int i;
        u8 *ANACtable, ANAC;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=%p)\n", s);
+       pr_debug("INFTL: INFTL_mount(inftl=%p)\n", s);
 
        /* Search for INFTL MediaHeader and Spare INFTL Media Header */
        if (find_boot_record(s) < 0) {
@@ -585,7 +576,7 @@ int INFTL_mount(struct INFTLrecord *s)
         * NOTEXPLORED state. Then at the end we will try to format it and
         * mark it as free.
         */
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
+       pr_debug("INFTL: pass 1, explore each unit\n");
        for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
                if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
                        continue;
@@ -717,17 +708,14 @@ int INFTL_mount(struct INFTLrecord *s)
                logical_block = BLOCK_NIL;
        }
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumptables(s);
-#endif
+       INFTL_dumptables(s);
 
        /*
         * Second pass, check for infinite loops in chains. These are
         * possible because we don't update the previous pointers when
         * we fold chains. No big deal, just fix them up in PUtable.
         */
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
+       pr_debug("INFTL: pass 2, validate virtual chains\n");
        for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
                block = s->VUtable[logical_block];
                last_block = BLOCK_NIL;
@@ -772,12 +760,8 @@ int INFTL_mount(struct INFTLrecord *s)
                }
        }
 
-#ifdef CONFIG_MTD_DEBUG_VERBOSE
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumptables(s);
-       if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-               INFTL_dumpVUchains(s);
-#endif
+       INFTL_dumptables(s);
+       INFTL_dumpVUchains(s);
 
        /*
         * Third pass, format unreferenced blocks and init free block count.
@@ -785,7 +769,7 @@ int INFTL_mount(struct INFTLrecord *s)
        s->numfreeEUNs = 0;
        s->LastFreeEUN = BLOCK_NIL;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
+       pr_debug("INFTL: pass 3, format unused blocks\n");
        for (block = s->firstEUN; block <= s->lastEUN; block++) {
                if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
                        printk("INFTL: unreferenced block %d, formatting it\n",
index 65655dd59e1f9e5948ac5bb138bd332abfa2cd05..1dca31d9a8b3dc189c06d4236e1d19bb77810a38 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mtd/pfow.h>
 #include <linux/mtd/qinfo.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
                                        size_t *retlen, u_char *buf);
index c0c328c5b133ccf51785a19385ae7a48a747aeaf..8e0c4bf9f7fb4e3b2a56f75b540ea8355d01c9c9 100644 (file)
@@ -41,8 +41,6 @@ config MTD_PHYSMAP_START
          are mapped on your particular target board. Refer to the
          memory map which should hopefully be in the documentation for
          your board.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_LEN
        hex "Physical length of flash mapping"
@@ -55,8 +53,6 @@ config MTD_PHYSMAP_LEN
          than the total amount of flash present. Refer to the memory
          map which should hopefully be in the documentation for your
          board.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_BANKWIDTH
        int "Bank width in octets"
@@ -67,8 +63,6 @@ config MTD_PHYSMAP_BANKWIDTH
          in octets. For example, if you have a data bus width of 32
          bits, you would set the bus width octet value to 4. This is
          used internally by the CFI drivers.
-         Ignore this option if you use run-time physmap configuration
-         (i.e., run-time calling physmap_configure()).
 
 config MTD_PHYSMAP_OF
        tristate "Flash device in physical memory map based on OF description"
@@ -260,7 +254,6 @@ config MTD_BCM963XX
 config MTD_LANTIQ
        tristate "Lantiq SoC NOR support"
        depends on LANTIQ
-       select MTD_PARTITIONS
        help
          Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
 
@@ -339,10 +332,6 @@ config MTD_SOLUTIONENGINE
          This enables access to the flash chips on the Hitachi SolutionEngine and
          similar boards. Say 'Y' if you are building a kernel for such a board.
 
-config MTD_ARM_INTEGRATOR
-       tristate "CFI Flash device mapped on ARM Integrator/P720T"
-       depends on ARM && MTD_CFI
-
 config MTD_CDB89712
        tristate "Cirrus CDB89712 evaluation board mappings"
        depends on MTD_CFI && ARCH_CDB89712
@@ -398,13 +387,6 @@ config MTD_AUTCPU12
          This enables access to the NV-RAM on autronix autcpu12 board.
          If you have such a board, say 'Y'.
 
-config MTD_EDB7312
-       tristate "CFI Flash device mapped on EDB7312"
-       depends on ARCH_EDB7312 && MTD_CFI
-       help
-         This enables access to the CFI Flash on the Cogent EDB7312 board.
-         If you have such a board, say 'Y' here.
-
 config MTD_IMPA7
        tristate "JEDEC Flash device mapped on impA7"
        depends on ARM && MTD_JEDECPROBE
@@ -412,14 +394,6 @@ config MTD_IMPA7
          This enables access to the NOR Flash on the impA7 board of
          implementa GmbH. If you have such a board, say 'Y' here.
 
-config MTD_CEIVA
-       tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
-       depends on MTD_JEDECPROBE && ARCH_CEIVA
-       help
-         This enables access to the flash chips on the Ceiva/Polaroid
-         PhotoMax Digital Picture Frame.
-         If you have such a device, say 'Y'.
-
 config MTD_H720X
        tristate "Hynix evaluation board mappings"
        depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
index cb48b11affff8aef535ac93cc96a936e85cd8c32..45dcb8b14f22f0b0cb3b4ed4d7ce85d447c4da79 100644 (file)
@@ -19,7 +19,6 @@ obj-$(CONFIG_MTD_CK804XROM)   += ck804xrom.o
 obj-$(CONFIG_MTD_TSUNAMI)      += tsunami_flash.o
 obj-$(CONFIG_MTD_PXA2XX)       += pxa2xx-flash.o
 obj-$(CONFIG_MTD_MBX860)       += mbx860.o
-obj-$(CONFIG_MTD_CEIVA)                += ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)      += octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)      += physmap.o
 obj-$(CONFIG_MTD_PHYSMAP_OF)   += physmap_of.o
@@ -40,7 +39,6 @@ obj-$(CONFIG_MTD_DBOX2)               += dbox2-flash.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)          += pci.o
 obj-$(CONFIG_MTD_AUTCPU12)     += autcpu12-nvram.o
-obj-$(CONFIG_MTD_EDB7312)      += edb7312.o
 obj-$(CONFIG_MTD_IMPA7)                += impa7.o
 obj-$(CONFIG_MTD_FORTUNET)     += fortunet.o
 obj-$(CONFIG_MTD_UCLINUX)      += uclinux.o
index 608967fe74c63b73c74268bed8306b1bba6a2079..736ca10ca9f11c0323d6062ef235f42a91f00727 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 67815eed2f0039b94a8e86301cf21bc4b88b9df5..6d6b2b5674ee6f4f27282e8356b301446a66c3eb 100644 (file)
@@ -41,7 +41,6 @@ struct async_state {
        uint32_t flash_ambctl0, flash_ambctl1;
        uint32_t save_ambctl0, save_ambctl1;
        unsigned long irq_flags;
-       struct mtd_partition *parts;
 };
 
 static void switch_to_flash(struct async_state *state)
@@ -165,18 +164,8 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
-       if (ret > 0) {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n");
-               mtd_device_register(state->mtd, pdata->parts, ret);
-               state->parts = pdata->parts;
-       } else if (pdata->nr_parts) {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n");
-               mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts);
-       } else {
-               pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n");
-               mtd_device_register(state->mtd, NULL, 0);
-       }
+       mtd_device_parse_register(state->mtd, part_probe_types, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, state);
 
@@ -188,7 +177,6 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev)
        struct async_state *state = platform_get_drvdata(pdev);
        gpio_free(state->enet_flash_pin);
        mtd_device_unregister(state->mtd);
-       kfree(state->parts);
        map_destroy(state->mtd);
        kfree(state);
        return 0;
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
deleted file mode 100644 (file)
index 06f9c98..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Ceiva flash memory driver.
- * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net>
- *
- * Note: this driver supports jedec compatible devices. Modification
- * for CFI compatible devices should be straight forward: change
- * jedec_probe to cfi_probe.
- *
- * Based on: sa1100-flash.c, which has the following copyright:
- * Flash memory access on SA11x0 based devices
- *
- * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/concat.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-/*
- * This isn't complete yet, so...
- */
-#define CONFIG_MTD_CEIVA_STATICMAP
-
-#ifdef CONFIG_MTD_CEIVA_STATICMAP
-/*
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
- * Please note:
- *  1. The flash size given should be the largest flash size that can
- *     be accommodated.
- *
- *  2. The bus width must defined in clps_setup_flash.
- *
- * The MTD layer will detect flash chip aliasing and reduce the size of
- * the map accordingly.
- *
- */
-
-#ifdef CONFIG_ARCH_CEIVA
-/* Flash / Partition sizing */
-/* For the 28F8003, we use the block mapping to calcuate the sizes */
-#define MAX_SIZE_KiB                  (16 + 8 + 8 + 96 + (7*128))
-#define BOOT_PARTITION_SIZE_KiB       (16)
-#define PARAMS_PARTITION_SIZE_KiB     (8)
-#define KERNEL_PARTITION_SIZE_KiB     (4*128)
-/* Use both remaining portion of first flash, and all of second flash */
-#define ROOT_PARTITION_SIZE_KiB       (3*128) + (8*128)
-
-static struct mtd_partition ceiva_partitions[] = {
-       {
-               .name = "Ceiva BOOT partition",
-               .size   = BOOT_PARTITION_SIZE_KiB*1024,
-               .offset = 0,
-
-       },{
-               .name = "Ceiva parameters partition",
-               .size   = PARAMS_PARTITION_SIZE_KiB*1024,
-               .offset = (16 + 8) * 1024,
-       },{
-               .name = "Ceiva kernel partition",
-               .size = (KERNEL_PARTITION_SIZE_KiB)*1024,
-               .offset = 0x20000,
-
-       },{
-               .name = "Ceiva root filesystem partition",
-               .offset = MTDPART_OFS_APPEND,
-               .size = (ROOT_PARTITION_SIZE_KiB)*1024,
-       }
-};
-#endif
-
-static int __init clps_static_partitions(struct mtd_partition **parts)
-{
-       int nb_parts = 0;
-
-#ifdef CONFIG_ARCH_CEIVA
-       if (machine_is_ceiva()) {
-               *parts       = ceiva_partitions;
-               nb_parts     = ARRAY_SIZE(ceiva_partitions);
-       }
-#endif
-       return nb_parts;
-}
-#endif
-
-struct clps_info {
-       unsigned long base;
-       unsigned long size;
-       int width;
-       void *vbase;
-       struct map_info *map;
-       struct mtd_info *mtd;
-       struct resource *res;
-};
-
-#define NR_SUBMTD 4
-
-static struct clps_info info[NR_SUBMTD];
-
-static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd)
-{
-       struct mtd_info *subdev[nr];
-       struct map_info *maps;
-       int i, found = 0, ret = 0;
-
-       /*
-        * Allocate the map_info structs in one go.
-        */
-       maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
-       if (!maps)
-               return -ENOMEM;
-       /*
-        * Claim and then map the memory regions.
-        */
-       for (i = 0; i < nr; i++) {
-               if (clps[i].base == (unsigned long)-1)
-                       break;
-
-               clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash");
-               if (!clps[i].res) {
-                       ret = -EBUSY;
-                       break;
-               }
-
-               clps[i].map = maps + i;
-
-               clps[i].map->name = "clps flash";
-               clps[i].map->phys = clps[i].base;
-
-               clps[i].vbase = ioremap(clps[i].base, clps[i].size);
-               if (!clps[i].vbase) {
-                       ret = -ENOMEM;
-                       break;
-               }
-
-               clps[i].map->virt = (void __iomem *)clps[i].vbase;
-               clps[i].map->bankwidth = clps[i].width;
-               clps[i].map->size = clps[i].size;
-
-               simple_map_init(&clps[i].map);
-
-               clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
-               if (clps[i].mtd == NULL) {
-                       ret = -ENXIO;
-                       break;
-               }
-               clps[i].mtd->owner = THIS_MODULE;
-               subdev[i] = clps[i].mtd;
-
-               printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
-                       "%d-bit\n", clps[i].base, clps[i].mtd->size >> 20,
-                       clps[i].width * 8);
-               found += 1;
-       }
-
-       /*
-        * ENXIO is special.  It means we didn't find a chip when
-        * we probed.  We need to tear down the mapping, free the
-        * resource and mark it as such.
-        */
-       if (ret == -ENXIO) {
-               iounmap(clps[i].vbase);
-               clps[i].vbase = NULL;
-               release_resource(clps[i].res);
-               clps[i].res = NULL;
-       }
-
-       /*
-        * If we found one device, don't bother with concat support.
-        * If we found multiple devices, use concat if we have it
-        * available, otherwise fail.
-        */
-       if (ret == 0 || ret == -ENXIO) {
-               if (found == 1) {
-                       *rmtd = subdev[0];
-                       ret = 0;
-               } else if (found > 1) {
-                       /*
-                        * We detected multiple devices.  Concatenate
-                        * them together.
-                        */
-                       *rmtd = mtd_concat_create(subdev, found,
-                                                 "clps flash");
-                       if (*rmtd == NULL)
-                               ret = -ENXIO;
-               }
-       }
-
-       /*
-        * If we failed, clean up.
-        */
-       if (ret) {
-               do {
-                       if (clps[i].mtd)
-                               map_destroy(clps[i].mtd);
-                       if (clps[i].vbase)
-                               iounmap(clps[i].vbase);
-                       if (clps[i].res)
-                               release_resource(clps[i].res);
-               } while (i--);
-
-               kfree(maps);
-       }
-
-       return ret;
-}
-
-static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd)
-{
-       int i;
-
-       mtd_device_unregister(mtd);
-
-       if (mtd != clps[0].mtd)
-               mtd_concat_destroy(mtd);
-
-       for (i = NR_SUBMTD; i >= 0; i--) {
-               if (clps[i].mtd)
-                       map_destroy(clps[i].mtd);
-               if (clps[i].vbase)
-                       iounmap(clps[i].vbase);
-               if (clps[i].res)
-                       release_resource(clps[i].res);
-       }
-       kfree(clps[0].map);
-}
-
-/*
- * We define the memory space, size, and width for the flash memory
- * space here.
- */
-
-static int __init clps_setup_flash(void)
-{
-       int nr = 0;
-
-#ifdef CONFIG_ARCH_CEIVA
-       if (machine_is_ceiva()) {
-               info[0].base = CS0_PHYS_BASE;
-               info[0].size = SZ_32M;
-               info[0].width = CEIVA_FLASH_WIDTH;
-               info[1].base = CS1_PHYS_BASE;
-               info[1].size = SZ_32M;
-               info[1].width = CEIVA_FLASH_WIDTH;
-               nr = 2;
-       }
-#endif
-       return nr;
-}
-
-static struct mtd_partition *parsed_parts;
-static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
-
-static void __init clps_locate_partitions(struct mtd_info *mtd)
-{
-       const char *part_type = NULL;
-       int nr_parts = 0;
-       do {
-               /*
-                * Partition selection stuff.
-                */
-               nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
-               if (nr_parts > 0) {
-                       part_type = "command line";
-                       break;
-               }
-#ifdef CONFIG_MTD_CEIVA_STATICMAP
-               nr_parts = clps_static_partitions(&parsed_parts);
-               if (nr_parts > 0) {
-                       part_type = "static";
-                       break;
-               }
-               printk("found: %d partitions\n", nr_parts);
-#endif
-       } while (0);
-
-       if (nr_parts == 0) {
-               printk(KERN_NOTICE "clps flash: no partition info "
-                       "available, registering whole flash\n");
-               mtd_device_register(mtd, NULL, 0);
-       } else {
-               printk(KERN_NOTICE "clps flash: using %s partition "
-                       "definition\n", part_type);
-               mtd_device_register(mtd, parsed_parts, nr_parts);
-       }
-
-       /* Always succeeds. */
-}
-
-static void __exit clps_destroy_partitions(void)
-{
-       kfree(parsed_parts);
-}
-
-static struct mtd_info *mymtd;
-
-static int __init clps_mtd_init(void)
-{
-       int ret;
-       int nr;
-
-       nr = clps_setup_flash();
-       if (nr < 0)
-               return nr;
-
-       ret = clps_setup_mtd(info, nr, &mymtd);
-       if (ret)
-               return ret;
-
-       clps_locate_partitions(mymtd);
-
-       return 0;
-}
-
-static void __exit clps_mtd_cleanup(void)
-{
-       clps_destroy_mtd(info, mymtd);
-       clps_destroy_partitions();
-}
-
-module_init(clps_mtd_init);
-module_exit(clps_mtd_cleanup);
-
-MODULE_AUTHOR("Rob Scott");
-MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver");
-MODULE_LICENSE("GPL");
index 7a9e1989c977a1c77694daead3cfd5b62013cb0d..f43b365b848c41ebf2e1a8614762de835b84bbbe 100644 (file)
@@ -145,14 +145,10 @@ static struct map_info dc21285_map = {
 
 
 /* Partition stuff */
-static struct mtd_partition *dc21285_parts;
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 static int __init init_dc21285(void)
 {
-
-       int nrparts;
-
        /* Determine bankwidth */
        switch (*CSR_SA110_CNTL & (3<<14)) {
                case SA110_CNTL_ROMWIDTH_8:
@@ -200,8 +196,7 @@ static int __init init_dc21285(void)
 
        dc21285_mtd->owner = THIS_MODULE;
 
-       nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
-       mtd_device_register(dc21285_mtd, dc21285_parts, nrparts);
+       mtd_device_parse_register(dc21285_mtd, probes, 0, NULL, 0);
 
        if(machine_is_ebsa285()) {
                /*
@@ -224,8 +219,6 @@ static int __init init_dc21285(void)
 static void __exit cleanup_dc21285(void)
 {
        mtd_device_unregister(dc21285_mtd);
-       if (dc21285_parts)
-               kfree(dc21285_parts);
        map_destroy(dc21285_mtd);
        iounmap(dc21285_map.virt);
 }
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
deleted file mode 100644 (file)
index fe42a21..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Handle mapping of the NOR flash on Cogent EDB7312 boards
- *
- * Copyright 2002 SYSGO Real-Time Solutions GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#define WINDOW_ADDR 0x00000000      /* physical properties of flash */
-#define WINDOW_SIZE 0x01000000
-#define BUSWIDTH    2
-#define FLASH_BLOCKSIZE_MAIN   0x20000
-#define FLASH_NUMBLOCKS_MAIN   128
-/* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
-#define PROBETYPES { "cfi_probe", NULL }
-
-#define MSG_PREFIX "EDB7312-NOR:"   /* prefix for our printk()'s */
-#define MTDID      "edb7312-nor"    /* for mtdparts= partitioning */
-
-static struct mtd_info *mymtd;
-
-struct map_info edb7312nor_map = {
-       .name = "NOR flash on EDB7312",
-       .size = WINDOW_SIZE,
-       .bankwidth = BUSWIDTH,
-       .phys = WINDOW_ADDR,
-};
-
-/*
- * MTD partitioning stuff
- */
-static struct mtd_partition static_partitions[3] =
-{
-       {
-               .name = "ARMboot",
-               .size = 0x40000,
-               .offset = 0
-       },
-       {
-               .name = "Kernel",
-               .size = 0x200000,
-               .offset = 0x40000
-       },
-       {
-               .name = "RootFS",
-               .size = 0xDC0000,
-               .offset = 0x240000
-       },
-};
-
-static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
-static int                   mtd_parts_nb = 0;
-static struct mtd_partition *mtd_parts    = 0;
-
-static int __init init_edb7312nor(void)
-{
-       static const char *rom_probe_types[] = PROBETYPES;
-       const char **type;
-       const char *part_type = 0;
-
-               printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
-              WINDOW_SIZE, WINDOW_ADDR);
-       edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-       if (!edb7312nor_map.virt) {
-               printk(MSG_PREFIX "failed to ioremap\n");
-               return -EIO;
-       }
-
-       simple_map_init(&edb7312nor_map);
-
-       mymtd = 0;
-       type = rom_probe_types;
-       for(; !mymtd && *type; type++) {
-               mymtd = do_map_probe(*type, &edb7312nor_map);
-       }
-       if (mymtd) {
-               mymtd->owner = THIS_MODULE;
-
-               mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
-               if (mtd_parts_nb > 0)
-                       part_type = "detected";
-
-               if (mtd_parts_nb == 0) {
-                       mtd_parts = static_partitions;
-                       mtd_parts_nb = ARRAY_SIZE(static_partitions);
-                       part_type = "static";
-               }
-
-               if (mtd_parts_nb == 0)
-                       printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
-               else
-                       printk(KERN_NOTICE MSG_PREFIX
-                              "using %s partition definition\n", part_type);
-               /* Register the whole device first. */
-               mtd_device_register(mymtd, NULL, 0);
-               mtd_device_register(mymtd, mtd_parts, mtd_parts_nb);
-               return 0;
-       }
-
-       iounmap((void *)edb7312nor_map.virt);
-       return -ENXIO;
-}
-
-static void __exit cleanup_edb7312nor(void)
-{
-       if (mymtd) {
-               mtd_device_unregister(mymtd);
-               map_destroy(mymtd);
-       }
-       if (edb7312nor_map.virt) {
-               iounmap((void *)edb7312nor_map.virt);
-               edb7312nor_map.virt = 0;
-       }
-}
-
-module_init(init_edb7312nor);
-module_exit(cleanup_edb7312nor);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-MODULE_DESCRIPTION("Generic configurable MTD map driver");
index 7568c5f8b8ae648cb88754e94b34e03ec19c2d65..1ec66f031c51655bb4904c985565f47fc2fc3bfe 100644 (file)
@@ -187,7 +187,6 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
  */
 static int __devinit gpio_flash_probe(struct platform_device *pdev)
 {
-       int nr_parts;
        size_t i, arr_size;
        struct physmap_flash_data *pdata;
        struct resource *memory;
@@ -252,20 +251,9 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       nr_parts = parse_mtd_partitions(state->mtd, part_probe_types,
-                                       &pdata->parts, 0);
-       if (nr_parts > 0) {
-               pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n");
-               kfree(pdata->parts);
-       } else if (pdata->nr_parts) {
-               pr_devinit(KERN_NOTICE PFX "Using board partition definition\n");
-               nr_parts = pdata->nr_parts;
-       } else {
-               pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n");
-               nr_parts = 0;
-       }
 
-       mtd_device_register(state->mtd, pdata->parts, nr_parts);
+       mtd_device_parse_register(state->mtd, part_probe_types, 0,
+                       pdata->parts, pdata->nr_parts);
 
        return 0;
 }
index 7f035860a36bd43b8683945804fee50690f32351..49c14187fc66dc0e469f071db2971d2c0ca4be10 100644 (file)
@@ -58,18 +58,11 @@ static struct mtd_partition h720x_partitions[] = {
 
 #define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
 
-static int                   nr_mtd_parts;
-static struct mtd_partition *mtd_parts;
-static const char *probes[] = { "cmdlinepart", NULL };
-
 /*
  * Initialize FLASH support
  */
 static int __init h720x_mtd_init(void)
 {
-
-       char    *part_type = NULL;
-
        h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size);
 
        if (!h720x_map.virt) {
@@ -92,16 +85,8 @@ static int __init h720x_mtd_init(void)
        if (mymtd) {
                mymtd->owner = THIS_MODULE;
 
-               nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
-               if (nr_mtd_parts > 0)
-                       part_type = "command line";
-               if (nr_mtd_parts <= 0) {
-                       mtd_parts = h720x_partitions;
-                       nr_mtd_parts = NUM_PARTITIONS;
-                       part_type = "builtin";
-               }
-               printk(KERN_INFO "Using %s partition table\n", part_type);
-               mtd_device_register(mymtd, mtd_parts, nr_mtd_parts);
+               mtd_device_parse_register(mymtd, NULL, 0,
+                               h720x_partitions, NUM_PARTITIONS);
                return 0;
        }
 
@@ -120,10 +105,6 @@ static void __exit h720x_mtd_cleanup(void)
                map_destroy(mymtd);
        }
 
-       /* Free partition info, if commandline partition was used */
-       if (mtd_parts && (mtd_parts != h720x_partitions))
-               kfree (mtd_parts);
-
        if (h720x_map.virt) {
                iounmap((void *)h720x_map.virt);
                h720x_map.virt = 0;
index 404a50cbafa0596ef7ea8d2e0d760607d90bf3df..f47aedb24366bb0f1073a1d6c5803a103f029709 100644 (file)
@@ -49,7 +49,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
 /*
  * MTD partitioning stuff
  */
-static struct mtd_partition static_partitions[] =
+static struct mtd_partition partitions[] =
 {
        {
                .name = "FileSystem",
@@ -58,16 +58,10 @@ static struct mtd_partition static_partitions[] =
        },
 };
 
-static int mtd_parts_nb[NUM_FLASHBANKS];
-static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
-
-static const char *probes[] = { "cmdlinepart", NULL };
-
 static int __init init_impa7(void)
 {
        static const char *rom_probe_types[] = PROBETYPES;
        const char **type;
-       const char *part_type = 0;
        int i;
        static struct { u_long addr; u_long size; } pt[NUM_FLASHBANKS] = {
          { WINDOW_ADDR0, WINDOW_SIZE0 },
@@ -97,23 +91,9 @@ static int __init init_impa7(void)
                if (impa7_mtd[i]) {
                        impa7_mtd[i]->owner = THIS_MODULE;
                        devicesfound++;
-                       mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
-                                                              probes,
-                                                              &mtd_parts[i],
-                                                              0);
-                       if (mtd_parts_nb[i] > 0) {
-                               part_type = "command line";
-                       } else {
-                               mtd_parts[i] = static_partitions;
-                               mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
-                               part_type = "static";
-                       }
-
-                       printk(KERN_NOTICE MSG_PREFIX
-                              "using %s partition definition\n",
-                              part_type);
-                       mtd_device_register(impa7_mtd[i],
-                                           mtd_parts[i], mtd_parts_nb[i]);
+                       mtd_device_parse_register(impa7_mtd[i], NULL, 0,
+                                                 partitions,
+                                                 ARRAY_SIZE(partitions));
                }
                else
                        iounmap((void *)impa7_map[i].virt);
index d2f47be8754b211392c0841fd32685396878481a..08c239604ee44e1b71438feda4d30f065b0663f6 100644 (file)
@@ -44,7 +44,6 @@ struct vr_nor_mtd {
        void __iomem *csr_base;
        struct map_info map;
        struct mtd_info *info;
-       int nr_parts;
        struct pci_dev *dev;
 };
 
@@ -71,13 +70,9 @@ static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p)
 
 static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p)
 {
-       struct mtd_partition *parts;
-       static const char *part_probes[] = { "cmdlinepart", NULL };
-
        /* register the flash bank */
        /* partition the flash bank */
-       p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0);
-       return mtd_device_register(p->info, parts, p->nr_parts);
+       return mtd_device_parse_register(p->info, NULL, 0, NULL, 0);
 }
 
 static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
index 1594a802631d439f008c58b601e5c29ab6d14a21..437fcd2f352f8095b658cc4a9d1ef28cc01eddf5 100644 (file)
@@ -38,7 +38,6 @@
 struct ixp2000_flash_info {
        struct          mtd_info *mtd;
        struct          map_info map;
-       struct          mtd_partition *partitions;
        struct          resource *res;
 };
 
@@ -125,8 +124,6 @@ static int ixp2000_flash_remove(struct platform_device *dev)
        if (info->map.map_priv_1)
                iounmap((void *) info->map.map_priv_1);
 
-       kfree(info->partitions);
-
        if (info->res) {
                release_resource(info->res);
                kfree(info->res);
@@ -229,13 +226,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
-       if (err > 0) {
-               err = mtd_device_register(info->mtd, info->partitions, err);
-               if(err)
-                       dev_err(&dev->dev, "Could not parse partitions\n");
-       }
-
+       err = mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
        if (err)
                goto Error;
 
index 155b21942f4777a1aea10a8a22b04778ca82ec33..30409015a3de1d67e9d37c2ce345b0a837a28006 100644 (file)
@@ -145,7 +145,6 @@ static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
 struct ixp4xx_flash_info {
        struct mtd_info *mtd;
        struct map_info map;
-       struct mtd_partition *partitions;
        struct resource *res;
 };
 
@@ -168,8 +167,6 @@ static int ixp4xx_flash_remove(struct platform_device *dev)
        if (info->map.virt)
                iounmap(info->map.virt);
 
-       kfree(info->partitions);
-
        if (info->res) {
                release_resource(info->res);
                kfree(info->res);
@@ -185,8 +182,6 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 {
        struct flash_platform_data *plat = dev->dev.platform_data;
        struct ixp4xx_flash_info *info;
-       const char *part_type = NULL;
-       int nr_parts = 0;
        int err = -1;
 
        if (!plat)
@@ -252,28 +247,12 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
        /* Use the fast version */
        info->map.write = ixp4xx_write16;
 
-       nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
-                                       dev->resource->start);
-       if (nr_parts > 0) {
-               part_type = "dynamic";
-       } else {
-               info->partitions = plat->parts;
-               nr_parts = plat->nr_parts;
-               part_type = "static";
-       }
-       if (nr_parts == 0)
-               printk(KERN_NOTICE "IXP4xx flash: no partition info "
-                       "available, registering whole flash\n");
-       else
-               printk(KERN_NOTICE "IXP4xx flash: using %s partition "
-                       "definition\n", part_type);
-
-       err = mtd_device_register(info->mtd, info->partitions, nr_parts);
-       if (err)
+       err = mtd_device_parse_register(info->mtd, probes, dev->resource->start,
+                       plat->parts, plat->nr_parts);
+       if (err) {
                printk(KERN_ERR "Could not parse partitions\n");
-
-       if (err)
                goto Error;
+       }
 
        return 0;
 
index 7e508969239e92060e3e3818840756cf0f9c2a4a..4f10e27ada551d12f77cfd4d72b02f15ef9c5c8d 100644 (file)
@@ -107,16 +107,12 @@ ltq_copy_to(struct map_info *map, unsigned long to,
        spin_unlock_irqrestore(&ebu_lock, flags);
 }
 
-static const char const *part_probe_types[] = { "cmdlinepart", NULL };
-
 static int __init
 ltq_mtd_probe(struct platform_device *pdev)
 {
        struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
        struct ltq_mtd *ltq_mtd;
-       struct mtd_partition *parts;
        struct resource *res;
-       int nr_parts = 0;
        struct cfi_private *cfi;
        int err;
 
@@ -172,17 +168,8 @@ ltq_mtd_probe(struct platform_device *pdev)
        cfi->addr_unlock1 ^= 1;
        cfi->addr_unlock2 ^= 1;
 
-       nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
-                               part_probe_types, &parts, 0);
-       if (nr_parts > 0) {
-               dev_info(&pdev->dev,
-                       "using %d partitions from cmdline", nr_parts);
-       } else {
-               nr_parts = ltq_mtd_data->nr_parts;
-               parts = ltq_mtd_data->parts;
-       }
-
-       err = mtd_device_register(ltq_mtd->mtd, parts, nr_parts);
+       err = mtd_device_parse_register(ltq_mtd->mtd, NULL, 0,
+                       ltq_mtd_data->parts, ltq_mtd_data->nr_parts);
        if (err) {
                dev_err(&pdev->dev, "failed to add partitions\n");
                goto err_destroy;
index 5936c466e901369be6b0d7a9a13c4330fe78fcdc..119baa7d74773088ea0f07ffd316b6ee2c807b7d 100644 (file)
@@ -33,9 +33,6 @@ struct latch_addr_flash_info {
        /* cache; could be found out of res */
        unsigned long           win_mask;
 
-       int                     nr_parts;
-       struct mtd_partition    *parts;
-
        spinlock_t              lock;
 };
 
@@ -97,8 +94,6 @@ static void lf_copy_from(struct map_info *map, void *to,
 
 static char *rom_probe_types[] = { "cfi_probe", NULL };
 
-static char *part_probe_types[] = { "cmdlinepart", NULL };
-
 static int latch_addr_flash_remove(struct platform_device *dev)
 {
        struct latch_addr_flash_info *info;
@@ -112,8 +107,6 @@ static int latch_addr_flash_remove(struct platform_device *dev)
        latch_addr_data = dev->dev.platform_data;
 
        if (info->mtd != NULL) {
-               if (info->nr_parts)
-                       kfree(info->parts);
                mtd_device_unregister(info->mtd);
                map_destroy(info->mtd);
        }
@@ -206,21 +199,8 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       err = parse_mtd_partitions(info->mtd, (const char **)part_probe_types,
-                                  &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->mtd, info->parts, err);
-               return 0;
-       }
-       if (latch_addr_data->nr_parts) {
-               pr_notice("Using latch-addr-flash partition information\n");
-               mtd_device_register(info->mtd,
-                                   latch_addr_data->parts,
-                                   latch_addr_data->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->mtd, NULL, 0);
+       mtd_device_parse_register(info->mtd, NULL, 0,
+                       latch_addr_data->parts, latch_addr_data->nr_parts);
        return 0;
 
 iounmap:
index bbe168b65c26a392e09bc8bdb4783b2d5c7ab06f..e8e9fec23553d06ea34410633c12c8cce558fdb2 100644 (file)
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 
-#ifdef CONFIG_MTD_DEBUG
-static int debug = CONFIG_MTD_DEBUG_VERBOSE;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
-#undef DEBUG
-#define DEBUG(n, format, arg...) \
-       if (n <= debug) {        \
-               printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
-       }
-
-#else
-#undef DEBUG
-#define DEBUG(n, arg...)
-static const int debug = 0;
-#endif
-
 #define info(format, arg...) printk(KERN_INFO "pcmciamtd: " format "\n" , ## arg)
 
 #define DRIVER_DESC    "PCMCIA Flash memory card driver"
@@ -105,13 +89,13 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
        int ret;
 
        if (!pcmcia_dev_present(dev->p_dev)) {
-               DEBUG(1, "device removed");
+               pr_debug("device removed\n");
                return 0;
        }
 
        offset = to & ~(dev->win_size-1);
        if (offset != dev->offset) {
-               DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
+               pr_debug("Remapping window from 0x%8.8x to 0x%8.8x\n",
                      dev->offset, offset);
                ret = pcmcia_map_mem_page(dev->p_dev, win, offset);
                if (ret != 0)
@@ -132,7 +116,7 @@ static map_word pcmcia_read8_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx", ofs, addr, d.x[0]);
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -147,7 +131,7 @@ static map_word pcmcia_read16_remap(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(addr);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx", ofs, addr, d.x[0]);
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n", ofs, addr, d.x[0]);
        return d;
 }
 
@@ -157,7 +141,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
+       pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
        while(len) {
                int toread = win_size - (from & (win_size-1));
                caddr_t addr;
@@ -169,7 +153,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
                if(!addr)
                        return;
 
-               DEBUG(4, "memcpy from %p to %p len = %d", addr, to, toread);
+               pr_debug("memcpy from %p to %p len = %d\n", addr, to, toread);
                memcpy_fromio(to, addr, toread);
                len -= toread;
                to += toread;
@@ -185,7 +169,7 @@ static void pcmcia_write8_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx", adr, addr, d.x[0]);
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%02lx\n", adr, addr, d.x[0]);
        writeb(d.x[0], addr);
 }
 
@@ -196,7 +180,7 @@ static void pcmcia_write16_remap(struct map_info *map, map_word d, unsigned long
        if(!addr)
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx", adr, addr, d.x[0]);
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%04lx\n", adr, addr, d.x[0]);
        writew(d.x[0], addr);
 }
 
@@ -206,7 +190,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        unsigned long win_size = dev->win_size;
 
-       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
+       pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
        while(len) {
                int towrite = win_size - (to & (win_size-1));
                caddr_t addr;
@@ -218,7 +202,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
                if(!addr)
                        return;
 
-               DEBUG(4, "memcpy from %p to %p len = %d", from, addr, towrite);
+               pr_debug("memcpy from %p to %p len = %d\n", from, addr, towrite);
                memcpy_toio(addr, from, towrite);
                len -= towrite;
                to += towrite;
@@ -240,7 +224,7 @@ static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readb(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%02lx",
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%02lx\n",
              ofs, win_base + ofs, d.x[0]);
        return d;
 }
@@ -255,7 +239,7 @@ static map_word pcmcia_read16(struct map_info *map, unsigned long ofs)
                return d;
 
        d.x[0] = readw(win_base + ofs);
-       DEBUG(3, "ofs = 0x%08lx (%p) data = 0x%04lx",
+       pr_debug("ofs = 0x%08lx (%p) data = 0x%04lx\n",
              ofs, win_base + ofs, d.x[0]);
        return d;
 }
@@ -268,7 +252,7 @@ static void pcmcia_copy_from(struct map_info *map, void *to, unsigned long from,
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %p from = %lu len = %zd", to, from, len);
+       pr_debug("to = %p from = %lu len = %zd\n", to, from, len);
        memcpy_fromio(to, win_base + from, len);
 }
 
@@ -280,7 +264,7 @@ static void pcmcia_write8(struct map_info *map, map_word d, unsigned long adr)
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%02lx",
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%02lx\n",
              adr, win_base + adr, d.x[0]);
        writeb(d.x[0], win_base + adr);
 }
@@ -293,7 +277,7 @@ static void pcmcia_write16(struct map_info *map, map_word d, unsigned long adr)
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "adr = 0x%08lx (%p)  data = 0x%04lx",
+       pr_debug("adr = 0x%08lx (%p)  data = 0x%04lx\n",
              adr, win_base + adr, d.x[0]);
        writew(d.x[0], win_base + adr);
 }
@@ -306,7 +290,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
        if(DEV_REMOVED(map))
                return;
 
-       DEBUG(3, "to = %lu from = %p len = %zd", to, from, len);
+       pr_debug("to = %lu from = %p len = %zd\n", to, from, len);
        memcpy_toio(win_base + to, from, len);
 }
 
@@ -316,7 +300,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        struct pcmcia_device *link = dev->p_dev;
 
-       DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
+       pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
        pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
 }
 
@@ -325,7 +309,7 @@ static void pcmciamtd_release(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
 
-       DEBUG(3, "link = 0x%p", link);
+       pr_debug("link = 0x%p\n", link);
 
        if (link->resource[2]->end) {
                if(dev->win_base) {
@@ -337,7 +321,6 @@ static void pcmciamtd_release(struct pcmcia_device *link)
 }
 
 
-#ifdef CONFIG_MTD_DEBUG
 static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
                                tuple_t *tuple,
                                void *priv_data)
@@ -347,7 +330,7 @@ static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
        if (!pcmcia_parse_tuple(tuple, &parse)) {
                cistpl_format_t *t = &parse.format;
                (void)t; /* Shut up, gcc */
-               DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
+               pr_debug("Format type: %u, Error Detection: %u, offset = %u, length =%u\n",
                        t->type, t->edc, t->offset, t->length);
        }
        return -ENOSPC;
@@ -363,12 +346,11 @@ static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
        if (!pcmcia_parse_tuple(tuple, &parse)) {
                cistpl_jedec_t *t = &parse.jedec;
                for (i = 0; i < t->nid; i++)
-                       DEBUG(2, "JEDEC: 0x%02x 0x%02x",
+                       pr_debug("JEDEC: 0x%02x 0x%02x\n",
                              t->id[i].mfr, t->id[i].info);
        }
        return -ENOSPC;
 }
-#endif
 
 static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
                                tuple_t *tuple,
@@ -382,14 +364,14 @@ static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
        if (pcmcia_parse_tuple(tuple, &parse))
                return -EINVAL;
 
-       DEBUG(2, "Common memory:");
+       pr_debug("Common memory:\n");
        dev->pcmcia_map.size = t->dev[0].size;
        /* from here on: DEBUG only */
        for (i = 0; i < t->ndev; i++) {
-               DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
-               DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
-               DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
-               DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
+               pr_debug("Region %d, type = %u\n", i, t->dev[i].type);
+               pr_debug("Region %d, wp = %u\n", i, t->dev[i].wp);
+               pr_debug("Region %d, speed = %u ns\n", i, t->dev[i].speed);
+               pr_debug("Region %d, size = %u bytes\n", i, t->dev[i].size);
        }
        return 0;
 }
@@ -409,12 +391,12 @@ static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
        dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
        /* from here on: DEBUG only */
        for (i = 0; i < t->ngeo; i++) {
-               DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
-               DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
-               DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
-               DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
-               DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
-               DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
+               pr_debug("region: %d bankwidth = %u\n", i, t->geo[i].buswidth);
+               pr_debug("region: %d erase_block = %u\n", i, t->geo[i].erase_block);
+               pr_debug("region: %d read_block = %u\n", i, t->geo[i].read_block);
+               pr_debug("region: %d write_block = %u\n", i, t->geo[i].write_block);
+               pr_debug("region: %d partition = %u\n", i, t->geo[i].partition);
+               pr_debug("region: %d interleave = %u\n", i, t->geo[i].interleave);
        }
        return 0;
 }
@@ -432,13 +414,11 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
                        if (p_dev->prod_id[i])
                                strcat(dev->mtd_name, p_dev->prod_id[i]);
                }
-               DEBUG(2, "Found name: %s", dev->mtd_name);
+               pr_debug("Found name: %s\n", dev->mtd_name);
        }
 
-#ifdef CONFIG_MTD_DEBUG
        pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
        pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
-#endif
        pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
        pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
 
@@ -450,12 +430,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
 
        if(force_size) {
                dev->pcmcia_map.size = force_size << 20;
-               DEBUG(2, "size forced to %dM", force_size);
+               pr_debug("size forced to %dM\n", force_size);
        }
 
        if(bankwidth) {
                dev->pcmcia_map.bankwidth = bankwidth;
-               DEBUG(2, "bankwidth forced to %d", bankwidth);
+               pr_debug("bankwidth forced to %d\n", bankwidth);
        }
 
        dev->pcmcia_map.name = dev->mtd_name;
@@ -464,7 +444,7 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
                *new_name = 1;
        }
 
-       DEBUG(1, "Device: Size: %lu Width:%d Name: %s",
+       pr_debug("Device: Size: %lu Width:%d Name: %s\n",
              dev->pcmcia_map.size,
              dev->pcmcia_map.bankwidth << 3, dev->mtd_name);
 }
@@ -479,7 +459,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        static char *probes[] = { "jedec_probe", "cfi_probe" };
        int new_name = 0;
 
-       DEBUG(3, "link=0x%p", link);
+       pr_debug("link=0x%p\n", link);
 
        card_settings(dev, link, &new_name);
 
@@ -512,11 +492,11 @@ static int pcmciamtd_config(struct pcmcia_device *link)
 
        do {
                int ret;
-               DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
+               pr_debug("requesting window with size = %luKiB memspeed = %d\n",
                        (unsigned long) resource_size(link->resource[2]) >> 10,
                        mem_speed);
                ret = pcmcia_request_window(link, link->resource[2], mem_speed);
-               DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
+               pr_debug("ret = %d dev->win_size = %d\n", ret, dev->win_size);
                if(ret) {
                        j++;
                        link->resource[2]->start = 0;
@@ -524,21 +504,21 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                                        force_size << 20 : MAX_PCMCIA_ADDR;
                        link->resource[2]->end >>= j;
                } else {
-                       DEBUG(2, "Got window of size %luKiB", (unsigned long)
+                       pr_debug("Got window of size %luKiB\n", (unsigned long)
                                resource_size(link->resource[2]) >> 10);
                        dev->win_size = resource_size(link->resource[2]);
                        break;
                }
        } while (link->resource[2]->end >= 0x1000);
 
-       DEBUG(2, "dev->win_size = %d", dev->win_size);
+       pr_debug("dev->win_size = %d\n", dev->win_size);
 
        if(!dev->win_size) {
                dev_err(&dev->p_dev->dev, "Cannot allocate memory window\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
-       DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
+       pr_debug("Allocated a window of %dKiB\n", dev->win_size >> 10);
 
        /* Get write protect status */
        dev->win_base = ioremap(link->resource[2]->start,
@@ -549,7 +529,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                pcmciamtd_release(link);
                return -ENODEV;
        }
-       DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
+       pr_debug("mapped window dev = %p @ %pR, base = %p\n",
              dev, link->resource[2], dev->win_base);
 
        dev->offset = 0;
@@ -564,7 +544,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        }
 
        link->config_index = 0;
-       DEBUG(2, "Setting Configuration");
+       pr_debug("Setting Configuration\n");
        ret = pcmcia_enable_device(link);
        if (ret != 0) {
                if (dev->win_base) {
@@ -580,17 +560,17 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                mtd = do_map_probe("map_rom", &dev->pcmcia_map);
        } else {
                for(i = 0; i < ARRAY_SIZE(probes); i++) {
-                       DEBUG(1, "Trying %s", probes[i]);
+                       pr_debug("Trying %s\n", probes[i]);
                        mtd = do_map_probe(probes[i], &dev->pcmcia_map);
                        if(mtd)
                                break;
 
-                       DEBUG(1, "FAILED: %s", probes[i]);
+                       pr_debug("FAILED: %s\n", probes[i]);
                }
        }
 
        if(!mtd) {
-               DEBUG(1, "Can not find an MTD");
+               pr_debug("Can not find an MTD\n");
                pcmciamtd_release(link);
                return -ENODEV;
        }
@@ -617,7 +597,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        /* If the memory found is fits completely into the mapped PCMCIA window,
           use the faster non-remapping read/write functions */
        if(mtd->size <= dev->win_size) {
-               DEBUG(1, "Using non remapping memory functions");
+               pr_debug("Using non remapping memory functions\n");
                dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
                if (dev->pcmcia_map.bankwidth == 1) {
                        dev->pcmcia_map.read = pcmcia_read8;
@@ -645,7 +625,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
 
 static int pcmciamtd_suspend(struct pcmcia_device *dev)
 {
-       DEBUG(2, "EVENT_PM_RESUME");
+       pr_debug("EVENT_PM_RESUME\n");
 
        /* get_lock(link); */
 
@@ -654,7 +634,7 @@ static int pcmciamtd_suspend(struct pcmcia_device *dev)
 
 static int pcmciamtd_resume(struct pcmcia_device *dev)
 {
-       DEBUG(2, "EVENT_PM_SUSPEND");
+       pr_debug("EVENT_PM_SUSPEND\n");
 
        /* free_lock(link); */
 
@@ -666,7 +646,7 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
 
-       DEBUG(3, "link=0x%p", link);
+       pr_debug("link=0x%p\n", link);
 
        if(dev->mtd_info) {
                mtd_device_unregister(dev->mtd_info);
@@ -686,7 +666,7 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
        /* Create new memory card device */
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev) return -ENOMEM;
-       DEBUG(1, "dev=0x%p", dev);
+       pr_debug("dev=0x%p\n", dev);
 
        dev->p_dev = link;
        link->priv = dev;
@@ -755,7 +735,7 @@ static int __init init_pcmciamtd(void)
 
 static void __exit exit_pcmciamtd(void)
 {
-       DEBUG(1, DRIVER_DESC " unloading");
+       pr_debug(DRIVER_DESC " unloading");
        pcmcia_unregister_driver(&pcmciamtd_driver);
 }
 
index f64cee4a3bfbeba9674fea84c4465e645d925594..66e8200079c2c25633db8f662967825575b89915 100644 (file)
@@ -27,8 +27,6 @@ struct physmap_flash_info {
        struct mtd_info         *mtd[MAX_RESOURCES];
        struct mtd_info         *cmtd;
        struct map_info         map[MAX_RESOURCES];
-       int                     nr_parts;
-       struct mtd_partition    *parts;
 };
 
 static int physmap_flash_remove(struct platform_device *dev)
@@ -46,8 +44,6 @@ static int physmap_flash_remove(struct platform_device *dev)
 
        if (info->cmtd) {
                mtd_device_unregister(info->cmtd);
-               if (info->nr_parts)
-                       kfree(info->parts);
                if (info->cmtd != info->mtd[0])
                        mtd_concat_destroy(info->cmtd);
        }
@@ -175,23 +171,8 @@ static int physmap_flash_probe(struct platform_device *dev)
        if (err)
                goto err_out;
 
-       err = parse_mtd_partitions(info->cmtd, part_probe_types,
-                                  &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->cmtd, info->parts, err);
-               info->nr_parts = err;
-               return 0;
-       }
-
-       if (physmap_data->nr_parts) {
-               printk(KERN_NOTICE "Using physmap partition information\n");
-               mtd_device_register(info->cmtd, physmap_data->parts,
-                                   physmap_data->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->cmtd, NULL, 0);
-
+       mtd_device_parse_register(info->cmtd, part_probe_types, 0,
+                                 physmap_data->parts, physmap_data->nr_parts);
        return 0;
 
 err_out:
@@ -245,21 +226,6 @@ static struct platform_device physmap_flash = {
        .num_resources  = 1,
        .resource       = &physmap_flash_resource,
 };
-
-void physmap_configure(unsigned long addr, unsigned long size,
-               int bankwidth, void (*set_vpp)(struct map_info *, int))
-{
-       physmap_flash_resource.start = addr;
-       physmap_flash_resource.end = addr + size - 1;
-       physmap_flash_data.width = bankwidth;
-       physmap_flash_data.set_vpp = set_vpp;
-}
-
-void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
-{
-       physmap_flash_data.nr_parts = num_parts;
-       physmap_flash_data.parts = parts;
-}
 #endif
 
 static int __init physmap_init(void)
index d251d1db129b3fd81391302b1add42b0052e869d..7d65f9d3e6902e442003dfd7455953d1199c2d9a 100644 (file)
@@ -34,58 +34,10 @@ struct of_flash_list {
 
 struct of_flash {
        struct mtd_info         *cmtd;
-       struct mtd_partition    *parts;
        int list_size; /* number of elements in of_flash_list */
        struct of_flash_list    list[0];
 };
 
-#define OF_FLASH_PARTS(info)   ((info)->parts)
-static int parse_obsolete_partitions(struct platform_device *dev,
-                                    struct of_flash *info,
-                                    struct device_node *dp)
-{
-       int i, plen, nr_parts;
-       const struct {
-               __be32 offset, len;
-       } *part;
-       const char *names;
-
-       part = of_get_property(dp, "partitions", &plen);
-       if (!part)
-               return 0; /* No partitions found */
-
-       dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
-
-       nr_parts = plen / sizeof(part[0]);
-
-       info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
-       if (!info->parts)
-               return -ENOMEM;
-
-       names = of_get_property(dp, "partition-names", &plen);
-
-       for (i = 0; i < nr_parts; i++) {
-               info->parts[i].offset = be32_to_cpu(part->offset);
-               info->parts[i].size   = be32_to_cpu(part->len) & ~1;
-               if (be32_to_cpu(part->len) & 1) /* bit 0 set signifies read only partition */
-                       info->parts[i].mask_flags = MTD_WRITEABLE;
-
-               if (names && (plen > 0)) {
-                       int len = strlen(names) + 1;
-
-                       info->parts[i].name = (char *)names;
-                       plen -= len;
-                       names += len;
-               } else {
-                       info->parts[i].name = "unnamed";
-               }
-
-               part++;
-       }
-
-       return nr_parts;
-}
-
 static int of_flash_remove(struct platform_device *dev)
 {
        struct of_flash *info;
@@ -101,11 +53,8 @@ static int of_flash_remove(struct platform_device *dev)
                mtd_concat_destroy(info->cmtd);
        }
 
-       if (info->cmtd) {
-               if (OF_FLASH_PARTS(info))
-                       kfree(OF_FLASH_PARTS(info));
+       if (info->cmtd)
                mtd_device_unregister(info->cmtd);
-       }
 
        for (i = 0; i < info->list_size; i++) {
                if (info->list[i].mtd)
@@ -165,7 +114,8 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
    specifies the list of partition probers to use. If none is given then the
    default is use. These take precedence over other device tree
    information. */
-static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
+static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
+                                       "ofpart", "ofoldpart", NULL };
 static const char ** __devinit of_get_probes(struct device_node *dp)
 {
        const char *cp;
@@ -218,6 +168,7 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        int reg_tuple_size;
        struct mtd_info **mtd_list = NULL;
        resource_size_t res_size;
+       struct mtd_part_parser_data ppdata;
 
        match = of_match_device(of_flash_match, &dev->dev);
        if (!match)
@@ -331,29 +282,12 @@ static int __devinit of_flash_probe(struct platform_device *dev)
        if (err)
                goto err_out;
 
+       ppdata.of_node = dp;
        part_probe_types = of_get_probes(dp);
-       err = parse_mtd_partitions(info->cmtd, part_probe_types,
-                                  &info->parts, 0);
-       if (err < 0) {
-               of_free_probes(part_probe_types);
-               goto err_out;
-       }
+       mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
+                       NULL, 0);
        of_free_probes(part_probe_types);
 
-       if (err == 0) {
-               err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
-               if (err < 0)
-                       goto err_out;
-       }
-
-       if (err == 0) {
-               err = parse_obsolete_partitions(dev, info, dp);
-               if (err < 0)
-                       goto err_out;
-       }
-
-       mtd_device_register(info->cmtd, info->parts, err);
-
        kfree(mtd_list);
 
        return 0;
index 9ca1eccba4bc2e70b0d5e7ea6c3be5d014f6da5e..94f553489725280d2ec851023f17745e86c48d9a 100644 (file)
@@ -44,8 +44,6 @@ struct platram_info {
        struct device           *dev;
        struct mtd_info         *mtd;
        struct map_info          map;
-       struct mtd_partition    *partitions;
-       bool                    free_partitions;
        struct resource         *area;
        struct platdata_mtd_ram *pdata;
 };
@@ -95,10 +93,6 @@ static int platram_remove(struct platform_device *pdev)
 
        if (info->mtd) {
                mtd_device_unregister(info->mtd);
-               if (info->partitions) {
-                       if (info->free_partitions)
-                               kfree(info->partitions);
-               }
                map_destroy(info->mtd);
        }
 
@@ -228,21 +222,8 @@ static int platram_probe(struct platform_device *pdev)
        /* check to see if there are any available partitions, or wether
         * to add this device whole */
 
-       if (!pdata->nr_partitions) {
-               /* try to probe using the supplied probe type */
-               if (pdata->probes) {
-                       err = parse_mtd_partitions(info->mtd, pdata->probes,
-                                          &info->partitions, 0);
-                       info->free_partitions = 1;
-                       if (err > 0)
-                               err = mtd_device_register(info->mtd,
-                                       info->partitions, err);
-               }
-       }
-       /* use the static mapping */
-       else
-               err = mtd_device_register(info->mtd, pdata->partitions,
-                                         pdata->nr_partitions);
+       err = mtd_device_parse_register(info->mtd, pdata->probes, 0,
+                       pdata->partitions, pdata->nr_partitions);
        if (!err)
                dev_info(&pdev->dev, "registered mtd device\n");
 
index 7ae137d4b99871bbbe94f6b11effa25b5537875d..411a17df9fc13ee2fd78d8e54456e18095bdd91f 100644 (file)
@@ -41,8 +41,6 @@ static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
 }
 
 struct pxa2xx_flash_info {
-       struct mtd_partition    *parts;
-       int                     nr_parts;
        struct mtd_info         *mtd;
        struct map_info         map;
 };
@@ -55,9 +53,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
-       struct mtd_partition *parts;
        struct resource *res;
-       int ret = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
@@ -71,8 +67,6 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
        info->map.bankwidth = flash->width;
        info->map.phys = res->start;
        info->map.size = resource_size(res);
-       info->parts = flash->parts;
-       info->nr_parts = flash->nr_parts;
 
        info->map.virt = ioremap(info->map.phys, info->map.size);
        if (!info->map.virt) {
@@ -104,18 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
        }
        info->mtd->owner = THIS_MODULE;
 
-       ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
-
-       if (ret > 0) {
-               info->nr_parts = ret;
-               info->parts = parts;
-       }
-
-       if (!info->nr_parts)
-               printk("Registering %s as whole device\n",
-                      info->map.name);
-
-       mtd_device_register(info->mtd, info->parts, info->nr_parts);
+       mtd_device_parse_register(info->mtd, probes, 0, NULL, 0);
 
        platform_set_drvdata(pdev, info);
        return 0;
@@ -133,7 +116,6 @@ static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
        iounmap(info->map.virt);
        if (info->map.cached)
                iounmap(info->map.cached);
-       kfree(info->parts);
        kfree(info);
        return 0;
 }
index 761fb459d2c74179105fb9ded586681c66ae6aae..0237f197fd1238f553732f73a2db64ddba98c0f6 100644 (file)
@@ -25,8 +25,6 @@
 struct rbtx4939_flash_info {
        struct mtd_info *mtd;
        struct map_info map;
-       int nr_parts;
-       struct mtd_partition *parts;
 };
 
 static int rbtx4939_flash_remove(struct platform_device *dev)
@@ -41,8 +39,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
        if (info->mtd) {
                struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
 
-               if (info->nr_parts)
-                       kfree(info->parts);
                mtd_device_unregister(info->mtd);
                map_destroy(info->mtd);
        }
@@ -50,7 +46,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
 }
 
 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
-static const char *part_probe_types[] = { "cmdlinepart", NULL };
 
 static int rbtx4939_flash_probe(struct platform_device *dev)
 {
@@ -107,22 +102,11 @@ static int rbtx4939_flash_probe(struct platform_device *dev)
        info->mtd->owner = THIS_MODULE;
        if (err)
                goto err_out;
+       err = mtd_device_parse_register(info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
-       err = parse_mtd_partitions(info->mtd, part_probe_types,
-                               &info->parts, 0);
-       if (err > 0) {
-               mtd_device_register(info->mtd, info->parts, err);
-               info->nr_parts = err;
-               return 0;
-       }
-
-       if (pdata->nr_parts) {
-               pr_notice("Using rbtx4939 partition information\n");
-               mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
-               return 0;
-       }
-
-       mtd_device_register(info->mtd, NULL, 0);
+       if (err)
+               goto err_out;
        return 0;
 
 err_out:
index a9b5e0e5c4c559b059842468d5c15a70f0bfc7c3..fa9c0a9670cd88a4e050ba65f0d70f51fee9f3d7 100644 (file)
@@ -131,10 +131,8 @@ struct sa_subdev_info {
 };
 
 struct sa_info {
-       struct mtd_partition    *parts;
        struct mtd_info         *mtd;
        int                     num_subdev;
-       unsigned int            nr_parts;
        struct sa_subdev_info   subdev[0];
 };
 
@@ -231,8 +229,6 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
                        mtd_concat_destroy(info->mtd);
        }
 
-       kfree(info->parts);
-
        for (i = info->num_subdev - 1; i >= 0; i--)
                sa1100_destroy_subdev(&info->subdev[i]);
        kfree(info);
@@ -341,10 +337,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *plat = pdev->dev.platform_data;
-       struct mtd_partition *parts;
-       const char *part_type = NULL;
        struct sa_info *info;
-       int err, nr_parts = 0;
+       int err;
 
        if (!plat)
                return -ENODEV;
@@ -358,26 +352,8 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
        /*
         * Partition selection stuff.
         */
-       nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
-       if (nr_parts > 0) {
-               info->parts = parts;
-               part_type = "dynamic";
-       } else {
-               parts = plat->parts;
-               nr_parts = plat->nr_parts;
-               part_type = "static";
-       }
-
-       if (nr_parts == 0)
-               printk(KERN_NOTICE "SA1100 flash: no partition info "
-                       "available, registering whole flash\n");
-       else
-               printk(KERN_NOTICE "SA1100 flash: using %s partition "
-                       "definition\n", part_type);
-
-       mtd_device_register(info->mtd, parts, nr_parts);
-
-       info->nr_parts = nr_parts;
+       mtd_device_parse_register(info->mtd, part_probes, 0,
+                       plat->parts, plat->nr_parts);
 
        platform_set_drvdata(pdev, info);
        err = 0;
index cbf6bade9354681164e707b2e43924b21a833578..496c40704aff6567dcd7546b0cb9c87742222263 100644 (file)
@@ -19,8 +19,6 @@
 static struct mtd_info *flash_mtd;
 static struct mtd_info *eprom_mtd;
 
-static struct mtd_partition *parsed_parts;
-
 struct map_info soleng_eprom_map = {
        .name = "Solution Engine EPROM",
        .size = 0x400000,
@@ -51,12 +49,14 @@ static struct mtd_partition superh_se_partitions[] = {
                .size = MTDPART_SIZ_FULL,
        }
 };
+#define NUM_PARTITIONS ARRAY_SIZE(superh_se_partitions)
+#else
+#define superh_se_partitions NULL
+#define NUM_PARTITIONS 0
 #endif /* CONFIG_MTD_SUPERH_RESERVE */
 
 static int __init init_soleng_maps(void)
 {
-       int nr_parts = 0;
-
        /* First probe at offset 0 */
        soleng_flash_map.phys = 0;
        soleng_flash_map.virt = (void __iomem *)P2SEGADDR(0);
@@ -92,21 +92,8 @@ static int __init init_soleng_maps(void)
                mtd_device_register(eprom_mtd, NULL, 0);
        }
 
-       nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-
-#ifdef CONFIG_MTD_SUPERH_RESERVE
-       if (nr_parts <= 0) {
-               printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
-                      CONFIG_MTD_SUPERH_RESERVE);
-               parsed_parts = superh_se_partitions;
-               nr_parts = sizeof(superh_se_partitions)/sizeof(*parsed_parts);
-       }
-#endif /* CONFIG_MTD_SUPERH_RESERVE */
-
-       if (nr_parts > 0)
-               mtd_device_register(flash_mtd, parsed_parts, nr_parts);
-       else
-               mtd_device_register(flash_mtd, NULL, 0);
+       mtd_device_parse_register(flash_mtd, probes, 0,
+                       superh_se_partitions, NUM_PARTITIONS);
 
        return 0;
 }
@@ -118,10 +105,7 @@ static void __exit cleanup_soleng_maps(void)
                map_destroy(eprom_mtd);
        }
 
-       if (parsed_parts)
-               mtd_device_unregister(flash_mtd);
-       else
-               mtd_device_unregister(flash_mtd);
+       mtd_device_unregister(flash_mtd);
        map_destroy(flash_mtd);
 }
 
index 901ce968efaebc11acf9e9c4e5460dfec7fc3e3d..aa7e0cb2893c791311e71356ec79d074745129a6 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/immap_cpm2.h>
 
 static struct mtd_info *sbcmtd[3];
-static struct mtd_partition *sbcmtd_parts[3];
 
 struct map_info sbc82xx_flash_map[3] = {
        {.name = "Boot flash"},
@@ -101,6 +100,7 @@ static int __init init_sbc82xx_flash(void)
        for (i=0; i<3; i++) {
                int8_t flashcs[3] = { 0, 6, 1 };
                int nr_parts;
+               struct mtd_partition *defparts;
 
                printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
                       sbc82xx_flash_map[i].name,
@@ -113,7 +113,8 @@ static int __init init_sbc82xx_flash(void)
                }
                printk(" at %08lx)\n",  sbc82xx_flash_map[i].phys);
 
-               sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size);
+               sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
+                                                   sbc82xx_flash_map[i].size);
 
                if (!sbc82xx_flash_map[i].virt) {
                        printk("Failed to ioremap\n");
@@ -129,24 +130,20 @@ static int __init init_sbc82xx_flash(void)
 
                sbcmtd[i]->owner = THIS_MODULE;
 
-               nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes,
-                                               &sbcmtd_parts[i], 0);
-               if (nr_parts > 0) {
-                       mtd_device_register(sbcmtd[i], sbcmtd_parts[i],
-                                           nr_parts);
-                       continue;
-               }
-
                /* No partitioning detected. Use default */
                if (i == 2) {
-                       mtd_device_register(sbcmtd[i], NULL, 0);
+                       defparts = NULL;
+                       nr_parts = 0;
                } else if (i == bigflash) {
-                       mtd_device_register(sbcmtd[i], bigflash_parts,
-                                           ARRAY_SIZE(bigflash_parts));
+                       defparts = bigflash_parts;
+                       nr_parts = ARRAY_SIZE(bigflash_parts);
                } else {
-                       mtd_device_register(sbcmtd[i], smallflash_parts,
-                                           ARRAY_SIZE(smallflash_parts));
+                       defparts = smallflash_parts;
+                       nr_parts = ARRAY_SIZE(smallflash_parts);
                }
+
+               mtd_device_parse_register(sbcmtd[i], part_probes, 0,
+                                         defparts, nr_parts);
        }
        return 0;
 }
@@ -159,12 +156,8 @@ static void __exit cleanup_sbc82xx_flash(void)
                if (!sbcmtd[i])
                        continue;
 
-               if (i<2 || sbcmtd_parts[i])
-                       mtd_device_unregister(sbcmtd[i]);
-               else
-                       mtd_device_unregister(sbcmtd[i]);
+               mtd_device_unregister(sbcmtd[i]);
 
-               kfree(sbcmtd_parts[i]);
                map_destroy(sbcmtd[i]);
 
                iounmap((void *)sbc82xx_flash_map[i].virt);
index ca385697446ece7ebfe387a4cd99b41cbca9ebbc..ed8b5e744b12abc15b0db0189c972b3331bd1f0b 100644 (file)
@@ -426,6 +426,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        new->rq->queuedata = new;
        blk_queue_logical_block_size(new->rq, tr->blksize);
 
+       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, new->rq);
+
        if (tr->discard) {
                queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, new->rq);
                new->rq->limits.max_discard_sectors = UINT_MAX;
index 3326615ad66b957c57234bf3eb83699a393ff62e..7c1dc908a17475eeb1f610deb8f36505e5b2e439 100644 (file)
@@ -44,7 +44,7 @@ struct mtdblk_dev {
        enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
 };
 
-static struct mutex mtdblks_lock;
+static DEFINE_MUTEX(mtdblks_lock);
 
 /*
  * Cache stuff...
@@ -119,7 +119,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
        if (mtdblk->cache_state != STATE_DIRTY)
                return 0;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
+       pr_debug("mtdblock: writing cached data for \"%s\" "
                        "at 0x%lx, size 0x%x\n", mtd->name,
                        mtdblk->cache_offset, mtdblk->cache_size);
 
@@ -148,7 +148,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
        size_t retlen;
        int ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
+       pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
                mtd->name, pos, len);
 
        if (!sect_size)
@@ -218,7 +218,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
        size_t retlen;
        int ret;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
+       pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
                        mtd->name, pos, len);
 
        if (!sect_size)
@@ -283,7 +283,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 {
        struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
 
-       DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
+       pr_debug("mtdblock_open\n");
 
        mutex_lock(&mtdblks_lock);
        if (mtdblk->count) {
@@ -303,7 +303,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 
        mutex_unlock(&mtdblks_lock);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
+       pr_debug("ok\n");
 
        return 0;
 }
@@ -312,7 +312,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 {
        struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
+       pr_debug("mtdblock_release\n");
 
        mutex_lock(&mtdblks_lock);
 
@@ -329,7 +329,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 
        mutex_unlock(&mtdblks_lock);
 
-       DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
+       pr_debug("ok\n");
 
        return 0;
 }
@@ -389,8 +389,6 @@ static struct mtd_blktrans_ops mtdblock_tr = {
 
 static int __init init_mtdblock(void)
 {
-       mutex_init(&mtdblks_lock);
-
        return register_mtd_blktrans(&mtdblock_tr);
 }
 
index 795a8c0a05b82cf4a7cf0bc5d1e31bed4890b9e4..0470a6e863096779a85b26200a133c4158d7f5a5 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
+#include <linux/module.h>
 
 static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
                              unsigned long block, char *buf)
index 61086ea3cc6bf7856b138042ea308d8b12af554a..e7dc732ddabc6588226211b8fc23e2799e37d628 100644 (file)
@@ -43,7 +43,7 @@ static struct vfsmount *mtd_inode_mnt __read_mostly;
 
 /*
  * Data structure to hold the pointer to the mtd device as well
- * as mode information ofr various use cases.
+ * as mode information of various use cases.
  */
 struct mtd_file_info {
        struct mtd_info *mtd;
@@ -86,7 +86,7 @@ static int mtd_open(struct inode *inode, struct file *file)
        struct mtd_file_info *mfi;
        struct inode *mtd_ino;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n");
+       pr_debug("MTD_open\n");
 
        /* You can't open the RO devices RW */
        if ((file->f_mode & FMODE_WRITE) && (minor & 1))
@@ -151,7 +151,7 @@ static int mtd_close(struct inode *inode, struct file *file)
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
+       pr_debug("MTD_close\n");
 
        /* Only sync if opened RW */
        if ((file->f_mode & FMODE_WRITE) && mtd->sync)
@@ -195,7 +195,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
        size_t size = count;
        char *kbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
+       pr_debug("MTD_read\n");
 
        if (*ppos + count > mtd->size)
                count = mtd->size - *ppos;
@@ -211,17 +211,17 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
                len = min_t(size_t, count, size);
 
                switch (mfi->mode) {
-               case MTD_MODE_OTP_FACTORY:
+               case MTD_FILE_MODE_OTP_FACTORY:
                        ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
                        break;
-               case MTD_MODE_OTP_USER:
+               case MTD_FILE_MODE_OTP_USER:
                        ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
                        break;
-               case MTD_MODE_RAW:
+               case MTD_FILE_MODE_RAW:
                {
                        struct mtd_oob_ops ops;
 
-                       ops.mode = MTD_OOB_RAW;
+                       ops.mode = MTD_OPS_RAW;
                        ops.datbuf = kbuf;
                        ops.oobbuf = NULL;
                        ops.len = len;
@@ -233,16 +233,16 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
                default:
                        ret = mtd->read(mtd, *ppos, len, &retlen, kbuf);
                }
-               /* Nand returns -EBADMSG on ecc errors, but it returns
+               /* Nand returns -EBADMSG on ECC errors, but it returns
                 * the data. For our userspace tools it is important
-                * to dump areas with ecc errors !
+                * to dump areas with ECC errors!
                 * For kernel internal usage it also might return -EUCLEAN
                 * to signal the caller that a bitflip has occurred and has
                 * been corrected by the ECC algorithm.
                 * Userspace software which accesses NAND this way
                 * must be aware of the fact that it deals with NAND
                 */
-               if (!ret || (ret == -EUCLEAN) || (ret == -EBADMSG)) {
+               if (!ret || mtd_is_bitflip_or_eccerr(ret)) {
                        *ppos += retlen;
                        if (copy_to_user(buf, kbuf, retlen)) {
                                kfree(kbuf);
@@ -278,7 +278,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
        int ret=0;
        int len;
 
-       DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
+       pr_debug("MTD_write\n");
 
        if (*ppos == mtd->size)
                return -ENOSPC;
@@ -302,10 +302,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
                }
 
                switch (mfi->mode) {
-               case MTD_MODE_OTP_FACTORY:
+               case MTD_FILE_MODE_OTP_FACTORY:
                        ret = -EROFS;
                        break;
-               case MTD_MODE_OTP_USER:
+               case MTD_FILE_MODE_OTP_USER:
                        if (!mtd->write_user_prot_reg) {
                                ret = -EOPNOTSUPP;
                                break;
@@ -313,13 +313,14 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
                        ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
                        break;
 
-               case MTD_MODE_RAW:
+               case MTD_FILE_MODE_RAW:
                {
                        struct mtd_oob_ops ops;
 
-                       ops.mode = MTD_OOB_RAW;
+                       ops.mode = MTD_OPS_RAW;
                        ops.datbuf = kbuf;
                        ops.oobbuf = NULL;
+                       ops.ooboffs = 0;
                        ops.len = len;
 
                        ret = mtd->write_oob(mtd, *ppos, &ops);
@@ -367,13 +368,13 @@ static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
                if (!mtd->read_fact_prot_reg)
                        ret = -EOPNOTSUPP;
                else
-                       mfi->mode = MTD_MODE_OTP_FACTORY;
+                       mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
                break;
        case MTD_OTP_USER:
                if (!mtd->read_fact_prot_reg)
                        ret = -EOPNOTSUPP;
                else
-                       mfi->mode = MTD_MODE_OTP_USER;
+                       mfi->mode = MTD_FILE_MODE_OTP_USER;
                break;
        default:
                ret = -EINVAL;
@@ -390,6 +391,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
        uint64_t start, uint32_t length, void __user *ptr,
        uint32_t __user *retp)
 {
+       struct mtd_file_info *mfi = file->private_data;
        struct mtd_oob_ops ops;
        uint32_t retlen;
        int ret = 0;
@@ -409,9 +411,10 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
                return ret;
 
        ops.ooblen = length;
-       ops.ooboffs = start & (mtd->oobsize - 1);
+       ops.ooboffs = start & (mtd->writesize - 1);
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
+               MTD_OPS_PLACE_OOB;
 
        if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
                return -EINVAL;
@@ -420,7 +423,7 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
        if (IS_ERR(ops.oobbuf))
                return PTR_ERR(ops.oobbuf);
 
-       start &= ~((uint64_t)mtd->oobsize - 1);
+       start &= ~((uint64_t)mtd->writesize - 1);
        ret = mtd->write_oob(mtd, start, &ops);
 
        if (ops.oobretlen > 0xFFFFFFFFU)
@@ -433,9 +436,11 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd,
        return ret;
 }
 
-static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
-       uint32_t length, void __user *ptr, uint32_t __user *retp)
+static int mtd_do_readoob(struct file *file, struct mtd_info *mtd,
+       uint64_t start, uint32_t length, void __user *ptr,
+       uint32_t __user *retp)
 {
+       struct mtd_file_info *mfi = file->private_data;
        struct mtd_oob_ops ops;
        int ret = 0;
 
@@ -451,9 +456,10 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
                return ret;
 
        ops.ooblen = length;
-       ops.ooboffs = start & (mtd->oobsize - 1);
+       ops.ooboffs = start & (mtd->writesize - 1);
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
+               MTD_OPS_PLACE_OOB;
 
        if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
                return -EINVAL;
@@ -462,7 +468,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
        if (!ops.oobbuf)
                return -ENOMEM;
 
-       start &= ~((uint64_t)mtd->oobsize - 1);
+       start &= ~((uint64_t)mtd->writesize - 1);
        ret = mtd->read_oob(mtd, start, &ops);
 
        if (put_user(ops.oobretlen, retp))
@@ -472,13 +478,29 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
                ret = -EFAULT;
 
        kfree(ops.oobbuf);
+
+       /*
+        * NAND returns -EBADMSG on ECC errors, but it returns the OOB
+        * data. For our userspace tools it is important to dump areas
+        * with ECC errors!
+        * For kernel internal usage it also might return -EUCLEAN
+        * to signal the caller that a bitflip has occured and has
+        * been corrected by the ECC algorithm.
+        *
+        * Note: currently the standard NAND function, nand_read_oob_std,
+        * does not calculate ECC for the OOB area, so do not rely on
+        * this behavior unless you have replaced it with your own.
+        */
+       if (mtd_is_bitflip_or_eccerr(ret))
+               return 0;
+
        return ret;
 }
 
 /*
  * Copies (and truncates, if necessary) data from the larger struct,
  * nand_ecclayout, to the smaller, deprecated layout struct,
- * nand_ecclayout_user. This is necessary only to suppport the deprecated
+ * nand_ecclayout_user. This is necessary only to support the deprecated
  * API ioctl ECCGETLAYOUT while allowing all new functionality to use
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
@@ -544,6 +566,55 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd,
        }
 }
 
+static int mtd_write_ioctl(struct mtd_info *mtd,
+               struct mtd_write_req __user *argp)
+{
+       struct mtd_write_req req;
+       struct mtd_oob_ops ops;
+       void __user *usr_data, *usr_oob;
+       int ret;
+
+       if (copy_from_user(&req, argp, sizeof(req)) ||
+                       !access_ok(VERIFY_READ, req.usr_data, req.len) ||
+                       !access_ok(VERIFY_READ, req.usr_oob, req.ooblen))
+               return -EFAULT;
+       if (!mtd->write_oob)
+               return -EOPNOTSUPP;
+
+       ops.mode = req.mode;
+       ops.len = (size_t)req.len;
+       ops.ooblen = (size_t)req.ooblen;
+       ops.ooboffs = 0;
+
+       usr_data = (void __user *)(uintptr_t)req.usr_data;
+       usr_oob = (void __user *)(uintptr_t)req.usr_oob;
+
+       if (req.usr_data) {
+               ops.datbuf = memdup_user(usr_data, ops.len);
+               if (IS_ERR(ops.datbuf))
+                       return PTR_ERR(ops.datbuf);
+       } else {
+               ops.datbuf = NULL;
+       }
+
+       if (req.usr_oob) {
+               ops.oobbuf = memdup_user(usr_oob, ops.ooblen);
+               if (IS_ERR(ops.oobbuf)) {
+                       kfree(ops.datbuf);
+                       return PTR_ERR(ops.oobbuf);
+               }
+       } else {
+               ops.oobbuf = NULL;
+       }
+
+       ret = mtd->write_oob(mtd, (loff_t)req.start, &ops);
+
+       kfree(ops.datbuf);
+       kfree(ops.oobbuf);
+
+       return ret;
+}
+
 static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
 {
        struct mtd_file_info *mfi = file->private_data;
@@ -553,7 +624,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        u_long size;
        struct mtd_info_user info;
 
-       DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
+       pr_debug("MTD_ioctl\n");
 
        size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
        if (cmd & IOC_IN) {
@@ -601,8 +672,8 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                info.erasesize  = mtd->erasesize;
                info.writesize  = mtd->writesize;
                info.oobsize    = mtd->oobsize;
-               /* The below fields are obsolete */
-               info.ecctype    = -1;
+               /* The below field is obsolete */
+               info.padding    = 0;
                if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
                        return -EFAULT;
                break;
@@ -698,7 +769,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                if (copy_from_user(&buf, argp, sizeof(buf)))
                        ret = -EFAULT;
                else
-                       ret = mtd_do_readoob(mtd, buf.start, buf.length,
+                       ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
                                buf.ptr, &buf_user->start);
                break;
        }
@@ -725,12 +796,19 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                if (copy_from_user(&buf, argp, sizeof(buf)))
                        ret = -EFAULT;
                else
-                       ret = mtd_do_readoob(mtd, buf.start, buf.length,
+                       ret = mtd_do_readoob(file, mtd, buf.start, buf.length,
                                (void __user *)(uintptr_t)buf.usr_ptr,
                                &buf_user->length);
                break;
        }
 
+       case MEMWRITE:
+       {
+               ret = mtd_write_ioctl(mtd,
+                     (struct mtd_write_req __user *)arg);
+               break;
+       }
+
        case MEMLOCK:
        {
                struct erase_info_user einfo;
@@ -827,7 +905,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                if (copy_from_user(&mode, argp, sizeof(int)))
                        return -EFAULT;
 
-               mfi->mode = MTD_MODE_NORMAL;
+               mfi->mode = MTD_FILE_MODE_NORMAL;
 
                ret = otp_select_filemode(mfi, mode);
 
@@ -843,11 +921,11 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                        return -ENOMEM;
                ret = -EOPNOTSUPP;
                switch (mfi->mode) {
-               case MTD_MODE_OTP_FACTORY:
+               case MTD_FILE_MODE_OTP_FACTORY:
                        if (mtd->get_fact_prot_info)
                                ret = mtd->get_fact_prot_info(mtd, buf, 4096);
                        break;
-               case MTD_MODE_OTP_USER:
+               case MTD_FILE_MODE_OTP_USER:
                        if (mtd->get_user_prot_info)
                                ret = mtd->get_user_prot_info(mtd, buf, 4096);
                        break;
@@ -871,7 +949,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        {
                struct otp_info oinfo;
 
-               if (mfi->mode != MTD_MODE_OTP_USER)
+               if (mfi->mode != MTD_FILE_MODE_OTP_USER)
                        return -EINVAL;
                if (copy_from_user(&oinfo, argp, sizeof(oinfo)))
                        return -EFAULT;
@@ -882,7 +960,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        }
 #endif
 
-       /* This ioctl is being deprecated - it truncates the ecc layout */
+       /* This ioctl is being deprecated - it truncates the ECC layout */
        case ECCGETLAYOUT:
        {
                struct nand_ecclayout_user *usrlay;
@@ -915,17 +993,17 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                mfi->mode = 0;
 
                switch(arg) {
-               case MTD_MODE_OTP_FACTORY:
-               case MTD_MODE_OTP_USER:
+               case MTD_FILE_MODE_OTP_FACTORY:
+               case MTD_FILE_MODE_OTP_USER:
                        ret = otp_select_filemode(mfi, arg);
                        break;
 
-               case MTD_MODE_RAW:
+               case MTD_FILE_MODE_RAW:
                        if (!mtd->read_oob || !mtd->write_oob)
                                return -EOPNOTSUPP;
                        mfi->mode = arg;
 
-               case MTD_MODE_NORMAL:
+               case MTD_FILE_MODE_NORMAL:
                        break;
                default:
                        ret = -EINVAL;
@@ -1011,7 +1089,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd,
                if (copy_from_user(&buf, argp, sizeof(buf)))
                        ret = -EFAULT;
                else
-                       ret = mtd_do_readoob(mtd, buf.start,
+                       ret = mtd_do_readoob(file, mtd, buf.start,
                                buf.length, compat_ptr(buf.ptr),
                                &buf_user->start);
                break;
index e601672a53050900d3d0b8cf084829db6d10d9bd..6df4d4d4eb92bb585c9f0bc08815be208cda2d53 100644 (file)
@@ -95,10 +95,10 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
 
                /* Save information about bitflips! */
                if (unlikely(err)) {
-                       if (err == -EBADMSG) {
+                       if (mtd_is_eccerr(err)) {
                                mtd->ecc_stats.failed++;
                                ret = err;
-                       } else if (err == -EUCLEAN) {
+                       } else if (mtd_is_bitflip(err)) {
                                mtd->ecc_stats.corrected++;
                                /* Do not overwrite -EBADMSG !! */
                                if (!ret)
@@ -279,10 +279,10 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
 
                /* Save information about bitflips! */
                if (unlikely(err)) {
-                       if (err == -EBADMSG) {
+                       if (mtd_is_eccerr(err)) {
                                mtd->ecc_stats.failed++;
                                ret = err;
-                       } else if (err == -EUCLEAN) {
+                       } else if (mtd_is_bitflip(err)) {
                                mtd->ecc_stats.corrected++;
                                /* Do not overwrite -EBADMSG !! */
                                if (!ret)
@@ -770,7 +770,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],       /* subdevices to c
 
        /*
         * Set up the new "super" device's MTD object structure, check for
-        * incompatibilites between the subdevices.
+        * incompatibilities between the subdevices.
         */
        concat->mtd.type = subdev[0]->type;
        concat->mtd.flags = subdev[0]->flags;
index c510aff289a88d077d9e42c6854bfdcd1533e3be..b01993ea260ef95b064a04763989bc324f61a342 100644 (file)
@@ -362,7 +362,7 @@ int add_mtd_device(struct mtd_info *mtd)
                              MTD_DEVT(i) + 1,
                              NULL, "mtd%dro", i);
 
-       DEBUG(0, "mtd: Giving out device %d to %s\n", i, mtd->name);
+       pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name);
        /* No need to get a refcount on the module containing
           the notifier, since we hold the mtd_table_mutex */
        list_for_each_entry(not, &mtd_notifiers, list)
@@ -429,27 +429,63 @@ out_error:
 }
 
 /**
- * mtd_device_register - register an MTD device.
+ * mtd_device_parse_register - parse partitions and register an MTD device.
  *
- * @master: the MTD device to register
- * @parts: the partitions to register - only valid if nr_parts > 0
- * @nr_parts: the number of partitions in parts.  If zero then the full MTD
- *            device is registered
+ * @mtd: the MTD device to register
+ * @types: the list of MTD partition probes to try, see
+ *         'parse_mtd_partitions()' for more information
+ * @parser_data: MTD partition parser-specific data
+ * @parts: fallback partition information to register, if parsing fails;
+ *         only valid if %nr_parts > %0
+ * @nr_parts: the number of partitions in parts, if zero then the full
+ *            MTD device is registered if no partition info is found
  *
- * Register an MTD device with the system and optionally, a number of
- * partitions.  If nr_parts is 0 then the whole device is registered, otherwise
- * only the partitions are registered.  To register both the full device *and*
- * the partitions, call mtd_device_register() twice, once with nr_parts == 0
- * and once equal to the number of partitions.
+ * This function aggregates MTD partitions parsing (done by
+ * 'parse_mtd_partitions()') and MTD device and partitions registering. It
+ * basically follows the most common pattern found in many MTD drivers:
+ *
+ * * It first tries to probe partitions on MTD device @mtd using parsers
+ *   specified in @types (if @types is %NULL, then the default list of parsers
+ *   is used, see 'parse_mtd_partitions()' for more information). If none are
+ *   found this functions tries to fallback to information specified in
+ *   @parts/@nr_parts.
+ * * If any partitioning info was found, this function registers the found
+ *   partitions.
+ * * If no partitions were found this function just registers the MTD device
+ *   @mtd and exits.
+ *
+ * Returns zero in case of success and a negative error code in case of failure.
  */
-int mtd_device_register(struct mtd_info *master,
-                       const struct mtd_partition *parts,
-                       int nr_parts)
+int mtd_device_parse_register(struct mtd_info *mtd, const char **types,
+                             struct mtd_part_parser_data *parser_data,
+                             const struct mtd_partition *parts,
+                             int nr_parts)
 {
-       return parts ? add_mtd_partitions(master, parts, nr_parts) :
-               add_mtd_device(master);
+       int err;
+       struct mtd_partition *real_parts;
+
+       err = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
+       if (err <= 0 && nr_parts && parts) {
+               real_parts = kmemdup(parts, sizeof(*parts) * nr_parts,
+                                    GFP_KERNEL);
+               if (!real_parts)
+                       err = -ENOMEM;
+               else
+                       err = nr_parts;
+       }
+
+       if (err > 0) {
+               err = add_mtd_partitions(mtd, real_parts, err);
+               kfree(real_parts);
+       } else if (err == 0) {
+               err = add_mtd_device(mtd);
+               if (err == 1)
+                       err = -ENODEV;
+       }
+
+       return err;
 }
-EXPORT_SYMBOL_GPL(mtd_device_register);
+EXPORT_SYMBOL_GPL(mtd_device_parse_register);
 
 /**
  * mtd_device_unregister - unregister an existing MTD device.
index 0ed6126b4c1ffb0cc40c7f161926daf20d14bb0b..961a38408542b70df255a8ba05871a2ffb43a3fa 100644 (file)
@@ -15,6 +15,9 @@ extern int del_mtd_device(struct mtd_info *mtd);
 extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *,
                              int);
 extern int del_mtd_partitions(struct mtd_info *);
+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
+                               struct mtd_partition **pparts,
+                               struct mtd_part_parser_data *data);
 
 #define mtd_for_each_device(mtd)                       \
        for ((mtd) = __mtd_next_device(0);              \
index e3e40f4403235540dc5ad5f6e3efd35aa981f647..1e2fa6236705941b9fea37b5f0d5bf4a713e56c7 100644 (file)
@@ -258,7 +258,7 @@ static void find_next_position(struct mtdoops_context *cxt)
                ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
                                &retlen, (u_char *) &count[0]);
                if (retlen != MTDOOPS_HEADER_SIZE ||
-                               (ret < 0 && ret != -EUCLEAN)) {
+                               (ret < 0 && !mtd_is_bitflip(ret))) {
                        printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
                               page * record_size, retlen,
                               MTDOOPS_HEADER_SIZE, ret);
index 630be3e7da04f2eed1ab628c21004ba077d4522c..a0bd2de4752baa3981b09a31b1efb0cc5f7b4a8b 100644 (file)
@@ -73,9 +73,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
        res = part->master->read(part->master, from + part->offset,
                                   len, retlen, buf);
        if (unlikely(res)) {
-               if (res == -EUCLEAN)
+               if (mtd_is_bitflip(res))
                        mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
-               if (res == -EBADMSG)
+               if (mtd_is_eccerr(res))
                        mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
        }
        return res;
@@ -130,7 +130,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
        if (ops->oobbuf) {
                size_t len, pages;
 
-               if (ops->mode == MTD_OOB_AUTO)
+               if (ops->mode == MTD_OPS_AUTO_OOB)
                        len = mtd->oobavail;
                else
                        len = mtd->oobsize;
@@ -142,9 +142,9 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
 
        res = part->master->read_oob(part->master, from + part->offset, ops);
        if (unlikely(res)) {
-               if (res == -EUCLEAN)
+               if (mtd_is_bitflip(res))
                        mtd->ecc_stats.corrected++;
-               if (res == -EBADMSG)
+               if (mtd_is_eccerr(res))
                        mtd->ecc_stats.failed++;
        }
        return res;
@@ -479,6 +479,19 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
                               (unsigned long long)cur_offset, (unsigned long long)slave->offset);
                }
        }
+       if (slave->offset == MTDPART_OFS_RETAIN) {
+               slave->offset = cur_offset;
+               if (master->size - slave->offset >= slave->mtd.size) {
+                       slave->mtd.size = master->size - slave->offset
+                                                       - slave->mtd.size;
+               } else {
+                       printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
+                               part->name, master->size - slave->offset,
+                               slave->mtd.size);
+                       /* register to preserve ordering */
+                       goto out_register;
+               }
+       }
        if (slave->mtd.size == MTDPART_SIZ_FULL)
                slave->mtd.size = master->size - slave->offset;
 
@@ -693,6 +706,8 @@ static struct mtd_part_parser *get_partition_parser(const char *name)
        return ret;
 }
 
+#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
+
 int register_mtd_parser(struct mtd_part_parser *p)
 {
        spin_lock(&part_parser_lock);
@@ -712,19 +727,51 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
 }
 EXPORT_SYMBOL_GPL(deregister_mtd_parser);
 
+/*
+ * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
+ * are changing this array!
+ */
+static const char *default_mtd_part_types[] = {
+       "cmdlinepart",
+       "ofpart",
+       NULL
+};
+
+/**
+ * parse_mtd_partitions - parse MTD partitions
+ * @master: the master partition (describes whole MTD device)
+ * @types: names of partition parsers to try or %NULL
+ * @pparts: array of partitions found is returned here
+ * @data: MTD partition parser-specific data
+ *
+ * This function tries to find partition on MTD device @master. It uses MTD
+ * partition parsers, specified in @types. However, if @types is %NULL, then
+ * the default list of parsers is used. The default list contains only the
+ * "cmdlinepart" and "ofpart" parsers ATM.
+ *
+ * This function may return:
+ * o a negative error code in case of failure
+ * o zero if no partitions were found
+ * o a positive number of found partitions, in which case on exit @pparts will
+ *   point to an array containing this number of &struct mtd_info objects.
+ */
 int parse_mtd_partitions(struct mtd_info *master, const char **types,
-                        struct mtd_partition **pparts, unsigned long origin)
+                        struct mtd_partition **pparts,
+                        struct mtd_part_parser_data *data)
 {
        struct mtd_part_parser *parser;
        int ret = 0;
 
+       if (!types)
+               types = default_mtd_part_types;
+
        for ( ; ret <= 0 && *types; types++) {
                parser = get_partition_parser(*types);
                if (!parser && !request_module("%s", *types))
                                parser = get_partition_parser(*types);
                if (!parser)
                        continue;
-               ret = (*parser->parse_fn)(master, pparts, origin);
+               ret = (*parser->parse_fn)(master, pparts, data);
                if (ret > 0) {
                        printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
                               ret, parser->name, master->name);
@@ -733,7 +780,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
        }
        return ret;
 }
-EXPORT_SYMBOL_GPL(parse_mtd_partitions);
 
 int mtd_is_partition(struct mtd_info *mtd)
 {
index 16b02a1fc100ce542bfdaad9bb6fdbf7f8b433fe..a90bfe79916d29c6f7c2460e9dc644dadc46904e 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/mtd/super.h>
 #include <linux/namei.h>
+#include <linux/export.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
 
@@ -26,12 +27,12 @@ static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
        struct mtd_info *mtd = _mtd;
 
        if (sb->s_mtd == mtd) {
-               DEBUG(2, "MTDSB: Match on device %d (\"%s\")\n",
+               pr_debug("MTDSB: Match on device %d (\"%s\")\n",
                      mtd->index, mtd->name);
                return 1;
        }
 
-       DEBUG(2, "MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
+       pr_debug("MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
              sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
        return 0;
 }
@@ -70,7 +71,7 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
                goto already_mounted;
 
        /* fresh new superblock */
-       DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n",
+       pr_debug("MTDSB: New superblock for device %d (\"%s\")\n",
              mtd->index, mtd->name);
 
        sb->s_flags = flags;
@@ -87,7 +88,7 @@ static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
 
        /* new mountpoint for an already mounted superblock */
 already_mounted:
-       DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
+       pr_debug("MTDSB: Device %d (\"%s\") is already mounted\n",
              mtd->index, mtd->name);
        put_mtd_device(mtd);
        return dget(sb->s_root);
@@ -108,7 +109,7 @@ static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags,
 
        mtd = get_mtd_device(NULL, mtdnr);
        if (IS_ERR(mtd)) {
-               DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
+               pr_debug("MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
                return ERR_CAST(mtd);
        }
 
@@ -131,7 +132,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
        if (!dev_name)
                return ERR_PTR(-EINVAL);
 
-       DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name);
+       pr_debug("MTDSB: dev_name \"%s\"\n", dev_name);
 
        /* the preferred way of mounting in future; especially when
         * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
@@ -142,7 +143,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
                        struct mtd_info *mtd;
 
                        /* mount by MTD device name */
-                       DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
+                       pr_debug("MTDSB: mtd:%%s, name \"%s\"\n",
                              dev_name + 4);
 
                        mtd = get_mtd_device_nm(dev_name + 4);
@@ -163,7 +164,7 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
                        mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
                        if (!*endptr) {
                                /* It was a valid number */
-                               DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n",
+                               pr_debug("MTDSB: mtd%%d, mtdnr %d\n",
                                      mtdnr);
                                return mount_mtd_nr(fs_type, flags,
                                                     dev_name, data,
@@ -179,10 +180,10 @@ struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
        bdev = lookup_bdev(dev_name);
        if (IS_ERR(bdev)) {
                ret = PTR_ERR(bdev);
-               DEBUG(1, "MTDSB: lookup_bdev() returned %d\n", ret);
+               pr_debug("MTDSB: lookup_bdev() returned %d\n", ret);
                return ERR_PTR(ret);
        }
-       DEBUG(1, "MTDSB: lookup_bdev() returned 0\n");
+       pr_debug("MTDSB: lookup_bdev() returned 0\n");
 
        ret = -EINVAL;
 
index fd7885327611d75d68a25e788fa7a44950109513..bd9590c723e41fcbb7055cc4dc61f49f402e340d 100644 (file)
@@ -86,7 +86,7 @@ struct swap_eb {
        unsigned int flags;
        unsigned int active_count;
        unsigned int erase_count;
-       unsigned int pad;               /* speeds up pointer decremtnt */
+       unsigned int pad;               /* speeds up pointer decrement */
 };
 
 #define MTDSWAP_ECNT_MIN(rbroot) (rb_entry(rb_first(rbroot), struct swap_eb, \
@@ -314,7 +314,7 @@ static int mtdswap_read_oob(struct mtdswap_dev *d, loff_t from,
 {
        int ret = d->mtd->read_oob(d->mtd, from, ops);
 
-       if (ret == -EUCLEAN)
+       if (mtd_is_bitflip(ret))
                return ret;
 
        if (ret) {
@@ -350,11 +350,11 @@ static int mtdswap_read_markers(struct mtdswap_dev *d, struct swap_eb *eb)
        ops.oobbuf = d->oob_buf;
        ops.ooboffs = 0;
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
 
        ret = mtdswap_read_oob(d, offset, &ops);
 
-       if (ret && ret != -EUCLEAN)
+       if (ret && !mtd_is_bitflip(ret))
                return ret;
 
        data = (struct mtdswap_oobdata *)d->oob_buf;
@@ -363,7 +363,7 @@ static int mtdswap_read_markers(struct mtdswap_dev *d, struct swap_eb *eb)
 
        if (le16_to_cpu(data->magic) == MTDSWAP_MAGIC_CLEAN) {
                eb->erase_count = le32_to_cpu(data->count);
-               if (ret == -EUCLEAN)
+               if (mtd_is_bitflip(ret))
                        ret = MTDSWAP_SCANNED_BITFLIP;
                else {
                        if (le16_to_cpu(data2->magic) == MTDSWAP_MAGIC_DIRTY)
@@ -389,7 +389,7 @@ static int mtdswap_write_marker(struct mtdswap_dev *d, struct swap_eb *eb,
 
        ops.ooboffs = 0;
        ops.oobbuf = (uint8_t *)&n;
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.datbuf = NULL;
 
        if (marker == MTDSWAP_TYPE_CLEAN) {
@@ -408,7 +408,7 @@ static int mtdswap_write_marker(struct mtdswap_dev *d, struct swap_eb *eb,
        if (ret) {
                dev_warn(d->dev, "Write OOB failed for block at %08llx "
                        "error %d\n", offset, ret);
-               if (ret == -EIO || ret == -EBADMSG)
+               if (ret == -EIO || mtd_is_eccerr(ret))
                        mtdswap_handle_write_error(d, eb);
                return ret;
        }
@@ -628,7 +628,7 @@ static int mtdswap_map_free_block(struct mtdswap_dev *d, unsigned int page,
                        TREE_COUNT(d, CLEAN)--;
 
                        ret = mtdswap_write_marker(d, eb, MTDSWAP_TYPE_DIRTY);
-               } while (ret == -EIO || ret == -EBADMSG);
+               } while (ret == -EIO || mtd_is_eccerr(ret));
 
                if (ret)
                        return ret;
@@ -678,7 +678,7 @@ retry:
        ret = mtdswap_map_free_block(d, page, bp);
        eb = d->eb_data + (*bp / d->pages_per_eblk);
 
-       if (ret == -EIO || ret == -EBADMSG) {
+       if (ret == -EIO || mtd_is_eccerr(ret)) {
                d->curr_write = NULL;
                eb->active_count--;
                d->revmap[*bp] = PAGE_UNDEF;
@@ -690,7 +690,7 @@ retry:
 
        writepos = (loff_t)*bp << PAGE_SHIFT;
        ret =  mtd->write(mtd, writepos, PAGE_SIZE, &retlen, buf);
-       if (ret == -EIO || ret == -EBADMSG) {
+       if (ret == -EIO || mtd_is_eccerr(ret)) {
                d->curr_write_pos--;
                eb->active_count--;
                d->revmap[*bp] = PAGE_UNDEF;
@@ -738,7 +738,7 @@ static int mtdswap_move_block(struct mtdswap_dev *d, unsigned int oldblock,
 retry:
        ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, d->page_buf);
 
-       if (ret < 0 && ret != -EUCLEAN) {
+       if (ret < 0 && !mtd_is_bitflip(ret)) {
                oldeb = d->eb_data + oldblock / d->pages_per_eblk;
                oldeb->flags |= EBLOCK_READERR;
 
@@ -931,7 +931,7 @@ static unsigned int mtdswap_eblk_passes(struct mtdswap_dev *d,
        struct mtd_oob_ops ops;
        int ret;
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.len = mtd->writesize;
        ops.ooblen = mtd->ecclayout->oobavail;
        ops.ooboffs = 0;
@@ -1016,7 +1016,7 @@ static int mtdswap_gc(struct mtdswap_dev *d, unsigned int background)
 
        if (ret == 0)
                mtdswap_rb_add(d, eb, MTDSWAP_CLEAN);
-       else if (ret != -EIO && ret != -EBADMSG)
+       else if (ret != -EIO && !mtd_is_eccerr(ret))
                mtdswap_rb_add(d, eb, MTDSWAP_DIRTY);
 
        return 0;
@@ -1164,7 +1164,7 @@ retry:
        ret = mtd->read(mtd, readpos, PAGE_SIZE, &retlen, buf);
 
        d->mtd_read_count++;
-       if (ret == -EUCLEAN) {
+       if (mtd_is_bitflip(ret)) {
                eb->flags |= EBLOCK_BITFLIP;
                mtdswap_rb_add(d, eb, MTDSWAP_BITFLIP);
                ret = 0;
@@ -1374,11 +1374,10 @@ static int mtdswap_init(struct mtdswap_dev *d, unsigned int eblocks,
                goto revmap_fail;
 
        eblk_bytes = sizeof(struct swap_eb)*d->eblks;
-       d->eb_data = vmalloc(eblk_bytes);
+       d->eb_data = vzalloc(eblk_bytes);
        if (!d->eb_data)
                goto eb_data_fail;
 
-       memset(d->eb_data, 0, eblk_bytes);
        for (i = 0; i < pages; i++)
                d->page_data[i] = BLOCK_UNDEF;
 
index dbfa0f7fb4643bb62d9405c9871170429d064012..cce7b70824c35076957664218e09c9a4e196a41c 100644 (file)
@@ -83,16 +83,9 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR
           scratch register here to enable this feature. On Intel Moorestown
           boards, the scratch register is at 0xFF108018.
 
-config MTD_NAND_EDB7312
-       tristate "Support for Cirrus Logic EBD7312 evaluation board"
-       depends on ARCH_EDB7312
-       help
-         This enables the driver for the Cirrus Logic EBD7312 evaluation
-         board to access the onboard NAND Flash.
-
 config MTD_NAND_H1900
        tristate "iPAQ H1900 flash"
-       depends on ARCH_PXA
+       depends on ARCH_PXA && BROKEN
        help
          This enables the driver for the iPAQ h1900 flash.
 
@@ -116,10 +109,11 @@ config MTD_NAND_AMS_DELTA
          Support for NAND flash on Amstrad E3 (Delta).
 
 config MTD_NAND_OMAP2
-       tristate "NAND Flash device on OMAP2 and OMAP3"
-       depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3)
+       tristate "NAND Flash device on OMAP2, OMAP3 and OMAP4"
+       depends on ARM && (ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4)
        help
-          Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
+          Support for NAND flash on Texas Instruments OMAP2, OMAP3 and OMAP4
+         platforms.
 
 config MTD_NAND_IDS
        tristate
@@ -423,6 +417,19 @@ config MTD_NAND_NANDSIM
          The simulator may simulate various NAND flash chips for the
          MTD nand layer.
 
+config MTD_NAND_GPMI_NAND
+        bool "GPMI NAND Flash Controller driver"
+        depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28)
+       select MTD_PARTITIONS
+       select MTD_CMDLINE_PARTS
+        help
+        Enables NAND Flash support for IMX23 or IMX28.
+        The GPMI controller is very powerful, with the help of BCH
+        module, it can do the hardware ECC. The GPMI supports several
+        NAND flashs at the same time. The GPMI may conflicts with other
+        block, such as SD card. So pay attention to it when you enable
+        the GPMI.
+
 config MTD_NAND_PLATFORM
        tristate "Support for generic platform NAND driver"
        help
index 5745d831168e4e6f581deb1e12bb3a5b77f456fd..618f4ba23699ecbd5115e17f720164fcdaa29c7a 100644 (file)
@@ -13,7 +13,6 @@ obj-$(CONFIG_MTD_NAND_SPIA)           += spia.o
 obj-$(CONFIG_MTD_NAND_AMS_DELTA)       += ams-delta.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)                += autcpu12.o
 obj-$(CONFIG_MTD_NAND_DENALI)          += denali.o
-obj-$(CONFIG_MTD_NAND_EDB7312)         += edb7312.o
 obj-$(CONFIG_MTD_NAND_AU1550)          += au1550nd.o
 obj-$(CONFIG_MTD_NAND_BF5XX)           += bf5xx_nand.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)  += ppchameleonevb.o
@@ -49,5 +48,6 @@ obj-$(CONFIG_MTD_NAND_BCM_UMI)                += bcm_umi_nand.o nand_bcm_umi.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)     += mpc5121_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)           += r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)          += jz4740_nand.o
+obj-$(CONFIG_MTD_NAND_GPMI_NAND)       += gpmi-nand/
 
 nand-objs := nand_base.o nand_bbt.o
index 55da20ccc7a8996f0d80be785b91452e35dd8225..23e5d77c39fcaf998f81125e51d22ccf1ce9b2d3 100644 (file)
@@ -161,37 +161,6 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
                 !!host->board->rdy_pin_active_low;
 }
 
-/*
- * Minimal-overhead PIO for data access.
- */
-static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_readsb(nand_chip->IO_ADDR_R, buf, len);
-}
-
-static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2);
-}
-
-static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_writesb(nand_chip->IO_ADDR_W, buf, len);
-}
-
-static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
-{
-       struct nand_chip        *nand_chip = mtd->priv;
-
-       __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2);
-}
-
 static void dma_complete_func(void *completion)
 {
        complete(completion);
@@ -266,33 +235,27 @@ err_buf:
 static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
-       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
                        return;
 
-       if (host->board->bus_width_16)
-               atmel_read_buf16(mtd, buf, len);
-       else
-               atmel_read_buf8(mtd, buf, len);
+       /* if no DMA operation possible, use PIO */
+       memcpy_fromio(buf, chip->IO_ADDR_R, len);
 }
 
 static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
-       struct atmel_nand_host *host = chip->priv;
 
        if (use_dma && len > mtd->oobsize)
                /* only use DMA for bigger than oob size: better performances */
                if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
                        return;
 
-       if (host->board->bus_width_16)
-               atmel_write_buf16(mtd, buf, len);
-       else
-               atmel_write_buf8(mtd, buf, len);
+       /* if no DMA operation possible, use PIO */
+       memcpy_toio(chip->IO_ADDR_W, buf, len);
 }
 
 /*
@@ -481,10 +444,6 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
        }
 }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
-
 /*
  * Probe for the NAND device.
  */
@@ -496,8 +455,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        struct resource *regs;
        struct resource *mem;
        int res;
-       struct mtd_partition *partitions = NULL;
-       int num_partitions = 0;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mem) {
@@ -583,7 +540,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
        if (on_flash_bbt) {
                printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
-               nand_chip->options |= NAND_USE_FLASH_BBT;
+               nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
        }
 
        if (!cpu_has_dma())
@@ -594,7 +551,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
 
                dma_cap_zero(mask);
                dma_cap_set(DMA_MEMCPY, mask);
-               host->dma_chan = dma_request_channel(mask, 0, NULL);
+               host->dma_chan = dma_request_channel(mask, NULL, NULL);
                if (!host->dma_chan) {
                        dev_err(host->dev, "Failed to request DMA channel\n");
                        use_dma = 0;
@@ -655,27 +612,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                goto err_scan_tail;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "atmel_nand";
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                             &partitions, 0);
-#endif
-       if (num_partitions <= 0 && host->board->partition_info)
-               partitions = host->board->partition_info(mtd->size,
-                                                        &num_partitions);
-
-       if ((!partitions) || (num_partitions == 0)) {
-               printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n");
-               res = -ENXIO;
-               goto err_no_partitions;
-       }
-
-       res = mtd_device_register(mtd, partitions, num_partitions);
+       res = mtd_device_parse_register(mtd, NULL, 0,
+                       host->board->parts, host->board->num_parts);
        if (!res)
                return res;
 
-err_no_partitions:
-       nand_release(mtd);
 err_scan_tail:
 err_scan_ident:
 err_no_card:
index fa5736b9286c2060bd6af631f704dd146b192566..7dd3700f2303097f14747098031a41d66acc130a 100644 (file)
@@ -52,7 +52,7 @@ static const struct mtd_partition partition_info[] = {
  * au_read_byte -  read one byte from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 8bit buswith
+ * read function for 8bit buswidth
  */
 static u_char au_read_byte(struct mtd_info *mtd)
 {
@@ -67,7 +67,7 @@ static u_char au_read_byte(struct mtd_info *mtd)
  * @mtd:       MTD device structure
  * @byte:      pointer to data byte to write
  *
- *  write function for 8it buswith
+ * write function for 8it buswidth
  */
 static void au_write_byte(struct mtd_info *mtd, u_char byte)
 {
@@ -77,11 +77,10 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
 }
 
 /**
- * au_read_byte16 -  read one byte endianess aware from the chip
+ * au_read_byte16 -  read one byte endianness aware from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 16bit buswith with
- * endianess conversion
+ * read function for 16bit buswidth with endianness conversion
  */
 static u_char au_read_byte16(struct mtd_info *mtd)
 {
@@ -92,12 +91,11 @@ static u_char au_read_byte16(struct mtd_info *mtd)
 }
 
 /**
- * au_write_byte16 -  write one byte endianess aware to the chip
+ * au_write_byte16 -  write one byte endianness aware to the chip
  * @mtd:       MTD device structure
  * @byte:      pointer to data byte to write
  *
- *  write function for 16bit buswith with
- * endianess conversion
+ * write function for 16bit buswidth with endianness conversion
  */
 static void au_write_byte16(struct mtd_info *mtd, u_char byte)
 {
@@ -110,8 +108,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
  * au_read_word -  read one word from the chip
  * @mtd:       MTD device structure
  *
- *  read function for 16bit buswith without
- * endianess conversion
+ * read function for 16bit buswidth without endianness conversion
  */
 static u16 au_read_word(struct mtd_info *mtd)
 {
@@ -127,7 +124,7 @@ static u16 au_read_word(struct mtd_info *mtd)
  * @buf:       data buffer
  * @len:       number of bytes to write
  *
- *  write function for 8bit buswith
+ * write function for 8bit buswidth
  */
 static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -146,7 +143,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       buffer to store date
  * @len:       number of bytes to read
  *
- *  read function for 8bit buswith
+ * read function for 8bit buswidth
  */
 static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
@@ -165,7 +162,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
  * @buf:       buffer containing the data to compare
  * @len:       number of bytes to compare
  *
- *  verify function for 8bit buswith
+ * verify function for 8bit buswidth
  */
 static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -187,7 +184,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       data buffer
  * @len:       number of bytes to write
  *
- *  write function for 16bit buswith
+ * write function for 16bit buswidth
  */
 static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
 {
@@ -209,7 +206,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
  * @buf:       buffer to store date
  * @len:       number of bytes to read
  *
- *  read function for 16bit buswith
+ * read function for 16bit buswidth
  */
 static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
 {
@@ -230,7 +227,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
  * @buf:       buffer containing the data to compare
  * @len:       number of bytes to compare
  *
- *  verify function for 16bit buswith
+ * verify function for 16bit buswidth
  */
 static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
 {
index eddc9a2249859efe157dac13f8042da3afaf26e6..2e42ec2e8ff48a285b939e7510ea91d22dd6035f 100644 (file)
@@ -172,9 +172,9 @@ static int __init autcpu12_init(void)
 
        /* Enable the following for a flash based bad block table */
        /*
-          this->options = NAND_USE_FLASH_BBT;
+          this->bbt_options = NAND_BBT_USE_FLASH;
         */
-       this->options = NAND_USE_FLASH_BBT;
+       this->bbt_options = NAND_BBT_USE_FLASH;
 
        /* Scan to find existence of the device */
        if (nand_scan(autcpu12_mtd, 1)) {
index 8c569e454dc5b52248fa98017e0d1071f6700f64..46b58d67284726fe2cee86852f9fe4640679a8a6 100644 (file)
@@ -52,8 +52,6 @@
 static const __devinitconst char gBanner[] = KERN_INFO \
        "BCM UMI MTD NAND Driver: 1.00\n";
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-
 #if NAND_ECC_BCH
 static uint8_t scan_ff_pattern[] = { 0xff };
 
@@ -376,16 +374,18 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       if (!r)
-               return -ENXIO;
+       if (!r) {
+               err = -ENXIO;
+               goto out_free;
+       }
 
        /* map physical address */
        bcm_umi_io_base = ioremap(r->start, resource_size(r));
 
        if (!bcm_umi_io_base) {
                printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n");
-               kfree(board_mtd);
-               return -EIO;
+               err = -EIO;
+               goto out_free;
        }
 
        /* Get pointer to private data */
@@ -401,9 +401,8 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        /* Initialize the NAND hardware.  */
        if (bcm_umi_nand_inithw() < 0) {
                printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n");
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return -EIO;
+               err = -EIO;
+               goto out_unmap;
        }
 
        /* Set address of NAND IO lines */
@@ -436,7 +435,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
 #if USE_DMA
        err = nand_dma_init();
        if (err != 0)
-               return err;
+               goto out_unmap;
 #endif
 
        /* Figure out the size of the device that we have.
@@ -447,9 +446,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        err = nand_scan_ident(board_mtd, 1, NULL);
        if (err) {
                printk(KERN_ERR "nand_scan failed: %d\n", err);
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return err;
+               goto out_unmap;
        }
 
        /* Now that we know the nand size, we can setup the ECC layout */
@@ -468,13 +465,14 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
                {
                        printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n",
                                         board_mtd->writesize);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out_unmap;
                }
        }
 
 #if NAND_ECC_BCH
        if (board_mtd->writesize > 512) {
-               if (this->options & NAND_USE_FLASH_BBT)
+               if (this->bbt_options & NAND_BBT_USE_FLASH)
                        largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
                this->badblock_pattern = &largepage_bbt;
        }
@@ -485,33 +483,20 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
        err = nand_scan_tail(board_mtd);
        if (err) {
                printk(KERN_ERR "nand_scan failed: %d\n", err);
-               iounmap(bcm_umi_io_base);
-               kfree(board_mtd);
-               return err;
+               goto out_unmap;
        }
 
        /* Register the partitions */
-       {
-               int nr_partitions;
-               struct mtd_partition *partition_info;
-
-               board_mtd->name = "bcm_umi-nand";
-               nr_partitions =
-                   parse_mtd_partitions(board_mtd, part_probes,
-                                        &partition_info, 0);
-
-               if (nr_partitions <= 0) {
-                       printk(KERN_ERR "BCM UMI NAND: Too few partitions - %d\n",
-                              nr_partitions);
-                       iounmap(bcm_umi_io_base);
-                       kfree(board_mtd);
-                       return -EIO;
-               }
-               mtd_device_register(board_mtd, partition_info, nr_partitions);
-       }
+       board_mtd->name = "bcm_umi-nand";
+       mtd_device_parse_register(board_mtd, NULL, 0, NULL, 0);
 
        /* Return happy */
        return 0;
+out_unmap:
+       iounmap(bcm_umi_io_base);
+out_free:
+       kfree(board_mtd);
+       return err;
 }
 
 static int bcm_umi_nand_remove(struct platform_device *pdev)
index 87ebb4e5b0c3b97949050ec10ff2a62b081c9bac..72d3f23490c58a548c962b1771c44f3781560da9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/io.h>
 
 #define CAFE_NAND_CTRL1                0x00
@@ -57,7 +58,6 @@
 
 struct cafe_priv {
        struct nand_chip nand;
-       struct mtd_partition *parts;
        struct pci_dev *pdev;
        void __iomem *mmio;
        struct rs_control *rs;
@@ -371,7 +371,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
        return 1;
 }
 /**
- * cafe_nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read
+ * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
  * @mtd:       mtd info structure
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
@@ -630,8 +630,6 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
        struct cafe_priv *cafe;
        uint32_t ctrl;
        int err = 0;
-       struct mtd_partition *parts;
-       int nr_parts;
 
        /* Very old versions shared the same PCI ident for all three
           functions on the chip. Verify the class too... */
@@ -686,7 +684,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
        cafe->nand.chip_delay = 0;
 
        /* Enable the following for a flash based bad block table */
-       cafe->nand.options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR | NAND_OWN_BUFFERS;
+       cafe->nand.bbt_options = NAND_BBT_USE_FLASH;
+       cafe->nand.options = NAND_NO_AUTOINCR | NAND_OWN_BUFFERS;
 
        if (skipbbt) {
                cafe->nand.options |= NAND_SKIP_BBTSCAN;
@@ -799,18 +798,9 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, mtd);
 
-       /* We register the whole device first, separate from the partitions */
-       mtd_device_register(mtd, NULL, 0);
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "cafe_nand";
-#endif
-       nr_parts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
-       if (nr_parts > 0) {
-               cafe->parts = parts;
-               dev_info(&cafe->pdev->dev, "%d partitions found\n", nr_parts);
-               mtd_device_register(mtd, parts, nr_parts);
-       }
+       mtd_device_parse_register(mtd, part_probes, 0, NULL, 0);
+
        goto out;
 
  out_irq:
index 6fc043a30d1e20809dccb6d3555ee1603823415e..737ef9a04fdbf35dc03253e49d26281ade9fff95 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -50,8 +51,6 @@ static struct mtd_partition partition_info[] = {
 };
 #define NUM_PARTITIONS (ARRAY_SIZE(partition_info))
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-
 static u_char cmx270_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
@@ -151,9 +150,6 @@ static int cmx270_device_ready(struct mtd_info *mtd)
 static int __init cmx270_init(void)
 {
        struct nand_chip *this;
-       const char *part_type;
-       struct mtd_partition *mtd_parts;
-       int mtd_parts_nb = 0;
        int ret;
 
        if (!(machine_is_armcore() && cpu_is_pxa27x()))
@@ -222,23 +218,9 @@ static int __init cmx270_init(void)
                goto err_scan;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       mtd_parts_nb = parse_mtd_partitions(cmx270_nand_mtd, part_probes,
-                                           &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-#endif
-       if (!mtd_parts_nb) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
-
        /* Register the partitions */
-       pr_notice("Using %s partition definition\n", part_type);
-       ret = mtd_device_register(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
+       ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, 0,
+                                       partition_info, NUM_PARTITIONS);
        if (ret)
                goto err_scan;
 
index f59ad1f2d5dbe7e23fa10a7762332ff2ee44e3cb..414afa7935637522709f6273f2df9930a1170a6a 100644 (file)
@@ -239,7 +239,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        this->ecc.correct  = nand_correct_data;
 
        /* Enable the following for a flash based bad block table */
-       this->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
+       this->bbt_options = NAND_BBT_USE_FLASH;
+       this->options = NAND_NO_AUTOINCR;
 
        /* Scan to find existence of the device */
        if (nand_scan(new_mtd, 1)) {
@@ -277,15 +278,11 @@ static int is_geode(void)
        return 0;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 static int __init cs553x_init(void)
 {
        int err = -ENXIO;
        int i;
        uint64_t val;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = NULL;
 
        /* If the CPU isn't a Geode GX or LX, abort */
        if (!is_geode())
@@ -315,13 +312,9 @@ static int __init cs553x_init(void)
           do mtdconcat etc. if we want to. */
        for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {
                if (cs553x_mtd[i]) {
-
                        /* If any devices registered, return success. Else the last error. */
-                       mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0);
-                       if (mtd_parts_nb > 0)
-                               printk(KERN_NOTICE "Using command line partition definition\n");
-                       mtd_device_register(cs553x_mtd[i], mtd_parts,
-                                           mtd_parts_nb);
+                       mtd_device_parse_register(cs553x_mtd[i], NULL, 0,
+                                                 NULL, 0);
                        err = 0;
                }
        }
index 1f34951ae1a7426f0344a7327c56a5b1105c7bc8..c153e1f77f90d0e58dc6d892f2395a71e500b7ef 100644 (file)
@@ -57,7 +57,6 @@ struct davinci_nand_info {
 
        struct device           *dev;
        struct clk              *clk;
-       bool                    partitioned;
 
        bool                    is_readmode;
 
@@ -530,8 +529,6 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
        int                             ret;
        uint32_t                        val;
        nand_ecc_modes_t                ecc_mode;
-       struct mtd_partition            *mtd_parts = NULL;
-       int                             mtd_parts_nb = 0;
 
        /* insist on board-specific configuration */
        if (!pdata)
@@ -581,7 +578,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
        info->chip.chip_delay   = 0;
        info->chip.select_chip  = nand_davinci_select_chip;
 
-       /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+       /* options such as NAND_BBT_USE_FLASH */
+       info->chip.bbt_options  = pdata->bbt_options;
+       /* options such as 16-bit widths */
        info->chip.options      = pdata->options;
        info->chip.bbt_td       = pdata->bbt_td;
        info->chip.bbt_md       = pdata->bbt_md;
@@ -751,33 +750,8 @@ syndrome_done:
        if (ret < 0)
                goto err_scan;
 
-       if (mtd_has_cmdlinepart()) {
-               static const char *probes[] __initconst = {
-                       "cmdlinepart", NULL
-               };
-
-               mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
-                                                   &mtd_parts, 0);
-       }
-
-       if (mtd_parts_nb <= 0) {
-               mtd_parts = pdata->parts;
-               mtd_parts_nb = pdata->nr_parts;
-       }
-
-       /* Register any partitions */
-       if (mtd_parts_nb > 0) {
-               ret = mtd_device_register(&info->mtd, mtd_parts,
-                                         mtd_parts_nb);
-               if (ret == 0)
-                       info->partitioned = true;
-       }
-
-       /* If there's no partition info, just package the whole chip
-        * as a single MTD device.
-        */
-       if (!info->partitioned)
-               ret = mtd_device_register(&info->mtd, NULL, 0) ? -ENODEV : 0;
+       ret = mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
        if (ret < 0)
                goto err_scan;
@@ -816,9 +790,6 @@ err_nomem:
 static int __exit nand_davinci_remove(struct platform_device *pdev)
 {
        struct davinci_nand_info *info = platform_get_drvdata(pdev);
-       int status;
-
-       status = mtd_device_unregister(&info->mtd);
 
        spin_lock_irq(&davinci_nand_lock);
        if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
index d5276218945fe296cb1c1b8c29cb8f21929dfb42..3984d488f9abbf5a3d6ed77fd49e2c4b7dc79381 100644 (file)
@@ -1346,6 +1346,7 @@ static void denali_hw_init(struct denali_nand_info *denali)
         * */
        denali->bbtskipbytes = ioread32(denali->flash_reg +
                                                SPARE_AREA_SKIP_BYTES);
+       detect_max_banks(denali);
        denali_nand_reset(denali);
        iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED);
        iowrite32(CHIP_EN_DONT_CARE__FLAG,
@@ -1356,7 +1357,6 @@ static void denali_hw_init(struct denali_nand_info *denali)
        /* Should set value for these registers when init */
        iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES);
        iowrite32(1, denali->flash_reg + ECC_ENABLE);
-       detect_max_banks(denali);
        denali_nand_timing_set(denali);
        denali_irq_init(denali);
 }
@@ -1577,7 +1577,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        denali->nand.bbt_md = &bbt_mirror_descr;
 
        /* skip the scan for now until we have OOB read and write support */
-       denali->nand.options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
+       denali->nand.bbt_options |= NAND_BBT_USE_FLASH;
+       denali->nand.options |= NAND_SKIP_BBTSCAN;
        denali->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
 
        /* Denali Controller only support 15bit and 8bit ECC in MRST,
@@ -1676,7 +1677,6 @@ static void denali_pci_remove(struct pci_dev *dev)
        struct denali_nand_info *denali = pci_get_drvdata(dev);
 
        nand_release(&denali->mtd);
-       mtd_device_unregister(&denali->mtd);
 
        denali_irq_cleanup(dev->irq, denali);
 
index 7837728d02ff4c15987d6275d593d3464b6cf073..5780dbab611360d546c0770fb378060a223edda8 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mtd/doc2000.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/inftl.h>
+#include <linux/module.h>
 
 /* Where to look for the devices? */
 #ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS
@@ -132,7 +133,7 @@ static struct rs_control *rs_decoder;
 
 /*
  * The HW decoder in the DoC ASIC's provides us a error syndrome,
- * which we must convert to a standard syndrom usable by the generic
+ * which we must convert to a standard syndrome usable by the generic
  * Reed-Solomon library code.
  *
  * Fabrice Bellard figured this out in the old docecc code. I added
@@ -153,7 +154,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
        ds[3] = ((ecc[3] & 0xc0) >> 6) | ((ecc[0] & 0xff) << 2);
        parity = ecc[1];
 
-       /* Initialize the syndrom buffer */
+       /* Initialize the syndrome buffer */
        for (i = 0; i < NROOTS; i++)
                s[i] = ds[0];
        /*
@@ -1031,7 +1032,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
                WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
        else
                WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-       if (no_ecc_failures && (ret == -EBADMSG)) {
+       if (no_ecc_failures && mtd_is_eccerr(ret)) {
                printk(KERN_ERR "suppressing ECC failure\n");
                ret = 0;
        }
@@ -1652,7 +1653,7 @@ static int __init doc_probe(unsigned long physadr)
        nand->ecc.mode          = NAND_ECC_HW_SYNDROME;
        nand->ecc.size          = 512;
        nand->ecc.bytes         = 6;
-       nand->options           = NAND_USE_FLASH_BBT;
+       nand->bbt_options       = NAND_BBT_USE_FLASH;
 
        doc->physadr            = physadr;
        doc->virtadr            = virtadr;
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
deleted file mode 100644 (file)
index 8400d0f..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- *  drivers/mtd/nand/edb7312.c
- *
- *  Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
- *
- *  Derived from drivers/mtd/nand/autcpu12.c
- *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   CLEP7312 board which utilizes the Toshiba TC58V64AFT part. This is
- *   a 64Mibit (8MiB x 8 bits) NAND flash device.
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <mach/hardware.h>     /* for CLPS7111_VIRT_BASE */
-#include <asm/sizes.h>
-#include <asm/hardware/clps7111.h>
-
-/*
- * MTD structure for EDB7312 board
- */
-static struct mtd_info *ep7312_mtd = NULL;
-
-/*
- * Values specific to the EDB7312 board (used with EP7312 processor)
- */
-#define EP7312_FIO_PBASE 0x10000000    /* Phys address of flash */
-#define EP7312_PXDR    0x0001  /*
-                                * IO offset to Port B data register
-                                * where the CLE, ALE and NCE pins
-                                * are wired to.
-                                */
-#define EP7312_PXDDR   0x0041  /*
-                                * IO offset to Port B data direction
-                                * register so we can control the IO
-                                * lines.
-                                */
-
-/*
- * Module stuff
- */
-
-static unsigned long ep7312_fio_pbase = EP7312_FIO_PBASE;
-static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
-static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
-
-/*
- * Define static partitions for flash device
- */
-static struct mtd_partition partition_info[] = {
-       {.name = "EP7312 Nand Flash",
-        .offset = 0,
-        .size = 8 * 1024 * 1024}
-};
-
-#define NUM_PARTITIONS 1
-
-/*
- *     hardware specific access to control-lines
- *
- *     NAND_NCE: bit 0 -> bit 6 (bit 7 = 1)
- *     NAND_CLE: bit 1 -> bit 4
- *     NAND_ALE: bit 2 -> bit 5
- */
-static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
-       struct nand_chip *chip = mtd->priv;
-
-       if (ctrl & NAND_CTRL_CHANGE) {
-               unsigned char bits = 0x80;
-
-               bits |= (ctrl & (NAND_CLE | NAND_ALE)) << 3;
-               bits |= (ctrl & NAND_NCE) ? 0x00 : 0x40;
-
-               clps_writeb((clps_readb(ep7312_pxdr)  & 0xF0) | bits,
-                           ep7312_pxdr);
-       }
-       if (cmd != NAND_CMD_NONE)
-               writeb(cmd, chip->IO_ADDR_W);
-}
-
-/*
- *     read device ready pin
- */
-static int ep7312_device_ready(struct mtd_info *mtd)
-{
-       return 1;
-}
-
-const char *part_probes[] = { "cmdlinepart", NULL };
-
-/*
- * Main initialization routine
- */
-static int __init ep7312_init(void)
-{
-       struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
-       void __iomem *ep7312_fio_base;
-
-       /* Allocate memory for MTD device structure and private data */
-       ep7312_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
-       if (!ep7312_mtd) {
-               printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
-               return -ENOMEM;
-       }
-
-       /* map physical address */
-       ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
-       if (!ep7312_fio_base) {
-               printk("ioremap EDB7312 NAND flash failed\n");
-               kfree(ep7312_mtd);
-               return -EIO;
-       }
-
-       /* Get pointer to private data */
-       this = (struct nand_chip *)(&ep7312_mtd[1]);
-
-       /* Initialize structures */
-       memset(ep7312_mtd, 0, sizeof(struct mtd_info));
-       memset(this, 0, sizeof(struct nand_chip));
-
-       /* Link the private data with the MTD structure */
-       ep7312_mtd->priv = this;
-       ep7312_mtd->owner = THIS_MODULE;
-
-       /*
-        * Set GPIO Port B control register so that the pins are configured
-        * to be outputs for controlling the NAND flash.
-        */
-       clps_writeb(0xf0, ep7312_pxddr);
-
-       /* insert callbacks */
-       this->IO_ADDR_R = ep7312_fio_base;
-       this->IO_ADDR_W = ep7312_fio_base;
-       this->cmd_ctrl = ep7312_hwcontrol;
-       this->dev_ready = ep7312_device_ready;
-       /* 15 us command delay time */
-       this->chip_delay = 15;
-
-       /* Scan to find existence of the device */
-       if (nand_scan(ep7312_mtd, 1)) {
-               iounmap((void *)ep7312_fio_base);
-               kfree(ep7312_mtd);
-               return -ENXIO;
-       }
-       ep7312_mtd->name = "edb7312-nand";
-       mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
-
-       /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ep7312_mtd, mtd_parts, mtd_parts_nb);
-
-       /* Return happy */
-       return 0;
-}
-
-module_init(ep7312_init);
-
-/*
- * Clean up routine
- */
-static void __exit ep7312_cleanup(void)
-{
-       struct nand_chip *this = (struct nand_chip *)&ep7312_mtd[1];
-
-       /* Release resources, unregister device */
-       nand_release(ap7312_mtd);
-
-       /* Release io resource */
-       iounmap(this->IO_ADDR_R);
-
-       /* Free the MTD device structure */
-       kfree(ep7312_mtd);
-}
-
-module_exit(ep7312_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-MODULE_DESCRIPTION("MTD map driver for Cogent EDB7312 board");
index 33d8aad8bba5a47b2c0135acf4132454bab12eea..eedd8ee2c9ac8b83059edf9cf5856a12e4a53e48 100644 (file)
@@ -75,7 +75,6 @@ struct fsl_elbc_fcm_ctrl {
        unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
        unsigned int oob;        /* Non zero if operating on OOB data     */
        unsigned int counter;    /* counter for the initializations       */
-       char *oob_poi;           /* Place to write ECC after read back    */
 };
 
 /* These map to the positions used by the FCM hardware ECC generator */
@@ -244,6 +243,25 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
                return -EIO;
        }
 
+       if (chip->ecc.mode != NAND_ECC_HW)
+               return 0;
+
+       if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) {
+               uint32_t lteccr = in_be32(&lbc->lteccr);
+               /*
+                * if command was a full page read and the ELBC
+                * has the LTECCR register, then bits 12-15 (ppc order) of
+                * LTECCR indicates which 512 byte sub-pages had fixed errors.
+                * bits 28-31 are uncorrectable errors, marked elsewhere.
+                * for small page nand only 1 bit is used.
+                * if the ELBC doesn't have the lteccr register it reads 0
+                */
+               if (lteccr & 0x000F000F)
+                       out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */
+               if (lteccr & 0x000F0000)
+                       mtd->ecc_stats.corrected++;
+       }
+
        return 0;
 }
 
@@ -435,7 +453,6 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
        case NAND_CMD_PAGEPROG: {
-               int full_page;
                dev_vdbg(priv->dev,
                         "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
                         "writing %d bytes.\n", elbc_fcm_ctrl->index);
@@ -445,34 +462,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                 * write so the HW generates the ECC.
                 */
                if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
-                   elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) {
+                   elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize)
                        out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
-                       full_page = 0;
-               } else {
+               else
                        out_be32(&lbc->fbcr, 0);
-                       full_page = 1;
-               }
 
                fsl_elbc_run_command(mtd);
-
-               /* Read back the page in order to fill in the ECC for the
-                * caller.  Is this really needed?
-                */
-               if (full_page && elbc_fcm_ctrl->oob_poi) {
-                       out_be32(&lbc->fbcr, 3);
-                       set_addr(mtd, 6, page_addr, 1);
-
-                       elbc_fcm_ctrl->read_bytes = mtd->writesize + 9;
-
-                       fsl_elbc_do_read(chip, 1);
-                       fsl_elbc_run_command(mtd);
-
-                       memcpy_fromio(elbc_fcm_ctrl->oob_poi + 6,
-                               &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], 3);
-                       elbc_fcm_ctrl->index += 3;
-               }
-
-               elbc_fcm_ctrl->oob_poi = NULL;
                return;
        }
 
@@ -752,13 +747,8 @@ static void fsl_elbc_write_page(struct mtd_info *mtd,
                                 struct nand_chip *chip,
                                 const uint8_t *buf)
 {
-       struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
-
        fsl_elbc_write_buf(mtd, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-       elbc_fcm_ctrl->oob_poi = chip->oob_poi;
 }
 
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
@@ -791,8 +781,8 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
        chip->bbt_md = &bbt_mirror_descr;
 
        /* set up nand options */
-       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
-                       NAND_USE_FLASH_BBT;
+       chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
 
        chip->controller = &elbc_fcm_ctrl->controller;
        chip->priv = priv;
@@ -829,7 +819,6 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
 
        elbc_fcm_ctrl->chips[priv->bank] = NULL;
        kfree(priv);
-       kfree(elbc_fcm_ctrl);
        return 0;
 }
 
@@ -842,13 +831,14 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
        struct resource res;
        struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl;
        static const char *part_probe_types[]
-               = { "cmdlinepart", "RedBoot", NULL };
-       struct mtd_partition *parts;
+               = { "cmdlinepart", "RedBoot", "ofpart", NULL };
        int ret;
        int bank;
        struct device *dev;
        struct device_node *node = pdev->dev.of_node;
+       struct mtd_part_parser_data ppdata;
 
+       ppdata.of_node = pdev->dev.of_node;
        if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
                return -ENODEV;
        lbc = fsl_lbc_ctrl_dev->regs;
@@ -934,17 +924,8 @@ static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
 
        /* First look for RedBoot table or partitions on the command
         * line, these take precedence over device tree information */
-       ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0);
-       if (ret < 0)
-               goto err;
-
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(priv->dev, node, &parts);
-               if (ret < 0)
-                       goto err;
-       }
-
-       mtd_device_register(&priv->mtd, parts, ret);
+       mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata,
+                                 NULL, 0);
 
        printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
               (unsigned long long)res.start, priv->bank);
index 23752fd5bc590d40e7ac5fb15ad93af05d9e6882..b4f3cc9f32fbe5614ad8d1a0a1cbe905ee01d3f5 100644 (file)
@@ -158,7 +158,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
 {
        int ret;
        struct device_node *flash_np;
-       static const char *part_types[] = { "cmdlinepart", NULL, };
+       struct mtd_part_parser_data ppdata;
 
        fun->chip.IO_ADDR_R = fun->io_base;
        fun->chip.IO_ADDR_W = fun->io_base;
@@ -192,18 +192,12 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
        if (ret)
                goto err;
 
-       ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
-
-#ifdef CONFIG_MTD_OF_PARTS
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(fun->dev, flash_np, &fun->parts);
-               if (ret < 0)
-                       goto err;
-       }
-#endif
-       ret = mtd_device_register(&fun->mtd, fun->parts, ret);
+       ppdata.of_node = flash_np;
+       ret = mtd_device_parse_register(&fun->mtd, NULL, &ppdata, NULL, 0);
 err:
        of_node_put(flash_np);
+       if (ret)
+               kfree(fun->mtd.name);
        return ret;
 }
 
index e9b275ac381ce89fd53f6d5fbb1895d205ce2462..e53b76064133fc52bded214fb57a94696abcb891 100644 (file)
@@ -146,7 +146,7 @@ static struct mtd_partition partition_info_16KB_blk[] = {
        {
                .name = "Root File System",
                .offset = 0x460000,
-               .size = 0,
+               .size = MTDPART_SIZ_FULL,
        },
 };
 
@@ -173,13 +173,10 @@ static struct mtd_partition partition_info_128KB_blk[] = {
        {
                .name = "Root File System",
                .offset = 0x800000,
-               .size = 0,
+               .size = MTDPART_SIZ_FULL,
        },
 };
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /**
  * struct fsmc_nand_data - structure for FSMC NAND device state
@@ -187,8 +184,6 @@ const char *part_probes[] = { "cmdlinepart", NULL };
  * @pid:               Part ID on the AMBA PrimeCell format
  * @mtd:               MTD info for a NAND flash.
  * @nand:              Chip related info for a NAND flash.
- * @partitions:                Partition info for a NAND Flash.
- * @nr_partitions:     Total number of partition of a NAND flash.
  *
  * @ecc_place:         ECC placing locations in oobfree type format.
  * @bank:              Bank number for probed device.
@@ -203,8 +198,6 @@ struct fsmc_nand_data {
        u32                     pid;
        struct mtd_info         mtd;
        struct nand_chip        nand;
-       struct mtd_partition    *partitions;
-       unsigned int            nr_partitions;
 
        struct fsmc_eccplace    *ecc_place;
        unsigned int            bank;
@@ -716,65 +709,17 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
         * platform data,
         * default partition information present in driver.
         */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        /*
-        * Check if partition info passed via command line
+        * Check for partition info passed
         */
        host->mtd.name = "nand";
-       host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes,
-                       &host->partitions, 0);
-       if (host->nr_partitions <= 0) {
-#endif
-               /*
-                * Check if partition info passed via command line
-                */
-               if (pdata->partitions) {
-                       host->partitions = pdata->partitions;
-                       host->nr_partitions = pdata->nr_partitions;
-               } else {
-                       struct mtd_partition *partition;
-                       int i;
-
-                       /* Select the default partitions info */
-                       switch (host->mtd.size) {
-                       case 0x01000000:
-                       case 0x02000000:
-                       case 0x04000000:
-                               host->partitions = partition_info_16KB_blk;
-                               host->nr_partitions =
-                                       sizeof(partition_info_16KB_blk) /
-                                       sizeof(struct mtd_partition);
-                               break;
-                       case 0x08000000:
-                       case 0x10000000:
-                       case 0x20000000:
-                       case 0x40000000:
-                               host->partitions = partition_info_128KB_blk;
-                               host->nr_partitions =
-                                       sizeof(partition_info_128KB_blk) /
-                                       sizeof(struct mtd_partition);
-                               break;
-                       default:
-                               ret = -ENXIO;
-                               pr_err("Unsupported NAND size\n");
-                               goto err_probe;
-                       }
-
-                       partition = host->partitions;
-                       for (i = 0; i < host->nr_partitions; i++, partition++) {
-                               if (partition->size == 0) {
-                                       partition->size = host->mtd.size -
-                                               partition->offset;
-                                       break;
-                               }
-                       }
-               }
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       }
-#endif
-
-       ret = mtd_device_register(&host->mtd, host->partitions,
-                                 host->nr_partitions);
+       ret = mtd_device_parse_register(&host->mtd, NULL, 0,
+                       host->mtd.size <= 0x04000000 ?
+                               partition_info_16KB_blk :
+                               partition_info_128KB_blk,
+                       host->mtd.size <= 0x04000000 ?
+                               ARRAY_SIZE(partition_info_16KB_blk) :
+                               ARRAY_SIZE(partition_info_128KB_blk));
        if (ret)
                goto err_probe;
 
@@ -822,7 +767,7 @@ static int fsmc_nand_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (host) {
-               mtd_device_unregister(&host->mtd);
+               nand_release(&host->mtd);
                clk_disable(host->clk);
                clk_put(host->clk);
 
diff --git a/drivers/mtd/nand/gpmi-nand/Makefile b/drivers/mtd/nand/gpmi-nand/Makefile
new file mode 100644 (file)
index 0000000..3a46248
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi_nand.o
+gpmi_nand-objs += gpmi-nand.o
+gpmi_nand-objs += gpmi-lib.o
diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h
new file mode 100644 (file)
index 0000000..4effb8c
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __GPMI_NAND_BCH_REGS_H
+#define __GPMI_NAND_BCH_REGS_H
+
+#define HW_BCH_CTRL                            0x00000000
+#define HW_BCH_CTRL_SET                                0x00000004
+#define HW_BCH_CTRL_CLR                                0x00000008
+#define HW_BCH_CTRL_TOG                                0x0000000c
+
+#define BM_BCH_CTRL_COMPLETE_IRQ_EN            (1 << 8)
+#define BM_BCH_CTRL_COMPLETE_IRQ               (1 << 0)
+
+#define HW_BCH_STATUS0                         0x00000010
+#define HW_BCH_MODE                            0x00000020
+#define HW_BCH_ENCODEPTR                       0x00000030
+#define HW_BCH_DATAPTR                         0x00000040
+#define HW_BCH_METAPTR                         0x00000050
+#define HW_BCH_LAYOUTSELECT                    0x00000070
+
+#define HW_BCH_FLASH0LAYOUT0                   0x00000080
+
+#define BP_BCH_FLASH0LAYOUT0_NBLOCKS           24
+#define BM_BCH_FLASH0LAYOUT0_NBLOCKS   (0xff << BP_BCH_FLASH0LAYOUT0_NBLOCKS)
+#define BF_BCH_FLASH0LAYOUT0_NBLOCKS(v)                \
+       (((v) << BP_BCH_FLASH0LAYOUT0_NBLOCKS) & BM_BCH_FLASH0LAYOUT0_NBLOCKS)
+
+#define BP_BCH_FLASH0LAYOUT0_META_SIZE         16
+#define BM_BCH_FLASH0LAYOUT0_META_SIZE (0xff << BP_BCH_FLASH0LAYOUT0_META_SIZE)
+#define BF_BCH_FLASH0LAYOUT0_META_SIZE(v)      \
+       (((v) << BP_BCH_FLASH0LAYOUT0_META_SIZE)\
+                                        & BM_BCH_FLASH0LAYOUT0_META_SIZE)
+
+#define BP_BCH_FLASH0LAYOUT0_ECC0              12
+#define BM_BCH_FLASH0LAYOUT0_ECC0      (0xf << BP_BCH_FLASH0LAYOUT0_ECC0)
+#define BF_BCH_FLASH0LAYOUT0_ECC0(v)           \
+       (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) & BM_BCH_FLASH0LAYOUT0_ECC0)
+
+#define BP_BCH_FLASH0LAYOUT0_DATA0_SIZE                0
+#define BM_BCH_FLASH0LAYOUT0_DATA0_SIZE                \
+                       (0xfff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
+#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v)     \
+       (((v) << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)\
+                                        & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE)
+
+#define HW_BCH_FLASH0LAYOUT1                   0x00000090
+
+#define BP_BCH_FLASH0LAYOUT1_PAGE_SIZE         16
+#define BM_BCH_FLASH0LAYOUT1_PAGE_SIZE         \
+                       (0xffff << BP_BCH_FLASH0LAYOUT1_PAGE_SIZE)
+#define BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(v)      \
+       (((v) << BP_BCH_FLASH0LAYOUT1_PAGE_SIZE) \
+                                        & BM_BCH_FLASH0LAYOUT1_PAGE_SIZE)
+
+#define BP_BCH_FLASH0LAYOUT1_ECCN              12
+#define BM_BCH_FLASH0LAYOUT1_ECCN      (0xf << BP_BCH_FLASH0LAYOUT1_ECCN)
+#define BF_BCH_FLASH0LAYOUT1_ECCN(v)           \
+       (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) & BM_BCH_FLASH0LAYOUT1_ECCN)
+
+#define BP_BCH_FLASH0LAYOUT1_DATAN_SIZE                0
+#define BM_BCH_FLASH0LAYOUT1_DATAN_SIZE                \
+                       (0xfff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
+#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v)     \
+       (((v) << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
+                                        & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE)
+#endif
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
new file mode 100644 (file)
index 0000000..de4db76
--- /dev/null
@@ -0,0 +1,1057 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/mtd/gpmi-nand.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <mach/mxs.h>
+
+#include "gpmi-nand.h"
+#include "gpmi-regs.h"
+#include "bch-regs.h"
+
+struct timing_threshod timing_default_threshold = {
+       .max_data_setup_cycles       = (BM_GPMI_TIMING0_DATA_SETUP >>
+                                               BP_GPMI_TIMING0_DATA_SETUP),
+       .internal_data_setup_in_ns   = 0,
+       .max_sample_delay_factor     = (BM_GPMI_CTRL1_RDN_DELAY >>
+                                               BP_GPMI_CTRL1_RDN_DELAY),
+       .max_dll_clock_period_in_ns  = 32,
+       .max_dll_delay_in_ns         = 16,
+};
+
+/*
+ * Clear the bit and poll it cleared.  This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+       int timeout = 0x400;
+
+       /* clear the bit */
+       __mxs_clrl(mask, addr);
+
+       /*
+        * SFTRST needs 3 GPMI clocks to settle, the reference manual
+        * recommends to wait 1us.
+        */
+       udelay(1);
+
+       /* poll the bit becoming clear */
+       while ((readl(addr) & mask) && --timeout)
+               /* nothing */;
+
+       return !timeout;
+}
+
+#define MODULE_CLKGATE         (1 << 30)
+#define MODULE_SFTRST          (1 << 31)
+/*
+ * The current mxs_reset_block() will do two things:
+ *  [1] enable the module.
+ *  [2] reset the module.
+ *
+ * In most of the cases, it's ok. But there is a hardware bug in the BCH block.
+ * If you try to soft reset the BCH block, it becomes unusable until
+ * the next hard reset. This case occurs in the NAND boot mode. When the board
+ * boots by NAND, the ROM of the chip will initialize the BCH blocks itself.
+ * So If the driver tries to reset the BCH again, the BCH will not work anymore.
+ * You will see a DMA timeout in this case.
+ *
+ * To avoid this bug, just add a new parameter `just_enable` for
+ * the mxs_reset_block(), and rewrite it here.
+ */
+int gpmi_reset_block(void __iomem *reset_addr, bool just_enable)
+{
+       int ret;
+       int timeout = 0x400;
+
+       /* clear and poll SFTRST */
+       ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+       if (unlikely(ret))
+               goto error;
+
+       /* clear CLKGATE */
+       __mxs_clrl(MODULE_CLKGATE, reset_addr);
+
+       if (!just_enable) {
+               /* set SFTRST to reset the block */
+               __mxs_setl(MODULE_SFTRST, reset_addr);
+               udelay(1);
+
+               /* poll CLKGATE becoming set */
+               while ((!(readl(reset_addr) & MODULE_CLKGATE)) && --timeout)
+                       /* nothing */;
+               if (unlikely(!timeout))
+                       goto error;
+       }
+
+       /* clear and poll SFTRST */
+       ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
+       if (unlikely(ret))
+               goto error;
+
+       /* clear and poll CLKGATE */
+       ret = clear_poll_bit(reset_addr, MODULE_CLKGATE);
+       if (unlikely(ret))
+               goto error;
+
+       return 0;
+
+error:
+       pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+       return -ETIMEDOUT;
+}
+
+int gpmi_init(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       int ret;
+
+       ret = clk_enable(r->clock);
+       if (ret)
+               goto err_out;
+       ret = gpmi_reset_block(r->gpmi_regs, false);
+       if (ret)
+               goto err_out;
+
+       /* Choose NAND mode. */
+       writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
+
+       /* Set the IRQ polarity. */
+       writel(BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY,
+                               r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       /* Disable Write-Protection. */
+       writel(BM_GPMI_CTRL1_DEV_RESET, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       /* Select BCH ECC. */
+       writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       clk_disable(r->clock);
+       return 0;
+err_out:
+       return ret;
+}
+
+/* This function is very useful. It is called only when the bug occur. */
+void gpmi_dump_info(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       struct bch_geometry *geo = &this->bch_geometry;
+       u32 reg;
+       int i;
+
+       pr_err("Show GPMI registers :\n");
+       for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) {
+               reg = readl(r->gpmi_regs + i * 0x10);
+               pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
+       }
+
+       /* start to print out the BCH info */
+       pr_err("BCH Geometry :\n");
+       pr_err("GF length              : %u\n", geo->gf_len);
+       pr_err("ECC Strength           : %u\n", geo->ecc_strength);
+       pr_err("Page Size in Bytes     : %u\n", geo->page_size);
+       pr_err("Metadata Size in Bytes : %u\n", geo->metadata_size);
+       pr_err("ECC Chunk Size in Bytes: %u\n", geo->ecc_chunk_size);
+       pr_err("ECC Chunk Count        : %u\n", geo->ecc_chunk_count);
+       pr_err("Payload Size in Bytes  : %u\n", geo->payload_size);
+       pr_err("Auxiliary Size in Bytes: %u\n", geo->auxiliary_size);
+       pr_err("Auxiliary Status Offset: %u\n", geo->auxiliary_status_offset);
+       pr_err("Block Mark Byte Offset : %u\n", geo->block_mark_byte_offset);
+       pr_err("Block Mark Bit Offset  : %u\n", geo->block_mark_bit_offset);
+}
+
+/* Configures the geometry for BCH.  */
+int bch_set_geometry(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       struct bch_geometry *bch_geo = &this->bch_geometry;
+       unsigned int block_count;
+       unsigned int block_size;
+       unsigned int metadata_size;
+       unsigned int ecc_strength;
+       unsigned int page_size;
+       int ret;
+
+       if (common_nfc_set_geometry(this))
+               return !0;
+
+       block_count   = bch_geo->ecc_chunk_count - 1;
+       block_size    = bch_geo->ecc_chunk_size;
+       metadata_size = bch_geo->metadata_size;
+       ecc_strength  = bch_geo->ecc_strength >> 1;
+       page_size     = bch_geo->page_size;
+
+       ret = clk_enable(r->clock);
+       if (ret)
+               goto err_out;
+
+       ret = gpmi_reset_block(r->bch_regs, true);
+       if (ret)
+               goto err_out;
+
+       /* Configure layout 0. */
+       writel(BF_BCH_FLASH0LAYOUT0_NBLOCKS(block_count)
+                       | BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
+                       | BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength)
+                       | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size),
+                       r->bch_regs + HW_BCH_FLASH0LAYOUT0);
+
+       writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
+                       | BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength)
+                       | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size),
+                       r->bch_regs + HW_BCH_FLASH0LAYOUT1);
+
+       /* Set *all* chip selects to use layout 0. */
+       writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT);
+
+       /* Enable interrupts. */
+       writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
+                               r->bch_regs + HW_BCH_CTRL_SET);
+
+       clk_disable(r->clock);
+       return 0;
+err_out:
+       return ret;
+}
+
+/* Converts time in nanoseconds to cycles. */
+static unsigned int ns_to_cycles(unsigned int time,
+                       unsigned int period, unsigned int min)
+{
+       unsigned int k;
+
+       k = (time + period - 1) / period;
+       return max(k, min);
+}
+
+/* Apply timing to current hardware conditions. */
+static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
+                                       struct gpmi_nfc_hardware_timing *hw)
+{
+       struct gpmi_nand_platform_data *pdata = this->pdata;
+       struct timing_threshod *nfc = &timing_default_threshold;
+       struct nand_chip *nand = &this->nand;
+       struct nand_timing target = this->timing;
+       bool improved_timing_is_available;
+       unsigned long clock_frequency_in_hz;
+       unsigned int clock_period_in_ns;
+       bool dll_use_half_periods;
+       unsigned int dll_delay_shift;
+       unsigned int max_sample_delay_in_ns;
+       unsigned int address_setup_in_cycles;
+       unsigned int data_setup_in_ns;
+       unsigned int data_setup_in_cycles;
+       unsigned int data_hold_in_cycles;
+       int ideal_sample_delay_in_ns;
+       unsigned int sample_delay_factor;
+       int tEYE;
+       unsigned int min_prop_delay_in_ns = pdata->min_prop_delay_in_ns;
+       unsigned int max_prop_delay_in_ns = pdata->max_prop_delay_in_ns;
+
+       /*
+        * If there are multiple chips, we need to relax the timings to allow
+        * for signal distortion due to higher capacitance.
+        */
+       if (nand->numchips > 2) {
+               target.data_setup_in_ns    += 10;
+               target.data_hold_in_ns     += 10;
+               target.address_setup_in_ns += 10;
+       } else if (nand->numchips > 1) {
+               target.data_setup_in_ns    += 5;
+               target.data_hold_in_ns     += 5;
+               target.address_setup_in_ns += 5;
+       }
+
+       /* Check if improved timing information is available. */
+       improved_timing_is_available =
+               (target.tREA_in_ns  >= 0) &&
+               (target.tRLOH_in_ns >= 0) &&
+               (target.tRHOH_in_ns >= 0) ;
+
+       /* Inspect the clock. */
+       clock_frequency_in_hz = nfc->clock_frequency_in_hz;
+       clock_period_in_ns    = 1000000000 / clock_frequency_in_hz;
+
+       /*
+        * The NFC quantizes setup and hold parameters in terms of clock cycles.
+        * Here, we quantize the setup and hold timing parameters to the
+        * next-highest clock period to make sure we apply at least the
+        * specified times.
+        *
+        * For data setup and data hold, the hardware interprets a value of zero
+        * as the largest possible delay. This is not what's intended by a zero
+        * in the input parameter, so we impose a minimum of one cycle.
+        */
+       data_setup_in_cycles    = ns_to_cycles(target.data_setup_in_ns,
+                                                       clock_period_in_ns, 1);
+       data_hold_in_cycles     = ns_to_cycles(target.data_hold_in_ns,
+                                                       clock_period_in_ns, 1);
+       address_setup_in_cycles = ns_to_cycles(target.address_setup_in_ns,
+                                                       clock_period_in_ns, 0);
+
+       /*
+        * The clock's period affects the sample delay in a number of ways:
+        *
+        * (1) The NFC HAL tells us the maximum clock period the sample delay
+        *     DLL can tolerate. If the clock period is greater than half that
+        *     maximum, we must configure the DLL to be driven by half periods.
+        *
+        * (2) We need to convert from an ideal sample delay, in ns, to a
+        *     "sample delay factor," which the NFC uses. This factor depends on
+        *     whether we're driving the DLL with full or half periods.
+        *     Paraphrasing the reference manual:
+        *
+        *         AD = SDF x 0.125 x RP
+        *
+        * where:
+        *
+        *     AD   is the applied delay, in ns.
+        *     SDF  is the sample delay factor, which is dimensionless.
+        *     RP   is the reference period, in ns, which is a full clock period
+        *          if the DLL is being driven by full periods, or half that if
+        *          the DLL is being driven by half periods.
+        *
+        * Let's re-arrange this in a way that's more useful to us:
+        *
+        *                        8
+        *         SDF  =  AD x ----
+        *                       RP
+        *
+        * The reference period is either the clock period or half that, so this
+        * is:
+        *
+        *                        8       AD x DDF
+        *         SDF  =  AD x -----  =  --------
+        *                      f x P        P
+        *
+        * where:
+        *
+        *       f  is 1 or 1/2, depending on how we're driving the DLL.
+        *       P  is the clock period.
+        *     DDF  is the DLL Delay Factor, a dimensionless value that
+        *          incorporates all the constants in the conversion.
+        *
+        * DDF will be either 8 or 16, both of which are powers of two. We can
+        * reduce the cost of this conversion by using bit shifts instead of
+        * multiplication or division. Thus:
+        *
+        *                 AD << DDS
+        *         SDF  =  ---------
+        *                     P
+        *
+        *     or
+        *
+        *         AD  =  (SDF >> DDS) x P
+        *
+        * where:
+        *
+        *     DDS  is the DLL Delay Shift, the logarithm to base 2 of the DDF.
+        */
+       if (clock_period_in_ns > (nfc->max_dll_clock_period_in_ns >> 1)) {
+               dll_use_half_periods = true;
+               dll_delay_shift      = 3 + 1;
+       } else {
+               dll_use_half_periods = false;
+               dll_delay_shift      = 3;
+       }
+
+       /*
+        * Compute the maximum sample delay the NFC allows, under current
+        * conditions. If the clock is running too slowly, no sample delay is
+        * possible.
+        */
+       if (clock_period_in_ns > nfc->max_dll_clock_period_in_ns)
+               max_sample_delay_in_ns = 0;
+       else {
+               /*
+                * Compute the delay implied by the largest sample delay factor
+                * the NFC allows.
+                */
+               max_sample_delay_in_ns =
+                       (nfc->max_sample_delay_factor * clock_period_in_ns) >>
+                                                               dll_delay_shift;
+
+               /*
+                * Check if the implied sample delay larger than the NFC
+                * actually allows.
+                */
+               if (max_sample_delay_in_ns > nfc->max_dll_delay_in_ns)
+                       max_sample_delay_in_ns = nfc->max_dll_delay_in_ns;
+       }
+
+       /*
+        * Check if improved timing information is available. If not, we have to
+        * use a less-sophisticated algorithm.
+        */
+       if (!improved_timing_is_available) {
+               /*
+                * Fold the read setup time required by the NFC into the ideal
+                * sample delay.
+                */
+               ideal_sample_delay_in_ns = target.gpmi_sample_delay_in_ns +
+                                               nfc->internal_data_setup_in_ns;
+
+               /*
+                * The ideal sample delay may be greater than the maximum
+                * allowed by the NFC. If so, we can trade off sample delay time
+                * for more data setup time.
+                *
+                * In each iteration of the following loop, we add a cycle to
+                * the data setup time and subtract a corresponding amount from
+                * the sample delay until we've satisified the constraints or
+                * can't do any better.
+                */
+               while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
+                       (data_setup_in_cycles < nfc->max_data_setup_cycles)) {
+
+                       data_setup_in_cycles++;
+                       ideal_sample_delay_in_ns -= clock_period_in_ns;
+
+                       if (ideal_sample_delay_in_ns < 0)
+                               ideal_sample_delay_in_ns = 0;
+
+               }
+
+               /*
+                * Compute the sample delay factor that corresponds most closely
+                * to the ideal sample delay. If the result is too large for the
+                * NFC, use the maximum value.
+                *
+                * Notice that we use the ns_to_cycles function to compute the
+                * sample delay factor. We do this because the form of the
+                * computation is the same as that for calculating cycles.
+                */
+               sample_delay_factor =
+                       ns_to_cycles(
+                               ideal_sample_delay_in_ns << dll_delay_shift,
+                                                       clock_period_in_ns, 0);
+
+               if (sample_delay_factor > nfc->max_sample_delay_factor)
+                       sample_delay_factor = nfc->max_sample_delay_factor;
+
+               /* Skip to the part where we return our results. */
+               goto return_results;
+       }
+
+       /*
+        * If control arrives here, we have more detailed timing information,
+        * so we can use a better algorithm.
+        */
+
+       /*
+        * Fold the read setup time required by the NFC into the maximum
+        * propagation delay.
+        */
+       max_prop_delay_in_ns += nfc->internal_data_setup_in_ns;
+
+       /*
+        * Earlier, we computed the number of clock cycles required to satisfy
+        * the data setup time. Now, we need to know the actual nanoseconds.
+        */
+       data_setup_in_ns = clock_period_in_ns * data_setup_in_cycles;
+
+       /*
+        * Compute tEYE, the width of the data eye when reading from the NAND
+        * Flash. The eye width is fundamentally determined by the data setup
+        * time, perturbed by propagation delays and some characteristics of the
+        * NAND Flash device.
+        *
+        * start of the eye = max_prop_delay + tREA
+        * end of the eye   = min_prop_delay + tRHOH + data_setup
+        */
+       tEYE = (int)min_prop_delay_in_ns + (int)target.tRHOH_in_ns +
+                                                       (int)data_setup_in_ns;
+
+       tEYE -= (int)max_prop_delay_in_ns + (int)target.tREA_in_ns;
+
+       /*
+        * The eye must be open. If it's not, we can try to open it by
+        * increasing its main forcer, the data setup time.
+        *
+        * In each iteration of the following loop, we increase the data setup
+        * time by a single clock cycle. We do this until either the eye is
+        * open or we run into NFC limits.
+        */
+       while ((tEYE <= 0) &&
+                       (data_setup_in_cycles < nfc->max_data_setup_cycles)) {
+               /* Give a cycle to data setup. */
+               data_setup_in_cycles++;
+               /* Synchronize the data setup time with the cycles. */
+               data_setup_in_ns += clock_period_in_ns;
+               /* Adjust tEYE accordingly. */
+               tEYE += clock_period_in_ns;
+       }
+
+       /*
+        * When control arrives here, the eye is open. The ideal time to sample
+        * the data is in the center of the eye:
+        *
+        *     end of the eye + start of the eye
+        *     ---------------------------------  -  data_setup
+        *                    2
+        *
+        * After some algebra, this simplifies to the code immediately below.
+        */
+       ideal_sample_delay_in_ns =
+               ((int)max_prop_delay_in_ns +
+                       (int)target.tREA_in_ns +
+                               (int)min_prop_delay_in_ns +
+                                       (int)target.tRHOH_in_ns -
+                                               (int)data_setup_in_ns) >> 1;
+
+       /*
+        * The following figure illustrates some aspects of a NAND Flash read:
+        *
+        *
+        *           __                   _____________________________________
+        * RDN         \_________________/
+        *
+        *                                         <---- tEYE ----->
+        *                                        /-----------------\
+        * Read Data ----------------------------<                   >---------
+        *                                        \-----------------/
+        *             ^                 ^                 ^              ^
+        *             |                 |                 |              |
+        *             |<--Data Setup -->|<--Delay Time -->|              |
+        *             |                 |                 |              |
+        *             |                 |                                |
+        *             |                 |<--   Quantized Delay Time   -->|
+        *             |                 |                                |
+        *
+        *
+        * We have some issues we must now address:
+        *
+        * (1) The *ideal* sample delay time must not be negative. If it is, we
+        *     jam it to zero.
+        *
+        * (2) The *ideal* sample delay time must not be greater than that
+        *     allowed by the NFC. If it is, we can increase the data setup
+        *     time, which will reduce the delay between the end of the data
+        *     setup and the center of the eye. It will also make the eye
+        *     larger, which might help with the next issue...
+        *
+        * (3) The *quantized* sample delay time must not fall either before the
+        *     eye opens or after it closes (the latter is the problem
+        *     illustrated in the above figure).
+        */
+
+       /* Jam a negative ideal sample delay to zero. */
+       if (ideal_sample_delay_in_ns < 0)
+               ideal_sample_delay_in_ns = 0;
+
+       /*
+        * Extend the data setup as needed to reduce the ideal sample delay
+        * below the maximum permitted by the NFC.
+        */
+       while ((ideal_sample_delay_in_ns > max_sample_delay_in_ns) &&
+                       (data_setup_in_cycles < nfc->max_data_setup_cycles)) {
+
+               /* Give a cycle to data setup. */
+               data_setup_in_cycles++;
+               /* Synchronize the data setup time with the cycles. */
+               data_setup_in_ns += clock_period_in_ns;
+               /* Adjust tEYE accordingly. */
+               tEYE += clock_period_in_ns;
+
+               /*
+                * Decrease the ideal sample delay by one half cycle, to keep it
+                * in the middle of the eye.
+                */
+               ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
+
+               /* Jam a negative ideal sample delay to zero. */
+               if (ideal_sample_delay_in_ns < 0)
+                       ideal_sample_delay_in_ns = 0;
+       }
+
+       /*
+        * Compute the sample delay factor that corresponds to the ideal sample
+        * delay. If the result is too large, then use the maximum allowed
+        * value.
+        *
+        * Notice that we use the ns_to_cycles function to compute the sample
+        * delay factor. We do this because the form of the computation is the
+        * same as that for calculating cycles.
+        */
+       sample_delay_factor =
+               ns_to_cycles(ideal_sample_delay_in_ns << dll_delay_shift,
+                                                       clock_period_in_ns, 0);
+
+       if (sample_delay_factor > nfc->max_sample_delay_factor)
+               sample_delay_factor = nfc->max_sample_delay_factor;
+
+       /*
+        * These macros conveniently encapsulate a computation we'll use to
+        * continuously evaluate whether or not the data sample delay is inside
+        * the eye.
+        */
+       #define IDEAL_DELAY  ((int) ideal_sample_delay_in_ns)
+
+       #define QUANTIZED_DELAY  \
+               ((int) ((sample_delay_factor * clock_period_in_ns) >> \
+                                                       dll_delay_shift))
+
+       #define DELAY_ERROR  (abs(QUANTIZED_DELAY - IDEAL_DELAY))
+
+       #define SAMPLE_IS_NOT_WITHIN_THE_EYE  (DELAY_ERROR > (tEYE >> 1))
+
+       /*
+        * While the quantized sample time falls outside the eye, reduce the
+        * sample delay or extend the data setup to move the sampling point back
+        * toward the eye. Do not allow the number of data setup cycles to
+        * exceed the maximum allowed by the NFC.
+        */
+       while (SAMPLE_IS_NOT_WITHIN_THE_EYE &&
+                       (data_setup_in_cycles < nfc->max_data_setup_cycles)) {
+               /*
+                * If control arrives here, the quantized sample delay falls
+                * outside the eye. Check if it's before the eye opens, or after
+                * the eye closes.
+                */
+               if (QUANTIZED_DELAY > IDEAL_DELAY) {
+                       /*
+                        * If control arrives here, the quantized sample delay
+                        * falls after the eye closes. Decrease the quantized
+                        * delay time and then go back to re-evaluate.
+                        */
+                       if (sample_delay_factor != 0)
+                               sample_delay_factor--;
+                       continue;
+               }
+
+               /*
+                * If control arrives here, the quantized sample delay falls
+                * before the eye opens. Shift the sample point by increasing
+                * data setup time. This will also make the eye larger.
+                */
+
+               /* Give a cycle to data setup. */
+               data_setup_in_cycles++;
+               /* Synchronize the data setup time with the cycles. */
+               data_setup_in_ns += clock_period_in_ns;
+               /* Adjust tEYE accordingly. */
+               tEYE += clock_period_in_ns;
+
+               /*
+                * Decrease the ideal sample delay by one half cycle, to keep it
+                * in the middle of the eye.
+                */
+               ideal_sample_delay_in_ns -= (clock_period_in_ns >> 1);
+
+               /* ...and one less period for the delay time. */
+               ideal_sample_delay_in_ns -= clock_period_in_ns;
+
+               /* Jam a negative ideal sample delay to zero. */
+               if (ideal_sample_delay_in_ns < 0)
+                       ideal_sample_delay_in_ns = 0;
+
+               /*
+                * We have a new ideal sample delay, so re-compute the quantized
+                * delay.
+                */
+               sample_delay_factor =
+                       ns_to_cycles(
+                               ideal_sample_delay_in_ns << dll_delay_shift,
+                                                       clock_period_in_ns, 0);
+
+               if (sample_delay_factor > nfc->max_sample_delay_factor)
+                       sample_delay_factor = nfc->max_sample_delay_factor;
+       }
+
+       /* Control arrives here when we're ready to return our results. */
+return_results:
+       hw->data_setup_in_cycles    = data_setup_in_cycles;
+       hw->data_hold_in_cycles     = data_hold_in_cycles;
+       hw->address_setup_in_cycles = address_setup_in_cycles;
+       hw->use_half_periods        = dll_use_half_periods;
+       hw->sample_delay_factor     = sample_delay_factor;
+
+       /* Return success. */
+       return 0;
+}
+
+/* Begin the I/O */
+void gpmi_begin(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       struct timing_threshod *nfc = &timing_default_threshold;
+       unsigned char  *gpmi_regs = r->gpmi_regs;
+       unsigned int   clock_period_in_ns;
+       uint32_t       reg;
+       unsigned int   dll_wait_time_in_us;
+       struct gpmi_nfc_hardware_timing  hw;
+       int ret;
+
+       /* Enable the clock. */
+       ret = clk_enable(r->clock);
+       if (ret) {
+               pr_err("We failed in enable the clk\n");
+               goto err_out;
+       }
+
+       /* set ready/busy timeout */
+       writel(0x500 << BP_GPMI_TIMING1_BUSY_TIMEOUT,
+               gpmi_regs + HW_GPMI_TIMING1);
+
+       /* Get the timing information we need. */
+       nfc->clock_frequency_in_hz = clk_get_rate(r->clock);
+       clock_period_in_ns = 1000000000 / nfc->clock_frequency_in_hz;
+
+       gpmi_nfc_compute_hardware_timing(this, &hw);
+
+       /* Set up all the simple timing parameters. */
+       reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
+               BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
+               BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles)       ;
+
+       writel(reg, gpmi_regs + HW_GPMI_TIMING0);
+
+       /*
+        * DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD.
+        */
+       writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
+
+       /* Clear out the DLL control fields. */
+       writel(BM_GPMI_CTRL1_RDN_DELAY,   gpmi_regs + HW_GPMI_CTRL1_CLR);
+       writel(BM_GPMI_CTRL1_HALF_PERIOD, gpmi_regs + HW_GPMI_CTRL1_CLR);
+
+       /* If no sample delay is called for, return immediately. */
+       if (!hw.sample_delay_factor)
+               return;
+
+       /* Configure the HALF_PERIOD flag. */
+       if (hw.use_half_periods)
+               writel(BM_GPMI_CTRL1_HALF_PERIOD,
+                                               gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       /* Set the delay factor. */
+       writel(BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor),
+                                               gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       /* Enable the DLL. */
+       writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
+
+       /*
+        * After we enable the GPMI DLL, we have to wait 64 clock cycles before
+        * we can use the GPMI.
+        *
+        * Calculate the amount of time we need to wait, in microseconds.
+        */
+       dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
+
+       if (!dll_wait_time_in_us)
+               dll_wait_time_in_us = 1;
+
+       /* Wait for the DLL to settle. */
+       udelay(dll_wait_time_in_us);
+
+err_out:
+       return;
+}
+
+void gpmi_end(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       clk_disable(r->clock);
+}
+
+/* Clears a BCH interrupt. */
+void gpmi_clear_bch(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+       writel(BM_BCH_CTRL_COMPLETE_IRQ, r->bch_regs + HW_BCH_CTRL_CLR);
+}
+
+/* Returns the Ready/Busy status of the given chip. */
+int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
+{
+       struct resources *r = &this->resources;
+       uint32_t mask = 0;
+       uint32_t reg = 0;
+
+       if (GPMI_IS_MX23(this)) {
+               mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
+               reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
+       } else if (GPMI_IS_MX28(this)) {
+               mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
+               reg = readl(r->gpmi_regs + HW_GPMI_STAT);
+       } else
+               pr_err("unknow arch.\n");
+       return reg & mask;
+}
+
+static inline void set_dma_type(struct gpmi_nand_data *this,
+                                       enum dma_ops_type type)
+{
+       this->last_dma_type = this->dma_type;
+       this->dma_type = type;
+}
+
+int gpmi_send_command(struct gpmi_nand_data *this)
+{
+       struct dma_chan *channel = get_dma_chan(this);
+       struct dma_async_tx_descriptor *desc;
+       struct scatterlist *sgl;
+       int chip = this->current_chip;
+       u32 pio[3];
+
+       /* [1] send out the PIO words */
+       pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__WRITE)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_CLE)
+               | BM_GPMI_CTRL0_ADDRESS_INCREMENT
+               | BF_GPMI_CTRL0_XFER_COUNT(this->command_length);
+       pio[1] = pio[2] = 0;
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_NONE, 0);
+       if (!desc) {
+               pr_err("step 1 error\n");
+               return -1;
+       }
+
+       /* [2] send out the COMMAND + ADDRESS string stored in @buffer */
+       sgl = &this->cmd_sgl;
+
+       sg_init_one(sgl, this->cmd_buffer, this->command_length);
+       dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       sgl, 1, DMA_TO_DEVICE, 1);
+       if (!desc) {
+               pr_err("step 2 error\n");
+               return -1;
+       }
+
+       /* [3] submit the DMA */
+       set_dma_type(this, DMA_FOR_COMMAND);
+       return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_send_data(struct gpmi_nand_data *this)
+{
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *channel = get_dma_chan(this);
+       int chip = this->current_chip;
+       uint32_t command_mode;
+       uint32_t address;
+       u32 pio[2];
+
+       /* [1] PIO */
+       command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
+       address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+       pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(address)
+               | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
+       pio[1] = 0;
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_NONE, 0);
+       if (!desc) {
+               pr_err("step 1 error\n");
+               return -1;
+       }
+
+       /* [2] send DMA request */
+       prepare_data_dma(this, DMA_TO_DEVICE);
+       desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
+                                               1, DMA_TO_DEVICE, 1);
+       if (!desc) {
+               pr_err("step 2 error\n");
+               return -1;
+       }
+       /* [3] submit the DMA */
+       set_dma_type(this, DMA_FOR_WRITE_DATA);
+       return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_read_data(struct gpmi_nand_data *this)
+{
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *channel = get_dma_chan(this);
+       int chip = this->current_chip;
+       u32 pio[2];
+
+       /* [1] : send PIO */
+       pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA)
+               | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
+       pio[1] = 0;
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_NONE, 0);
+       if (!desc) {
+               pr_err("step 1 error\n");
+               return -1;
+       }
+
+       /* [2] : send DMA request */
+       prepare_data_dma(this, DMA_FROM_DEVICE);
+       desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
+                                               1, DMA_FROM_DEVICE, 1);
+       if (!desc) {
+               pr_err("step 2 error\n");
+               return -1;
+       }
+
+       /* [3] : submit the DMA */
+       set_dma_type(this, DMA_FOR_READ_DATA);
+       return start_dma_without_bch_irq(this, desc);
+}
+
+int gpmi_send_page(struct gpmi_nand_data *this,
+                       dma_addr_t payload, dma_addr_t auxiliary)
+{
+       struct bch_geometry *geo = &this->bch_geometry;
+       uint32_t command_mode;
+       uint32_t address;
+       uint32_t ecc_command;
+       uint32_t buffer_mask;
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *channel = get_dma_chan(this);
+       int chip = this->current_chip;
+       u32 pio[6];
+
+       /* A DMA descriptor that does an ECC page read. */
+       command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE;
+       address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+       ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE;
+       buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE |
+                               BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
+
+       pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(address)
+               | BF_GPMI_CTRL0_XFER_COUNT(0);
+       pio[1] = 0;
+       pio[2] = BM_GPMI_ECCCTRL_ENABLE_ECC
+               | BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
+               | BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
+       pio[3] = geo->page_size;
+       pio[4] = payload;
+       pio[5] = auxiliary;
+
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_NONE, 0);
+       if (!desc) {
+               pr_err("step 2 error\n");
+               return -1;
+       }
+       set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
+       return start_dma_with_bch_irq(this, desc);
+}
+
+int gpmi_read_page(struct gpmi_nand_data *this,
+                               dma_addr_t payload, dma_addr_t auxiliary)
+{
+       struct bch_geometry *geo = &this->bch_geometry;
+       uint32_t command_mode;
+       uint32_t address;
+       uint32_t ecc_command;
+       uint32_t buffer_mask;
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *channel = get_dma_chan(this);
+       int chip = this->current_chip;
+       u32 pio[6];
+
+       /* [1] Wait for the chip to report ready. */
+       command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
+       address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+       pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(address)
+               | BF_GPMI_CTRL0_XFER_COUNT(0);
+       pio[1] = 0;
+       desc = channel->device->device_prep_slave_sg(channel,
+                               (struct scatterlist *)pio, 2, DMA_NONE, 0);
+       if (!desc) {
+               pr_err("step 1 error\n");
+               return -1;
+       }
+
+       /* [2] Enable the BCH block and read. */
+       command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ;
+       address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+       ecc_command  = BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE;
+       buffer_mask  = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE
+                       | BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY;
+
+       pio[0] =  BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(address)
+               | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
+
+       pio[1] = 0;
+       pio[2] =  BM_GPMI_ECCCTRL_ENABLE_ECC
+               | BF_GPMI_ECCCTRL_ECC_CMD(ecc_command)
+               | BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask);
+       pio[3] = geo->page_size;
+       pio[4] = payload;
+       pio[5] = auxiliary;
+       desc = channel->device->device_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_NONE, 1);
+       if (!desc) {
+               pr_err("step 2 error\n");
+               return -1;
+       }
+
+       /* [3] Disable the BCH block */
+       command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
+       address      = BV_GPMI_CTRL0_ADDRESS__NAND_DATA;
+
+       pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode)
+               | BM_GPMI_CTRL0_WORD_LENGTH
+               | BF_GPMI_CTRL0_CS(chip, this)
+               | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this)
+               | BF_GPMI_CTRL0_ADDRESS(address)
+               | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
+       pio[1] = 0;
+       desc = channel->device->device_prep_slave_sg(channel,
+                               (struct scatterlist *)pio, 2, DMA_NONE, 1);
+       if (!desc) {
+               pr_err("step 3 error\n");
+               return -1;
+       }
+
+       /* [4] submit the DMA */
+       set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
+       return start_dma_with_bch_irq(this, desc);
+}
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
new file mode 100644 (file)
index 0000000..071b634
--- /dev/null
@@ -0,0 +1,1619 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/gpmi-nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "gpmi-nand.h"
+
+/* add our owner bbt descriptor */
+static uint8_t scan_ff_pattern[] = { 0xff };
+static struct nand_bbt_descr gpmi_bbt_descr = {
+       .options        = 0,
+       .offs           = 0,
+       .len            = 1,
+       .pattern        = scan_ff_pattern
+};
+
+/*  We will use all the (page + OOB). */
+static struct nand_ecclayout gpmi_hw_ecclayout = {
+       .eccbytes = 0,
+       .eccpos = { 0, },
+       .oobfree = { {.offset = 0, .length = 0} }
+};
+
+static irqreturn_t bch_irq(int irq, void *cookie)
+{
+       struct gpmi_nand_data *this = cookie;
+
+       gpmi_clear_bch(this);
+       complete(&this->bch_done);
+       return IRQ_HANDLED;
+}
+
+/*
+ *  Calculate the ECC strength by hand:
+ *     E : The ECC strength.
+ *     G : the length of Galois Field.
+ *     N : The chunk count of per page.
+ *     O : the oobsize of the NAND chip.
+ *     M : the metasize of per page.
+ *
+ *     The formula is :
+ *             E * G * N
+ *           ------------ <= (O - M)
+ *                  8
+ *
+ *      So, we get E by:
+ *                    (O - M) * 8
+ *              E <= -------------
+ *                       G * N
+ */
+static inline int get_ecc_strength(struct gpmi_nand_data *this)
+{
+       struct bch_geometry *geo = &this->bch_geometry;
+       struct mtd_info *mtd = &this->mtd;
+       int ecc_strength;
+
+       ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8)
+                       / (geo->gf_len * geo->ecc_chunk_count);
+
+       /* We need the minor even number. */
+       return round_down(ecc_strength, 2);
+}
+
+int common_nfc_set_geometry(struct gpmi_nand_data *this)
+{
+       struct bch_geometry *geo = &this->bch_geometry;
+       struct mtd_info *mtd = &this->mtd;
+       unsigned int metadata_size;
+       unsigned int status_size;
+       unsigned int block_mark_bit_offset;
+
+       /*
+        * The size of the metadata can be changed, though we set it to 10
+        * bytes now. But it can't be too large, because we have to save
+        * enough space for BCH.
+        */
+       geo->metadata_size = 10;
+
+       /* The default for the length of Galois Field. */
+       geo->gf_len = 13;
+
+       /* The default for chunk size. There is no oobsize greater then 512. */
+       geo->ecc_chunk_size = 512;
+       while (geo->ecc_chunk_size < mtd->oobsize)
+               geo->ecc_chunk_size *= 2; /* keep C >= O */
+
+       geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
+
+       /* We use the same ECC strength for all chunks. */
+       geo->ecc_strength = get_ecc_strength(this);
+       if (!geo->ecc_strength) {
+               pr_err("We get a wrong ECC strength.\n");
+               return -EINVAL;
+       }
+
+       geo->page_size = mtd->writesize + mtd->oobsize;
+       geo->payload_size = mtd->writesize;
+
+       /*
+        * The auxiliary buffer contains the metadata and the ECC status. The
+        * metadata is padded to the nearest 32-bit boundary. The ECC status
+        * contains one byte for every ECC chunk, and is also padded to the
+        * nearest 32-bit boundary.
+        */
+       metadata_size = ALIGN(geo->metadata_size, 4);
+       status_size   = ALIGN(geo->ecc_chunk_count, 4);
+
+       geo->auxiliary_size = metadata_size + status_size;
+       geo->auxiliary_status_offset = metadata_size;
+
+       if (!this->swap_block_mark)
+               return 0;
+
+       /*
+        * We need to compute the byte and bit offsets of
+        * the physical block mark within the ECC-based view of the page.
+        *
+        * NAND chip with 2K page shows below:
+        *                                             (Block Mark)
+        *                                                   |      |
+        *                                                   |  D   |
+        *                                                   |<---->|
+        *                                                   V      V
+        *    +---+----------+-+----------+-+----------+-+----------+-+
+        *    | M |   data   |E|   data   |E|   data   |E|   data   |E|
+        *    +---+----------+-+----------+-+----------+-+----------+-+
+        *
+        * The position of block mark moves forward in the ECC-based view
+        * of page, and the delta is:
+        *
+        *                   E * G * (N - 1)
+        *             D = (---------------- + M)
+        *                          8
+        *
+        * With the formula to compute the ECC strength, and the condition
+        *       : C >= O         (C is the ecc chunk size)
+        *
+        * It's easy to deduce to the following result:
+        *
+        *         E * G       (O - M)      C - M         C - M
+        *      ----------- <= ------- <=  --------  <  ---------
+        *           8            N           N          (N - 1)
+        *
+        *  So, we get:
+        *
+        *                   E * G * (N - 1)
+        *             D = (---------------- + M) < C
+        *                          8
+        *
+        *  The above inequality means the position of block mark
+        *  within the ECC-based view of the page is still in the data chunk,
+        *  and it's NOT in the ECC bits of the chunk.
+        *
+        *  Use the following to compute the bit position of the
+        *  physical block mark within the ECC-based view of the page:
+        *          (page_size - D) * 8
+        *
+        *  --Huang Shijie
+        */
+       block_mark_bit_offset = mtd->writesize * 8 -
+               (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1)
+                               + geo->metadata_size * 8);
+
+       geo->block_mark_byte_offset = block_mark_bit_offset / 8;
+       geo->block_mark_bit_offset  = block_mark_bit_offset % 8;
+       return 0;
+}
+
+struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
+{
+       int chipnr = this->current_chip;
+
+       return this->dma_chans[chipnr];
+}
+
+/* Can we use the upper's buffer directly for DMA? */
+void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
+{
+       struct scatterlist *sgl = &this->data_sgl;
+       int ret;
+
+       this->direct_dma_map_ok = true;
+
+       /* first try to map the upper buffer directly */
+       sg_init_one(sgl, this->upper_buf, this->upper_len);
+       ret = dma_map_sg(this->dev, sgl, 1, dr);
+       if (ret == 0) {
+               /* We have to use our own DMA buffer. */
+               sg_init_one(sgl, this->data_buffer_dma, PAGE_SIZE);
+
+               if (dr == DMA_TO_DEVICE)
+                       memcpy(this->data_buffer_dma, this->upper_buf,
+                               this->upper_len);
+
+               ret = dma_map_sg(this->dev, sgl, 1, dr);
+               if (ret == 0)
+                       pr_err("map failed.\n");
+
+               this->direct_dma_map_ok = false;
+       }
+}
+
+/* This will be called after the DMA operation is finished. */
+static void dma_irq_callback(void *param)
+{
+       struct gpmi_nand_data *this = param;
+       struct completion *dma_c = &this->dma_done;
+
+       complete(dma_c);
+
+       switch (this->dma_type) {
+       case DMA_FOR_COMMAND:
+               dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE);
+               break;
+
+       case DMA_FOR_READ_DATA:
+               dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE);
+               if (this->direct_dma_map_ok == false)
+                       memcpy(this->upper_buf, this->data_buffer_dma,
+                               this->upper_len);
+               break;
+
+       case DMA_FOR_WRITE_DATA:
+               dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE);
+               break;
+
+       case DMA_FOR_READ_ECC_PAGE:
+       case DMA_FOR_WRITE_ECC_PAGE:
+               /* We have to wait the BCH interrupt to finish. */
+               break;
+
+       default:
+               pr_err("in wrong DMA operation.\n");
+       }
+}
+
+int start_dma_without_bch_irq(struct gpmi_nand_data *this,
+                               struct dma_async_tx_descriptor *desc)
+{
+       struct completion *dma_c = &this->dma_done;
+       int err;
+
+       init_completion(dma_c);
+
+       desc->callback          = dma_irq_callback;
+       desc->callback_param    = this;
+       dmaengine_submit(desc);
+
+       /* Wait for the interrupt from the DMA block. */
+       err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000));
+       if (!err) {
+               pr_err("DMA timeout, last DMA :%d\n", this->last_dma_type);
+               gpmi_dump_info(this);
+               return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+/*
+ * This function is used in BCH reading or BCH writing pages.
+ * It will wait for the BCH interrupt as long as ONE second.
+ * Actually, we must wait for two interrupts :
+ *     [1] firstly the DMA interrupt and
+ *     [2] secondly the BCH interrupt.
+ */
+int start_dma_with_bch_irq(struct gpmi_nand_data *this,
+                       struct dma_async_tx_descriptor *desc)
+{
+       struct completion *bch_c = &this->bch_done;
+       int err;
+
+       /* Prepare to receive an interrupt from the BCH block. */
+       init_completion(bch_c);
+
+       /* start the DMA */
+       start_dma_without_bch_irq(this, desc);
+
+       /* Wait for the interrupt from the BCH block. */
+       err = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000));
+       if (!err) {
+               pr_err("BCH timeout, last DMA :%d\n", this->last_dma_type);
+               gpmi_dump_info(this);
+               return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+static int __devinit
+acquire_register_block(struct gpmi_nand_data *this, const char *res_name)
+{
+       struct platform_device *pdev = this->pdev;
+       struct resources *res = &this->resources;
+       struct resource *r;
+       void *p;
+
+       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+       if (!r) {
+               pr_err("Can't get resource for %s\n", res_name);
+               return -ENXIO;
+       }
+
+       p = ioremap(r->start, resource_size(r));
+       if (!p) {
+               pr_err("Can't remap %s\n", res_name);
+               return -ENOMEM;
+       }
+
+       if (!strcmp(res_name, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME))
+               res->gpmi_regs = p;
+       else if (!strcmp(res_name, GPMI_NAND_BCH_REGS_ADDR_RES_NAME))
+               res->bch_regs = p;
+       else
+               pr_err("unknown resource name : %s\n", res_name);
+
+       return 0;
+}
+
+static void release_register_block(struct gpmi_nand_data *this)
+{
+       struct resources *res = &this->resources;
+       if (res->gpmi_regs)
+               iounmap(res->gpmi_regs);
+       if (res->bch_regs)
+               iounmap(res->bch_regs);
+       res->gpmi_regs = NULL;
+       res->bch_regs = NULL;
+}
+
+static int __devinit
+acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)
+{
+       struct platform_device *pdev = this->pdev;
+       struct resources *res = &this->resources;
+       const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME;
+       struct resource *r;
+       int err;
+
+       r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
+       if (!r) {
+               pr_err("Can't get resource for %s\n", res_name);
+               return -ENXIO;
+       }
+
+       err = request_irq(r->start, irq_h, 0, res_name, this);
+       if (err) {
+               pr_err("Can't own %s\n", res_name);
+               return err;
+       }
+
+       res->bch_low_interrupt = r->start;
+       res->bch_high_interrupt = r->end;
+       return 0;
+}
+
+static void release_bch_irq(struct gpmi_nand_data *this)
+{
+       struct resources *res = &this->resources;
+       int i = res->bch_low_interrupt;
+
+       for (; i <= res->bch_high_interrupt; i++)
+               free_irq(i, this);
+}
+
+static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
+{
+       struct gpmi_nand_data *this = param;
+       struct resource *r = this->private;
+
+       if (!mxs_dma_is_apbh(chan))
+               return false;
+       /*
+        * only catch the GPMI dma channels :
+        *      for mx23 :      MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3
+        *              (These four channels share the same IRQ!)
+        *
+        *      for mx28 :      MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7
+        *              (These eight channels share the same IRQ!)
+        */
+       if (r->start <= chan->chan_id && chan->chan_id <= r->end) {
+               chan->private = &this->dma_data;
+               return true;
+       }
+       return false;
+}
+
+static void release_dma_channels(struct gpmi_nand_data *this)
+{
+       unsigned int i;
+       for (i = 0; i < DMA_CHANS; i++)
+               if (this->dma_chans[i]) {
+                       dma_release_channel(this->dma_chans[i]);
+                       this->dma_chans[i] = NULL;
+               }
+}
+
+static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
+{
+       struct platform_device *pdev = this->pdev;
+       struct gpmi_nand_platform_data *pdata = this->pdata;
+       struct resources *res = &this->resources;
+       struct resource *r, *r_dma;
+       unsigned int i;
+
+       r = platform_get_resource_byname(pdev, IORESOURCE_DMA,
+                                       GPMI_NAND_DMA_CHANNELS_RES_NAME);
+       r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+                                       GPMI_NAND_DMA_INTERRUPT_RES_NAME);
+       if (!r || !r_dma) {
+               pr_err("Can't get resource for DMA\n");
+               return -ENXIO;
+       }
+
+       /* used in gpmi_dma_filter() */
+       this->private = r;
+
+       for (i = r->start; i <= r->end; i++) {
+               struct dma_chan *dma_chan;
+               dma_cap_mask_t mask;
+
+               if (i - r->start >= pdata->max_chip_count)
+                       break;
+
+               dma_cap_zero(mask);
+               dma_cap_set(DMA_SLAVE, mask);
+
+               /* get the DMA interrupt */
+               if (r_dma->start == r_dma->end) {
+                       /* only register the first. */
+                       if (i == r->start)
+                               this->dma_data.chan_irq = r_dma->start;
+                       else
+                               this->dma_data.chan_irq = NO_IRQ;
+               } else
+                       this->dma_data.chan_irq = r_dma->start + (i - r->start);
+
+               dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
+               if (!dma_chan)
+                       goto acquire_err;
+
+               /* fill the first empty item */
+               this->dma_chans[i - r->start] = dma_chan;
+       }
+
+       res->dma_low_channel = r->start;
+       res->dma_high_channel = i;
+       return 0;
+
+acquire_err:
+       pr_err("Can't acquire DMA channel %u\n", i);
+       release_dma_channels(this);
+       return -EINVAL;
+}
+
+static int __devinit acquire_resources(struct gpmi_nand_data *this)
+{
+       struct resources *res = &this->resources;
+       int ret;
+
+       ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME);
+       if (ret)
+               goto exit_regs;
+
+       ret = acquire_register_block(this, GPMI_NAND_BCH_REGS_ADDR_RES_NAME);
+       if (ret)
+               goto exit_regs;
+
+       ret = acquire_bch_irq(this, bch_irq);
+       if (ret)
+               goto exit_regs;
+
+       ret = acquire_dma_channels(this);
+       if (ret)
+               goto exit_dma_channels;
+
+       res->clock = clk_get(&this->pdev->dev, NULL);
+       if (IS_ERR(res->clock)) {
+               pr_err("can not get the clock\n");
+               ret = -ENOENT;
+               goto exit_clock;
+       }
+       return 0;
+
+exit_clock:
+       release_dma_channels(this);
+exit_dma_channels:
+       release_bch_irq(this);
+exit_regs:
+       release_register_block(this);
+       return ret;
+}
+
+static void release_resources(struct gpmi_nand_data *this)
+{
+       struct resources *r = &this->resources;
+
+       clk_put(r->clock);
+       release_register_block(this);
+       release_bch_irq(this);
+       release_dma_channels(this);
+}
+
+static int __devinit init_hardware(struct gpmi_nand_data *this)
+{
+       int ret;
+
+       /*
+        * This structure contains the "safe" GPMI timing that should succeed
+        * with any NAND Flash device
+        * (although, with less-than-optimal performance).
+        */
+       struct nand_timing  safe_timing = {
+               .data_setup_in_ns        = 80,
+               .data_hold_in_ns         = 60,
+               .address_setup_in_ns     = 25,
+               .gpmi_sample_delay_in_ns =  6,
+               .tREA_in_ns              = -1,
+               .tRLOH_in_ns             = -1,
+               .tRHOH_in_ns             = -1,
+       };
+
+       /* Initialize the hardwares. */
+       ret = gpmi_init(this);
+       if (ret)
+               return ret;
+
+       this->timing = safe_timing;
+       return 0;
+}
+
+static int read_page_prepare(struct gpmi_nand_data *this,
+                       void *destination, unsigned length,
+                       void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
+                       void **use_virt, dma_addr_t *use_phys)
+{
+       struct device *dev = this->dev;
+
+       if (virt_addr_valid(destination)) {
+               dma_addr_t dest_phys;
+
+               dest_phys = dma_map_single(dev, destination,
+                                               length, DMA_FROM_DEVICE);
+               if (dma_mapping_error(dev, dest_phys)) {
+                       if (alt_size < length) {
+                               pr_err("Alternate buffer is too small\n");
+                               return -ENOMEM;
+                       }
+                       goto map_failed;
+               }
+               *use_virt = destination;
+               *use_phys = dest_phys;
+               this->direct_dma_map_ok = true;
+               return 0;
+       }
+
+map_failed:
+       *use_virt = alt_virt;
+       *use_phys = alt_phys;
+       this->direct_dma_map_ok = false;
+       return 0;
+}
+
+static inline void read_page_end(struct gpmi_nand_data *this,
+                       void *destination, unsigned length,
+                       void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
+                       void *used_virt, dma_addr_t used_phys)
+{
+       if (this->direct_dma_map_ok)
+               dma_unmap_single(this->dev, used_phys, length, DMA_FROM_DEVICE);
+}
+
+static inline void read_page_swap_end(struct gpmi_nand_data *this,
+                       void *destination, unsigned length,
+                       void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
+                       void *used_virt, dma_addr_t used_phys)
+{
+       if (!this->direct_dma_map_ok)
+               memcpy(destination, alt_virt, length);
+}
+
+static int send_page_prepare(struct gpmi_nand_data *this,
+                       const void *source, unsigned length,
+                       void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
+                       const void **use_virt, dma_addr_t *use_phys)
+{
+       struct device *dev = this->dev;
+
+       if (virt_addr_valid(source)) {
+               dma_addr_t source_phys;
+
+               source_phys = dma_map_single(dev, (void *)source, length,
+                                               DMA_TO_DEVICE);
+               if (dma_mapping_error(dev, source_phys)) {
+                       if (alt_size < length) {
+                               pr_err("Alternate buffer is too small\n");
+                               return -ENOMEM;
+                       }
+                       goto map_failed;
+               }
+               *use_virt = source;
+               *use_phys = source_phys;
+               return 0;
+       }
+map_failed:
+       /*
+        * Copy the content of the source buffer into the alternate
+        * buffer and set up the return values accordingly.
+        */
+       memcpy(alt_virt, source, length);
+
+       *use_virt = alt_virt;
+       *use_phys = alt_phys;
+       return 0;
+}
+
+static void send_page_end(struct gpmi_nand_data *this,
+                       const void *source, unsigned length,
+                       void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
+                       const void *used_virt, dma_addr_t used_phys)
+{
+       struct device *dev = this->dev;
+       if (used_virt == source)
+               dma_unmap_single(dev, used_phys, length, DMA_TO_DEVICE);
+}
+
+static void gpmi_free_dma_buffer(struct gpmi_nand_data *this)
+{
+       struct device *dev = this->dev;
+
+       if (this->page_buffer_virt && virt_addr_valid(this->page_buffer_virt))
+               dma_free_coherent(dev, this->page_buffer_size,
+                                       this->page_buffer_virt,
+                                       this->page_buffer_phys);
+       kfree(this->cmd_buffer);
+       kfree(this->data_buffer_dma);
+
+       this->cmd_buffer        = NULL;
+       this->data_buffer_dma   = NULL;
+       this->page_buffer_virt  = NULL;
+       this->page_buffer_size  =  0;
+}
+
+/* Allocate the DMA buffers */
+static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
+{
+       struct bch_geometry *geo = &this->bch_geometry;
+       struct device *dev = this->dev;
+
+       /* [1] Allocate a command buffer. PAGE_SIZE is enough. */
+       this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA);
+       if (this->cmd_buffer == NULL)
+               goto error_alloc;
+
+       /* [2] Allocate a read/write data buffer. PAGE_SIZE is enough. */
+       this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA);
+       if (this->data_buffer_dma == NULL)
+               goto error_alloc;
+
+       /*
+        * [3] Allocate the page buffer.
+        *
+        * Both the payload buffer and the auxiliary buffer must appear on
+        * 32-bit boundaries. We presume the size of the payload buffer is a
+        * power of two and is much larger than four, which guarantees the
+        * auxiliary buffer will appear on a 32-bit boundary.
+        */
+       this->page_buffer_size = geo->payload_size + geo->auxiliary_size;
+       this->page_buffer_virt = dma_alloc_coherent(dev, this->page_buffer_size,
+                                       &this->page_buffer_phys, GFP_DMA);
+       if (!this->page_buffer_virt)
+               goto error_alloc;
+
+
+       /* Slice up the page buffer. */
+       this->payload_virt = this->page_buffer_virt;
+       this->payload_phys = this->page_buffer_phys;
+       this->auxiliary_virt = this->payload_virt + geo->payload_size;
+       this->auxiliary_phys = this->payload_phys + geo->payload_size;
+       return 0;
+
+error_alloc:
+       gpmi_free_dma_buffer(this);
+       pr_err("allocate DMA buffer ret!!\n");
+       return -ENOMEM;
+}
+
+static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+       int ret;
+
+       /*
+        * Every operation begins with a command byte and a series of zero or
+        * more address bytes. These are distinguished by either the Address
+        * Latch Enable (ALE) or Command Latch Enable (CLE) signals being
+        * asserted. When MTD is ready to execute the command, it will deassert
+        * both latch enables.
+        *
+        * Rather than run a separate DMA operation for every single byte, we
+        * queue them up and run a single DMA operation for the entire series
+        * of command and data bytes. NAND_CMD_NONE means the END of the queue.
+        */
+       if ((ctrl & (NAND_ALE | NAND_CLE))) {
+               if (data != NAND_CMD_NONE)
+                       this->cmd_buffer[this->command_length++] = data;
+               return;
+       }
+
+       if (!this->command_length)
+               return;
+
+       ret = gpmi_send_command(this);
+       if (ret)
+               pr_err("Chip: %u, Error %d\n", this->current_chip, ret);
+
+       this->command_length = 0;
+}
+
+static int gpmi_dev_ready(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+
+       return gpmi_is_ready(this, this->current_chip);
+}
+
+static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+
+       if ((this->current_chip < 0) && (chipnr >= 0))
+               gpmi_begin(this);
+       else if ((this->current_chip >= 0) && (chipnr < 0))
+               gpmi_end(this);
+
+       this->current_chip = chipnr;
+}
+
+static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+
+       pr_debug("len is %d\n", len);
+       this->upper_buf = buf;
+       this->upper_len = len;
+
+       gpmi_read_data(this);
+}
+
+static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+
+       pr_debug("len is %d\n", len);
+       this->upper_buf = (uint8_t *)buf;
+       this->upper_len = len;
+
+       gpmi_send_data(this);
+}
+
+static uint8_t gpmi_read_byte(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+       uint8_t *buf = this->data_buffer_dma;
+
+       gpmi_read_buf(mtd, buf, 1);
+       return buf[0];
+}
+
+/*
+ * Handles block mark swapping.
+ * It can be called in swapping the block mark, or swapping it back,
+ * because the the operations are the same.
+ */
+static void block_mark_swapping(struct gpmi_nand_data *this,
+                               void *payload, void *auxiliary)
+{
+       struct bch_geometry *nfc_geo = &this->bch_geometry;
+       unsigned char *p;
+       unsigned char *a;
+       unsigned int  bit;
+       unsigned char mask;
+       unsigned char from_data;
+       unsigned char from_oob;
+
+       if (!this->swap_block_mark)
+               return;
+
+       /*
+        * If control arrives here, we're swapping. Make some convenience
+        * variables.
+        */
+       bit = nfc_geo->block_mark_bit_offset;
+       p   = payload + nfc_geo->block_mark_byte_offset;
+       a   = auxiliary;
+
+       /*
+        * Get the byte from the data area that overlays the block mark. Since
+        * the ECC engine applies its own view to the bits in the page, the
+        * physical block mark won't (in general) appear on a byte boundary in
+        * the data.
+        */
+       from_data = (p[0] >> bit) | (p[1] << (8 - bit));
+
+       /* Get the byte from the OOB. */
+       from_oob = a[0];
+
+       /* Swap them. */
+       a[0] = from_data;
+
+       mask = (0x1 << bit) - 1;
+       p[0] = (p[0] & mask) | (from_oob << bit);
+
+       mask = ~0 << bit;
+       p[1] = (p[1] & mask) | (from_oob >> (8 - bit));
+}
+
+static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+                               uint8_t *buf, int page)
+{
+       struct gpmi_nand_data *this = chip->priv;
+       struct bch_geometry *nfc_geo = &this->bch_geometry;
+       void          *payload_virt;
+       dma_addr_t    payload_phys;
+       void          *auxiliary_virt;
+       dma_addr_t    auxiliary_phys;
+       unsigned int  i;
+       unsigned char *status;
+       unsigned int  failed;
+       unsigned int  corrected;
+       int           ret;
+
+       pr_debug("page number is : %d\n", page);
+       ret = read_page_prepare(this, buf, mtd->writesize,
+                                       this->payload_virt, this->payload_phys,
+                                       nfc_geo->payload_size,
+                                       &payload_virt, &payload_phys);
+       if (ret) {
+               pr_err("Inadequate DMA buffer\n");
+               ret = -ENOMEM;
+               return ret;
+       }
+       auxiliary_virt = this->auxiliary_virt;
+       auxiliary_phys = this->auxiliary_phys;
+
+       /* go! */
+       ret = gpmi_read_page(this, payload_phys, auxiliary_phys);
+       read_page_end(this, buf, mtd->writesize,
+                       this->payload_virt, this->payload_phys,
+                       nfc_geo->payload_size,
+                       payload_virt, payload_phys);
+       if (ret) {
+               pr_err("Error in ECC-based read: %d\n", ret);
+               goto exit_nfc;
+       }
+
+       /* handle the block mark swapping */
+       block_mark_swapping(this, payload_virt, auxiliary_virt);
+
+       /* Loop over status bytes, accumulating ECC status. */
+       failed          = 0;
+       corrected       = 0;
+       status          = auxiliary_virt + nfc_geo->auxiliary_status_offset;
+
+       for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
+               if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
+                       continue;
+
+               if (*status == STATUS_UNCORRECTABLE) {
+                       failed++;
+                       continue;
+               }
+               corrected += *status;
+       }
+
+       /*
+        * Propagate ECC status to the owning MTD only when failed or
+        * corrected times nearly reaches our ECC correction threshold.
+        */
+       if (failed || corrected >= (nfc_geo->ecc_strength - 1)) {
+               mtd->ecc_stats.failed    += failed;
+               mtd->ecc_stats.corrected += corrected;
+       }
+
+       /*
+        * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() for
+        * details about our policy for delivering the OOB.
+        *
+        * We fill the caller's buffer with set bits, and then copy the block
+        * mark to th caller's buffer. Note that, if block mark swapping was
+        * necessary, it has already been done, so we can rely on the first
+        * byte of the auxiliary buffer to contain the block mark.
+        */
+       memset(chip->oob_poi, ~0, mtd->oobsize);
+       chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
+
+       read_page_swap_end(this, buf, mtd->writesize,
+                       this->payload_virt, this->payload_phys,
+                       nfc_geo->payload_size,
+                       payload_virt, payload_phys);
+exit_nfc:
+       return ret;
+}
+
+static void gpmi_ecc_write_page(struct mtd_info *mtd,
+                               struct nand_chip *chip, const uint8_t *buf)
+{
+       struct gpmi_nand_data *this = chip->priv;
+       struct bch_geometry *nfc_geo = &this->bch_geometry;
+       const void *payload_virt;
+       dma_addr_t payload_phys;
+       const void *auxiliary_virt;
+       dma_addr_t auxiliary_phys;
+       int        ret;
+
+       pr_debug("ecc write page.\n");
+       if (this->swap_block_mark) {
+               /*
+                * If control arrives here, we're doing block mark swapping.
+                * Since we can't modify the caller's buffers, we must copy them
+                * into our own.
+                */
+               memcpy(this->payload_virt, buf, mtd->writesize);
+               payload_virt = this->payload_virt;
+               payload_phys = this->payload_phys;
+
+               memcpy(this->auxiliary_virt, chip->oob_poi,
+                               nfc_geo->auxiliary_size);
+               auxiliary_virt = this->auxiliary_virt;
+               auxiliary_phys = this->auxiliary_phys;
+
+               /* Handle block mark swapping. */
+               block_mark_swapping(this,
+                               (void *) payload_virt, (void *) auxiliary_virt);
+       } else {
+               /*
+                * If control arrives here, we're not doing block mark swapping,
+                * so we can to try and use the caller's buffers.
+                */
+               ret = send_page_prepare(this,
+                               buf, mtd->writesize,
+                               this->payload_virt, this->payload_phys,
+                               nfc_geo->payload_size,
+                               &payload_virt, &payload_phys);
+               if (ret) {
+                       pr_err("Inadequate payload DMA buffer\n");
+                       return;
+               }
+
+               ret = send_page_prepare(this,
+                               chip->oob_poi, mtd->oobsize,
+                               this->auxiliary_virt, this->auxiliary_phys,
+                               nfc_geo->auxiliary_size,
+                               &auxiliary_virt, &auxiliary_phys);
+               if (ret) {
+                       pr_err("Inadequate auxiliary DMA buffer\n");
+                       goto exit_auxiliary;
+               }
+       }
+
+       /* Ask the NFC. */
+       ret = gpmi_send_page(this, payload_phys, auxiliary_phys);
+       if (ret)
+               pr_err("Error in ECC-based write: %d\n", ret);
+
+       if (!this->swap_block_mark) {
+               send_page_end(this, chip->oob_poi, mtd->oobsize,
+                               this->auxiliary_virt, this->auxiliary_phys,
+                               nfc_geo->auxiliary_size,
+                               auxiliary_virt, auxiliary_phys);
+exit_auxiliary:
+               send_page_end(this, buf, mtd->writesize,
+                               this->payload_virt, this->payload_phys,
+                               nfc_geo->payload_size,
+                               payload_virt, payload_phys);
+       }
+}
+
+/*
+ * There are several places in this driver where we have to handle the OOB and
+ * block marks. This is the function where things are the most complicated, so
+ * this is where we try to explain it all. All the other places refer back to
+ * here.
+ *
+ * These are the rules, in order of decreasing importance:
+ *
+ * 1) Nothing the caller does can be allowed to imperil the block mark.
+ *
+ * 2) In read operations, the first byte of the OOB we return must reflect the
+ *    true state of the block mark, no matter where that block mark appears in
+ *    the physical page.
+ *
+ * 3) ECC-based read operations return an OOB full of set bits (since we never
+ *    allow ECC-based writes to the OOB, it doesn't matter what ECC-based reads
+ *    return).
+ *
+ * 4) "Raw" read operations return a direct view of the physical bytes in the
+ *    page, using the conventional definition of which bytes are data and which
+ *    are OOB. This gives the caller a way to see the actual, physical bytes
+ *    in the page, without the distortions applied by our ECC engine.
+ *
+ *
+ * What we do for this specific read operation depends on two questions:
+ *
+ * 1) Are we doing a "raw" read, or an ECC-based read?
+ *
+ * 2) Are we using block mark swapping or transcription?
+ *
+ * There are four cases, illustrated by the following Karnaugh map:
+ *
+ *                    |           Raw           |         ECC-based       |
+ *       -------------+-------------------------+-------------------------+
+ *                    | Read the conventional   |                         |
+ *                    | OOB at the end of the   |                         |
+ *       Swapping     | page and return it. It  |                         |
+ *                    | contains exactly what   |                         |
+ *                    | we want.                | Read the block mark and |
+ *       -------------+-------------------------+ return it in a buffer   |
+ *                    | Read the conventional   | full of set bits.       |
+ *                    | OOB at the end of the   |                         |
+ *                    | page and also the block |                         |
+ *       Transcribing | mark in the metadata.   |                         |
+ *                    | Copy the block mark     |                         |
+ *                    | into the first byte of  |                         |
+ *                    | the OOB.                |                         |
+ *       -------------+-------------------------+-------------------------+
+ *
+ * Note that we break rule #4 in the Transcribing/Raw case because we're not
+ * giving an accurate view of the actual, physical bytes in the page (we're
+ * overwriting the block mark). That's OK because it's more important to follow
+ * rule #2.
+ *
+ * It turns out that knowing whether we want an "ECC-based" or "raw" read is not
+ * easy. When reading a page, for example, the NAND Flash MTD code calls our
+ * ecc.read_page or ecc.read_page_raw function. Thus, the fact that MTD wants an
+ * ECC-based or raw view of the page is implicit in which function it calls
+ * (there is a similar pair of ECC-based/raw functions for writing).
+ *
+ * Since MTD assumes the OOB is not covered by ECC, there is no pair of
+ * ECC-based/raw functions for reading or or writing the OOB. The fact that the
+ * caller wants an ECC-based or raw view of the page is not propagated down to
+ * this driver.
+ */
+static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+                               int page, int sndcmd)
+{
+       struct gpmi_nand_data *this = chip->priv;
+
+       pr_debug("page number is %d\n", page);
+       /* clear the OOB buffer */
+       memset(chip->oob_poi, ~0, mtd->oobsize);
+
+       /* Read out the conventional OOB. */
+       chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
+       chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       /*
+        * Now, we want to make sure the block mark is correct. In the
+        * Swapping/Raw case, we already have it. Otherwise, we need to
+        * explicitly read it.
+        */
+       if (!this->swap_block_mark) {
+               /* Read the block mark into the first byte of the OOB buffer. */
+               chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+               chip->oob_poi[0] = chip->read_byte(mtd);
+       }
+
+       /*
+        * Return true, indicating that the next call to this function must send
+        * a command.
+        */
+       return true;
+}
+
+static int
+gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
+{
+       /*
+        * The BCH will use all the (page + oob).
+        * Our gpmi_hw_ecclayout can only prohibit the JFFS2 to write the oob.
+        * But it can not stop some ioctls such MEMWRITEOOB which uses
+        * MTD_OPS_PLACE_OOB. So We have to implement this function to prohibit
+        * these ioctls too.
+        */
+       return -EPERM;
+}
+
+static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+       int block, ret = 0;
+       uint8_t *block_mark;
+       int column, page, status, chipnr;
+
+       /* Get block number */
+       block = (int)(ofs >> chip->bbt_erase_shift);
+       if (chip->bbt)
+               chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+
+       /* Do we have a flash based bad block table ? */
+       if (chip->options & NAND_BBT_USE_FLASH)
+               ret = nand_update_bbt(mtd, ofs);
+       else {
+               chipnr = (int)(ofs >> chip->chip_shift);
+               chip->select_chip(mtd, chipnr);
+
+               column = this->swap_block_mark ? mtd->writesize : 0;
+
+               /* Write the block mark. */
+               block_mark = this->data_buffer_dma;
+               block_mark[0] = 0; /* bad block marker */
+
+               /* Shift to get page */
+               page = (int)(ofs >> chip->page_shift);
+
+               chip->cmdfunc(mtd, NAND_CMD_SEQIN, column, page);
+               chip->write_buf(mtd, block_mark, 1);
+               chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+               status = chip->waitfunc(mtd, chip);
+               if (status & NAND_STATUS_FAIL)
+                       ret = -EIO;
+
+               chip->select_chip(mtd, -1);
+       }
+       if (!ret)
+               mtd->ecc_stats.badblocks++;
+
+       return ret;
+}
+
+static int __devinit nand_boot_set_geometry(struct gpmi_nand_data *this)
+{
+       struct boot_rom_geometry *geometry = &this->rom_geometry;
+
+       /*
+        * Set the boot block stride size.
+        *
+        * In principle, we should be reading this from the OTP bits, since
+        * that's where the ROM is going to get it. In fact, we don't have any
+        * way to read the OTP bits, so we go with the default and hope for the
+        * best.
+        */
+       geometry->stride_size_in_pages = 64;
+
+       /*
+        * Set the search area stride exponent.
+        *
+        * In principle, we should be reading this from the OTP bits, since
+        * that's where the ROM is going to get it. In fact, we don't have any
+        * way to read the OTP bits, so we go with the default and hope for the
+        * best.
+        */
+       geometry->search_area_stride_exponent = 2;
+       return 0;
+}
+
+static const char  *fingerprint = "STMP";
+static int __devinit mx23_check_transcription_stamp(struct gpmi_nand_data *this)
+{
+       struct boot_rom_geometry *rom_geo = &this->rom_geometry;
+       struct device *dev = this->dev;
+       struct mtd_info *mtd = &this->mtd;
+       struct nand_chip *chip = &this->nand;
+       unsigned int search_area_size_in_strides;
+       unsigned int stride;
+       unsigned int page;
+       loff_t byte;
+       uint8_t *buffer = chip->buffers->databuf;
+       int saved_chip_number;
+       int found_an_ncb_fingerprint = false;
+
+       /* Compute the number of strides in a search area. */
+       search_area_size_in_strides = 1 << rom_geo->search_area_stride_exponent;
+
+       saved_chip_number = this->current_chip;
+       chip->select_chip(mtd, 0);
+
+       /*
+        * Loop through the first search area, looking for the NCB fingerprint.
+        */
+       dev_dbg(dev, "Scanning for an NCB fingerprint...\n");
+
+       for (stride = 0; stride < search_area_size_in_strides; stride++) {
+               /* Compute the page and byte addresses. */
+               page = stride * rom_geo->stride_size_in_pages;
+               byte = page   * mtd->writesize;
+
+               dev_dbg(dev, "Looking for a fingerprint in page 0x%x\n", page);
+
+               /*
+                * Read the NCB fingerprint. The fingerprint is four bytes long
+                * and starts in the 12th byte of the page.
+                */
+               chip->cmdfunc(mtd, NAND_CMD_READ0, 12, page);
+               chip->read_buf(mtd, buffer, strlen(fingerprint));
+
+               /* Look for the fingerprint. */
+               if (!memcmp(buffer, fingerprint, strlen(fingerprint))) {
+                       found_an_ncb_fingerprint = true;
+                       break;
+               }
+
+       }
+
+       chip->select_chip(mtd, saved_chip_number);
+
+       if (found_an_ncb_fingerprint)
+               dev_dbg(dev, "\tFound a fingerprint\n");
+       else
+               dev_dbg(dev, "\tNo fingerprint found\n");
+       return found_an_ncb_fingerprint;
+}
+
+/* Writes a transcription stamp. */
+static int __devinit mx23_write_transcription_stamp(struct gpmi_nand_data *this)
+{
+       struct device *dev = this->dev;
+       struct boot_rom_geometry *rom_geo = &this->rom_geometry;
+       struct mtd_info *mtd = &this->mtd;
+       struct nand_chip *chip = &this->nand;
+       unsigned int block_size_in_pages;
+       unsigned int search_area_size_in_strides;
+       unsigned int search_area_size_in_pages;
+       unsigned int search_area_size_in_blocks;
+       unsigned int block;
+       unsigned int stride;
+       unsigned int page;
+       loff_t       byte;
+       uint8_t      *buffer = chip->buffers->databuf;
+       int saved_chip_number;
+       int status;
+
+       /* Compute the search area geometry. */
+       block_size_in_pages = mtd->erasesize / mtd->writesize;
+       search_area_size_in_strides = 1 << rom_geo->search_area_stride_exponent;
+       search_area_size_in_pages = search_area_size_in_strides *
+                                       rom_geo->stride_size_in_pages;
+       search_area_size_in_blocks =
+                 (search_area_size_in_pages + (block_size_in_pages - 1)) /
+                                   block_size_in_pages;
+
+       dev_dbg(dev, "Search Area Geometry :\n");
+       dev_dbg(dev, "\tin Blocks : %u\n", search_area_size_in_blocks);
+       dev_dbg(dev, "\tin Strides: %u\n", search_area_size_in_strides);
+       dev_dbg(dev, "\tin Pages  : %u\n", search_area_size_in_pages);
+
+       /* Select chip 0. */
+       saved_chip_number = this->current_chip;
+       chip->select_chip(mtd, 0);
+
+       /* Loop over blocks in the first search area, erasing them. */
+       dev_dbg(dev, "Erasing the search area...\n");
+
+       for (block = 0; block < search_area_size_in_blocks; block++) {
+               /* Compute the page address. */
+               page = block * block_size_in_pages;
+
+               /* Erase this block. */
+               dev_dbg(dev, "\tErasing block 0x%x\n", block);
+               chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
+               chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
+
+               /* Wait for the erase to finish. */
+               status = chip->waitfunc(mtd, chip);
+               if (status & NAND_STATUS_FAIL)
+                       dev_err(dev, "[%s] Erase failed.\n", __func__);
+       }
+
+       /* Write the NCB fingerprint into the page buffer. */
+       memset(buffer, ~0, mtd->writesize);
+       memset(chip->oob_poi, ~0, mtd->oobsize);
+       memcpy(buffer + 12, fingerprint, strlen(fingerprint));
+
+       /* Loop through the first search area, writing NCB fingerprints. */
+       dev_dbg(dev, "Writing NCB fingerprints...\n");
+       for (stride = 0; stride < search_area_size_in_strides; stride++) {
+               /* Compute the page and byte addresses. */
+               page = stride * rom_geo->stride_size_in_pages;
+               byte = page   * mtd->writesize;
+
+               /* Write the first page of the current stride. */
+               dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
+               chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
+               chip->ecc.write_page_raw(mtd, chip, buffer);
+               chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+               /* Wait for the write to finish. */
+               status = chip->waitfunc(mtd, chip);
+               if (status & NAND_STATUS_FAIL)
+                       dev_err(dev, "[%s] Write failed.\n", __func__);
+       }
+
+       /* Deselect chip 0. */
+       chip->select_chip(mtd, saved_chip_number);
+       return 0;
+}
+
+static int __devinit mx23_boot_init(struct gpmi_nand_data  *this)
+{
+       struct device *dev = this->dev;
+       struct nand_chip *chip = &this->nand;
+       struct mtd_info *mtd = &this->mtd;
+       unsigned int block_count;
+       unsigned int block;
+       int     chipnr;
+       int     page;
+       loff_t  byte;
+       uint8_t block_mark;
+       int     ret = 0;
+
+       /*
+        * If control arrives here, we can't use block mark swapping, which
+        * means we're forced to use transcription. First, scan for the
+        * transcription stamp. If we find it, then we don't have to do
+        * anything -- the block marks are already transcribed.
+        */
+       if (mx23_check_transcription_stamp(this))
+               return 0;
+
+       /*
+        * If control arrives here, we couldn't find a transcription stamp, so
+        * so we presume the block marks are in the conventional location.
+        */
+       dev_dbg(dev, "Transcribing bad block marks...\n");
+
+       /* Compute the number of blocks in the entire medium. */
+       block_count = chip->chipsize >> chip->phys_erase_shift;
+
+       /*
+        * Loop over all the blocks in the medium, transcribing block marks as
+        * we go.
+        */
+       for (block = 0; block < block_count; block++) {
+               /*
+                * Compute the chip, page and byte addresses for this block's
+                * conventional mark.
+                */
+               chipnr = block >> (chip->chip_shift - chip->phys_erase_shift);
+               page = block << (chip->phys_erase_shift - chip->page_shift);
+               byte = block <<  chip->phys_erase_shift;
+
+               /* Send the command to read the conventional block mark. */
+               chip->select_chip(mtd, chipnr);
+               chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
+               block_mark = chip->read_byte(mtd);
+               chip->select_chip(mtd, -1);
+
+               /*
+                * Check if the block is marked bad. If so, we need to mark it
+                * again, but this time the result will be a mark in the
+                * location where we transcribe block marks.
+                */
+               if (block_mark != 0xff) {
+                       dev_dbg(dev, "Transcribing mark in block %u\n", block);
+                       ret = chip->block_markbad(mtd, byte);
+                       if (ret)
+                               dev_err(dev, "Failed to mark block bad with "
+                                                       "ret %d\n", ret);
+               }
+       }
+
+       /* Write the stamp that indicates we've transcribed the block marks. */
+       mx23_write_transcription_stamp(this);
+       return 0;
+}
+
+static int __devinit nand_boot_init(struct gpmi_nand_data  *this)
+{
+       nand_boot_set_geometry(this);
+
+       /* This is ROM arch-specific initilization before the BBT scanning. */
+       if (GPMI_IS_MX23(this))
+               return mx23_boot_init(this);
+       return 0;
+}
+
+static int __devinit gpmi_set_geometry(struct gpmi_nand_data *this)
+{
+       int ret;
+
+       /* Free the temporary DMA memory for reading ID. */
+       gpmi_free_dma_buffer(this);
+
+       /* Set up the NFC geometry which is used by BCH. */
+       ret = bch_set_geometry(this);
+       if (ret) {
+               pr_err("set geometry ret : %d\n", ret);
+               return ret;
+       }
+
+       /* Alloc the new DMA buffers according to the pagesize and oobsize */
+       return gpmi_alloc_dma_buffer(this);
+}
+
+static int gpmi_pre_bbt_scan(struct gpmi_nand_data  *this)
+{
+       int ret;
+
+       /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
+       if (GPMI_IS_MX23(this))
+               this->swap_block_mark = false;
+       else
+               this->swap_block_mark = true;
+
+       /* Set up the medium geometry */
+       ret = gpmi_set_geometry(this);
+       if (ret)
+               return ret;
+
+       /* NAND boot init, depends on the gpmi_set_geometry(). */
+       return nand_boot_init(this);
+}
+
+static int gpmi_scan_bbt(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct gpmi_nand_data *this = chip->priv;
+       int ret;
+
+       /* Prepare for the BBT scan. */
+       ret = gpmi_pre_bbt_scan(this);
+       if (ret)
+               return ret;
+
+       /* use the default BBT implementation */
+       return nand_default_bbt(mtd);
+}
+
+void gpmi_nfc_exit(struct gpmi_nand_data *this)
+{
+       nand_release(&this->mtd);
+       gpmi_free_dma_buffer(this);
+}
+
+static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this)
+{
+       struct gpmi_nand_platform_data *pdata = this->pdata;
+       struct mtd_info  *mtd = &this->mtd;
+       struct nand_chip *chip = &this->nand;
+       int ret;
+
+       /* init current chip */
+       this->current_chip      = -1;
+
+       /* init the MTD data structures */
+       mtd->priv               = chip;
+       mtd->name               = "gpmi-nand";
+       mtd->owner              = THIS_MODULE;
+
+       /* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */
+       chip->priv              = this;
+       chip->select_chip       = gpmi_select_chip;
+       chip->cmd_ctrl          = gpmi_cmd_ctrl;
+       chip->dev_ready         = gpmi_dev_ready;
+       chip->read_byte         = gpmi_read_byte;
+       chip->read_buf          = gpmi_read_buf;
+       chip->write_buf         = gpmi_write_buf;
+       chip->ecc.read_page     = gpmi_ecc_read_page;
+       chip->ecc.write_page    = gpmi_ecc_write_page;
+       chip->ecc.read_oob      = gpmi_ecc_read_oob;
+       chip->ecc.write_oob     = gpmi_ecc_write_oob;
+       chip->scan_bbt          = gpmi_scan_bbt;
+       chip->badblock_pattern  = &gpmi_bbt_descr;
+       chip->block_markbad     = gpmi_block_markbad;
+       chip->options           |= NAND_NO_SUBPAGE_WRITE;
+       chip->ecc.mode          = NAND_ECC_HW;
+       chip->ecc.size          = 1;
+       chip->ecc.layout        = &gpmi_hw_ecclayout;
+
+       /* Allocate a temporary DMA buffer for reading ID in the nand_scan() */
+       this->bch_geometry.payload_size = 1024;
+       this->bch_geometry.auxiliary_size = 128;
+       ret = gpmi_alloc_dma_buffer(this);
+       if (ret)
+               goto err_out;
+
+       ret = nand_scan(mtd, pdata->max_chip_count);
+       if (ret) {
+               pr_err("Chip scan failed\n");
+               goto err_out;
+       }
+
+       ret = mtd_device_parse_register(mtd, NULL, NULL,
+                       pdata->partitions, pdata->partition_count);
+       if (ret)
+               goto err_out;
+       return 0;
+
+err_out:
+       gpmi_nfc_exit(this);
+       return ret;
+}
+
+static int __devinit gpmi_nand_probe(struct platform_device *pdev)
+{
+       struct gpmi_nand_platform_data *pdata = pdev->dev.platform_data;
+       struct gpmi_nand_data *this;
+       int ret;
+
+       this = kzalloc(sizeof(*this), GFP_KERNEL);
+       if (!this) {
+               pr_err("Failed to allocate per-device memory\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(pdev, this);
+       this->pdev  = pdev;
+       this->dev   = &pdev->dev;
+       this->pdata = pdata;
+
+       if (pdata->platform_init) {
+               ret = pdata->platform_init();
+               if (ret)
+                       goto platform_init_error;
+       }
+
+       ret = acquire_resources(this);
+       if (ret)
+               goto exit_acquire_resources;
+
+       ret = init_hardware(this);
+       if (ret)
+               goto exit_nfc_init;
+
+       ret = gpmi_nfc_init(this);
+       if (ret)
+               goto exit_nfc_init;
+
+       return 0;
+
+exit_nfc_init:
+       release_resources(this);
+platform_init_error:
+exit_acquire_resources:
+       platform_set_drvdata(pdev, NULL);
+       kfree(this);
+       return ret;
+}
+
+static int __exit gpmi_nand_remove(struct platform_device *pdev)
+{
+       struct gpmi_nand_data *this = platform_get_drvdata(pdev);
+
+       gpmi_nfc_exit(this);
+       release_resources(this);
+       platform_set_drvdata(pdev, NULL);
+       kfree(this);
+       return 0;
+}
+
+static const struct platform_device_id gpmi_ids[] = {
+       {
+               .name = "imx23-gpmi-nand",
+               .driver_data = IS_MX23,
+       }, {
+               .name = "imx28-gpmi-nand",
+               .driver_data = IS_MX28,
+       }, {},
+};
+
+static struct platform_driver gpmi_nand_driver = {
+       .driver = {
+               .name = "gpmi-nand",
+       },
+       .probe   = gpmi_nand_probe,
+       .remove  = __exit_p(gpmi_nand_remove),
+       .id_table = gpmi_ids,
+};
+
+static int __init gpmi_nand_init(void)
+{
+       int err;
+
+       err = platform_driver_register(&gpmi_nand_driver);
+       if (err == 0)
+               printk(KERN_INFO "GPMI NAND driver registered. (IMX)\n");
+       else
+               pr_err("i.MX GPMI NAND driver registration failed\n");
+       return err;
+}
+
+static void __exit gpmi_nand_exit(void)
+{
+       platform_driver_unregister(&gpmi_nand_driver);
+}
+
+module_init(gpmi_nand_init);
+module_exit(gpmi_nand_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("i.MX GPMI NAND Flash Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
new file mode 100644 (file)
index 0000000..e023bcc
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DRIVERS_MTD_NAND_GPMI_NAND_H
+#define __DRIVERS_MTD_NAND_GPMI_NAND_H
+
+#include <linux/mtd/nand.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <mach/dma.h>
+
+struct resources {
+       void          *gpmi_regs;
+       void          *bch_regs;
+       unsigned int  bch_low_interrupt;
+       unsigned int  bch_high_interrupt;
+       unsigned int  dma_low_channel;
+       unsigned int  dma_high_channel;
+       struct clk    *clock;
+};
+
+/**
+ * struct bch_geometry - BCH geometry description.
+ * @gf_len:                   The length of Galois Field. (e.g., 13 or 14)
+ * @ecc_strength:             A number that describes the strength of the ECC
+ *                            algorithm.
+ * @page_size:                The size, in bytes, of a physical page, including
+ *                            both data and OOB.
+ * @metadata_size:            The size, in bytes, of the metadata.
+ * @ecc_chunk_size:           The size, in bytes, of a single ECC chunk. Note
+ *                            the first chunk in the page includes both data and
+ *                            metadata, so it's a bit larger than this value.
+ * @ecc_chunk_count:          The number of ECC chunks in the page,
+ * @payload_size:             The size, in bytes, of the payload buffer.
+ * @auxiliary_size:           The size, in bytes, of the auxiliary buffer.
+ * @auxiliary_status_offset:  The offset into the auxiliary buffer at which
+ *                            the ECC status appears.
+ * @block_mark_byte_offset:   The byte offset in the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ * @block_mark_bit_offset:    The bit offset into the ECC-based page view at
+ *                            which the underlying physical block mark appears.
+ */
+struct bch_geometry {
+       unsigned int  gf_len;
+       unsigned int  ecc_strength;
+       unsigned int  page_size;
+       unsigned int  metadata_size;
+       unsigned int  ecc_chunk_size;
+       unsigned int  ecc_chunk_count;
+       unsigned int  payload_size;
+       unsigned int  auxiliary_size;
+       unsigned int  auxiliary_status_offset;
+       unsigned int  block_mark_byte_offset;
+       unsigned int  block_mark_bit_offset;
+};
+
+/**
+ * struct boot_rom_geometry - Boot ROM geometry description.
+ * @stride_size_in_pages:        The size of a boot block stride, in pages.
+ * @search_area_stride_exponent: The logarithm to base 2 of the size of a
+ *                               search area in boot block strides.
+ */
+struct boot_rom_geometry {
+       unsigned int  stride_size_in_pages;
+       unsigned int  search_area_stride_exponent;
+};
+
+/* DMA operations types */
+enum dma_ops_type {
+       DMA_FOR_COMMAND = 1,
+       DMA_FOR_READ_DATA,
+       DMA_FOR_WRITE_DATA,
+       DMA_FOR_READ_ECC_PAGE,
+       DMA_FOR_WRITE_ECC_PAGE
+};
+
+/**
+ * struct nand_timing - Fundamental timing attributes for NAND.
+ * @data_setup_in_ns:         The data setup time, in nanoseconds. Usually the
+ *                            maximum of tDS and tWP. A negative value
+ *                            indicates this characteristic isn't known.
+ * @data_hold_in_ns:          The data hold time, in nanoseconds. Usually the
+ *                            maximum of tDH, tWH and tREH. A negative value
+ *                            indicates this characteristic isn't known.
+ * @address_setup_in_ns:      The address setup time, in nanoseconds. Usually
+ *                            the maximum of tCLS, tCS and tALS. A negative
+ *                            value indicates this characteristic isn't known.
+ * @gpmi_sample_delay_in_ns:  A GPMI-specific timing parameter. A negative value
+ *                            indicates this characteristic isn't known.
+ * @tREA_in_ns:               tREA, in nanoseconds, from the data sheet. A
+ *                            negative value indicates this characteristic isn't
+ *                            known.
+ * @tRLOH_in_ns:              tRLOH, in nanoseconds, from the data sheet. A
+ *                            negative value indicates this characteristic isn't
+ *                            known.
+ * @tRHOH_in_ns:              tRHOH, in nanoseconds, from the data sheet. A
+ *                            negative value indicates this characteristic isn't
+ *                            known.
+ */
+struct nand_timing {
+       int8_t  data_setup_in_ns;
+       int8_t  data_hold_in_ns;
+       int8_t  address_setup_in_ns;
+       int8_t  gpmi_sample_delay_in_ns;
+       int8_t  tREA_in_ns;
+       int8_t  tRLOH_in_ns;
+       int8_t  tRHOH_in_ns;
+};
+
+struct gpmi_nand_data {
+       /* System Interface */
+       struct device           *dev;
+       struct platform_device  *pdev;
+       struct gpmi_nand_platform_data  *pdata;
+
+       /* Resources */
+       struct resources        resources;
+
+       /* Flash Hardware */
+       struct nand_timing      timing;
+
+       /* BCH */
+       struct bch_geometry     bch_geometry;
+       struct completion       bch_done;
+
+       /* NAND Boot issue */
+       bool                    swap_block_mark;
+       struct boot_rom_geometry rom_geometry;
+
+       /* MTD / NAND */
+       struct nand_chip        nand;
+       struct mtd_info         mtd;
+
+       /* General-use Variables */
+       int                     current_chip;
+       unsigned int            command_length;
+
+       /* passed from upper layer */
+       uint8_t                 *upper_buf;
+       int                     upper_len;
+
+       /* for DMA operations */
+       bool                    direct_dma_map_ok;
+
+       struct scatterlist      cmd_sgl;
+       char                    *cmd_buffer;
+
+       struct scatterlist      data_sgl;
+       char                    *data_buffer_dma;
+
+       void                    *page_buffer_virt;
+       dma_addr_t              page_buffer_phys;
+       unsigned int            page_buffer_size;
+
+       void                    *payload_virt;
+       dma_addr_t              payload_phys;
+
+       void                    *auxiliary_virt;
+       dma_addr_t              auxiliary_phys;
+
+       /* DMA channels */
+#define DMA_CHANS              8
+       struct dma_chan         *dma_chans[DMA_CHANS];
+       struct mxs_dma_data     dma_data;
+       enum dma_ops_type       last_dma_type;
+       enum dma_ops_type       dma_type;
+       struct completion       dma_done;
+
+       /* private */
+       void                    *private;
+};
+
+/**
+ * struct gpmi_nfc_hardware_timing - GPMI hardware timing parameters.
+ * @data_setup_in_cycles:      The data setup time, in cycles.
+ * @data_hold_in_cycles:       The data hold time, in cycles.
+ * @address_setup_in_cycles:   The address setup time, in cycles.
+ * @use_half_periods:          Indicates the clock is running slowly, so the
+ *                             NFC DLL should use half-periods.
+ * @sample_delay_factor:       The sample delay factor.
+ */
+struct gpmi_nfc_hardware_timing {
+       uint8_t  data_setup_in_cycles;
+       uint8_t  data_hold_in_cycles;
+       uint8_t  address_setup_in_cycles;
+       bool     use_half_periods;
+       uint8_t  sample_delay_factor;
+};
+
+/**
+ * struct timing_threshod - Timing threshold
+ * @max_data_setup_cycles:       The maximum number of data setup cycles that
+ *                               can be expressed in the hardware.
+ * @internal_data_setup_in_ns:   The time, in ns, that the NFC hardware requires
+ *                               for data read internal setup. In the Reference
+ *                               Manual, see the chapter "High-Speed NAND
+ *                               Timing" for more details.
+ * @max_sample_delay_factor:     The maximum sample delay factor that can be
+ *                               expressed in the hardware.
+ * @max_dll_clock_period_in_ns:  The maximum period of the GPMI clock that the
+ *                               sample delay DLL hardware can possibly work
+ *                               with (the DLL is unusable with longer periods).
+ *                               If the full-cycle period is greater than HALF
+ *                               this value, the DLL must be configured to use
+ *                               half-periods.
+ * @max_dll_delay_in_ns:         The maximum amount of delay, in ns, that the
+ *                               DLL can implement.
+ * @clock_frequency_in_hz:       The clock frequency, in Hz, during the current
+ *                               I/O transaction. If no I/O transaction is in
+ *                               progress, this is the clock frequency during
+ *                               the most recent I/O transaction.
+ */
+struct timing_threshod {
+       const unsigned int      max_chip_count;
+       const unsigned int      max_data_setup_cycles;
+       const unsigned int      internal_data_setup_in_ns;
+       const unsigned int      max_sample_delay_factor;
+       const unsigned int      max_dll_clock_period_in_ns;
+       const unsigned int      max_dll_delay_in_ns;
+       unsigned long           clock_frequency_in_hz;
+
+};
+
+/* Common Services */
+extern int common_nfc_set_geometry(struct gpmi_nand_data *);
+extern struct dma_chan *get_dma_chan(struct gpmi_nand_data *);
+extern void prepare_data_dma(struct gpmi_nand_data *,
+                               enum dma_data_direction dr);
+extern int start_dma_without_bch_irq(struct gpmi_nand_data *,
+                               struct dma_async_tx_descriptor *);
+extern int start_dma_with_bch_irq(struct gpmi_nand_data *,
+                               struct dma_async_tx_descriptor *);
+
+/* GPMI-NAND helper function library */
+extern int gpmi_init(struct gpmi_nand_data *);
+extern void gpmi_clear_bch(struct gpmi_nand_data *);
+extern void gpmi_dump_info(struct gpmi_nand_data *);
+extern int bch_set_geometry(struct gpmi_nand_data *);
+extern int gpmi_is_ready(struct gpmi_nand_data *, unsigned chip);
+extern int gpmi_send_command(struct gpmi_nand_data *);
+extern void gpmi_begin(struct gpmi_nand_data *);
+extern void gpmi_end(struct gpmi_nand_data *);
+extern int gpmi_read_data(struct gpmi_nand_data *);
+extern int gpmi_send_data(struct gpmi_nand_data *);
+extern int gpmi_send_page(struct gpmi_nand_data *,
+                       dma_addr_t payload, dma_addr_t auxiliary);
+extern int gpmi_read_page(struct gpmi_nand_data *,
+                       dma_addr_t payload, dma_addr_t auxiliary);
+
+/* BCH : Status Block Completion Codes */
+#define STATUS_GOOD            0x00
+#define STATUS_ERASED          0xff
+#define STATUS_UNCORRECTABLE   0xfe
+
+/* Use the platform_id to distinguish different Archs. */
+#define IS_MX23                        0x1
+#define IS_MX28                        0x2
+#define GPMI_IS_MX23(x)                ((x)->pdev->id_entry->driver_data == IS_MX23)
+#define GPMI_IS_MX28(x)                ((x)->pdev->id_entry->driver_data == IS_MX28)
+#endif
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
new file mode 100644 (file)
index 0000000..8343124
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Freescale GPMI NAND Flash Driver
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __GPMI_NAND_GPMI_REGS_H
+#define __GPMI_NAND_GPMI_REGS_H
+
+#define HW_GPMI_CTRL0                                  0x00000000
+#define HW_GPMI_CTRL0_SET                              0x00000004
+#define HW_GPMI_CTRL0_CLR                              0x00000008
+#define HW_GPMI_CTRL0_TOG                              0x0000000c
+
+#define BP_GPMI_CTRL0_COMMAND_MODE                     24
+#define BM_GPMI_CTRL0_COMMAND_MODE     (3 << BP_GPMI_CTRL0_COMMAND_MODE)
+#define BF_GPMI_CTRL0_COMMAND_MODE(v)  \
+       (((v) << BP_GPMI_CTRL0_COMMAND_MODE) & BM_GPMI_CTRL0_COMMAND_MODE)
+#define BV_GPMI_CTRL0_COMMAND_MODE__WRITE              0x0
+#define BV_GPMI_CTRL0_COMMAND_MODE__READ               0x1
+#define BV_GPMI_CTRL0_COMMAND_MODE__READ_AND_COMPARE   0x2
+#define BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY     0x3
+
+#define BM_GPMI_CTRL0_WORD_LENGTH                      (1 << 23)
+#define BV_GPMI_CTRL0_WORD_LENGTH__16_BIT              0x0
+#define BV_GPMI_CTRL0_WORD_LENGTH__8_BIT               0x1
+
+/*
+ *  Difference in LOCK_CS between imx23 and imx28 :
+ *  This bit may impact the _POWER_ consumption. So some chips
+ *  do not set it.
+ */
+#define MX23_BP_GPMI_CTRL0_LOCK_CS                     22
+#define MX28_BP_GPMI_CTRL0_LOCK_CS                     27
+#define LOCK_CS_ENABLE                                 0x1
+#define BF_GPMI_CTRL0_LOCK_CS(v, x)                    0x0
+
+/* Difference in CS between imx23 and imx28 */
+#define BP_GPMI_CTRL0_CS                               20
+#define MX23_BM_GPMI_CTRL0_CS          (3 << BP_GPMI_CTRL0_CS)
+#define MX28_BM_GPMI_CTRL0_CS          (7 << BP_GPMI_CTRL0_CS)
+#define BF_GPMI_CTRL0_CS(v, x)         (((v) << BP_GPMI_CTRL0_CS) & \
+                                               (GPMI_IS_MX23((x)) \
+                                               ? MX23_BM_GPMI_CTRL0_CS \
+                                               : MX28_BM_GPMI_CTRL0_CS))
+
+#define BP_GPMI_CTRL0_ADDRESS                          17
+#define BM_GPMI_CTRL0_ADDRESS          (3 << BP_GPMI_CTRL0_ADDRESS)
+#define BF_GPMI_CTRL0_ADDRESS(v)       \
+               (((v) << BP_GPMI_CTRL0_ADDRESS) & BM_GPMI_CTRL0_ADDRESS)
+#define BV_GPMI_CTRL0_ADDRESS__NAND_DATA               0x0
+#define BV_GPMI_CTRL0_ADDRESS__NAND_CLE                        0x1
+#define BV_GPMI_CTRL0_ADDRESS__NAND_ALE                        0x2
+
+#define BM_GPMI_CTRL0_ADDRESS_INCREMENT                        (1 << 16)
+#define BV_GPMI_CTRL0_ADDRESS_INCREMENT__DISABLED      0x0
+#define BV_GPMI_CTRL0_ADDRESS_INCREMENT__ENABLED       0x1
+
+#define BP_GPMI_CTRL0_XFER_COUNT                       0
+#define BM_GPMI_CTRL0_XFER_COUNT       (0xffff << BP_GPMI_CTRL0_XFER_COUNT)
+#define BF_GPMI_CTRL0_XFER_COUNT(v)    \
+               (((v) << BP_GPMI_CTRL0_XFER_COUNT) & BM_GPMI_CTRL0_XFER_COUNT)
+
+#define HW_GPMI_COMPARE                                        0x00000010
+
+#define HW_GPMI_ECCCTRL                                        0x00000020
+#define HW_GPMI_ECCCTRL_SET                            0x00000024
+#define HW_GPMI_ECCCTRL_CLR                            0x00000028
+#define HW_GPMI_ECCCTRL_TOG                            0x0000002c
+
+#define BP_GPMI_ECCCTRL_ECC_CMD                                13
+#define BM_GPMI_ECCCTRL_ECC_CMD                (3 << BP_GPMI_ECCCTRL_ECC_CMD)
+#define BF_GPMI_ECCCTRL_ECC_CMD(v)     \
+               (((v) << BP_GPMI_ECCCTRL_ECC_CMD) & BM_GPMI_ECCCTRL_ECC_CMD)
+#define BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE            0x0
+#define BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE            0x1
+
+#define BM_GPMI_ECCCTRL_ENABLE_ECC                     (1 << 12)
+#define BV_GPMI_ECCCTRL_ENABLE_ECC__ENABLE             0x1
+#define BV_GPMI_ECCCTRL_ENABLE_ECC__DISABLE            0x0
+
+#define BP_GPMI_ECCCTRL_BUFFER_MASK                    0
+#define BM_GPMI_ECCCTRL_BUFFER_MASK    (0x1ff << BP_GPMI_ECCCTRL_BUFFER_MASK)
+#define BF_GPMI_ECCCTRL_BUFFER_MASK(v) \
+       (((v) << BP_GPMI_ECCCTRL_BUFFER_MASK) & BM_GPMI_ECCCTRL_BUFFER_MASK)
+#define BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY       0x100
+#define BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE          0x1FF
+
+#define HW_GPMI_ECCCOUNT                               0x00000030
+#define HW_GPMI_PAYLOAD                                        0x00000040
+#define HW_GPMI_AUXILIARY                              0x00000050
+#define HW_GPMI_CTRL1                                  0x00000060
+#define HW_GPMI_CTRL1_SET                              0x00000064
+#define HW_GPMI_CTRL1_CLR                              0x00000068
+#define HW_GPMI_CTRL1_TOG                              0x0000006c
+
+#define BM_GPMI_CTRL1_BCH_MODE                         (1 << 18)
+
+#define BP_GPMI_CTRL1_DLL_ENABLE                       17
+#define BM_GPMI_CTRL1_DLL_ENABLE       (1 << BP_GPMI_CTRL1_DLL_ENABLE)
+
+#define BP_GPMI_CTRL1_HALF_PERIOD                      16
+#define BM_GPMI_CTRL1_HALF_PERIOD      (1 << BP_GPMI_CTRL1_HALF_PERIOD)
+
+#define BP_GPMI_CTRL1_RDN_DELAY                                12
+#define BM_GPMI_CTRL1_RDN_DELAY                (0xf << BP_GPMI_CTRL1_RDN_DELAY)
+#define BF_GPMI_CTRL1_RDN_DELAY(v)     \
+               (((v) << BP_GPMI_CTRL1_RDN_DELAY) & BM_GPMI_CTRL1_RDN_DELAY)
+
+#define BM_GPMI_CTRL1_DEV_RESET                                (1 << 3)
+#define BV_GPMI_CTRL1_DEV_RESET__ENABLED               0x0
+#define BV_GPMI_CTRL1_DEV_RESET__DISABLED              0x1
+
+#define BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY              (1 << 2)
+#define BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVELOW   0x0
+#define BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH  0x1
+
+#define BM_GPMI_CTRL1_CAMERA_MODE                      (1 << 1)
+#define BV_GPMI_CTRL1_GPMI_MODE__NAND                  0x0
+#define BV_GPMI_CTRL1_GPMI_MODE__ATA                   0x1
+
+#define BM_GPMI_CTRL1_GPMI_MODE                                (1 << 0)
+
+#define HW_GPMI_TIMING0                                        0x00000070
+
+#define BP_GPMI_TIMING0_ADDRESS_SETUP                  16
+#define BM_GPMI_TIMING0_ADDRESS_SETUP  (0xff << BP_GPMI_TIMING0_ADDRESS_SETUP)
+#define BF_GPMI_TIMING0_ADDRESS_SETUP(v)       \
+       (((v) << BP_GPMI_TIMING0_ADDRESS_SETUP) & BM_GPMI_TIMING0_ADDRESS_SETUP)
+
+#define BP_GPMI_TIMING0_DATA_HOLD                      8
+#define BM_GPMI_TIMING0_DATA_HOLD      (0xff << BP_GPMI_TIMING0_DATA_HOLD)
+#define BF_GPMI_TIMING0_DATA_HOLD(v)           \
+       (((v) << BP_GPMI_TIMING0_DATA_HOLD) & BM_GPMI_TIMING0_DATA_HOLD)
+
+#define BP_GPMI_TIMING0_DATA_SETUP                     0
+#define BM_GPMI_TIMING0_DATA_SETUP     (0xff << BP_GPMI_TIMING0_DATA_SETUP)
+#define BF_GPMI_TIMING0_DATA_SETUP(v)          \
+       (((v) << BP_GPMI_TIMING0_DATA_SETUP) & BM_GPMI_TIMING0_DATA_SETUP)
+
+#define HW_GPMI_TIMING1                                        0x00000080
+#define BP_GPMI_TIMING1_BUSY_TIMEOUT                   16
+
+#define HW_GPMI_TIMING2                                        0x00000090
+#define HW_GPMI_DATA                                   0x000000a0
+
+/* MX28 uses this to detect READY. */
+#define HW_GPMI_STAT                                   0x000000b0
+#define MX28_BP_GPMI_STAT_READY_BUSY                   24
+#define MX28_BM_GPMI_STAT_READY_BUSY   (0xff << MX28_BP_GPMI_STAT_READY_BUSY)
+#define MX28_BF_GPMI_STAT_READY_BUSY(v)                \
+       (((v) << MX28_BP_GPMI_STAT_READY_BUSY) & MX28_BM_GPMI_STAT_READY_BUSY)
+
+/* MX23 uses this to detect READY. */
+#define HW_GPMI_DEBUG                                  0x000000c0
+#define MX23_BP_GPMI_DEBUG_READY0                      28
+#define MX23_BM_GPMI_DEBUG_READY0      (1 << MX23_BP_GPMI_DEBUG_READY0)
+#endif
index 02a03e67109c90ce2534757b4053ada8e8469956..5dc6f0d92f1af7be563fd269b70ee505b0a08b9c 100644 (file)
@@ -81,9 +81,6 @@ static int h1910_device_ready(struct mtd_info *mtd)
 static int __init h1910_init(void)
 {
        struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
        void __iomem *nandaddr;
 
        if (!machine_is_h1900())
@@ -136,22 +133,10 @@ static int __init h1910_init(void)
                iounmap((void *)nandaddr);
                return -ENXIO;
        }
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand");
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-#endif
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(h1910_nand_mtd, NULL, 0,
+                       partition_info, NUM_PARTITIONS);
 
        /* Return happy */
        return 0;
index 6e813daed068d359f66f3c2ffb65abf46d924a44..e2664073a89b8eae1afa5c2ef5fe3d81e0348722 100644 (file)
@@ -251,10 +251,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
        return 0;
 }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = {"cmdline", NULL};
-#endif
-
 static int jz_nand_ioremap_resource(struct platform_device *pdev,
        const char *name, struct resource **res, void __iomem **base)
 {
@@ -299,8 +295,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
        struct nand_chip *chip;
        struct mtd_info *mtd;
        struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
-       struct mtd_partition *partition_info;
-       int num_partitions = 0;
 
        nand = kzalloc(sizeof(*nand), GFP_KERNEL);
        if (!nand) {
@@ -373,15 +367,9 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
                goto err_gpio_free;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                               &partition_info, 0);
-#endif
-       if (num_partitions <= 0 && pdata) {
-               num_partitions = pdata->num_partitions;
-               partition_info = pdata->partitions;
-       }
-       ret = mtd_device_register(mtd, partition_info, num_partitions);
+       ret = mtd_device_parse_register(mtd, NULL, 0,
+                       pdata ? pdata->partitions : NULL,
+                       pdata ? pdata->num_partitions : 0);
 
        if (ret) {
                dev_err(&pdev->dev, "Failed to add mtd device\n");
index eb1fbac63eb6015ce2804d7e676698c4b51cd3ed..5ede64706346084dd5cdd6d38612d532ec493992 100644 (file)
@@ -131,8 +131,6 @@ struct mpc5121_nfc_prv {
 
 static void mpc5121_nfc_done(struct mtd_info *mtd);
 
-static const char *mpc5121_nfc_pprobes[] = { "cmdlinepart", NULL };
-
 /* Read NFC register */
 static inline u16 nfc_read(struct mtd_info *mtd, uint reg)
 {
@@ -656,13 +654,13 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        struct mpc5121_nfc_prv *prv;
        struct resource res;
        struct mtd_info *mtd;
-       struct mtd_partition *parts;
        struct nand_chip *chip;
        unsigned long regs_paddr, regs_size;
        const __be32 *chips_no;
        int resettime = 0;
        int retval = 0;
        int rev, len;
+       struct mtd_part_parser_data ppdata;
 
        /*
         * Check SoC revision. This driver supports only NFC
@@ -727,6 +725,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        }
 
        mtd->name = "MPC5121 NAND";
+       ppdata.of_node = dn;
        chip->dev_ready = mpc5121_nfc_dev_ready;
        chip->cmdfunc = mpc5121_nfc_command;
        chip->read_byte = mpc5121_nfc_read_byte;
@@ -735,7 +734,8 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        chip->write_buf = mpc5121_nfc_write_buf;
        chip->verify_buf = mpc5121_nfc_verify_buf;
        chip->select_chip = mpc5121_nfc_select_chip;
-       chip->options = NAND_NO_AUTOINCR | NAND_USE_FLASH_BBT;
+       chip->options = NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
        chip->ecc.mode = NAND_ECC_SOFT;
 
        /* Support external chip-select logic on ADS5121 board */
@@ -837,19 +837,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op)
        dev_set_drvdata(dev, mtd);
 
        /* Register device in MTD */
-       retval = parse_mtd_partitions(mtd, mpc5121_nfc_pprobes, &parts, 0);
-#ifdef CONFIG_MTD_OF_PARTS
-       if (retval == 0)
-               retval = of_mtd_parse_partitions(dev, dn, &parts);
-#endif
-       if (retval < 0) {
-               dev_err(dev, "Error parsing MTD partitions!\n");
-               devm_free_irq(dev, prv->irq, mtd);
-               retval = -EINVAL;
-               goto error;
-       }
-
-       retval = mtd_device_register(mtd, parts, retval);
+       retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
        if (retval) {
                dev_err(dev, "Error adding MTD device!\n");
                devm_free_irq(dev, prv->irq, mtd);
index 90df34c4d26cae887454de88099fa6c672c6b88d..74a43b818d0e0401616dcc5ace7af52bcf53c726 100644 (file)
@@ -41,7 +41,7 @@
 
 #define nfc_is_v21()           (cpu_is_mx25() || cpu_is_mx35())
 #define nfc_is_v1()            (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2()          cpu_is_mx51()
+#define nfc_is_v3_2()          (cpu_is_mx51() || cpu_is_mx53())
 #define nfc_is_v3()            nfc_is_v3_2()
 
 /* Addresses for NFC registers */
 struct mxc_nand_host {
        struct mtd_info         mtd;
        struct nand_chip        nand;
-       struct mtd_partition    *parts;
        struct device           *dev;
 
        void                    *spare0;
@@ -350,8 +349,7 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq)
                        udelay(1);
                }
                if (max_retries < 0)
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: INT not set\n",
-                             __func__);
+                       pr_debug("%s: INT not set\n", __func__);
        }
 }
 
@@ -371,7 +369,7 @@ static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)
  * waits for completion. */
 static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
+       pr_debug("send_cmd(host, 0x%x, %d)\n", cmd, useirq);
 
        writew(cmd, NFC_V1_V2_FLASH_CMD);
        writew(NFC_CMD, NFC_V1_V2_CONFIG2);
@@ -387,8 +385,7 @@ static void send_cmd_v1_v2(struct mxc_nand_host *host, uint16_t cmd, int useirq)
                        udelay(1);
                }
                if (max_retries < 0)
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: RESET failed\n",
-                             __func__);
+                       pr_debug("%s: RESET failed\n", __func__);
        } else {
                /* Wait for operation to complete */
                wait_op_done(host, useirq);
@@ -411,7 +408,7 @@ static void send_addr_v3(struct mxc_nand_host *host, uint16_t addr, int islast)
  * a NAND command. */
 static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islast)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
+       pr_debug("send_addr(host, 0x%x %d)\n", addr, islast);
 
        writew(addr, NFC_V1_V2_FLASH_ADDR);
        writew(NFC_ADDR, NFC_V1_V2_CONFIG2);
@@ -561,8 +558,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
        uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
 
        if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
+               pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
                return -1;
        }
 
@@ -849,7 +845,7 @@ static void preset_v1_v2(struct mtd_info *mtd)
                writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
        } else if (nfc_is_v1()) {
                writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
-               writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
+               writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR);
        } else
                BUG();
 
@@ -932,8 +928,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-             "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
+       pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
              command, column, page_addr);
 
        /* Reset command state information */
@@ -1044,7 +1039,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
        struct mxc_nand_host *host;
        struct resource *res;
-       int err = 0, __maybe_unused nr_parts = 0;
+       int err = 0;
        struct nand_ecclayout *oob_smallpage, *oob_largepage;
 
        /* Allocate memory for MTD device structure and private data */
@@ -1179,7 +1174,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                this->bbt_td = &bbt_main_descr;
                this->bbt_md = &bbt_mirror_descr;
                /* update flash based bbt */
-               this->options |= NAND_USE_FLASH_BBT;
+               this->bbt_options |= NAND_BBT_USE_FLASH;
        }
 
        init_completion(&host->op_completion);
@@ -1231,16 +1226,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        }
 
        /* Register the partitions */
-       nr_parts =
-           parse_mtd_partitions(mtd, part_probes, &host->parts, 0);
-       if (nr_parts > 0)
-               mtd_device_register(mtd, host->parts, nr_parts);
-       else if (pdata->parts)
-               mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
-       else {
-               pr_info("Registering %s as whole device\n", mtd->name);
-               mtd_device_register(mtd, NULL, 0);
-       }
+       mtd_device_parse_register(mtd, part_probes, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, host);
 
index a46e9bb847bd0ac52743f14ab07133cc9a98b231..3ed9c5e4d34e7bfbc51351a8475878424c325ab6 100644 (file)
@@ -21,7 +21,7 @@
  *  TODO:
  *     Enable cached programming for 2k page size chips
  *     Check, if mtd->ecctype should be set to MTD_ECC_HW
- *     if we have HW ecc support.
+ *     if we have HW ECC support.
  *     The AG-AND chips have nice features for speed improvement,
  *     which are not supported yet. Read / program 4 pages in one go.
  *     BBT table is not serialized, has to be fixed
@@ -113,21 +113,19 @@ static int check_offs_len(struct mtd_info *mtd,
 
        /* Start address must align on block boundary */
        if (ofs & ((1 << chip->phys_erase_shift) - 1)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Unaligned address\n", __func__);
+               pr_debug("%s: unaligned address\n", __func__);
                ret = -EINVAL;
        }
 
        /* Length must align on block boundary */
        if (len & ((1 << chip->phys_erase_shift) - 1)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Length not block aligned\n",
-                                       __func__);
+               pr_debug("%s: length not block aligned\n", __func__);
                ret = -EINVAL;
        }
 
        /* Do not allow past end of device */
        if (ofs + len > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Past end of device\n",
-                                       __func__);
+               pr_debug("%s: past end of device\n", __func__);
                ret = -EINVAL;
        }
 
@@ -136,9 +134,9 @@ static int check_offs_len(struct mtd_info *mtd,
 
 /**
  * nand_release_device - [GENERIC] release chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Deselect, release chip lock and wake up anyone waiting on the device
+ * Deselect, release chip lock and wake up anyone waiting on the device.
  */
 static void nand_release_device(struct mtd_info *mtd)
 {
@@ -157,9 +155,9 @@ static void nand_release_device(struct mtd_info *mtd)
 
 /**
  * nand_read_byte - [DEFAULT] read one byte from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth
  */
 static uint8_t nand_read_byte(struct mtd_info *mtd)
 {
@@ -169,10 +167,11 @@ static uint8_t nand_read_byte(struct mtd_info *mtd)
 
 /**
  * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
- * @mtd:       MTD device structure
+ * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip
+ * @mtd: MTD device structure
+ *
+ * Default read function for 16bit buswidth with endianness conversion.
  *
- * Default read function for 16bit buswith with
- * endianess conversion
  */
 static uint8_t nand_read_byte16(struct mtd_info *mtd)
 {
@@ -182,10 +181,9 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
 
 /**
  * nand_read_word - [DEFAULT] read one word from the chip
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Default read function for 16bit buswith without
- * endianess conversion
+ * Default read function for 16bit buswidth without endianness conversion.
  */
 static u16 nand_read_word(struct mtd_info *mtd)
 {
@@ -195,8 +193,8 @@ static u16 nand_read_word(struct mtd_info *mtd)
 
 /**
  * nand_select_chip - [DEFAULT] control CE line
- * @mtd:       MTD device structure
- * @chipnr:    chipnumber to select, -1 for deselect
+ * @mtd: MTD device structure
+ * @chipnr: chipnumber to select, -1 for deselect
  *
  * Default select function for 1 chip devices.
  */
@@ -218,11 +216,11 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
 
 /**
  * nand_write_buf - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 8bit buswith
+ * Default write function for 8bit buswidth.
  */
 static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -235,11 +233,11 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 8bit buswith
+ * Default read function for 8bit buswidth.
  */
 static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -252,11 +250,11 @@ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 8bit buswith
+ * Default verify function for 8bit buswidth.
  */
 static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -271,11 +269,11 @@ static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_write_buf16 - [DEFAULT] write buffer to chip
- * @mtd:       MTD device structure
- * @buf:       data buffer
- * @len:       number of bytes to write
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
  *
- * Default write function for 16bit buswith
+ * Default write function for 16bit buswidth.
  */
 static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -291,11 +289,11 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_read_buf16 - [DEFAULT] read chip data into buffer
- * @mtd:       MTD device structure
- * @buf:       buffer to store date
- * @len:       number of bytes to read
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
  *
- * Default read function for 16bit buswith
+ * Default read function for 16bit buswidth.
  */
 static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 {
@@ -310,11 +308,11 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 
 /**
  * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd:       MTD device structure
- * @buf:       buffer containing the data to compare
- * @len:       number of bytes to compare
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
  *
- * Default verify function for 16bit buswith
+ * Default verify function for 16bit buswidth.
  */
 static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
@@ -332,9 +330,9 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 
 /**
  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
  *
  * Check, if the block is bad.
  */
@@ -344,7 +342,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
        struct nand_chip *chip = mtd->priv;
        u16 bad;
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
+       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
@@ -384,11 +382,11 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 
 /**
  * nand_default_block_markbad - [DEFAULT] mark a block bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
  *
- * This is the default implementation, which can be overridden by
- * a hardware specific driver.
+ * This is the default implementation, which can be overridden by a hardware
+ * specific driver.
 */
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -396,7 +394,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        uint8_t buf[2] = { 0, 0 };
        int block, ret, i = 0;
 
-       if (chip->options & NAND_BBT_SCANLASTPAGE)
+       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        /* Get block number */
@@ -404,33 +402,31 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        if (chip->bbt)
                chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
-       /* Do we have a flash based bad block table ? */
-       if (chip->options & NAND_USE_FLASH_BBT)
+       /* Do we have a flash based bad block table? */
+       if (chip->bbt_options & NAND_BBT_USE_FLASH)
                ret = nand_update_bbt(mtd, ofs);
        else {
+               struct mtd_oob_ops ops;
+
                nand_get_device(chip, mtd, FL_WRITING);
 
-               /* Write to first two pages and to byte 1 and 6 if necessary.
-                * If we write to more than one location, the first error
-                * encountered quits the procedure. We write two bytes per
-                * location, so we dont have to mess with 16 bit access.
+               /*
+                * Write to first two pages if necessary. If we write to more
+                * than one location, the first error encountered quits the
+                * procedure. We write two bytes per location, so we dont have
+                * to mess with 16 bit access.
                 */
+               ops.len = ops.ooblen = 2;
+               ops.datbuf = NULL;
+               ops.oobbuf = buf;
+               ops.ooboffs = chip->badblockpos & ~0x01;
+               ops.mode = MTD_OPS_PLACE_OOB;
                do {
-                       chip->ops.len = chip->ops.ooblen = 2;
-                       chip->ops.datbuf = NULL;
-                       chip->ops.oobbuf = buf;
-                       chip->ops.ooboffs = chip->badblockpos & ~0x01;
-
-                       ret = nand_do_write_oob(mtd, ofs, &chip->ops);
+                       ret = nand_do_write_oob(mtd, ofs, &ops);
 
-                       if (!ret && (chip->options & NAND_BBT_SCANBYTE1AND6)) {
-                               chip->ops.ooboffs = NAND_SMALL_BADBLOCK_POS
-                                       & ~0x01;
-                               ret = nand_do_write_oob(mtd, ofs, &chip->ops);
-                       }
                        i++;
                        ofs += mtd->writesize;
-               } while (!ret && (chip->options & NAND_BBT_SCAN2NDPAGE) &&
+               } while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) &&
                                i < 2);
 
                nand_release_device(mtd);
@@ -443,16 +439,16 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 /**
  * nand_check_wp - [GENERIC] check if the chip is write protected
- * @mtd:       MTD device structure
- * Check, if the device is write protected
+ * @mtd: MTD device structure
  *
- * The function expects, that the device is already selected
+ * Check, if the device is write protected. The function expects, that the
+ * device is already selected.
  */
 static int nand_check_wp(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       /* broken xD cards report WP despite being writable */
+       /* Broken xD cards report WP despite being writable */
        if (chip->options & NAND_BROKEN_XD)
                return 0;
 
@@ -463,10 +459,10 @@ static int nand_check_wp(struct mtd_info *mtd)
 
 /**
  * nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd:       MTD device structure
- * @ofs:       offset from device start
- * @getchip:   0, if the chip is already selected
- * @allowbbt:  1, if its allowed to access the bbt area
+ * @mtd: MTD device structure
+ * @ofs: offset from device start
+ * @getchip: 0, if the chip is already selected
+ * @allowbbt: 1, if its allowed to access the bbt area
  *
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
@@ -485,8 +481,8 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
 
 /**
  * panic_nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
- * @mtd:       MTD device structure
- * @timeo:     Timeout
+ * @mtd: MTD device structure
+ * @timeo: Timeout
  *
  * Helper function for nand_wait_ready used when needing to wait in interrupt
  * context.
@@ -505,10 +501,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
        }
 }
 
-/*
- * Wait for the ready pin, after a command
- * The timeout is catched later.
- */
+/* Wait for the ready pin, after a command. The timeout is caught later. */
 void nand_wait_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
@@ -519,7 +512,7 @@ void nand_wait_ready(struct mtd_info *mtd)
                return panic_nand_wait_ready(mtd, 400);
 
        led_trigger_event(nand_led_trigger, LED_FULL);
-       /* wait until command is processed or timeout occures */
+       /* Wait until command is processed or timeout occurs */
        do {
                if (chip->dev_ready(mtd))
                        break;
@@ -531,13 +524,13 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
 
 /**
  * nand_command - [DEFAULT] Send command to NAND device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
- * Send command to NAND device. This function is used for small page
- * devices (256/512 Bytes per page)
+ * Send command to NAND device. This function is used for small page devices
+ * (256/512 Bytes per page).
  */
 static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
@@ -545,9 +538,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        register struct nand_chip *chip = mtd->priv;
        int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
 
-       /*
-        * Write out the command to the device.
-        */
+       /* Write out the command to the device */
        if (command == NAND_CMD_SEQIN) {
                int readcmd;
 
@@ -567,9 +558,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        }
        chip->cmd_ctrl(mtd, command, ctrl);
 
-       /*
-        * Address cycle, when necessary
-        */
+       /* Address cycle, when necessary */
        ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE;
        /* Serially input address */
        if (column != -1) {
@@ -590,8 +579,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status and sequential in needs no delay
+        * Program and erase have their own busy handlers status and sequential
+        * in needs no delay
         */
        switch (command) {
 
@@ -625,8 +614,10 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                        return;
                }
        }
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -634,14 +625,14 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 
 /**
  * nand_command_lp - [DEFAULT] Send command to NAND large page device
- * @mtd:       MTD device structure
- * @command:   the command to be sent
- * @column:    the column address for this command, -1 if none
- * @page_addr: the page address for this command, -1 if none
+ * @mtd: MTD device structure
+ * @command: the command to be sent
+ * @column: the column address for this command, -1 if none
+ * @page_addr: the page address for this command, -1 if none
  *
  * Send command to NAND device. This is the version for the new large page
- * devices We dont have the separate regions as we have in the small page
- * devices.  We must emulate NAND_CMD_READOOB to keep the code compatible.
+ * devices. We don't have the separate regions as we have in the small page
+ * devices. We must emulate NAND_CMD_READOOB to keep the code compatible.
  */
 static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                            int column, int page_addr)
@@ -683,8 +674,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
 
        /*
-        * program and erase have their own busy handlers
-        * status, sequential in, and deplete1 need no delay
+        * Program and erase have their own busy handlers status, sequential
+        * in, and deplete1 need no delay.
         */
        switch (command) {
 
@@ -698,14 +689,12 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        case NAND_CMD_DEPLETE1:
                return;
 
-               /*
-                * read error status commands require only a short delay
-                */
        case NAND_CMD_STATUS_ERROR:
        case NAND_CMD_STATUS_ERROR0:
        case NAND_CMD_STATUS_ERROR1:
        case NAND_CMD_STATUS_ERROR2:
        case NAND_CMD_STATUS_ERROR3:
+               /* Read error status commands require only a short delay */
                udelay(chip->chip_delay);
                return;
 
@@ -739,7 +728,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
        default:
                /*
                 * If we don't have access to the busy pin, we apply the given
-                * command delay
+                * command delay.
                 */
                if (!chip->dev_ready) {
                        udelay(chip->chip_delay);
@@ -747,8 +736,10 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                }
        }
 
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in
+        * any case on any machine.
+        */
        ndelay(100);
 
        nand_wait_ready(mtd);
@@ -756,25 +747,25 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
 
 /**
  * panic_nand_get_device - [GENERIC] Get chip for selected access
- * @chip:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
+ * @chip: the nand chip descriptor
+ * @mtd: MTD device structure
+ * @new_state: the state which is requested
  *
  * Used when in panic, no locks are taken.
  */
 static void panic_nand_get_device(struct nand_chip *chip,
                      struct mtd_info *mtd, int new_state)
 {
-       /* Hardware controller shared among independend devices */
+       /* Hardware controller shared among independent devices */
        chip->controller->active = chip;
        chip->state = new_state;
 }
 
 /**
  * nand_get_device - [GENERIC] Get chip for selected access
- * @chip:      the nand chip descriptor
- * @mtd:       MTD device structure
- * @new_state: the state which is requested
+ * @chip: the nand chip descriptor
+ * @mtd: MTD device structure
+ * @new_state: the state which is requested
  *
  * Get the device and lock it for exclusive access
  */
@@ -812,10 +803,10 @@ retry:
 }
 
 /**
- * panic_nand_wait - [GENERIC]  wait until the command is done
- * @mtd:       MTD device structure
- * @chip:      NAND chip structure
- * @timeo:     Timeout
+ * panic_nand_wait - [GENERIC] wait until the command is done
+ * @mtd: MTD device structure
+ * @chip: NAND chip structure
+ * @timeo: timeout
  *
  * Wait for command done. This is a helper function for nand_wait used when
  * we are in interrupt context. May happen when in panic and trying to write
@@ -838,13 +829,13 @@ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_wait - [DEFAULT]  wait until the command is done
- * @mtd:       MTD device structure
- * @chip:      NAND chip structure
+ * nand_wait - [DEFAULT] wait until the command is done
+ * @mtd: MTD device structure
+ * @chip: NAND chip structure
  *
- * Wait for command done. This applies to erase and program only
- * Erase can take up to 400ms and program up to 20ms according to
- * general NAND and SmartMedia specs
+ * Wait for command done. This applies to erase and program only. Erase can
+ * take up to 400ms and program up to 20ms according to general NAND and
+ * SmartMedia specs.
  */
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
@@ -859,8 +850,10 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 
        led_trigger_event(nand_led_trigger, LED_FULL);
 
-       /* Apply this short delay always to ensure that we do wait tWB in
-        * any case on any machine. */
+       /*
+        * Apply this short delay always to ensure that we do wait tWB in any
+        * case on any machine.
+        */
        ndelay(100);
 
        if ((state == FL_ERASING) && (chip->options & NAND_IS_AND))
@@ -890,16 +883,15 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 
 /**
  * __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
- * @invert:   when = 0, unlock the range of blocks within the lower and
- *                      upper boundary address
- *            when = 1, unlock the range of blocks outside the boundaries
- *                      of the lower and upper boundary address
+ * @invert: when = 0, unlock the range of blocks within the lower and
+ *                    upper boundary address
+ *          when = 1, unlock the range of blocks outside the boundaries
+ *                    of the lower and upper boundary address
  *
- * return - unlock status
+ * Returs unlock status.
  */
 static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
                                        uint64_t len, int invert)
@@ -919,10 +911,9 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
-       udelay(1000);
        /* See if device thinks it succeeded */
        if (status & 0x01) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Error status = 0x%08x\n",
+               pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
        }
@@ -932,12 +923,11 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
 
 /**
  * nand_unlock - [REPLACEABLE] unlocks specified locked blocks
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
  *
- * return - unlock status
+ * Returns unlock status.
  */
 int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
@@ -945,7 +935,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        int chipnr;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
                        __func__, (unsigned long long)ofs, len);
 
        if (check_offs_len(mtd, ofs, len))
@@ -964,7 +954,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
+               pr_debug("%s: device is write protected!\n",
                                        __func__);
                ret = -EIO;
                goto out;
@@ -981,18 +971,16 @@ EXPORT_SYMBOL(nand_unlock);
 
 /**
  * nand_lock - [REPLACEABLE] locks all blocks present in the device
- *
  * @mtd: mtd info
  * @ofs: offset to start unlock from
  * @len: length to unlock
  *
- * return - lock status
+ * This feature is not supported in many NAND parts. 'Micron' NAND parts do
+ * have this feature, but it allows only to lock all blocks, not for specified
+ * range for block. Implementing 'lock' feature by making use of 'unlock', for
+ * now.
  *
- * This feature is not supported in many NAND parts. 'Micron' NAND parts
- * do have this feature, but it allows only to lock all blocks, not for
- * specified range for block.
- *
- * Implementing 'lock' feature by making use of 'unlock', for now.
+ * Returns lock status.
  */
 int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
@@ -1000,7 +988,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        int chipnr, status, page;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
                        __func__, (unsigned long long)ofs, len);
 
        if (check_offs_len(mtd, ofs, len))
@@ -1015,7 +1003,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
+               pr_debug("%s: device is write protected!\n",
                                        __func__);
                status = MTD_ERASE_FAILED;
                ret = -EIO;
@@ -1028,10 +1016,9 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 
        /* Call wait ready function */
        status = chip->waitfunc(mtd, chip);
-       udelay(1000);
        /* See if device thinks it succeeded */
        if (status & 0x01) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Error status = 0x%08x\n",
+               pr_debug("%s: error status = 0x%08x\n",
                                        __func__, status);
                ret = -EIO;
                goto out;
@@ -1047,13 +1034,13 @@ out:
 EXPORT_SYMBOL(nand_lock);
 
 /**
- * nand_read_page_raw - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                              uint8_t *buf, int page)
@@ -1064,11 +1051,11 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_raw_syndrome - [INTERN] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
@@ -1107,11 +1094,11 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_swecc - [REPLACABLE] software ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_swecc - [REPLACEABLE] software ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  */
 static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int page)
@@ -1148,12 +1135,12 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @data_offs: offset of requested data within the page
- * @readlen:   data length
- * @bufpoi:    buffer to store read data
+ * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @data_offs: offset of requested data within the page
+ * @readlen: data length
+ * @bufpoi: buffer to store read data
  */
 static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                        uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
@@ -1166,12 +1153,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
        int index = 0;
 
-       /* Column address wihin the page aligned to ECC size (256bytes). */
+       /* Column address within the page aligned to ECC size (256bytes) */
        start_step = data_offs / chip->ecc.size;
        end_step = (data_offs + readlen - 1) / chip->ecc.size;
        num_steps = end_step - start_step + 1;
 
-       /* Data size aligned to ECC ecc.size*/
+       /* Data size aligned to ECC ecc.size */
        datafrag_len = num_steps * chip->ecc.size;
        eccfrag_len = num_steps * chip->ecc.bytes;
 
@@ -1183,13 +1170,14 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
        p = bufpoi + data_col_addr;
        chip->read_buf(mtd, p, datafrag_len);
 
-       /* Calculate  ECC */
+       /* Calculate ECC */
        for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size)
                chip->ecc.calculate(mtd, p, &chip->buffers->ecccalc[i]);
 
-       /* The performance is faster if to position offsets
-          according to ecc.pos. Let make sure here that
-          there are no gaps in ecc positions */
+       /*
+        * The performance is faster if we position offsets according to
+        * ecc.pos. Let's make sure that there are no gaps in ECC positions.
+        */
        for (i = 0; i < eccfrag_len - 1; i++) {
                if (eccpos[i + start_step * chip->ecc.bytes] + 1 !=
                        eccpos[i + start_step * chip->ecc.bytes + 1]) {
@@ -1201,8 +1189,10 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
                chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
                chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
        } else {
-               /* send the command to read the particular ecc bytes */
-               /* take care about buswidth alignment in read_buf */
+               /*
+                * Send the command to read the particular ECC bytes take care
+                * about buswidth alignment in read_buf.
+                */
                index = start_step * chip->ecc.bytes;
 
                aligned_pos = eccpos[index] & ~(busw - 1);
@@ -1235,13 +1225,13 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc - [REPLACEABLE] hardware ECC based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Not for syndrome calculating ecc controllers which need a special oob layout
+ * Not for syndrome calculating ECC controllers which need a special oob layout.
  */
 static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                                uint8_t *buf, int page)
@@ -1280,18 +1270,17 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_page_hwecc_oob_first - [REPLACABLE] hw ecc, read oob first
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_hwecc_oob_first - [REPLACEABLE] hw ecc, read oob first
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * Hardware ECC for large page chips, require OOB to be read first.
- * For this ECC mode, the write_page method is re-used from ECC_HW.
- * These methods read/write ECC from the OOB area, unlike the
- * ECC_HW_SYNDROME support with multiple ECC steps, follows the
- * "infix ECC" scheme and reads/writes ECC from the data area, by
- * overwriting the NAND manufacturer bad block markings.
+ * Hardware ECC for large page chips, require OOB to be read first. For this
+ * ECC mode, the write_page method is re-used from ECC_HW. These methods
+ * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
+ * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
+ * the data area, by overwriting the NAND manufacturer bad block markings.
  */
 static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
        struct nand_chip *chip, uint8_t *buf, int page)
@@ -1329,14 +1318,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 }
 
 /**
- * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       buffer to store read data
- * @page:      page number to read
+ * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
 static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                                   uint8_t *buf, int page)
@@ -1384,29 +1373,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_transfer_oob - [Internal] Transfer oob to client buffer
- * @chip:      nand chip structure
- * @oob:       oob destination address
- * @ops:       oob ops structure
- * @len:       size of oob to transfer
+ * nand_transfer_oob - [INTERN] Transfer oob to client buffer
+ * @chip: nand chip structure
+ * @oob: oob destination address
+ * @ops: oob ops structure
+ * @len: size of oob to transfer
  */
 static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                                  struct mtd_oob_ops *ops, size_t len)
 {
        switch (ops->mode) {
 
-       case MTD_OOB_PLACE:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_RAW:
                memcpy(oob, chip->oob_poi + ops->ooboffs, len);
                return oob + len;
 
-       case MTD_OOB_AUTO: {
+       case MTD_OPS_AUTO_OOB: {
                struct nand_oobfree *free = chip->ecc.layout->oobfree;
                uint32_t boffs = 0, roffs = ops->ooboffs;
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Read request not from offset 0 ? */
+                       /* Read request not from offset 0? */
                        if (unlikely(roffs)) {
                                if (roffs >= free->length) {
                                        roffs -= free->length;
@@ -1432,11 +1421,10 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 }
 
 /**
- * nand_do_read_ops - [Internal] Read data with ECC
- *
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob ops structure
+ * nand_do_read_ops - [INTERN] Read data with ECC
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob ops structure
  *
  * Internal function. Called with chip held.
  */
@@ -1451,7 +1439,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
        int ret = 0;
        uint32_t readlen = ops->len;
        uint32_t oobreadlen = ops->ooblen;
-       uint32_t max_oobsize = ops->mode == MTD_OOB_AUTO ?
+       uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ?
                mtd->oobavail : mtd->oobsize;
 
        uint8_t *bufpoi, *oob, *buf;
@@ -1473,7 +1461,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                bytes = min(mtd->writesize - col, readlen);
                aligned = (bytes == mtd->writesize);
 
-               /* Is the current page in the buffer ? */
+               /* Is the current page in the buffer? */
                if (realpage != chip->pagebuf || oob) {
                        bufpoi = aligned ? buf : chip->buffers->databuf;
 
@@ -1483,7 +1471,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        }
 
                        /* Now read the page into the buffer */
-                       if (unlikely(ops->mode == MTD_OOB_RAW))
+                       if (unlikely(ops->mode == MTD_OPS_RAW))
                                ret = chip->ecc.read_page_raw(mtd, chip,
                                                              bufpoi, page);
                        else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
@@ -1492,14 +1480,22 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        else
                                ret = chip->ecc.read_page(mtd, chip, bufpoi,
                                                          page);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               if (!aligned)
+                                       /* Invalidate page cache */
+                                       chip->pagebuf = -1;
                                break;
+                       }
 
                        /* Transfer not aligned data */
                        if (!aligned) {
                                if (!NAND_SUBPAGE_READ(chip) && !oob &&
-                                   !(mtd->ecc_stats.failed - stats.failed))
+                                   !(mtd->ecc_stats.failed - stats.failed) &&
+                                   (ops->mode != MTD_OPS_RAW))
                                        chip->pagebuf = realpage;
+                               else
+                                       /* Invalidate page cache */
+                                       chip->pagebuf = -1;
                                memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
 
@@ -1539,7 +1535,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                if (!readlen)
                        break;
 
-               /* For subsequent reads align to page boundary. */
+               /* For subsequent reads align to page boundary */
                col = 0;
                /* Increment page address */
                realpage++;
@@ -1552,8 +1548,9 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
 
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
+               /*
+                * Check, if the chip supports auto page increment or if we
+                * have hit a block boundary.
                 */
                if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
                        sndcmd = 1;
@@ -1574,18 +1571,19 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
 /**
  * nand_read - [MTD Interface] MTD compatibility function for nand_do_read_ecc
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @len:       number of bytes to read
- * @retlen:    pointer to variable to store the number of read bytes
- * @buf:       the databuffer to put data
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @retlen: pointer to variable to store the number of read bytes
+ * @buf: the databuffer to put data
  *
- * Get hold of the chip and call nand_do_read
+ * Get hold of the chip and call nand_do_read.
  */
 static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, uint8_t *buf)
 {
        struct nand_chip *chip = mtd->priv;
+       struct mtd_oob_ops ops;
        int ret;
 
        /* Do not allow reads past end of device */
@@ -1596,13 +1594,14 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        nand_get_device(chip, mtd, FL_READING);
 
-       chip->ops.len = len;
-       chip->ops.datbuf = buf;
-       chip->ops.oobbuf = NULL;
+       ops.len = len;
+       ops.datbuf = buf;
+       ops.oobbuf = NULL;
+       ops.mode = 0;
 
-       ret = nand_do_read_ops(mtd, from, &chip->ops);
+       ret = nand_do_read_ops(mtd, from, &ops);
 
-       *retlen = chip->ops.retlen;
+       *retlen = ops.retlen;
 
        nand_release_device(mtd);
 
@@ -1610,11 +1609,11 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 }
 
 /**
- * nand_read_oob_std - [REPLACABLE] the most common OOB data read function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * nand_read_oob_std - [REPLACEABLE] the most common OOB data read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
+ * @sndcmd: flag whether to issue read command or not
  */
 static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                             int page, int sndcmd)
@@ -1628,12 +1627,12 @@ static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC
+ * nand_read_oob_syndrome - [REPLACEABLE] OOB data read function for HW ECC
  *                         with syndromes
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to read
- * @sndcmd:    flag whether to issue read command or not
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
+ * @sndcmd: flag whether to issue read command or not
  */
 static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                                  int page, int sndcmd)
@@ -1667,10 +1666,10 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_oob_std - [REPLACABLE] the most common OOB data write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_std - [REPLACEABLE] the most common OOB data write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
                              int page)
@@ -1690,11 +1689,11 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC
- *                          with syndrome - only for large page flash !
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @page:      page number to write
+ * nand_write_oob_syndrome - [REPLACEABLE] OOB data write function for HW ECC
+ *                          with syndrome - only for large page flash
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
  */
 static int nand_write_oob_syndrome(struct mtd_info *mtd,
                                   struct nand_chip *chip, int page)
@@ -1749,34 +1748,37 @@ static int nand_write_oob_syndrome(struct mtd_info *mtd,
 }
 
 /**
- * nand_do_read_oob - [Intern] NAND read out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operations description structure
+ * nand_do_read_oob - [INTERN] NAND read out-of-band
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operations description structure
  *
- * NAND read out-of-band data from the spare area
+ * NAND read out-of-band data from the spare area.
  */
 static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
        int page, realpage, chipnr, sndcmd = 1;
        struct nand_chip *chip = mtd->priv;
+       struct mtd_ecc_stats stats;
        int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
        int readlen = ops->ooblen;
        int len;
        uint8_t *buf = ops->oobbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08Lx, len = %i\n",
+       pr_debug("%s: from = 0x%08Lx, len = %i\n",
                        __func__, (unsigned long long)from, readlen);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       stats = mtd->ecc_stats;
+
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                len = chip->ecc.layout->oobavail;
        else
                len = mtd->oobsize;
 
        if (unlikely(ops->ooboffs >= len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read "
-                                       "outside oob\n", __func__);
+               pr_debug("%s: attempt to start read outside oob\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -1784,8 +1786,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        if (unlikely(from >= mtd->size ||
                     ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) -
                                        (from >> chip->page_shift)) * len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read beyond end "
-                                       "of device\n", __func__);
+               pr_debug("%s: attempt to read beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -1797,7 +1799,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        page = realpage & chip->pagemask;
 
        while (1) {
-               sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
+               if (ops->mode == MTD_OPS_RAW)
+                       sndcmd = chip->ecc.read_oob_raw(mtd, chip, page, sndcmd);
+               else
+                       sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
 
                len = min(len, readlen);
                buf = nand_transfer_oob(chip, buf, ops, len);
@@ -1830,24 +1835,29 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                        chip->select_chip(mtd, chipnr);
                }
 
-               /* Check, if the chip supports auto page increment
-                * or if we have hit a block boundary.
+               /*
+                * Check, if the chip supports auto page increment or if we
+                * have hit a block boundary.
                 */
                if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck))
                        sndcmd = 1;
        }
 
        ops->oobretlen = ops->ooblen;
-       return 0;
+
+       if (mtd->ecc_stats.failed - stats.failed)
+               return -EBADMSG;
+
+       return  mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;
 }
 
 /**
  * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @from: offset to read from
+ * @ops: oob operation description structure
  *
- * NAND read data and/or out-of-band data
+ * NAND read data and/or out-of-band data.
  */
 static int nand_read_oob(struct mtd_info *mtd, loff_t from,
                         struct mtd_oob_ops *ops)
@@ -1859,17 +1869,17 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 
        /* Do not allow reads past end of device */
        if (ops->datbuf && (from + ops->len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt read "
-                               "beyond end of device\n", __func__);
+               pr_debug("%s: attempt to read beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
        nand_get_device(chip, mtd, FL_READING);
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
+       case MTD_OPS_RAW:
                break;
 
        default:
@@ -1888,12 +1898,12 @@ out:
 
 
 /**
- * nand_write_page_raw - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
- * Not for syndrome calculating ecc controllers, which use a special oob layout
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
                                const uint8_t *buf)
@@ -1903,10 +1913,10 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_raw_syndrome - [Intern] raw page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_raw_syndrome - [INTERN] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
@@ -1942,10 +1952,10 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
                chip->write_buf(mtd, oob, size);
 }
 /**
- * nand_write_page_swecc - [REPLACABLE] software ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  */
 static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
                                  const uint8_t *buf)
@@ -1957,7 +1967,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        const uint8_t *p = buf;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
 
-       /* Software ecc calculation */
+       /* Software ECC calculation */
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
@@ -1968,10 +1978,10 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_hwecc - [REPLACEABLE] hardware ECC based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  */
 static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                                  const uint8_t *buf)
@@ -1996,13 +2006,13 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @buf:       data buffer
+ * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
  *
- * The hw generator calculates the error syndrome automatically. Therefor
- * we need a special oob layout and handling.
+ * The hw generator calculates the error syndrome automatically. Therefore we
+ * need a special oob layout and handling.
  */
 static void nand_write_page_syndrome(struct mtd_info *mtd,
                                    struct nand_chip *chip, const uint8_t *buf)
@@ -2041,12 +2051,12 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
 
 /**
  * nand_write_page - [REPLACEABLE] write one page
- * @mtd:       MTD device structure
- * @chip:      NAND chip descriptor
- * @buf:       the data to write
- * @page:      page number to write
- * @cached:    cached programming
- * @raw:       use _raw version of write_page
+ * @mtd: MTD device structure
+ * @chip: NAND chip descriptor
+ * @buf: the data to write
+ * @page: page number to write
+ * @cached: cached programming
+ * @raw: use _raw version of write_page
  */
 static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                           const uint8_t *buf, int page, int cached, int raw)
@@ -2061,8 +2071,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                chip->ecc.write_page(mtd, chip, buf);
 
        /*
-        * Cached progamming disabled for now, Not sure if its worth the
-        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
+        * Cached progamming disabled for now. Not sure if it's worth the
+        * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s).
         */
        cached = 0;
 
@@ -2072,7 +2082,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
                status = chip->waitfunc(mtd, chip);
                /*
                 * See if operation failed and additional status checks are
-                * available
+                * available.
                 */
                if ((status & NAND_STATUS_FAIL) && (chip->errstat))
                        status = chip->errstat(mtd, chip, FL_WRITING, status,
@@ -2096,29 +2106,37 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * nand_fill_oob - [Internal] Transfer client buffer to oob
- * @chip:      nand chip structure
- * @oob:       oob data buffer
- * @len:       oob data write length
- * @ops:       oob ops structure
+ * nand_fill_oob - [INTERN] Transfer client buffer to oob
+ * @mtd: MTD device structure
+ * @oob: oob data buffer
+ * @len: oob data write length
+ * @ops: oob ops structure
  */
-static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
-                                               struct mtd_oob_ops *ops)
+static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
+                             struct mtd_oob_ops *ops)
 {
+       struct nand_chip *chip = mtd->priv;
+
+       /*
+        * Initialise to all 0xFF, to avoid the possibility of left over OOB
+        * data from a previous OOB read.
+        */
+       memset(chip->oob_poi, 0xff, mtd->oobsize);
+
        switch (ops->mode) {
 
-       case MTD_OOB_PLACE:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_RAW:
                memcpy(chip->oob_poi + ops->ooboffs, oob, len);
                return oob + len;
 
-       case MTD_OOB_AUTO: {
+       case MTD_OPS_AUTO_OOB: {
                struct nand_oobfree *free = chip->ecc.layout->oobfree;
                uint32_t boffs = 0, woffs = ops->ooboffs;
                size_t bytes = 0;
 
                for (; free->length && len; free++, len -= bytes) {
-                       /* Write request not from offset 0 ? */
+                       /* Write request not from offset 0? */
                        if (unlikely(woffs)) {
                                if (woffs >= free->length) {
                                        woffs -= free->length;
@@ -2146,12 +2164,12 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
 #define NOTALIGNED(x)  ((x & (chip->subpagesize - 1)) != 0)
 
 /**
- * nand_do_write_ops - [Internal] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operations description structure
+ * nand_do_write_ops - [INTERN] NAND write with ECC
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operations description structure
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -2161,7 +2179,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        uint32_t writelen = ops->len;
 
        uint32_t oobwritelen = ops->ooblen;
-       uint32_t oobmaxlen = ops->mode == MTD_OOB_AUTO ?
+       uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ?
                                mtd->oobavail : mtd->oobsize;
 
        uint8_t *oob = ops->oobbuf;
@@ -2172,10 +2190,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
        if (!writelen)
                return 0;
 
-       /* reject writes, which are not page aligned */
+       /* Reject writes, which are not page aligned */
        if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
-               printk(KERN_NOTICE "%s: Attempt to write not "
-                               "page aligned data\n", __func__);
+               pr_notice("%s: attempt to write non page aligned data\n",
+                          __func__);
                return -EINVAL;
        }
 
@@ -2201,10 +2219,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
            (chip->pagebuf << chip->page_shift) < (to + ops->len))
                chip->pagebuf = -1;
 
-       /* If we're not given explicit OOB data, let it be 0xFF */
-       if (likely(!oob))
-               memset(chip->oob_poi, 0xff, mtd->oobsize);
-
        /* Don't allow multipage oob writes with offset */
        if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
                return -EINVAL;
@@ -2214,7 +2228,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
 
-               /* Partial page write ? */
+               /* Partial page write? */
                if (unlikely(column || writelen < (mtd->writesize - 1))) {
                        cached = 0;
                        bytes = min_t(int, bytes - column, (int) writelen);
@@ -2226,12 +2240,15 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
                if (unlikely(oob)) {
                        size_t len = min(oobwritelen, oobmaxlen);
-                       oob = nand_fill_oob(chip, oob, len, ops);
+                       oob = nand_fill_oob(mtd, oob, len, ops);
                        oobwritelen -= len;
+               } else {
+                       /* We still need to erase leftover OOB data */
+                       memset(chip->oob_poi, 0xff, mtd->oobsize);
                }
 
                ret = chip->write_page(mtd, chip, wbuf, page, cached,
-                                      (ops->mode == MTD_OOB_RAW));
+                                      (ops->mode == MTD_OPS_RAW));
                if (ret)
                        break;
 
@@ -2260,11 +2277,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
 
 /**
  * panic_nand_write - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @len: number of bytes to write
+ * @retlen: pointer to variable to store the number of written bytes
+ * @buf: the data to write
  *
  * NAND write with ECC. Used when performing writes in interrupt context, this
  * may for example be called by mtdoops when writing an oops while in panic.
@@ -2273,6 +2290,7 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                            size_t *retlen, const uint8_t *buf)
 {
        struct nand_chip *chip = mtd->priv;
+       struct mtd_oob_ops ops;
        int ret;
 
        /* Do not allow reads past end of device */
@@ -2281,36 +2299,38 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
        if (!len)
                return 0;
 
-       /* Wait for the device to get ready */
+       /* Wait for the device to get ready */
        panic_nand_wait(mtd, chip, 400);
 
-       /* Grab the device */
+       /* Grab the device */
        panic_nand_get_device(chip, mtd, FL_WRITING);
 
-       chip->ops.len = len;
-       chip->ops.datbuf = (uint8_t *)buf;
-       chip->ops.oobbuf = NULL;
+       ops.len = len;
+       ops.datbuf = (uint8_t *)buf;
+       ops.oobbuf = NULL;
+       ops.mode = 0;
 
-       ret = nand_do_write_ops(mtd, to, &chip->ops);
+       ret = nand_do_write_ops(mtd, to, &ops);
 
-       *retlen = chip->ops.retlen;
+       *retlen = ops.retlen;
        return ret;
 }
 
 /**
  * nand_write - [MTD Interface] NAND write with ECC
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @len:       number of bytes to write
- * @retlen:    pointer to variable to store the number of written bytes
- * @buf:       the data to write
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @len: number of bytes to write
+ * @retlen: pointer to variable to store the number of written bytes
+ * @buf: the data to write
  *
- * NAND write with ECC
+ * NAND write with ECC.
  */
 static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                          size_t *retlen, const uint8_t *buf)
 {
        struct nand_chip *chip = mtd->priv;
+       struct mtd_oob_ops ops;
        int ret;
 
        /* Do not allow reads past end of device */
@@ -2321,13 +2341,14 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 
        nand_get_device(chip, mtd, FL_WRITING);
 
-       chip->ops.len = len;
-       chip->ops.datbuf = (uint8_t *)buf;
-       chip->ops.oobbuf = NULL;
+       ops.len = len;
+       ops.datbuf = (uint8_t *)buf;
+       ops.oobbuf = NULL;
+       ops.mode = 0;
 
-       ret = nand_do_write_ops(mtd, to, &chip->ops);
+       ret = nand_do_write_ops(mtd, to, &ops);
 
-       *retlen = chip->ops.retlen;
+       *retlen = ops.retlen;
 
        nand_release_device(mtd);
 
@@ -2336,11 +2357,11 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 /**
  * nand_do_write_oob - [MTD Interface] NAND write out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  *
- * NAND write out-of-band
+ * NAND write out-of-band.
  */
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -2348,24 +2369,24 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        int chipnr, page, status, len;
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
+       pr_debug("%s: to = 0x%08x, len = %i\n",
                         __func__, (unsigned int)to, (int)ops->ooblen);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                len = chip->ecc.layout->oobavail;
        else
                len = mtd->oobsize;
 
        /* Do not allow write past end of page */
        if ((ops->ooboffs + ops->ooblen) > len) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write "
-                               "past end of page\n", __func__);
+               pr_debug("%s: attempt to write past end of page\n",
+                               __func__);
                return -EINVAL;
        }
 
        if (unlikely(ops->ooboffs >= len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start "
-                               "write outside oob\n", __func__);
+               pr_debug("%s: attempt to start write outside oob\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -2374,8 +2395,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                     ops->ooboffs + ops->ooblen >
                        ((mtd->size >> chip->page_shift) -
                         (to >> chip->page_shift)) * len)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
-                               "end of device\n", __func__);
+               pr_debug("%s: attempt to write beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
@@ -2401,10 +2422,12 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
        if (page == chip->pagebuf)
                chip->pagebuf = -1;
 
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
-       nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
-       status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
-       memset(chip->oob_poi, 0xff, mtd->oobsize);
+       nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops);
+
+       if (ops->mode == MTD_OPS_RAW)
+               status = chip->ecc.write_oob_raw(mtd, chip, page & chip->pagemask);
+       else
+               status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
 
        if (status)
                return status;
@@ -2416,9 +2439,9 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 
 /**
  * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @to:                offset to write to
- * @ops:       oob operation description structure
+ * @mtd: MTD device structure
+ * @to: offset to write to
+ * @ops: oob operation description structure
  */
 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
                          struct mtd_oob_ops *ops)
@@ -2430,17 +2453,17 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 
        /* Do not allow writes past end of device */
        if (ops->datbuf && (to + ops->len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt write beyond "
-                               "end of device\n", __func__);
+               pr_debug("%s: attempt to write beyond end of device\n",
+                               __func__);
                return -EINVAL;
        }
 
        nand_get_device(chip, mtd, FL_WRITING);
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
-       case MTD_OOB_RAW:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
+       case MTD_OPS_RAW:
                break;
 
        default:
@@ -2458,11 +2481,11 @@ out:
 }
 
 /**
- * single_erease_cmd - [GENERIC] NAND standard block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * single_erase_cmd - [GENERIC] NAND standard block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * Standard erase command for NAND chips
+ * Standard erase command for NAND chips.
  */
 static void single_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2473,12 +2496,11 @@ static void single_erase_cmd(struct mtd_info *mtd, int page)
 }
 
 /**
- * multi_erease_cmd - [GENERIC] AND specific block erase command function
- * @mtd:       MTD device structure
- * @page:      the page address of the block which will be erased
+ * multi_erase_cmd - [GENERIC] AND specific block erase command function
+ * @mtd: MTD device structure
+ * @page: the page address of the block which will be erased
  *
- * AND multi block erase command function
- * Erase 4 consecutive blocks
+ * AND multi block erase command function. Erase 4 consecutive blocks.
  */
 static void multi_erase_cmd(struct mtd_info *mtd, int page)
 {
@@ -2493,10 +2515,10 @@ static void multi_erase_cmd(struct mtd_info *mtd, int page)
 
 /**
  * nand_erase - [MTD Interface] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
+ * @mtd: MTD device structure
+ * @instr: erase instruction
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
@@ -2505,12 +2527,12 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 #define BBT_PAGE_MASK  0xffffff3f
 /**
- * nand_erase_nand - [Internal] erase block(s)
- * @mtd:       MTD device structure
- * @instr:     erase instruction
- * @allowbbt:  allow erasing the bbt area
+ * nand_erase_nand - [INTERN] erase block(s)
+ * @mtd: MTD device structure
+ * @instr: erase instruction
+ * @allowbbt: allow erasing the bbt area
  *
- * Erase one ore more blocks
+ * Erase one ore more blocks.
  */
 int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                    int allowbbt)
@@ -2521,9 +2543,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        unsigned int bbt_masked_page = 0xffffffff;
        loff_t len;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start = 0x%012llx, len = %llu\n",
-                               __func__, (unsigned long long)instr->addr,
-                               (unsigned long long)instr->len);
+       pr_debug("%s: start = 0x%012llx, len = %llu\n",
+                       __func__, (unsigned long long)instr->addr,
+                       (unsigned long long)instr->len);
 
        if (check_offs_len(mtd, instr->addr, instr->len))
                return -EINVAL;
@@ -2545,8 +2567,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
        /* Check, if it is write protected */
        if (nand_check_wp(mtd)) {
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: Device is write protected!!!\n",
-                                       __func__);
+               pr_debug("%s: device is write protected!\n",
+                               __func__);
                instr->state = MTD_ERASE_FAILED;
                goto erase_exit;
        }
@@ -2555,7 +2577,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
         * If BBT requires refresh, set the BBT page mask to see if the BBT
         * should be rewritten. Otherwise the mask is set to 0xffffffff which
         * can not be matched. This is also done when the bbt is actually
-        * erased to avoid recusrsive updates
+        * erased to avoid recursive updates.
         */
        if (chip->options & BBT_AUTO_REFRESH && !allowbbt)
                bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2566,20 +2588,18 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        instr->state = MTD_ERASING;
 
        while (len) {
-               /*
-                * heck if we have a bad block, we do not erase bad blocks !
-                */
+               /* Heck if we have a bad block, we do not erase bad blocks! */
                if (nand_block_checkbad(mtd, ((loff_t) page) <<
                                        chip->page_shift, 0, allowbbt)) {
-                       printk(KERN_WARNING "%s: attempt to erase a bad block "
-                                       "at page 0x%08x\n", __func__, page);
+                       pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
+                                   __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        goto erase_exit;
                }
 
                /*
                 * Invalidate the page cache, if we erase the block which
-                * contains the current cached page
+                * contains the current cached page.
                 */
                if (page <= chip->pagebuf && chip->pagebuf <
                    (page + pages_per_block))
@@ -2599,8 +2619,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /* See if block erase succeeded */
                if (status & NAND_STATUS_FAIL) {
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: Failed erase, "
-                                       "page 0x%08x\n", __func__, page);
+                       pr_debug("%s: failed erase, page 0x%08x\n",
+                                       __func__, page);
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr =
                                ((loff_t)page << chip->page_shift);
@@ -2609,7 +2629,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /*
                 * If BBT requires refresh, set the BBT rewrite flag to the
-                * page being erased
+                * page being erased.
                 */
                if (bbt_masked_page != 0xffffffff &&
                    (page & BBT_PAGE_MASK) == bbt_masked_page)
@@ -2628,7 +2648,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                        /*
                         * If BBT requires refresh and BBT-PERCHIP, set the BBT
-                        * page mask to see if this BBT should be rewritten
+                        * page mask to see if this BBT should be rewritten.
                         */
                        if (bbt_masked_page != 0xffffffff &&
                            (chip->bbt_td->options & NAND_BBT_PERCHIP))
@@ -2651,7 +2671,7 @@ erase_exit:
 
        /*
         * If BBT requires refresh and erase was successful, rewrite any
-        * selected bad block tables
+        * selected bad block tables.
         */
        if (bbt_masked_page == 0xffffffff || ret)
                return ret;
@@ -2659,10 +2679,10 @@ erase_exit:
        for (chipnr = 0; chipnr < chip->numchips; chipnr++) {
                if (!rewrite_bbt[chipnr])
                        continue;
-               /* update the BBT for chip */
-               DEBUG(MTD_DEBUG_LEVEL0, "%s: nand_update_bbt "
-                       "(%d:0x%0llx 0x%0x)\n", __func__, chipnr,
-                       rewrite_bbt[chipnr], chip->bbt_td->pages[chipnr]);
+               /* Update the BBT for chip */
+               pr_debug("%s: nand_update_bbt (%d:0x%0llx 0x%0x)\n",
+                               __func__, chipnr, rewrite_bbt[chipnr],
+                               chip->bbt_td->pages[chipnr]);
                nand_update_bbt(mtd, rewrite_bbt[chipnr]);
        }
 
@@ -2672,15 +2692,15 @@ erase_exit:
 
 /**
  * nand_sync - [MTD Interface] sync
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  *
- * Sync is actually a wait for chip ready function
+ * Sync is actually a wait for chip ready function.
  */
 static void nand_sync(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
+       pr_debug("%s: called\n", __func__);
 
        /* Grab the lock and see if the device is available */
        nand_get_device(chip, mtd, FL_SYNCING);
@@ -2690,8 +2710,8 @@ static void nand_sync(struct mtd_info *mtd)
 
 /**
  * nand_block_isbad - [MTD Interface] Check if block at offset is bad
- * @mtd:       MTD device structure
- * @offs:      offset relative to mtd start
+ * @mtd: MTD device structure
+ * @offs: offset relative to mtd start
  */
 static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
@@ -2704,8 +2724,8 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 
 /**
  * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad
- * @mtd:       MTD device structure
- * @ofs:       offset relative to mtd start
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
  */
 static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
@@ -2714,7 +2734,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
        ret = nand_block_isbad(mtd, ofs);
        if (ret) {
-               /* If it was bad already, return success and do nothing. */
+               /* If it was bad already, return success and do nothing */
                if (ret > 0)
                        return 0;
                return ret;
@@ -2725,7 +2745,7 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
 /**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  */
 static int nand_suspend(struct mtd_info *mtd)
 {
@@ -2736,7 +2756,7 @@ static int nand_suspend(struct mtd_info *mtd)
 
 /**
  * nand_resume - [MTD Interface] Resume the NAND flash
- * @mtd:       MTD device structure
+ * @mtd: MTD device structure
  */
 static void nand_resume(struct mtd_info *mtd)
 {
@@ -2745,13 +2765,11 @@ static void nand_resume(struct mtd_info *mtd)
        if (chip->state == FL_PM_SUSPENDED)
                nand_release_device(mtd);
        else
-               printk(KERN_ERR "%s called for a chip which is not "
-                      "in suspended state\n", __func__);
+               pr_err("%s called for a chip which is not in suspended state\n",
+                       __func__);
 }
 
-/*
- * Set default functions
- */
+/* Set default functions */
 static void nand_set_defaults(struct nand_chip *chip, int busw)
 {
        /* check for proper chip_delay setup, set 20us if not */
@@ -2793,23 +2811,21 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 
 }
 
-/*
- * sanitize ONFI strings so we can safely print them
- */
+/* Sanitize ONFI strings so we can safely print them */
 static void sanitize_string(uint8_t *s, size_t len)
 {
        ssize_t i;
 
-       /* null terminate */
+       /* Null terminate */
        s[len - 1] = 0;
 
-       /* remove non printable chars */
+       /* Remove non printable chars */
        for (i = 0; i < len - 1; i++) {
                if (s[i] < ' ' || s[i] > 127)
                        s[i] = '?';
        }
 
-       /* remove trailing spaces */
+       /* Remove trailing spaces */
        strim(s);
 }
 
@@ -2826,28 +2842,28 @@ static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
 }
 
 /*
- * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
  */
 static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
-                                       int busw)
+                                       int *busw)
 {
        struct nand_onfi_params *p = &chip->onfi_params;
        int i;
        int val;
 
-       /* try ONFI for unknow chip or LP */
+       /* Try ONFI for unknown chip or LP */
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
        if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
                chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
                return 0;
 
-       printk(KERN_INFO "ONFI flash detected\n");
+       pr_info("ONFI flash detected\n");
        chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
        for (i = 0; i < 3; i++) {
                chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
                                le16_to_cpu(p->crc)) {
-                       printk(KERN_INFO "ONFI param page %d valid\n", i);
+                       pr_info("ONFI param page %d valid\n", i);
                        break;
                }
        }
@@ -2855,7 +2871,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        if (i == 3)
                return 0;
 
-       /* check version */
+       /* Check version */
        val = le16_to_cpu(p->revision);
        if (val & (1 << 5))
                chip->onfi_version = 23;
@@ -2871,8 +2887,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
                chip->onfi_version = 0;
 
        if (!chip->onfi_version) {
-               printk(KERN_INFO "%s: unsupported ONFI version: %d\n",
-                                                               __func__, val);
+               pr_info("%s: unsupported ONFI version: %d\n", __func__, val);
                return 0;
        }
 
@@ -2884,9 +2899,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
        mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
        mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
        chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
-       busw = 0;
+       *busw = 0;
        if (le16_to_cpu(p->features) & 1)
-               busw = NAND_BUSWIDTH_16;
+               *busw = NAND_BUSWIDTH_16;
 
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
        chip->options |= (NAND_NO_READRDY |
@@ -2896,7 +2911,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /*
- * Get the flash and manufacturer id and lookup if the type is supported
+ * Get the flash and manufacturer id and lookup if the type is supported.
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
@@ -2913,7 +2928,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        /*
         * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
-        * after power-up
+        * after power-up.
         */
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
 
@@ -2924,7 +2939,8 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        *maf_id = chip->read_byte(mtd);
        *dev_id = chip->read_byte(mtd);
 
-       /* Try again to make sure, as some systems the bus-hold or other
+       /*
+        * Try again to make sure, as some systems the bus-hold or other
         * interface concerns can cause random data which looks like a
         * possibly credible NAND flash to appear. If the two results do
         * not match, ignore the device completely.
@@ -2936,9 +2952,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                id_data[i] = chip->read_byte(mtd);
 
        if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
-               printk(KERN_INFO "%s: second ID read did not match "
-                      "%02x,%02x against %02x,%02x\n", __func__,
-                      *maf_id, *dev_id, id_data[0], id_data[1]);
+               pr_info("%s: second ID read did not match "
+                       "%02x,%02x against %02x,%02x\n", __func__,
+                       *maf_id, *dev_id, id_data[0], id_data[1]);
                return ERR_PTR(-ENODEV);
        }
 
@@ -2952,7 +2968,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->onfi_version = 0;
        if (!type->name || !type->pagesize) {
                /* Check is chip is ONFI compliant */
-               ret = nand_flash_detect_onfi(mtd, chip, busw);
+               ret = nand_flash_detect_onfi(mtd, chip, &busw);
                if (ret)
                        goto ident_done;
        }
@@ -2973,7 +2989,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->chipsize = (uint64_t)type->chipsize << 20;
 
        if (!type->pagesize && chip->init_size) {
-               /* set the pagesize, oobsize, erasesize by the driver*/
+               /* Set the pagesize, oobsize, erasesize by the driver */
                busw = chip->init_size(mtd, chip, id_data);
        } else if (!type->pagesize) {
                int extid;
@@ -3033,7 +3049,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                }
        } else {
                /*
-                * Old devices have chip data hardcoded in the device id table
+                * Old devices have chip data hardcoded in the device id table.
                 */
                mtd->erasesize = type->erasesize;
                mtd->writesize = type->pagesize;
@@ -3043,7 +3059,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                /*
                 * Check for Spansion/AMD ID + repeating 5th, 6th byte since
                 * some Spansion chips have erasesize that conflicts with size
-                * listed in nand_ids table
+                * listed in nand_ids table.
                 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
                 */
                if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
@@ -3057,15 +3073,16 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        chip->options &= ~NAND_CHIPOPTIONS_MSK;
        chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
 
-       /* Check if chip is a not a samsung device. Do not clear the
-        * options for chips which are not having an extended id.
+       /*
+        * Check if chip is not a Samsung device. Do not clear the
+        * options for chips which do not have an extended id.
         */
        if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
                chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
 ident_done:
 
        /*
-        * Set chip as a default. Board drivers can override it, if necessary
+        * Set chip as a default. Board drivers can override it, if necessary.
         */
        chip->options |= NAND_NO_AUTOINCR;
 
@@ -3077,21 +3094,21 @@ ident_done:
 
        /*
         * Check, if buswidth is correct. Hardware drivers should set
-        * chip correct !
+        * chip correct!
         */
        if (busw != (chip->options & NAND_BUSWIDTH_16)) {
-               printk(KERN_INFO "NAND device: Manufacturer ID:"
-                      " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
-                      *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
-               printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
-                      (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
-                      busw ? 16 : 8);
+               pr_info("NAND device: Manufacturer ID:"
+                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
+                       *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+               pr_warn("NAND bus width %d instead %d bit\n",
+                          (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
+                          busw ? 16 : 8);
                return ERR_PTR(-EINVAL);
        }
 
        /* Calculate the address shift from the page size */
        chip->page_shift = ffs(mtd->writesize) - 1;
-       /* Convert chipsize to number of pages per chip -1. */
+       /* Convert chipsize to number of pages per chip -1 */
        chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
 
        chip->bbt_erase_shift = chip->phys_erase_shift =
@@ -3121,7 +3138,7 @@ ident_done:
        if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                        (*maf_id == NAND_MFR_SAMSUNG ||
                         *maf_id == NAND_MFR_HYNIX))
-               chip->options |= NAND_BBT_SCANLASTPAGE;
+               chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
        else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                                (*maf_id == NAND_MFR_SAMSUNG ||
                                 *maf_id == NAND_MFR_HYNIX ||
@@ -3129,17 +3146,7 @@ ident_done:
                                 *maf_id == NAND_MFR_AMD)) ||
                        (mtd->writesize == 2048 &&
                         *maf_id == NAND_MFR_MICRON))
-               chip->options |= NAND_BBT_SCAN2NDPAGE;
-
-       /*
-        * Numonyx/ST 2K pages, x8 bus use BOTH byte 1 and 6
-        */
-       if (!(busw & NAND_BUSWIDTH_16) &&
-                       *maf_id == NAND_MFR_STMICRO &&
-                       mtd->writesize == 2048) {
-               chip->options |= NAND_BBT_SCANBYTE1AND6;
-               chip->badblockpos = 0;
-       }
+               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
 
        /* Check for AND chips with 4 page planes */
        if (chip->options & NAND_4PAGE_ARRAY)
@@ -3147,12 +3154,11 @@ ident_done:
        else
                chip->erase_cmd = single_erase_cmd;
 
-       /* Do not replace user supplied command function ! */
+       /* Do not replace user supplied command function! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
-       /* TODO onfi flash name */
-       printk(KERN_INFO "NAND device: Manufacturer ID:"
+       pr_info("NAND device: Manufacturer ID:"
                " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
                nand_manuf_ids[maf_idx].name,
                chip->onfi_version ? chip->onfi_params.model : type->name);
@@ -3162,12 +3168,12 @@ ident_done:
 
 /**
  * nand_scan_ident - [NAND Interface] Scan for the NAND device
- * @mtd:            MTD device structure
- * @maxchips:       Number of chips to scan for
- * @table:          Alternative NAND ID table
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
+ * @table: alternative NAND ID table
  *
- * This is the first phase of the normal nand_scan() function. It
- * reads the flash ID and sets up MTD fields accordingly.
+ * This is the first phase of the normal nand_scan() function. It reads the
+ * flash ID and sets up MTD fields accordingly.
  *
  * The mtd->owner field must be set to the module of the caller.
  */
@@ -3189,7 +3195,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 
        if (IS_ERR(type)) {
                if (!(chip->options & NAND_SCAN_SILENT_NODEV))
-                       printk(KERN_WARNING "No NAND device found.\n");
+                       pr_warn("No NAND device found\n");
                chip->select_chip(mtd, -1);
                return PTR_ERR(type);
        }
@@ -3207,7 +3213,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                        break;
        }
        if (i > 1)
-               printk(KERN_INFO "%d NAND chips detected\n", i);
+               pr_info("%d NAND chips detected\n", i);
 
        /* Store the number of chips and calc total size for mtd */
        chip->numchips = i;
@@ -3220,11 +3226,11 @@ EXPORT_SYMBOL(nand_scan_ident);
 
 /**
  * nand_scan_tail - [NAND Interface] Scan for the NAND device
- * @mtd:           MTD device structure
+ * @mtd: MTD device structure
  *
- * This is the second phase of the normal nand_scan() function. It
- * fills out all the uninitialized function pointers with the defaults
- * and scans for a bad block table if appropriate.
+ * This is the second phase of the normal nand_scan() function. It fills out
+ * all the uninitialized function pointers with the defaults and scans for a
+ * bad block table if appropriate.
  */
 int nand_scan_tail(struct mtd_info *mtd)
 {
@@ -3240,7 +3246,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        chip->oob_poi = chip->buffers->databuf + mtd->writesize;
 
        /*
-        * If no default placement scheme is given, select an appropriate one
+        * If no default placement scheme is given, select an appropriate one.
         */
        if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
                switch (mtd->oobsize) {
@@ -3257,8 +3263,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                        chip->ecc.layout = &nand_oob_128;
                        break;
                default:
-                       printk(KERN_WARNING "No oob scheme defined for "
-                              "oobsize %d\n", mtd->oobsize);
+                       pr_warn("No oob scheme defined for oobsize %d\n",
+                                  mtd->oobsize);
                        BUG();
                }
        }
@@ -3267,7 +3273,7 @@ int nand_scan_tail(struct mtd_info *mtd)
                chip->write_page = nand_write_page;
 
        /*
-        * check ECC mode, default to software if 3byte/512byte hardware ECC is
+        * Check ECC mode, default to software if 3byte/512byte hardware ECC is
         * selected and we have 256 byte pagesize fallback to software ECC
         */
 
@@ -3276,15 +3282,15 @@ int nand_scan_tail(struct mtd_info *mtd)
                /* Similar to NAND_ECC_HW, but a separate read_page handle */
                if (!chip->ecc.calculate || !chip->ecc.correct ||
                     !chip->ecc.hwctl) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc_oob_first;
 
        case NAND_ECC_HW:
-               /* Use standard hwecc read page function ? */
+               /* Use standard hwecc read page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_hwecc;
                if (!chip->ecc.write_page)
@@ -3305,11 +3311,11 @@ int nand_scan_tail(struct mtd_info *mtd)
                     chip->ecc.read_page == nand_read_page_hwecc ||
                     !chip->ecc.write_page ||
                     chip->ecc.write_page == nand_write_page_hwecc)) {
-                       printk(KERN_WARNING "No ECC functions supplied; "
-                              "Hardware ECC not possible\n");
+                       pr_warn("No ECC functions supplied; "
+                                  "hardware ECC not possible\n");
                        BUG();
                }
-               /* Use standard syndrome read/write page function ? */
+               /* Use standard syndrome read/write page function? */
                if (!chip->ecc.read_page)
                        chip->ecc.read_page = nand_read_page_syndrome;
                if (!chip->ecc.write_page)
@@ -3325,9 +3331,9 @@ int nand_scan_tail(struct mtd_info *mtd)
 
                if (mtd->writesize >= chip->ecc.size)
                        break;
-               printk(KERN_WARNING "%d byte HW ECC not possible on "
-                      "%d byte page size, fallback to SW ECC\n",
-                      chip->ecc.size, mtd->writesize);
+               pr_warn("%d byte HW ECC not possible on "
+                          "%d byte page size, fallback to SW ECC\n",
+                          chip->ecc.size, mtd->writesize);
                chip->ecc.mode = NAND_ECC_SOFT;
 
        case NAND_ECC_SOFT:
@@ -3347,7 +3353,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        case NAND_ECC_SOFT_BCH:
                if (!mtd_nand_has_bch()) {
-                       printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n");
+                       pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
                        BUG();
                }
                chip->ecc.calculate = nand_bch_calculate_ecc;
@@ -3362,8 +3368,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                /*
                 * Board driver should supply ecc.size and ecc.bytes values to
                 * select how many bits are correctable; see nand_bch_init()
-                * for details.
-                * Otherwise, default to 4 bits for large page devices
+                * for details. Otherwise, default to 4 bits for large page
+                * devices.
                 */
                if (!chip->ecc.size && (mtd->oobsize >= 64)) {
                        chip->ecc.size = 512;
@@ -3374,14 +3380,14 @@ int nand_scan_tail(struct mtd_info *mtd)
                                               chip->ecc.bytes,
                                               &chip->ecc.layout);
                if (!chip->ecc.priv) {
-                       printk(KERN_WARNING "BCH ECC initialization failed!\n");
+                       pr_warn("BCH ECC initialization failed!\n");
                        BUG();
                }
                break;
 
        case NAND_ECC_NONE:
-               printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
-                      "This is not recommended !!\n");
+               pr_warn("NAND_ECC_NONE selected by board driver. "
+                          "This is not recommended!\n");
                chip->ecc.read_page = nand_read_page_raw;
                chip->ecc.write_page = nand_write_page_raw;
                chip->ecc.read_oob = nand_read_oob_std;
@@ -3393,14 +3399,19 @@ int nand_scan_tail(struct mtd_info *mtd)
                break;
 
        default:
-               printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
-                      chip->ecc.mode);
+               pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
                BUG();
        }
 
+       /* For many systems, the standard OOB write also works for raw */
+       if (!chip->ecc.read_oob_raw)
+               chip->ecc.read_oob_raw = chip->ecc.read_oob;
+       if (!chip->ecc.write_oob_raw)
+               chip->ecc.write_oob_raw = chip->ecc.write_oob;
+
        /*
         * The number of bytes available for a client to place data into
-        * the out of band area
+        * the out of band area.
         */
        chip->ecc.layout->oobavail = 0;
        for (i = 0; chip->ecc.layout->oobfree[i].length
@@ -3411,19 +3422,16 @@ int nand_scan_tail(struct mtd_info *mtd)
 
        /*
         * Set the number of read / write steps for one page depending on ECC
-        * mode
+        * mode.
         */
        chip->ecc.steps = mtd->writesize / chip->ecc.size;
        if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
-               printk(KERN_WARNING "Invalid ecc parameters\n");
+               pr_warn("Invalid ECC parameters\n");
                BUG();
        }
        chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
 
-       /*
-        * Allow subpage writes up to ecc.steps. Not possible for MLC
-        * FLASH.
-        */
+       /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
        if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
            !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
                switch (chip->ecc.steps) {
@@ -3481,9 +3489,11 @@ int nand_scan_tail(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL(nand_scan_tail);
 
-/* is_module_text_address() isn't exported, and it's mostly a pointless
+/*
+ * is_module_text_address() isn't exported, and it's mostly a pointless
  * test if this is a module _anyway_ -- they'd have to try _really_ hard
- * to call us from in-kernel code if the core NAND support is modular. */
+ * to call us from in-kernel code if the core NAND support is modular.
+ */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
@@ -3493,15 +3503,13 @@ EXPORT_SYMBOL(nand_scan_tail);
 
 /**
  * nand_scan - [NAND Interface] Scan for the NAND device
- * @mtd:       MTD device structure
- * @maxchips:  Number of chips to scan for
- *
- * This fills out all the uninitialized function pointers
- * with the defaults.
- * The flash ID is read and the mtd/chip structures are
- * filled with the appropriate values.
- * The mtd->owner field must be set to the module of the caller
+ * @mtd: MTD device structure
+ * @maxchips: number of chips to scan for
  *
+ * This fills out all the uninitialized function pointers with the defaults.
+ * The flash ID is read and the mtd/chip structures are filled with the
+ * appropriate values. The mtd->owner field must be set to the module of the
+ * caller.
  */
 int nand_scan(struct mtd_info *mtd, int maxchips)
 {
@@ -3509,8 +3517,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
 
        /* Many callers got this wrong, so check for it for a while... */
        if (!mtd->owner && caller_is_module()) {
-               printk(KERN_CRIT "%s called with NULL mtd->owner!\n",
-                               __func__);
+               pr_crit("%s called with NULL mtd->owner!\n", __func__);
                BUG();
        }
 
@@ -3523,8 +3530,8 @@ EXPORT_SYMBOL(nand_scan);
 
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
- * @mtd:       MTD device structure
-*/
+ * @mtd: MTD device structure
+ */
 void nand_release(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
index ccbeaa1e4a8ed42ccddac88f2780915dc3407736..69148ae3bf58aaf806be617894725eb72d1483f1 100644 (file)
@@ -14,7 +14,7 @@
  *
  * When nand_scan_bbt is called, then it tries to find the bad block table
  * depending on the options in the BBT descriptor(s). If no flash based BBT
- * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
+ * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory
  * marked good / bad blocks. This information is used to create a memory BBT.
  * Once a new bad block is discovered then the "factory" information is updated
  * on the device.
@@ -36,9 +36,9 @@
  * The table is marked in the OOB area with an ident pattern and a version
  * number which indicates which of both tables is more up to date. If the NAND
  * controller needs the complete OOB area for the ECC information then the
- * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
- * and the version byte into the data area and the OOB area will remain
- * untouched.
+ * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of
+ * course): it moves the ident pattern and the version byte into the data area
+ * and the OOB area will remain untouched.
  *
  * The table uses 2 bits per block
  * 11b:                block is good
@@ -67,6 +67,7 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
 {
@@ -80,17 +81,15 @@ static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
 
 /**
  * check_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @len:       the length of buffer to search
- * @paglen:    the pagelength
- * @td:                search pattern descriptor
+ * @buf: the buffer to search
+ * @len: the length of buffer to search
+ * @paglen: the pagelength
+ * @td: search pattern descriptor
  *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers.
- * If the SCAN_EMPTY option is set then check, if all bytes except the
- * pattern area contain 0xff
- *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. If the SCAN_EMPTY option is set then check, if
+ * all bytes except the pattern area contain 0xff.
+ */
 static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
        int i, end = 0;
@@ -109,32 +108,8 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
        p += end;
 
        /* Compare the pattern */
-       for (i = 0; i < td->len; i++) {
-               if (p[i] != td->pattern[i])
-                       return -1;
-       }
-
-       /* Check both positions 1 and 6 for pattern? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               if (td->options & NAND_BBT_SCANEMPTY) {
-                       p += td->len;
-                       end += NAND_SMALL_BADBLOCK_POS - td->offs;
-                       /* Check region between positions 1 and 6 */
-                       for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len;
-                                       i++) {
-                               if (*p++ != 0xff)
-                                       return -1;
-                       }
-               }
-               else {
-                       p += NAND_SMALL_BADBLOCK_POS - td->offs;
-               }
-               /* Compare the pattern */
-               for (i = 0; i < td->len; i++) {
-                       if (p[i] != td->pattern[i])
-                               return -1;
-               }
-       }
+       if (memcmp(p, td->pattern, td->len))
+               return -1;
 
        if (td->options & NAND_BBT_SCANEMPTY) {
                p += td->len;
@@ -149,14 +124,13 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf:       the buffer to search
- * @td:                search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block
- * tables and good / bad block identifiers. Same as check_pattern, but
- * no optional empty check
+ * @buf: the buffer to search
+ * @td:        search pattern descriptor
  *
-*/
+ * Check for a pattern at the given place. Used to search bad block tables and
+ * good / bad block identifiers. Same as check_pattern, but no optional empty
+ * check.
+ */
 static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
 {
        int i;
@@ -167,21 +141,14 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
                if (p[td->offs + i] != td->pattern[i])
                        return -1;
        }
-       /* Need to check location 1 AND 6? */
-       if (td->options & NAND_BBT_SCANBYTE1AND6) {
-               for (i = 0; i < td->len; i++) {
-                       if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i])
-                               return -1;
-               }
-       }
        return 0;
 }
 
 /**
  * add_marker_len - compute the length of the marker in data area
- * @td:                BBT descriptor used for computation
+ * @td: BBT descriptor used for computation
  *
- * The length will be 0 if the markeris located in OOB area.
+ * The length will be 0 if the marker is located in OOB area.
  */
 static u32 add_marker_len(struct nand_bbt_descr *td)
 {
@@ -198,34 +165,33 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @page:      the starting page
- * @num:       the number of bbt descriptors to read
- * @td:                the bbt describtion table
- * @offs:      offset in the memory table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @page: the starting page
+ * @num: the number of bbt descriptors to read
+ * @td: the bbt describtion table
+ * @offs: offset in the memory table
  *
  * Read the bad block table starting from page.
- *
  */
 static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                struct nand_bbt_descr *td, int offs)
 {
-       int res, i, j, act = 0;
+       int res, ret = 0, i, j, act = 0;
        struct nand_chip *this = mtd->priv;
        size_t retlen, len, totlen;
        loff_t from;
        int bits = td->options & NAND_BBT_NRBITS_MSK;
-       uint8_t msk = (uint8_t) ((1 << bits) - 1);
+       uint8_t msk = (uint8_t)((1 << bits) - 1);
        u32 marker_len;
        int reserved_block_code = td->reserved_block_code;
 
        totlen = (num * bits) >> 3;
        marker_len = add_marker_len(td);
-       from = ((loff_t) page) << this->page_shift;
+       from = ((loff_t)page) << this->page_shift;
 
        while (totlen) {
-               len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
+               len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
                if (marker_len) {
                        /*
                         * In case the BBT marker is not in the OOB area it
@@ -237,11 +203,18 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                }
                res = mtd->read(mtd, from, len, &retlen, buf);
                if (res < 0) {
-                       if (retlen != len) {
-                               printk(KERN_INFO "nand_bbt: Error reading bad block table\n");
+                       if (mtd_is_eccerr(res)) {
+                               pr_info("nand_bbt: ECC error in BBT at "
+                                       "0x%012llx\n", from & ~mtd->writesize);
+                               return res;
+                       } else if (mtd_is_bitflip(res)) {
+                               pr_info("nand_bbt: corrected error in BBT at "
+                                       "0x%012llx\n", from & ~mtd->writesize);
+                               ret = res;
+                       } else {
+                               pr_info("nand_bbt: error reading BBT\n");
                                return res;
                        }
-                       printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
                }
 
                /* Analyse data */
@@ -252,17 +225,19 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                                if (tmp == msk)
                                        continue;
                                if (reserved_block_code && (tmp == reserved_block_code)) {
-                                       printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n",
-                                              (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                                       pr_info("nand_read_bbt: reserved block at 0x%012llx\n",
+                                                (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
                                        this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
                                        mtd->ecc_stats.bbtblocks++;
                                        continue;
                                }
-                               /* Leave it for now, if its matured we can move this
-                                * message to MTD_DEBUG_LEVEL0 */
-                               printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n",
-                                      (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
-                               /* Factory marked bad or worn out ? */
+                               /*
+                                * Leave it for now, if it's matured we can
+                                * move this message to pr_debug.
+                                */
+                               pr_info("nand_read_bbt: bad block at 0x%012llx\n",
+                                        (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+                               /* Factory marked bad or worn out? */
                                if (tmp == 0)
                                        this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
                                else
@@ -273,20 +248,20 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
                totlen -= len;
                from += len;
        }
-       return 0;
+       return ret;
 }
 
 /**
  * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @chip:      read the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @chip: read the table for a specific chip, -1 read all chips; applies only if
+ *        NAND_BBT_PERCHIP option is set
  *
- * Read the bad block table for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
-*/
+ * Read the bad block table for all chips starting at a given page. We assume
+ * that the bbt bits are in consecutive order.
+ */
 static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
 {
        struct nand_chip *this = mtd->priv;
@@ -312,9 +287,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
        return 0;
 }
 
-/*
- * BBT marker is in the first page, no OOB.
- */
+/* BBT marker is in the first page, no OOB */
 static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         struct nand_bbt_descr *td)
 {
@@ -328,35 +301,26 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
        return mtd->read(mtd, offs, len, &retlen, buf);
 }
 
-/*
- * Scan read raw data from flash
- */
+/* Scan read raw data from flash */
 static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         size_t len)
 {
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_RAW;
+       ops.mode = MTD_OPS_RAW;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
 
-
        while (len > 0) {
-               if (len <= mtd->writesize) {
-                       ops.oobbuf = buf + len;
-                       ops.datbuf = buf;
-                       ops.len = len;
-                       return mtd->read_oob(mtd, offs, &ops);
-               } else {
-                       ops.oobbuf = buf + mtd->writesize;
-                       ops.datbuf = buf;
-                       ops.len = mtd->writesize;
-                       res = mtd->read_oob(mtd, offs, &ops);
+               ops.datbuf = buf;
+               ops.len = min(len, (size_t)mtd->writesize);
+               ops.oobbuf = buf + ops.len;
 
-                       if (res)
-                               return res;
-               }
+               res = mtd->read_oob(mtd, offs, &ops);
+
+               if (res)
+                       return res;
 
                buf += mtd->oobsize + mtd->writesize;
                len -= mtd->writesize;
@@ -373,15 +337,13 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                return scan_read_raw_oob(mtd, buf, offs, len);
 }
 
-/*
- * Scan write data with oob to flash
- */
+/* Scan write data with oob to flash */
 static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
                          uint8_t *buf, uint8_t *oob)
 {
        struct mtd_oob_ops ops;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
        ops.datbuf = buf;
@@ -402,15 +364,14 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md:        descriptor for the bad block table mirror
  *
- * Read the bad block table(s) for all chips starting at a given page
- * We assume that the bbt bits are in consecutive order.
- *
-*/
+ * Read the bad block table(s) for all chips starting at a given page. We
+ * assume that the bbt bits are in consecutive order.
+ */
 static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                         struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
@@ -421,8 +382,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
                              mtd->writesize, td);
                td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      td->pages[0], td->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        td->pages[0], td->version[0]);
        }
 
        /* Read the mirror version, if available */
@@ -430,15 +391,13 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
                scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
                              mtd->writesize, td);
                md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
-               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
-                      md->pages[0], md->version[0]);
+               pr_info("Bad block table at page %d, version 0x%02X\n",
+                        md->pages[0], md->version[0]);
        }
        return 1;
 }
 
-/*
- * Scan a given block full
- */
+/* Scan a given block full */
 static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
                           loff_t offs, uint8_t *buf, size_t readlen,
                           int scanlen, int len)
@@ -446,7 +405,8 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
        int ret, j;
 
        ret = scan_read_raw_oob(mtd, buf, offs, readlen);
-       if (ret)
+       /* Ignore ECC errors when checking for BBM */
+       if (ret && !mtd_is_bitflip_or_eccerr(ret))
                return ret;
 
        for (j = 0; j < len; j++, buf += scanlen) {
@@ -456,9 +416,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
        return 0;
 }
 
-/*
- * Scan a given block partially
- */
+/* Scan a given block partially */
 static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
                           loff_t offs, uint8_t *buf, int len)
 {
@@ -469,16 +427,16 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
        ops.oobbuf = buf;
        ops.ooboffs = 0;
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
 
        for (j = 0; j < len; j++) {
                /*
-                * Read the full oob until read_oob is fixed to
-                * handle single byte reads for 16 bit
-                * buswidth
+                * Read the full oob until read_oob is fixed to handle single
+                * byte reads for 16 bit buswidth.
                 */
                ret = mtd->read_oob(mtd, offs, &ops);
-               if (ret)
+               /* Ignore ECC errors when checking for BBM */
+               if (ret && !mtd_is_bitflip_or_eccerr(ret))
                        return ret;
 
                if (check_short_pattern(buf, bd))
@@ -491,14 +449,14 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
- * @chip:      create the table for a specific chip, -1 read all chips.
- *             Applies only if NAND_BBT_PERCHIP option is set
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
+ * @chip: create the table for a specific chip, -1 read all chips; applies only
+ *        if NAND_BBT_PERCHIP option is set
  *
- * Create a bad block table by scanning the device
- * for the given good/bad block identify pattern
+ * Create a bad block table by scanning the device for the given good/bad block
+ * identify pattern.
  */
 static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        struct nand_bbt_descr *bd, int chip)
@@ -509,7 +467,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        loff_t from;
        size_t readlen;
 
-       printk(KERN_INFO "Scanning device for bad blocks\n");
+       pr_info("Scanning device for bad blocks\n");
 
        if (bd->options & NAND_BBT_SCANALLPAGES)
                len = 1 << (this->bbt_erase_shift - this->page_shift);
@@ -529,14 +487,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        }
 
        if (chip == -1) {
-               /* Note that numblocks is 2 * (real numblocks) here, see i+=2
-                * below as it makes shifting and masking less painful */
+               /*
+                * Note that numblocks is 2 * (real numblocks) here, see i+=2
+                * below as it makes shifting and masking less painful
+                */
                numblocks = mtd->size >> (this->bbt_erase_shift - 1);
                startblock = 0;
                from = 0;
        } else {
                if (chip >= this->numchips) {
-                       printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
+                       pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
                               chip + 1, this->numchips);
                        return -EINVAL;
                }
@@ -546,7 +506,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
                from = (loff_t)startblock << (this->bbt_erase_shift - 1);
        }
 
-       if (this->options & NAND_BBT_SCANLASTPAGE)
+       if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
                from += mtd->erasesize - (mtd->writesize * len);
 
        for (i = startblock; i < numblocks;) {
@@ -565,8 +525,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                if (ret) {
                        this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-                       printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n",
-                              i >> 1, (unsigned long long)from);
+                       pr_warn("Bad eraseblock %d at 0x%012llx\n",
+                               i >> 1, (unsigned long long)from);
                        mtd->ecc_stats.badblocks++;
                }
 
@@ -578,20 +538,18 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 /**
  * search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
  *
- * Read the bad block table by searching for a given ident pattern.
- * Search is preformed either from the beginning up or from the end of
- * the device downwards. The search starts always at the start of a
- * block.
- * If the option NAND_BBT_PERCHIP is given, each chip is searched
- * for a bbt, which contains the bad block information of this chip.
- * This is necessary to provide support for certain DOC devices.
+ * Read the bad block table by searching for a given ident pattern. Search is
+ * preformed either from the beginning up or from the end of the device
+ * downwards. The search starts always at the start of a block. If the option
+ * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains
+ * the bad block information of this chip. This is necessary to provide support
+ * for certain DOC devices.
  *
- * The bbt ident pattern resides in the oob area of the first page
- * in a block.
+ * The bbt ident pattern resides in the oob area of the first page in a block.
  */
 static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
 {
@@ -602,7 +560,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        int bbtblocks;
        int blocktopage = this->bbt_erase_shift - this->page_shift;
 
-       /* Search direction top -> down ? */
+       /* Search direction top -> down? */
        if (td->options & NAND_BBT_LASTBLOCK) {
                startblock = (mtd->size >> this->bbt_erase_shift) - 1;
                dir = -1;
@@ -611,7 +569,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                dir = 1;
        }
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                bbtblocks = this->chipsize >> this->bbt_erase_shift;
@@ -650,23 +608,23 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        /* Check, if we found a bbt for each requested chip */
        for (i = 0; i < chips; i++) {
                if (td->pages[i] == -1)
-                       printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
+                       pr_warn("Bad block table not found for chip %d\n", i);
                else
-                       printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
-                              td->version[i]);
+                       pr_info("Bad block table found at page %d, version "
+                                "0x%02X\n", td->pages[i], td->version[i]);
        }
        return 0;
 }
 
 /**
  * search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
  *
- * Search and read the bad block table(s)
-*/
+ * Search and read the bad block table(s).
+ */
 static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
        /* Search the primary table */
@@ -682,16 +640,14 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
 
 /**
  * write_bbt - [GENERIC] (Re)write the bad block table
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @td: descriptor for the bad block table
+ * @md: descriptor for the bad block table mirror
+ * @chipsel: selector for a specific chip, -1 for all
  *
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @td:                descriptor for the bad block table
- * @md:                descriptor for the bad block table mirror
- * @chipsel:   selector for a specific chip, -1 for all
- *
- * (Re)write the bad block table
- *
-*/
+ * (Re)write the bad block table.
+ */
 static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
                     int chipsel)
@@ -710,14 +666,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
        ops.ooblen = mtd->oobsize;
        ops.ooboffs = 0;
        ops.datbuf = NULL;
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
 
        if (!rcode)
                rcode = 0xff;
-       /* Write bad block table per chip rather than per device ? */
+       /* Write bad block table per chip rather than per device? */
        if (td->options & NAND_BBT_PERCHIP) {
                numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
-               /* Full device write or specific chip ? */
+               /* Full device write or specific chip? */
                if (chipsel == -1) {
                        nrchips = this->numchips;
                } else {
@@ -731,8 +687,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
        /* Loop through the chips */
        for (; chip < nrchips; chip++) {
-
-               /* There was already a version of the table, reuse the page
+               /*
+                * There was already a version of the table, reuse the page
                 * This applies for absolute placement too, as we have the
                 * page nr. in td->pages.
                 */
@@ -741,8 +697,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        goto write;
                }
 
-               /* Automatic placement of the bad block table */
-               /* Search direction top -> down ? */
+               /*
+                * Automatic placement of the bad block table. Search direction
+                * top -> down?
+                */
                if (td->options & NAND_BBT_LASTBLOCK) {
                        startblock = numblocks * (chip + 1) - 1;
                        dir = -1;
@@ -766,7 +724,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        if (!md || md->pages[chip] != page)
                                goto write;
                }
-               printk(KERN_ERR "No space left to write bad block table\n");
+               pr_err("No space left to write bad block table\n");
                return -ENOSPC;
        write:
 
@@ -791,24 +749,22 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
                bbtoffs = chip * (numblocks >> 2);
 
-               to = ((loff_t) page) << this->page_shift;
+               to = ((loff_t)page) << this->page_shift;
 
-               /* Must we save the block contents ? */
+               /* Must we save the block contents? */
                if (td->options & NAND_BBT_SAVECONTENT) {
                        /* Make it block aligned */
-                       to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1));
+                       to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1));
                        len = 1 << this->bbt_erase_shift;
                        res = mtd->read(mtd, to, len, &retlen, buf);
                        if (res < 0) {
                                if (retlen != len) {
-                                       printk(KERN_INFO "nand_bbt: Error "
-                                              "reading block for writing "
-                                              "the bad block table\n");
+                                       pr_info("nand_bbt: error reading block "
+                                               "for writing the bad block table\n");
                                        return res;
                                }
-                               printk(KERN_WARNING "nand_bbt: ECC error "
-                                      "while reading block for writing "
-                                      "bad block table\n");
+                               pr_warn("nand_bbt: ECC error while reading "
+                                       "block for writing bad block table\n");
                        }
                        /* Read oob data */
                        ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
@@ -821,19 +777,19 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        pageoffs = page - (int)(to >> this->page_shift);
                        offs = pageoffs << this->page_shift;
                        /* Preset the bbt area with 0xff */
-                       memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
+                       memset(&buf[offs], 0xff, (size_t)(numblocks >> sft));
                        ooboffs = len + (pageoffs * mtd->oobsize);
 
                } else if (td->options & NAND_BBT_NO_OOB) {
                        ooboffs = 0;
                        offs = td->len;
-                       /* the version byte */
+                       /* The version byte */
                        if (td->options & NAND_BBT_VERSION)
                                offs++;
                        /* Calc length */
-                       len = (size_t) (numblocks >> sft);
+                       len = (size_t)(numblocks >> sft);
                        len += offs;
-                       /* Make it page aligned ! */
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len);
@@ -841,8 +797,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        memcpy(buf, td->pattern, td->len);
                } else {
                        /* Calc length */
-                       len = (size_t) (numblocks >> sft);
-                       /* Make it page aligned ! */
+                       len = (size_t)(numblocks >> sft);
+                       /* Make it page aligned! */
                        len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len +
@@ -856,13 +812,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (td->options & NAND_BBT_VERSION)
                        buf[ooboffs + td->veroffs] = td->version[chip];
 
-               /* walk through the memory table */
+               /* Walk through the memory table */
                for (i = 0; i < numblocks;) {
                        uint8_t dat;
                        dat = this->bbt[bbtoffs + (i >> 2)];
                        for (j = 0; j < 4; j++, i++) {
                                int sftcnt = (i << (3 - sft)) & sftmsk;
-                               /* Do not store the reserved bbt blocks ! */
+                               /* Do not store the reserved bbt blocks! */
                                buf[offs + (i >> sft)] &=
                                        ~(msk[dat & 0x03] << sftcnt);
                                dat >>= 2;
@@ -883,8 +839,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (res < 0)
                        goto outerr;
 
-               printk(KERN_DEBUG "Bad block table written to 0x%012llx, version "
-                      "0x%02X\n", (unsigned long long)to, td->version[chip]);
+               pr_info("Bad block table written to 0x%012llx, version 0x%02X\n",
+                        (unsigned long long)to, td->version[chip]);
 
                /* Mark it as used */
                td->pages[chip] = page;
@@ -892,19 +848,18 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
        return 0;
 
  outerr:
-       printk(KERN_WARNING
-              "nand_bbt: Error while writing bad block table %d\n", res);
+       pr_warn("nand_bbt: error while writing bad block table %d\n", res);
        return res;
 }
 
 /**
  * nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function creates a memory based bbt by scanning the device
- * for manufacturer / software marked good / bad blocks
-*/
+ * The function creates a memory based bbt by scanning the device for
+ * manufacturer / software marked good / bad blocks.
+ */
 static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -915,25 +870,24 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b
 
 /**
  * check_create - [GENERIC] create and write bbt(s) if necessary
- * @mtd:       MTD device structure
- * @buf:       temporary buffer
- * @bd:                descriptor for the good/bad block search pattern
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The function checks the results of the previous call to read_bbt
- * and creates / updates the bbt(s) if necessary
- * Creation is necessary if no bbt was found for the chip/device
- * Update is necessary if one of the tables is missing or the
- * version nr. of one table is less than the other
-*/
+ * The function checks the results of the previous call to read_bbt and creates
+ * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found
+ * for the chip/device. Update is necessary if one of the tables is missing or
+ * the version nr. of one table is less than the other.
+ */
 static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
 {
-       int i, chips, writeops, chipsel, res;
+       int i, chips, writeops, create, chipsel, res, res2;
        struct nand_chip *this = mtd->priv;
        struct nand_bbt_descr *td = this->bbt_td;
        struct nand_bbt_descr *md = this->bbt_md;
        struct nand_bbt_descr *rd, *rd2;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP)
                chips = this->numchips;
        else
@@ -941,86 +895,98 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
        for (i = 0; i < chips; i++) {
                writeops = 0;
+               create = 0;
                rd = NULL;
                rd2 = NULL;
-               /* Per chip or per device ? */
+               res = res2 = 0;
+               /* Per chip or per device? */
                chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
-               /* Mirrored table available ? */
+               /* Mirrored table available? */
                if (md) {
                        if (td->pages[i] == -1 && md->pages[i] == -1) {
+                               create = 1;
                                writeops = 0x03;
-                               goto create;
-                       }
-
-                       if (td->pages[i] == -1) {
+                       } else if (td->pages[i] == -1) {
                                rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
-                               goto writecheck;
-                       }
-
-                       if (md->pages[i] == -1) {
+                               writeops = 0x01;
+                       } else if (md->pages[i] == -1) {
                                rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
-                               goto writecheck;
-                       }
-
-                       if (td->version[i] == md->version[i]) {
+                               writeops = 0x02;
+                       } else if (td->version[i] == md->version[i]) {
                                rd = td;
                                if (!(td->options & NAND_BBT_VERSION))
                                        rd2 = md;
-                               goto writecheck;
-                       }
-
-                       if (((int8_t) (td->version[i] - md->version[i])) > 0) {
+                       } else if (((int8_t)(td->version[i] - md->version[i])) > 0) {
                                rd = td;
-                               md->version[i] = td->version[i];
-                               writeops = 2;
+                               writeops = 0x02;
                        } else {
                                rd = md;
-                               td->version[i] = md->version[i];
-                               writeops = 1;
+                               writeops = 0x01;
                        }
-
-                       goto writecheck;
-
                } else {
                        if (td->pages[i] == -1) {
+                               create = 1;
                                writeops = 0x01;
-                               goto create;
+                       } else {
+                               rd = td;
                        }
-                       rd = td;
-                       goto writecheck;
                }
-       create:
-               /* Create the bad block table by scanning the device ? */
-               if (!(td->options & NAND_BBT_CREATE))
-                       continue;
 
-               /* Create the table in memory by scanning the chip(s) */
-               if (!(this->options & NAND_CREATE_EMPTY_BBT))
-                       create_bbt(mtd, buf, bd, chipsel);
-
-               td->version[i] = 1;
-               if (md)
-                       md->version[i] = 1;
-       writecheck:
-               /* read back first ? */
-               if (rd)
-                       read_abs_bbt(mtd, buf, rd, chipsel);
-               /* If they weren't versioned, read both. */
-               if (rd2)
-                       read_abs_bbt(mtd, buf, rd2, chipsel);
-
-               /* Write the bad block table to the device ? */
+               if (create) {
+                       /* Create the bad block table by scanning the device? */
+                       if (!(td->options & NAND_BBT_CREATE))
+                               continue;
+
+                       /* Create the table in memory by scanning the chip(s) */
+                       if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
+                               create_bbt(mtd, buf, bd, chipsel);
+
+                       td->version[i] = 1;
+                       if (md)
+                               md->version[i] = 1;
+               }
+
+               /* Read back first? */
+               if (rd) {
+                       res = read_abs_bbt(mtd, buf, rd, chipsel);
+                       if (mtd_is_eccerr(res)) {
+                               /* Mark table as invalid */
+                               rd->pages[i] = -1;
+                               rd->version[i] = 0;
+                               i--;
+                               continue;
+                       }
+               }
+               /* If they weren't versioned, read both */
+               if (rd2) {
+                       res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
+                       if (mtd_is_eccerr(res2)) {
+                               /* Mark table as invalid */
+                               rd2->pages[i] = -1;
+                               rd2->version[i] = 0;
+                               i--;
+                               continue;
+                       }
+               }
+
+               /* Scrub the flash table(s)? */
+               if (mtd_is_bitflip(res) || mtd_is_bitflip(res2))
+                       writeops = 0x03;
+
+               /* Update version numbers before writing */
+               if (md) {
+                       td->version[i] = max(td->version[i], md->version[i]);
+                       md->version[i] = td->version[i];
+               }
+
+               /* Write the bad block table to the device? */
                if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, td, md, chipsel);
                        if (res < 0)
                                return res;
                }
 
-               /* Write the mirror bad block table to the device ? */
+               /* Write the mirror bad block table to the device? */
                if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
                        res = write_bbt(mtd, buf, md, td, chipsel);
                        if (res < 0)
@@ -1032,20 +998,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
 /**
  * mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd:       MTD device structure
- * @td:                bad block table descriptor
+ * @mtd: MTD device structure
+ * @td: bad block table descriptor
  *
- * The bad block table regions are marked as "bad" to prevent
- * accidental erasures / writes. The regions are identified by
- * the mark 0x02.
-*/
+ * The bad block table regions are marked as "bad" to prevent accidental
+ * erasures / writes. The regions are identified by the mark 0x02.
+ */
 static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 {
        struct nand_chip *this = mtd->priv;
        int i, j, chips, block, nrblocks, update;
        uint8_t oldval, newval;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chips = this->numchips;
                nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
@@ -1082,9 +1047,11 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
                                update = 1;
                        block += 2;
                }
-               /* If we want reserved blocks to be recorded to flash, and some
-                  new ones have been marked, then we need to update the stored
-                  bbts.  This should only happen once. */
+               /*
+                * If we want reserved blocks to be recorded to flash, and some
+                * new ones have been marked, then we need to update the stored
+                * bbts.  This should only happen once.
+                */
                if (update && td->reserved_block_code)
                        nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
        }
@@ -1092,8 +1059,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 
 /**
  * verify_bbt_descr - verify the bad block description
- * @mtd:       MTD device structure
- * @bd:                the table to verify
+ * @mtd: MTD device structure
+ * @bd: the table to verify
  *
  * This functions performs a few sanity checks on the bad block description
  * table.
@@ -1111,16 +1078,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        pattern_len = bd->len;
        bits = bd->options & NAND_BBT_NRBITS_MSK;
 
-       BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
-                       !(this->options & NAND_USE_FLASH_BBT));
+       BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) &&
+                       !(this->bbt_options & NAND_BBT_USE_FLASH));
        BUG_ON(!bits);
 
        if (bd->options & NAND_BBT_VERSION)
                pattern_len++;
 
        if (bd->options & NAND_BBT_NO_OOB) {
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
-               BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
+               BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH));
+               BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB));
                BUG_ON(bd->offs);
                if (bd->options & NAND_BBT_VERSION)
                        BUG_ON(bd->veroffs != bd->len);
@@ -1140,18 +1107,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd:       MTD device structure
- * @bd:                descriptor for the good/bad block search pattern
- *
- * The function checks, if a bad block table(s) is/are already
- * available. If not it scans the device for manufacturer
- * marked good / bad blocks and writes the bad block table(s) to
- * the selected place.
+ * @mtd: MTD device structure
+ * @bd: descriptor for the good/bad block search pattern
  *
- * The bad block table memory is allocated here. It must be freed
- * by calling the nand_free_bbt function.
+ * The function checks, if a bad block table(s) is/are already available. If
+ * not it scans the device for manufacturer marked good / bad blocks and writes
+ * the bad block table(s) to the selected place.
  *
-*/
+ * The bad block table memory is allocated here. It must be freed by calling
+ * the nand_free_bbt function.
+ */
 int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
        struct nand_chip *this = mtd->priv;
@@ -1161,19 +1126,21 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        struct nand_bbt_descr *md = this->bbt_md;
 
        len = mtd->size >> (this->bbt_erase_shift + 2);
-       /* Allocate memory (2bit per block) and clear the memory bad block table */
+       /*
+        * Allocate memory (2bit per block) and clear the memory bad block
+        * table.
+        */
        this->bbt = kzalloc(len, GFP_KERNEL);
-       if (!this->bbt) {
-               printk(KERN_ERR "nand_scan_bbt: Out of memory\n");
+       if (!this->bbt)
                return -ENOMEM;
-       }
 
-       /* If no primary table decriptor is given, scan the device
-        * to build a memory based bad block table
+       /*
+        * If no primary table decriptor is given, scan the device to build a
+        * memory based bad block table.
         */
        if (!td) {
                if ((res = nand_memory_bbt(mtd, bd))) {
-                       printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+                       pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
                        kfree(this->bbt);
                        this->bbt = NULL;
                }
@@ -1187,13 +1154,12 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = vmalloc(len);
        if (!buf) {
-               printk(KERN_ERR "nand_bbt: Out of memory\n");
                kfree(this->bbt);
                this->bbt = NULL;
                return -ENOMEM;
        }
 
-       /* Is the bbt at a given page ? */
+       /* Is the bbt at a given page? */
        if (td->options & NAND_BBT_ABSPAGE) {
                res = read_abs_bbts(mtd, buf, td, md);
        } else {
@@ -1215,15 +1181,15 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 
 /**
  * nand_update_bbt - [NAND Interface] update bad block table(s)
- * @mtd:       MTD device structure
- * @offs:      the offset of the newly marked block
+ * @mtd: MTD device structure
+ * @offs: the offset of the newly marked block
  *
- * The function updates the bad block table(s)
-*/
+ * The function updates the bad block table(s).
+ */
 int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 {
        struct nand_chip *this = mtd->priv;
-       int len, res = 0, writeops = 0;
+       int len, res = 0;
        int chip, chipsel;
        uint8_t *buf;
        struct nand_bbt_descr *td = this->bbt_td;
@@ -1236,14 +1202,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        len = (1 << this->bbt_erase_shift);
        len += (len >> this->page_shift) * mtd->oobsize;
        buf = kmalloc(len, GFP_KERNEL);
-       if (!buf) {
-               printk(KERN_ERR "nand_update_bbt: Out of memory\n");
+       if (!buf)
                return -ENOMEM;
-       }
-
-       writeops = md != NULL ? 0x03 : 0x01;
 
-       /* Do we have a bbt per chip ? */
+       /* Do we have a bbt per chip? */
        if (td->options & NAND_BBT_PERCHIP) {
                chip = (int)(offs >> this->chip_shift);
                chipsel = chip;
@@ -1256,14 +1218,14 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        if (md)
                md->version[chip]++;
 
-       /* Write the bad block table to the device ? */
-       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
+       /* Write the bad block table to the device? */
+       if (td->options & NAND_BBT_WRITE) {
                res = write_bbt(mtd, buf, td, md, chipsel);
                if (res < 0)
                        goto out;
        }
-       /* Write the mirror bad block table to the device ? */
-       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
+       /* Write the mirror bad block table to the device? */
+       if (md && (md->options & NAND_BBT_WRITE)) {
                res = write_bbt(mtd, buf, md, td, chipsel);
        }
 
@@ -1272,8 +1234,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
        return res;
 }
 
-/* Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks. */
+/*
+ * Define some generic bad / good block scan pattern which are used
+ * while scanning a device for factory marked good / bad blocks.
+ */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
@@ -1285,8 +1249,7 @@ static struct nand_bbt_descr agand_flashbased = {
        .pattern = scan_agand_pattern
 };
 
-/* Generic flash bbt decriptors
-*/
+/* Generic flash bbt descriptors */
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
 static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
 
@@ -1330,31 +1293,27 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
        .pattern = mirror_pattern
 };
 
-#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
-               NAND_BBT_SCANBYTE1AND6)
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
 /**
- * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
- * @this:      NAND chip to create descriptor for
+ * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure
+ * @this: NAND chip to create descriptor for
  *
  * This function allocates and initializes a nand_bbt_descr for BBM detection
- * based on the properties of "this". The new descriptor is stored in
+ * based on the properties of @this. The new descriptor is stored in
  * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
  * passed to this function.
- *
  */
-static int nand_create_default_bbt_descr(struct nand_chip *this)
+static int nand_create_badblock_pattern(struct nand_chip *this)
 {
        struct nand_bbt_descr *bd;
        if (this->badblock_pattern) {
-               printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
+               pr_warn("Bad block pattern already allocated; not replacing\n");
                return -EINVAL;
        }
        bd = kzalloc(sizeof(*bd), GFP_KERNEL);
-       if (!bd) {
-               printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
+       if (!bd)
                return -ENOMEM;
-       }
-       bd->options = this->options & BBT_SCAN_OPTIONS;
+       bd->options = this->bbt_options & BADBLOCK_SCAN_MASK;
        bd->offs = this->badblockpos;
        bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
        bd->pattern = scan_ff_pattern;
@@ -1365,22 +1324,20 @@ static int nand_create_default_bbt_descr(struct nand_chip *this)
 
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
- * @mtd:       MTD device structure
- *
- * This function selects the default bad block table
- * support for the device and calls the nand_scan_bbt function
+ * @mtd: MTD device structure
  *
-*/
+ * This function selects the default bad block table support for the device and
+ * calls the nand_scan_bbt function.
+ */
 int nand_default_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *this = mtd->priv;
 
-       /* Default for AG-AND. We must use a flash based
-        * bad block table as the devices have factory marked
-        * _good_ blocks. Erasing those blocks leads to loss
-        * of the good / bad information, so we _must_ store
-        * this information in a good / bad table during
-        * startup
+       /*
+        * Default for AG-AND. We must use a flash based bad block table as the
+        * devices have factory marked _good_ blocks. Erasing those blocks
+        * leads to loss of the good / bad information, so we _must_ store this
+        * information in a good / bad table during startup.
         */
        if (this->options & NAND_IS_AND) {
                /* Use the default pattern descriptors */
@@ -1388,15 +1345,15 @@ int nand_default_bbt(struct mtd_info *mtd)
                        this->bbt_td = &bbt_main_descr;
                        this->bbt_md = &bbt_mirror_descr;
                }
-               this->options |= NAND_USE_FLASH_BBT;
+               this->bbt_options |= NAND_BBT_USE_FLASH;
                return nand_scan_bbt(mtd, &agand_flashbased);
        }
 
-       /* Is a flash based bad block table requested ? */
-       if (this->options & NAND_USE_FLASH_BBT) {
+       /* Is a flash based bad block table requested? */
+       if (this->bbt_options & NAND_BBT_USE_FLASH) {
                /* Use the default pattern descriptors */
                if (!this->bbt_td) {
-                       if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
+                       if (this->bbt_options & NAND_BBT_NO_OOB) {
                                this->bbt_td = &bbt_main_no_bbt_descr;
                                this->bbt_md = &bbt_mirror_no_bbt_descr;
                        } else {
@@ -1410,18 +1367,17 @@ int nand_default_bbt(struct mtd_info *mtd)
        }
 
        if (!this->badblock_pattern)
-               nand_create_default_bbt_descr(this);
+               nand_create_badblock_pattern(this);
 
        return nand_scan_bbt(mtd, this->badblock_pattern);
 }
 
 /**
  * nand_isbad_bbt - [NAND Interface] Check if a block is bad
- * @mtd:       MTD device structure
- * @offs:      offset in the device
- * @allowbbt:  allow access to bad block table region
- *
-*/
+ * @mtd: MTD device structure
+ * @offs: offset in the device
+ * @allowbbt: allow access to bad block table region
+ */
 int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 {
        struct nand_chip *this = mtd->priv;
@@ -1432,8 +1388,9 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
        block = (int)(offs >> (this->bbt_erase_shift - 1));
        res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
-             (unsigned int)offs, block >> 1, res);
+       pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: "
+                       "(block %d) 0x%02x\n",
+                       (unsigned int)offs, block >> 1, res);
 
        switch ((int)res) {
        case 0x00:
index 0f931e757116fa73b904c2783e46c29cc5a1312b..3803e0bba23be42444b8ab229052478a21bccabd 100644 (file)
@@ -93,8 +93,8 @@ int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
                                buf[errloc[i] >> 3] ^= (1 << (errloc[i] & 7));
                        /* else error in ecc, no action needed */
 
-                       DEBUG(MTD_DEBUG_LEVEL0, "%s: corrected bitflip %u\n",
-                             __func__, errloc[i]);
+                       pr_debug("%s: corrected bitflip %u\n", __func__,
+                                       errloc[i]);
                }
        } else if (count < 0) {
                printk(KERN_ERR "ecc unrecoverable error\n");
index 271b8e735e8fa1ea21f64a0751d5ab94e147c398..b7cfe0d37121c8bdf78e5147f1cbed41c90b2f0c 100644 (file)
@@ -110,7 +110,7 @@ static const char bitsperbyte[256] = {
 
 /*
  * addressbits is a lookup table to filter out the bits from the xor-ed
- * ecc data that identify the faulty location.
+ * ECC data that identify the faulty location.
  * this is only used for repairing parity
  * see the comments in nand_correct_data for more details
  */
@@ -153,7 +153,7 @@ static const char addressbits[256] = {
  * __nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
  *                      block
  * @buf:       input buffer with raw data
- * @eccsize:   data bytes per ecc step (256 or 512)
+ * @eccsize:   data bytes per ECC step (256 or 512)
  * @code:      output buffer with ECC
  */
 void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
@@ -348,7 +348,7 @@ void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize,
                rp17 = (par ^ rp16) & 0xff;
 
        /*
-        * Finally calculate the ecc bits.
+        * Finally calculate the ECC bits.
         * Again here it might seem that there are performance optimisations
         * possible, but benchmarks showed that on the system this is developed
         * the code below is the fastest
@@ -436,7 +436,7 @@ EXPORT_SYMBOL(nand_calculate_ecc);
  * @buf:       raw data read from the chip
  * @read_ecc:  ECC from the chip
  * @calc_ecc:  the ECC calculated from raw data
- * @eccsize:   data bytes per ecc step (256 or 512)
+ * @eccsize:   data bytes per ECC step (256 or 512)
  *
  * Detect and correct a 1 bit error for eccsize byte block
  */
@@ -505,7 +505,7 @@ int __nand_correct_data(unsigned char *buf,
        }
        /* count nr of bits; use table lookup, faster than calculating it */
        if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
-               return 1;       /* error in ecc data; no action needed */
+               return 1;       /* error in ECC data; no action needed */
 
        printk(KERN_ERR "uncorrectable error : ");
        return -1;
index 357e8c5252a8c38df3d8ba3885a7fc948b34303c..34c03be7730105c3a26867637700f8c0ade83219 100644 (file)
@@ -2273,9 +2273,9 @@ static int __init ns_init_module(void)
 
        switch (bbt) {
        case 2:
-                chip->options |= NAND_USE_FLASH_BBT_NO_OOB;
+                chip->bbt_options |= NAND_BBT_NO_OOB;
        case 1:
-                chip->options |= NAND_USE_FLASH_BBT;
+                chip->bbt_options |= NAND_BBT_USE_FLASH;
        case 0:
                break;
        default:
index ea2dea8a9c88b6f72e8b59fcd724b085617abfca..ee1713907b92b0684a64de524ca564214699f705 100644 (file)
@@ -42,7 +42,6 @@ struct ndfc_controller {
        struct nand_chip chip;
        int chip_select;
        struct nand_hw_control ndfc_control;
-       struct mtd_partition *parts;
 };
 
 static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];
@@ -159,13 +158,9 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 static int ndfc_chip_init(struct ndfc_controller *ndfc,
                          struct device_node *node)
 {
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       static const char *part_types[] = { "cmdlinepart", NULL };
-#else
-       static const char *part_types[] = { NULL };
-#endif
        struct device_node *flash_np;
        struct nand_chip *chip = &ndfc->chip;
+       struct mtd_part_parser_data ppdata;
        int ret;
 
        chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
@@ -193,6 +188,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
        if (!flash_np)
                return -ENODEV;
 
+       ppdata->of_node = flash_np;
        ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
                        dev_name(&ndfc->ofdev->dev), flash_np->name);
        if (!ndfc->mtd.name) {
@@ -204,18 +200,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
        if (ret)
                goto err;
 
-       ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);
-       if (ret < 0)
-               goto err;
-
-       if (ret == 0) {
-               ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,
-                                             &ndfc->parts);
-               if (ret < 0)
-                       goto err;
-       }
-
-       ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret);
+       ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0);
 
 err:
        of_node_put(flash_np);
@@ -288,6 +273,7 @@ static int __devexit ndfc_remove(struct platform_device *ofdev)
        struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev);
 
        nand_release(&ndfc->mtd);
+       kfree(ndfc->mtd.name);
 
        return 0;
 }
index b6a5c86ab31e922e1ddcf81dc88257012d61ad08..b463ecfb4c1a248713073ab019efed1af2f3d538 100644 (file)
@@ -187,6 +187,7 @@ static int nomadik_nand_remove(struct platform_device *pdev)
                pdata->exit();
 
        if (host) {
+               nand_release(&host->mtd);
                iounmap(host->cmd_va);
                iounmap(host->data_va);
                iounmap(host->addr_va);
index 9c30a0b031715f5d8a26dfd3fb3abbb7418adb6f..fa8faedfad6ee086d15bad4d249b3b0bd0874991 100644 (file)
@@ -339,6 +339,7 @@ static int __devexit nuc900_nand_remove(struct platform_device *pdev)
        struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);
        struct resource *res;
 
+       nand_release(&nuc900_nand->mtd);
        iounmap(nuc900_nand->reg);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
index 0db2c0e7656ae7abbde5536ca8c842a465482696..f745f00f3167d455f3d802a0b5ea9dc82a66b617 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/sched.h>
@@ -94,8 +95,6 @@
 #define P4e_s(a)       (TF(a & NAND_Ecc_P4e)           << 0)
 #define P4o_s(a)       (TF(a & NAND_Ecc_P4o)           << 1)
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -114,7 +113,6 @@ struct omap_nand_info {
        struct nand_hw_control          controller;
        struct omap_nand_platform_data  *pdata;
        struct mtd_info                 mtd;
-       struct mtd_partition            *parts;
        struct nand_chip                nand;
        struct platform_device          *pdev;
 
@@ -744,12 +742,12 @@ static int omap_compare_ecc(u8 *ecc_data1,        /* read from NAND memory */
 
        case 1:
                /* Uncorrectable error */
-               DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
+               pr_debug("ECC UNCORRECTED_ERROR 1\n");
                return -1;
 
        case 11:
                /* UN-Correctable error */
-               DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR B\n");
+               pr_debug("ECC UNCORRECTED_ERROR B\n");
                return -1;
 
        case 12:
@@ -766,8 +764,8 @@ static int omap_compare_ecc(u8 *ecc_data1,  /* read from NAND memory */
 
                find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
 
-               DEBUG(MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at "
-                               "offset: %d, bit: %d\n", find_byte, find_bit);
+               pr_debug("Correcting single bit ECC error at offset: "
+                               "%d, bit: %d\n", find_byte, find_bit);
 
                page_data[find_byte] ^= (1 << find_bit);
 
@@ -779,7 +777,7 @@ static int omap_compare_ecc(u8 *ecc_data1,  /* read from NAND memory */
                            ecc_data2[2] == 0)
                                return 0;
                }
-               DEBUG(MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
+               pr_debug("UNCORRECTED_ERROR default\n");
                return -1;
        }
 }
@@ -1103,13 +1101,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
                goto out_release_mem_region;
        }
 
-       err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
-       if (err > 0)
-               mtd_device_register(&info->mtd, info->parts, err);
-       else if (pdata->parts)
-               mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
-       else
-               mtd_device_register(&info->mtd, NULL, 0);
+       mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata->parts, pdata->nr_parts);
 
        platform_set_drvdata(pdev, &info->mtd);
 
index 7794d0680f913b87932ba28d20729e642db382fb..29f505adaf8411581fcbb8d78d09935bef07f36d 100644 (file)
@@ -21,8 +21,6 @@
 #include <mach/hardware.h>
 #include <plat/orion_nand.h>
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
        struct nand_chip *nc = mtd->priv;
@@ -81,8 +79,6 @@ static int __init orion_nand_probe(struct platform_device *pdev)
        struct resource *res;
        void __iomem *io_base;
        int ret = 0;
-       struct mtd_partition *partitions = NULL;
-       int num_part = 0;
 
        nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);
        if (!nc) {
@@ -132,17 +128,9 @@ static int __init orion_nand_probe(struct platform_device *pdev)
                goto no_dev;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
        mtd->name = "orion_nand";
-       num_part = parse_mtd_partitions(mtd, part_probes, &partitions, 0);
-#endif
-       /* If cmdline partitions have been passed, let them be used */
-       if (num_part <= 0) {
-               num_part = board->nr_parts;
-               partitions = board->parts;
-       }
-
-       ret = mtd_device_register(mtd, partitions, num_part);
+       ret = mtd_device_parse_register(mtd, NULL, 0,
+                       board->parts, board->nr_parts);
        if (ret) {
                nand_release(mtd);
                goto no_dev;
index b1aa41b8a4eb6cd0d660d7c38eef8d1be00c0190..a97264ececdbe2278edf20b11a2d072bd38feba4 100644 (file)
@@ -155,7 +155,8 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev)
        chip->ecc.mode = NAND_ECC_SOFT;
 
        /* Enable the following for a flash based bad block table */
-       chip->options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR;
+       chip->options = NAND_NO_AUTOINCR;
+       chip->bbt_options = NAND_BBT_USE_FLASH;
 
        /* Scan to find existence of the device */
        if (nand_scan(pasemi_nand_mtd, 1)) {
index 633c04bf76f6c158aa4029ab83dc6a3d7f3ddca9..ea8e1234e0e25895ed2a731ae1a0225d616468fa 100644 (file)
@@ -21,8 +21,6 @@ struct plat_nand_data {
        struct nand_chip        chip;
        struct mtd_info         mtd;
        void __iomem            *io_base;
-       int                     nr_parts;
-       struct mtd_partition    *parts;
 };
 
 /*
@@ -79,6 +77,7 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
        data->chip.read_buf = pdata->ctrl.read_buf;
        data->chip.chip_delay = pdata->chip.chip_delay;
        data->chip.options |= pdata->chip.options;
+       data->chip.bbt_options |= pdata->chip.bbt_options;
 
        data->chip.ecc.hwctl = pdata->ctrl.hwcontrol;
        data->chip.ecc.layout = pdata->chip.ecclayout;
@@ -99,23 +98,9 @@ static int __devinit plat_nand_probe(struct platform_device *pdev)
                goto out;
        }
 
-       if (pdata->chip.part_probe_types) {
-               err = parse_mtd_partitions(&data->mtd,
-                                       pdata->chip.part_probe_types,
-                                       &data->parts, 0);
-               if (err > 0) {
-                       mtd_device_register(&data->mtd, data->parts, err);
-                       return 0;
-               }
-       }
-       if (pdata->chip.set_parts)
-               pdata->chip.set_parts(data->mtd.size, &pdata->chip);
-       if (pdata->chip.partitions) {
-               data->parts = pdata->chip.partitions;
-               err = mtd_device_register(&data->mtd, data->parts,
-                       pdata->chip.nr_partitions);
-       } else
-               err = mtd_device_register(&data->mtd, NULL, 0);
+       err = mtd_device_parse_register(&data->mtd,
+                       pdata->chip.part_probe_types, 0,
+                       pdata->chip.partitions, pdata->chip.nr_partitions);
 
        if (!err)
                return err;
@@ -145,8 +130,6 @@ static int __devexit plat_nand_remove(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        nand_release(&data->mtd);
-       if (data->parts && data->parts != pdata->chip.partitions)
-               kfree(data->parts);
        if (pdata->ctrl.remove)
                pdata->ctrl.remove(pdev);
        iounmap(data->io_base);
index 3bbb796b451c7994ab754610c433333308329a88..7e52af51a1986a419e66501bc3286c1e53397651 100644 (file)
@@ -99,8 +99,6 @@ static struct mtd_partition partition_info_evb[] = {
 
 #define NUM_PARTITIONS 1
 
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
-
 /*
  *     hardware specific access to control-lines
  */
@@ -187,18 +185,12 @@ static int ppchameleonevb_device_ready(struct mtd_info *minfo)
 }
 #endif
 
-const char *part_probes[] = { "cmdlinepart", NULL };
-const char *part_probes_evb[] = { "cmdlinepart", NULL };
-
 /*
  * Main initialization routine
  */
 static int __init ppchameleonevb_init(void)
 {
        struct nand_chip *this;
-       const char *part_type = 0;
-       int mtd_parts_nb = 0;
-       struct mtd_partition *mtd_parts = 0;
        void __iomem *ppchameleon_fio_base;
        void __iomem *ppchameleonevb_fio_base;
 
@@ -281,24 +273,13 @@ static int __init ppchameleonevb_init(void)
 #endif
 
        ppchameleon_mtd->name = "ppchameleon-nand";
-       mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-
-       if (mtd_parts_nb == 0) {
-               if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
-                       mtd_parts = partition_info_me;
-               else
-                       mtd_parts = partition_info_hi;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(ppchameleon_mtd, NULL, 0,
+                       ppchameleon_mtd->size == NAND_SMALL_SIZE ?
+                               partition_info_me :
+                               partition_info_hi,
+                       NUM_PARTITIONS);
 
  nand_evb_init:
        /****************************
@@ -382,21 +363,13 @@ static int __init ppchameleonevb_init(void)
        }
 
        ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
-       mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
-       if (mtd_parts_nb > 0)
-               part_type = "command line";
-       else
-               mtd_parts_nb = 0;
-
-       if (mtd_parts_nb == 0) {
-               mtd_parts = partition_info_evb;
-               mtd_parts_nb = NUM_PARTITIONS;
-               part_type = "static";
-       }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-       mtd_device_register(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb);
+       mtd_device_parse_register(ppchameleonevb_mtd, NULL, 0,
+                       ppchameleon_mtd->size == NAND_SMALL_SIZE ?
+                               partition_info_me :
+                               partition_info_hi,
+                       NUM_PARTITIONS);
 
        /* Return happy */
        return 0;
index 1fb3b3a805818edca37ed2e07bfd8bd90b3d0f4b..9eb7f879969e31a2e5bd987bd27a5295f992516e 100644 (file)
@@ -110,6 +110,7 @@ enum {
 
 enum {
        STATE_IDLE = 0,
+       STATE_PREPARED,
        STATE_CMD_HANDLE,
        STATE_DMA_READING,
        STATE_DMA_WRITING,
@@ -120,21 +121,40 @@ enum {
        STATE_READY,
 };
 
-struct pxa3xx_nand_info {
-       struct nand_chip        nand_chip;
+struct pxa3xx_nand_host {
+       struct nand_chip        chip;
+       struct pxa3xx_nand_cmdset *cmdset;
+       struct mtd_info         *mtd;
+       void                    *info_data;
+
+       /* page size of attached chip */
+       unsigned int            page_size;
+       int                     use_ecc;
+       int                     cs;
 
+       /* calculated from pxa3xx_nand_flash data */
+       unsigned int            col_addr_cycles;
+       unsigned int            row_addr_cycles;
+       size_t                  read_id_bytes;
+
+       /* cached register value */
+       uint32_t                reg_ndcr;
+       uint32_t                ndtr0cs0;
+       uint32_t                ndtr1cs0;
+};
+
+struct pxa3xx_nand_info {
        struct nand_hw_control  controller;
        struct platform_device   *pdev;
-       struct pxa3xx_nand_cmdset *cmdset;
 
        struct clk              *clk;
        void __iomem            *mmio_base;
        unsigned long           mmio_phys;
+       struct completion       cmd_complete;
 
        unsigned int            buf_start;
        unsigned int            buf_count;
 
-       struct mtd_info         *mtd;
        /* DMA information */
        int                     drcmr_dat;
        int                     drcmr_cmd;
@@ -142,44 +162,27 @@ struct pxa3xx_nand_info {
        unsigned char           *data_buff;
        unsigned char           *oob_buff;
        dma_addr_t              data_buff_phys;
-       size_t                  data_buff_size;
        int                     data_dma_ch;
        struct pxa_dma_desc     *data_desc;
        dma_addr_t              data_desc_addr;
 
-       uint32_t                reg_ndcr;
-
-       /* saved column/page_addr during CMD_SEQIN */
-       int                     seqin_column;
-       int                     seqin_page_addr;
-
-       /* relate to the command */
+       struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
        unsigned int            state;
 
+       int                     cs;
        int                     use_ecc;        /* use HW ECC ? */
        int                     use_dma;        /* use DMA ? */
        int                     is_ready;
 
        unsigned int            page_size;      /* page size of attached chip */
        unsigned int            data_size;      /* data size in FIFO */
+       unsigned int            oob_size;
        int                     retcode;
-       struct completion       cmd_complete;
 
        /* generated NDCBx register values */
        uint32_t                ndcb0;
        uint32_t                ndcb1;
        uint32_t                ndcb2;
-
-       /* timing calcuted from setting */
-       uint32_t                ndtr0cs0;
-       uint32_t                ndtr1cs0;
-
-       /* calculated from pxa3xx_nand_flash data */
-       size_t          oob_size;
-       size_t          read_id_bytes;
-
-       unsigned int    col_addr_cycles;
-       unsigned int    row_addr_cycles;
 };
 
 static int use_dma = 1;
@@ -225,7 +228,7 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 /* Define a default flash type setting serve as flash detecting only */
 #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
-const char *mtd_names[] = {"pxa3xx_nand-0", NULL};
+const char *mtd_names[] = {"pxa3xx_nand-0", "pxa3xx_nand-1", NULL};
 
 #define NDTR0_tCH(c)   (min((c), 7) << 19)
 #define NDTR0_tCS(c)   (min((c), 7) << 16)
@@ -241,9 +244,10 @@ const char *mtd_names[] = {"pxa3xx_nand-0", NULL};
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)      (int)((ns) * (clk / 1000000) / 1000)
 
-static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
+static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
                                   const struct pxa3xx_nand_timing *t)
 {
+       struct pxa3xx_nand_info *info = host->info_data;
        unsigned long nand_clk = clk_get_rate(info->clk);
        uint32_t ndtr0, ndtr1;
 
@@ -258,23 +262,24 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
                NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
                NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
 
-       info->ndtr0cs0 = ndtr0;
-       info->ndtr1cs0 = ndtr1;
+       host->ndtr0cs0 = ndtr0;
+       host->ndtr1cs0 = ndtr1;
        nand_writel(info, NDTR0CS0, ndtr0);
        nand_writel(info, NDTR1CS0, ndtr1);
 }
 
 static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
-       int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
+       struct pxa3xx_nand_host *host = info->host[info->cs];
+       int oob_enable = host->reg_ndcr & NDCR_SPARE_EN;
 
-       info->data_size = info->page_size;
+       info->data_size = host->page_size;
        if (!oob_enable) {
                info->oob_size = 0;
                return;
        }
 
-       switch (info->page_size) {
+       switch (host->page_size) {
        case 2048:
                info->oob_size = (info->use_ecc) ? 40 : 64;
                break;
@@ -292,9 +297,10 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
  */
 static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
 {
+       struct pxa3xx_nand_host *host = info->host[info->cs];
        uint32_t ndcr;
 
-       ndcr = info->reg_ndcr;
+       ndcr = host->reg_ndcr;
        ndcr |= info->use_ecc ? NDCR_ECC_EN : 0;
        ndcr |= info->use_dma ? NDCR_DMA_EN : 0;
        ndcr |= NDCR_ND_RUN;
@@ -359,7 +365,7 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
                                        DIV_ROUND_UP(info->oob_size, 4));
                break;
        default:
-               printk(KERN_ERR "%s: invalid state %d\n", __func__,
+               dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
                                info->state);
                BUG();
        }
@@ -385,7 +391,7 @@ static void start_data_dma(struct pxa3xx_nand_info *info)
                desc->dcmd |= DCMD_INCTRGADDR | DCMD_FLOWSRC;
                break;
        default:
-               printk(KERN_ERR "%s: invalid state %d\n", __func__,
+               dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
                                info->state);
                BUG();
        }
@@ -416,6 +422,15 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 {
        struct pxa3xx_nand_info *info = devid;
        unsigned int status, is_completed = 0;
+       unsigned int ready, cmd_done;
+
+       if (info->cs == 0) {
+               ready           = NDSR_FLASH_RDY;
+               cmd_done        = NDSR_CS0_CMDD;
+       } else {
+               ready           = NDSR_RDY;
+               cmd_done        = NDSR_CS1_CMDD;
+       }
 
        status = nand_readl(info, NDSR);
 
@@ -437,11 +452,11 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
                        handle_data_pio(info);
                }
        }
-       if (status & NDSR_CS0_CMDD) {
+       if (status & cmd_done) {
                info->state = STATE_CMD_DONE;
                is_completed = 1;
        }
-       if (status & NDSR_FLASH_RDY) {
+       if (status & ready) {
                info->is_ready = 1;
                info->state = STATE_READY;
        }
@@ -463,12 +478,6 @@ NORMAL_IRQ_EXIT:
        return IRQ_HANDLED;
 }
 
-static int pxa3xx_nand_dev_ready(struct mtd_info *mtd)
-{
-       struct pxa3xx_nand_info *info = mtd->priv;
-       return (nand_readl(info, NDSR) & NDSR_RDY) ? 1 : 0;
-}
-
 static inline int is_buf_blank(uint8_t *buf, size_t len)
 {
        for (; len > 0; len--)
@@ -481,10 +490,12 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                uint16_t column, int page_addr)
 {
        uint16_t cmd;
-       int addr_cycle, exec_cmd, ndcb0;
-       struct mtd_info *mtd = info->mtd;
+       int addr_cycle, exec_cmd;
+       struct pxa3xx_nand_host *host;
+       struct mtd_info *mtd;
 
-       ndcb0 = 0;
+       host = info->host[info->cs];
+       mtd = host->mtd;
        addr_cycle = 0;
        exec_cmd = 1;
 
@@ -495,6 +506,10 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
        info->use_ecc           = 0;
        info->is_ready          = 0;
        info->retcode           = ERR_NONE;
+       if (info->cs != 0)
+               info->ndcb0 = NDCB0_CSEL;
+       else
+               info->ndcb0 = 0;
 
        switch (command) {
        case NAND_CMD_READ0:
@@ -512,20 +527,19 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
        }
 
-       info->ndcb0 = ndcb0;
-       addr_cycle = NDCB0_ADDR_CYC(info->row_addr_cycles
-                                   + info->col_addr_cycles);
+       addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
+                                   + host->col_addr_cycles);
 
        switch (command) {
        case NAND_CMD_READOOB:
        case NAND_CMD_READ0:
-               cmd = info->cmdset->read1;
+               cmd = host->cmdset->read1;
                if (command == NAND_CMD_READOOB)
                        info->buf_start = mtd->writesize + column;
                else
                        info->buf_start = column;
 
-               if (unlikely(info->page_size < PAGE_CHUNK_SIZE))
+               if (unlikely(host->page_size < PAGE_CHUNK_SIZE))
                        info->ndcb0 |= NDCB0_CMD_TYPE(0)
                                        | addr_cycle
                                        | (cmd & NDCB0_CMD1_MASK);
@@ -537,7 +551,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
        case NAND_CMD_SEQIN:
                /* small page addr setting */
-               if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) {
+               if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) {
                        info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
                                        | (column & 0xFF);
 
@@ -564,7 +578,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                        break;
                }
 
-               cmd = info->cmdset->program;
+               cmd = host->cmdset->program;
                info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
                                | NDCB0_AUTO_RS
                                | NDCB0_ST_ROW_EN
@@ -574,8 +588,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
 
        case NAND_CMD_READID:
-               cmd = info->cmdset->read_id;
-               info->buf_count = info->read_id_bytes;
+               cmd = host->cmdset->read_id;
+               info->buf_count = host->read_id_bytes;
                info->ndcb0 |= NDCB0_CMD_TYPE(3)
                                | NDCB0_ADDR_CYC(1)
                                | cmd;
@@ -583,7 +597,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                info->data_size = 8;
                break;
        case NAND_CMD_STATUS:
-               cmd = info->cmdset->read_status;
+               cmd = host->cmdset->read_status;
                info->buf_count = 1;
                info->ndcb0 |= NDCB0_CMD_TYPE(4)
                                | NDCB0_ADDR_CYC(1)
@@ -593,7 +607,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
                break;
 
        case NAND_CMD_ERASE1:
-               cmd = info->cmdset->erase;
+               cmd = host->cmdset->erase;
                info->ndcb0 |= NDCB0_CMD_TYPE(2)
                                | NDCB0_AUTO_RS
                                | NDCB0_ADDR_CYC(3)
@@ -604,7 +618,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
                break;
        case NAND_CMD_RESET:
-               cmd = info->cmdset->reset;
+               cmd = host->cmdset->reset;
                info->ndcb0 |= NDCB0_CMD_TYPE(5)
                                | cmd;
 
@@ -616,8 +630,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 
        default:
                exec_cmd = 0;
-               printk(KERN_ERR "pxa3xx-nand: non-supported"
-                       " command %x\n", command);
+               dev_err(&info->pdev->dev, "non-supported command %x\n",
+                               command);
                break;
        }
 
@@ -627,7 +641,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                                int column, int page_addr)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int ret, exec_cmd;
 
        /*
@@ -635,9 +650,21 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
         * "byte" address into a "word" address appropriate
         * for indexing a word-oriented device
         */
-       if (info->reg_ndcr & NDCR_DWIDTH_M)
+       if (host->reg_ndcr & NDCR_DWIDTH_M)
                column /= 2;
 
+       /*
+        * There may be different NAND chip hooked to
+        * different chip select, so check whether
+        * chip select has been changed, if yes, reset the timing
+        */
+       if (info->cs != host->cs) {
+               info->cs = host->cs;
+               nand_writel(info, NDTR0CS0, host->ndtr0cs0);
+               nand_writel(info, NDTR1CS0, host->ndtr1cs0);
+       }
+
+       info->state = STATE_PREPARED;
        exec_cmd = prepare_command_pool(info, command, column, page_addr);
        if (exec_cmd) {
                init_completion(&info->cmd_complete);
@@ -646,12 +673,12 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                ret = wait_for_completion_timeout(&info->cmd_complete,
                                CHIP_DELAY_TIMEOUT);
                if (!ret) {
-                       printk(KERN_ERR "Wait time out!!!\n");
+                       dev_err(&info->pdev->dev, "Wait time out!!!\n");
                        /* Stop State Machine for next command cycle */
                        pxa3xx_nand_stop(info);
                }
-               info->state = STATE_IDLE;
        }
+       info->state = STATE_IDLE;
 }
 
 static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
@@ -664,7 +691,8 @@ static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
                struct nand_chip *chip, uint8_t *buf, int page)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
 
        chip->read_buf(mtd, buf, mtd->writesize);
        chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -685,6 +713,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
                 * OOB, ignore such double bit errors
                 */
                if (is_buf_blank(buf, mtd->writesize))
+                       info->retcode = ERR_NONE;
+               else
                        mtd->ecc_stats.failed++;
        }
 
@@ -693,7 +723,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 
 static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        char retval = 0xFF;
 
        if (info->buf_start < info->buf_count)
@@ -705,7 +736,8 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
 
 static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        u16 retval = 0xFFFF;
 
        if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) {
@@ -717,7 +749,8 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd)
 
 static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
 
        memcpy(buf, info->data_buff + info->buf_start, real_len);
@@ -727,7 +760,8 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 static void pxa3xx_nand_write_buf(struct mtd_info *mtd,
                const uint8_t *buf, int len)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        int real_len = min_t(size_t, len, info->buf_count - info->buf_start);
 
        memcpy(info->data_buff + info->buf_start, buf, real_len);
@@ -747,7 +781,8 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
 
 static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
 
        /* pxa3xx_nand_send_command has waited for command complete */
        if (this->state == FL_WRITING || this->state == FL_ERASING) {
@@ -770,54 +805,70 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 {
        struct platform_device *pdev = info->pdev;
        struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
+       struct pxa3xx_nand_host *host = info->host[info->cs];
        uint32_t ndcr = 0x0; /* enable all interrupts */
 
-       if (f->page_size != 2048 && f->page_size != 512)
+       if (f->page_size != 2048 && f->page_size != 512) {
+               dev_err(&pdev->dev, "Current only support 2048 and 512 size\n");
                return -EINVAL;
+       }
 
-       if (f->flash_width != 16 && f->flash_width != 8)
+       if (f->flash_width != 16 && f->flash_width != 8) {
+               dev_err(&pdev->dev, "Only support 8bit and 16 bit!\n");
                return -EINVAL;
+       }
 
        /* calculate flash information */
-       info->cmdset = &default_cmdset;
-       info->page_size = f->page_size;
-       info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+       host->cmdset = &default_cmdset;
+       host->page_size = f->page_size;
+       host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
        /* calculate addressing information */
-       info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
+       host->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
 
        if (f->num_blocks * f->page_per_block > 65536)
-               info->row_addr_cycles = 3;
+               host->row_addr_cycles = 3;
        else
-               info->row_addr_cycles = 2;
+               host->row_addr_cycles = 2;
 
        ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
-       ndcr |= (info->col_addr_cycles == 2) ? NDCR_RA_START : 0;
+       ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0;
        ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0;
        ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0;
        ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0;
        ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0;
 
-       ndcr |= NDCR_RD_ID_CNT(info->read_id_bytes);
+       ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
        ndcr |= NDCR_SPARE_EN; /* enable spare by default */
 
-       info->reg_ndcr = ndcr;
+       host->reg_ndcr = ndcr;
 
-       pxa3xx_nand_set_timing(info, f->timing);
+       pxa3xx_nand_set_timing(host, f->timing);
        return 0;
 }
 
 static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 {
+       /*
+        * We set 0 by hard coding here, for we don't support keep_config
+        * when there is more than one chip attached to the controller
+        */
+       struct pxa3xx_nand_host *host = info->host[0];
        uint32_t ndcr = nand_readl(info, NDCR);
-       info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-       /* set info fields needed to read id */
-       info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
-       info->reg_ndcr = ndcr;
-       info->cmdset = &default_cmdset;
 
-       info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
-       info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
+       if (ndcr & NDCR_PAGE_SZ) {
+               host->page_size = 2048;
+               host->read_id_bytes = 4;
+       } else {
+               host->page_size = 512;
+               host->read_id_bytes = 2;
+       }
+
+       host->reg_ndcr = ndcr & ~NDCR_INT_MASK;
+       host->cmdset = &default_cmdset;
+
+       host->ndtr0cs0 = nand_readl(info, NDTR0CS0);
+       host->ndtr1cs0 = nand_readl(info, NDTR1CS0);
 
        return 0;
 }
@@ -847,7 +898,6 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
                return -ENOMEM;
        }
 
-       info->data_buff_size = MAX_BUFF_SIZE;
        info->data_desc = (void *)info->data_buff + data_desc_offset;
        info->data_desc_addr = info->data_buff_phys + data_desc_offset;
 
@@ -855,7 +905,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
                                pxa3xx_nand_data_dma_irq, info);
        if (info->data_dma_ch < 0) {
                dev_err(&pdev->dev, "failed to request data dma\n");
-               dma_free_coherent(&pdev->dev, info->data_buff_size,
+               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
                                info->data_buff, info->data_buff_phys);
                return info->data_dma_ch;
        }
@@ -865,24 +915,28 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 
 static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 {
-       struct mtd_info *mtd = info->mtd;
-       struct nand_chip *chip = mtd->priv;
-
+       struct mtd_info *mtd;
+       int ret;
+       mtd = info->host[info->cs]->mtd;
        /* use the common timing to make a try */
-       pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
-       chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+       ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
+       if (ret)
+               return ret;
+
+       pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
        if (info->is_ready)
-               return 1;
-       else
                return 0;
+
+       return -ENODEV;
 }
 
 static int pxa3xx_nand_scan(struct mtd_info *mtd)
 {
-       struct pxa3xx_nand_info *info = mtd->priv;
+       struct pxa3xx_nand_host *host = mtd->priv;
+       struct pxa3xx_nand_info *info = host->info_data;
        struct platform_device *pdev = info->pdev;
        struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
-       struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} };
+       struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL;
        const struct pxa3xx_nand_flash *f = NULL;
        struct nand_chip *chip = mtd->priv;
        uint32_t id = -1;
@@ -893,22 +947,20 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
                goto KEEP_CONFIG;
 
        ret = pxa3xx_nand_sensing(info);
-       if (!ret) {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_INFO "There is no nand chip on cs 0!\n");
+       if (ret) {
+               dev_info(&info->pdev->dev, "There is no chip on cs %d!\n",
+                        info->cs);
 
-               return -EINVAL;
+               return ret;
        }
 
        chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0);
        id = *((uint16_t *)(info->data_buff));
        if (id != 0)
-               printk(KERN_INFO "Detect a flash id %x\n", id);
+               dev_info(&info->pdev->dev, "Detect a flash id %x\n", id);
        else {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_WARNING "Read out ID 0, potential timing set wrong!!\n");
+               dev_warn(&info->pdev->dev,
+                        "Read out ID 0, potential timing set wrong!!\n");
 
                return -EINVAL;
        }
@@ -926,14 +978,17 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        }
 
        if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) {
-               kfree(mtd);
-               info->mtd = NULL;
-               printk(KERN_ERR "ERROR!! flash not defined!!!\n");
+               dev_err(&info->pdev->dev, "ERROR!! flash not defined!!!\n");
 
                return -EINVAL;
        }
 
-       pxa3xx_nand_config_flash(info, f);
+       ret = pxa3xx_nand_config_flash(info, f);
+       if (ret) {
+               dev_err(&info->pdev->dev, "ERROR! Configure failed\n");
+               return ret;
+       }
+
        pxa3xx_flash_ids[0].name = f->name;
        pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff;
        pxa3xx_flash_ids[0].pagesize = f->page_size;
@@ -942,62 +997,78 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
        pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block;
        if (f->flash_width == 16)
                pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16;
+       pxa3xx_flash_ids[1].name = NULL;
+       def = pxa3xx_flash_ids;
 KEEP_CONFIG:
-       if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids))
+       chip->ecc.mode = NAND_ECC_HW;
+       chip->ecc.size = host->page_size;
+
+       chip->options = NAND_NO_AUTOINCR;
+       chip->options |= NAND_NO_READRDY;
+       if (host->reg_ndcr & NDCR_DWIDTH_M)
+               chip->options |= NAND_BUSWIDTH_16;
+
+       if (nand_scan_ident(mtd, 1, def))
                return -ENODEV;
        /* calculate addressing information */
-       info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1;
+       if (mtd->writesize >= 2048)
+               host->col_addr_cycles = 2;
+       else
+               host->col_addr_cycles = 1;
+
        info->oob_buff = info->data_buff + mtd->writesize;
        if ((mtd->size >> chip->page_shift) > 65536)
-               info->row_addr_cycles = 3;
+               host->row_addr_cycles = 3;
        else
-               info->row_addr_cycles = 2;
-       mtd->name = mtd_names[0];
-       chip->ecc.mode = NAND_ECC_HW;
-       chip->ecc.size = f->page_size;
-
-       chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0;
-       chip->options |= NAND_NO_AUTOINCR;
-       chip->options |= NAND_NO_READRDY;
+               host->row_addr_cycles = 2;
 
+       mtd->name = mtd_names[0];
        return nand_scan_tail(mtd);
 }
 
-static
-struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
+static int alloc_nand_resource(struct platform_device *pdev)
 {
+       struct pxa3xx_nand_platform_data *pdata;
        struct pxa3xx_nand_info *info;
+       struct pxa3xx_nand_host *host;
        struct nand_chip *chip;
        struct mtd_info *mtd;
        struct resource *r;
-       int ret, irq;
+       int ret, irq, cs;
 
-       mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info),
-                       GFP_KERNEL);
-       if (!mtd) {
+       pdata = pdev->dev.platform_data;
+       info = kzalloc(sizeof(*info) + (sizeof(*mtd) +
+                      sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
+       if (!info) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
-               return NULL;
+               return -ENOMEM;
        }
 
-       info = (struct pxa3xx_nand_info *)(&mtd[1]);
-       chip = (struct nand_chip *)(&mtd[1]);
        info->pdev = pdev;
-       info->mtd = mtd;
-       mtd->priv = info;
-       mtd->owner = THIS_MODULE;
-
-       chip->ecc.read_page     = pxa3xx_nand_read_page_hwecc;
-       chip->ecc.write_page    = pxa3xx_nand_write_page_hwecc;
-       chip->controller        = &info->controller;
-       chip->waitfunc          = pxa3xx_nand_waitfunc;
-       chip->select_chip       = pxa3xx_nand_select_chip;
-       chip->dev_ready         = pxa3xx_nand_dev_ready;
-       chip->cmdfunc           = pxa3xx_nand_cmdfunc;
-       chip->read_word         = pxa3xx_nand_read_word;
-       chip->read_byte         = pxa3xx_nand_read_byte;
-       chip->read_buf          = pxa3xx_nand_read_buf;
-       chip->write_buf         = pxa3xx_nand_write_buf;
-       chip->verify_buf        = pxa3xx_nand_verify_buf;
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = (struct mtd_info *)((unsigned int)&info[1] +
+                     (sizeof(*mtd) + sizeof(*host)) * cs);
+               chip = (struct nand_chip *)(&mtd[1]);
+               host = (struct pxa3xx_nand_host *)chip;
+               info->host[cs] = host;
+               host->mtd = mtd;
+               host->cs = cs;
+               host->info_data = info;
+               mtd->priv = host;
+               mtd->owner = THIS_MODULE;
+
+               chip->ecc.read_page     = pxa3xx_nand_read_page_hwecc;
+               chip->ecc.write_page    = pxa3xx_nand_write_page_hwecc;
+               chip->controller        = &info->controller;
+               chip->waitfunc          = pxa3xx_nand_waitfunc;
+               chip->select_chip       = pxa3xx_nand_select_chip;
+               chip->cmdfunc           = pxa3xx_nand_cmdfunc;
+               chip->read_word         = pxa3xx_nand_read_word;
+               chip->read_byte         = pxa3xx_nand_read_byte;
+               chip->read_buf          = pxa3xx_nand_read_buf;
+               chip->write_buf         = pxa3xx_nand_write_buf;
+               chip->verify_buf        = pxa3xx_nand_verify_buf;
+       }
 
        spin_lock_init(&chip->controller->lock);
        init_waitqueue_head(&chip->controller->wq);
@@ -1070,13 +1141,13 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, info);
 
-       return info;
+       return 0;
 
 fail_free_buf:
        free_irq(irq, info);
        if (use_dma) {
                pxa_free_dma(info->data_dma_ch);
-               dma_free_coherent(&pdev->dev, info->data_buff_size,
+               dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
                        info->data_buff, info->data_buff_phys);
        } else
                kfree(info->data_buff);
@@ -1088,17 +1159,21 @@ fail_put_clk:
        clk_disable(info->clk);
        clk_put(info->clk);
 fail_free_mtd:
-       kfree(mtd);
-       return NULL;
+       kfree(info);
+       return ret;
 }
 
 static int pxa3xx_nand_remove(struct platform_device *pdev)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
        struct resource *r;
-       int irq;
+       int irq, cs;
 
+       if (!info)
+               return 0;
+
+       pdata = pdev->dev.platform_data;
        platform_set_drvdata(pdev, NULL);
 
        irq = platform_get_irq(pdev, 0);
@@ -1106,7 +1181,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
                free_irq(irq, info);
        if (use_dma) {
                pxa_free_dma(info->data_dma_ch);
-               dma_free_writecombine(&pdev->dev, info->data_buff_size,
+               dma_free_writecombine(&pdev->dev, MAX_BUFF_SIZE,
                                info->data_buff, info->data_buff_phys);
        } else
                kfree(info->data_buff);
@@ -1118,10 +1193,9 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
        clk_disable(info->clk);
        clk_put(info->clk);
 
-       if (mtd) {
-               mtd_device_unregister(mtd);
-               kfree(mtd);
-       }
+       for (cs = 0; cs < pdata->num_cs; cs++)
+               nand_release(info->host[cs]->mtd);
+       kfree(info);
        return 0;
 }
 
@@ -1129,6 +1203,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 {
        struct pxa3xx_nand_platform_data *pdata;
        struct pxa3xx_nand_info *info;
+       int ret, cs, probe_success;
 
        pdata = pdev->dev.platform_data;
        if (!pdata) {
@@ -1136,52 +1211,88 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       info = alloc_nand_resource(pdev);
-       if (info == NULL)
-               return -ENOMEM;
-
-       if (pxa3xx_nand_scan(info->mtd)) {
-               dev_err(&pdev->dev, "failed to scan nand\n");
-               pxa3xx_nand_remove(pdev);
-               return -ENODEV;
+       ret = alloc_nand_resource(pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "alloc nand resource failed\n");
+               return ret;
        }
 
-       if (mtd_has_cmdlinepart()) {
-               const char *probes[] = { "cmdlinepart", NULL };
-               struct mtd_partition *parts;
-               int nr_parts;
+       info = platform_get_drvdata(pdev);
+       probe_success = 0;
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               info->cs = cs;
+               ret = pxa3xx_nand_scan(info->host[cs]->mtd);
+               if (ret) {
+                       dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
+                               cs);
+                       continue;
+               }
 
-               nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0);
+               ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, 0,
+                               pdata->parts[cs], pdata->nr_parts[cs]);
+               if (!ret)
+                       probe_success = 1;
+       }
 
-               if (nr_parts)
-                       return mtd_device_register(info->mtd, parts, nr_parts);
+       if (!probe_success) {
+               pxa3xx_nand_remove(pdev);
+               return -ENODEV;
        }
 
-       return mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
+       return 0;
 }
 
 #ifdef CONFIG_PM
 static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
+       struct mtd_info *mtd;
+       int cs;
 
+       pdata = pdev->dev.platform_data;
        if (info->state) {
                dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
                return -EAGAIN;
        }
 
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = info->host[cs]->mtd;
+               mtd->suspend(mtd);
+       }
+
        return 0;
 }
 
 static int pxa3xx_nand_resume(struct platform_device *pdev)
 {
        struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
-       struct mtd_info *mtd = info->mtd;
+       struct pxa3xx_nand_platform_data *pdata;
+       struct mtd_info *mtd;
+       int cs;
 
-       nand_writel(info, NDTR0CS0, info->ndtr0cs0);
-       nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-       clk_enable(info->clk);
+       pdata = pdev->dev.platform_data;
+       /* We don't want to handle interrupt without calling mtd routine */
+       disable_int(info, NDCR_INT_MASK);
+
+       /*
+        * Directly set the chip select to a invalid value,
+        * then the driver would reset the timing according
+        * to current chip select at the beginning of cmdfunc
+        */
+       info->cs = 0xff;
+
+       /*
+        * As the spec says, the NDSR would be updated to 0x1800 when
+        * doing the nand_clk disable/enable.
+        * To prevent it damaging state machine of the driver, clear
+        * all status before resume
+        */
+       nand_writel(info, NDSR, NDSR_MASK);
+       for (cs = 0; cs < pdata->num_cs; cs++) {
+               mtd = info->host[cs]->mtd;
+               mtd->resume(mtd);
+       }
 
        return 0;
 }
index cae2e013c986fde685be317e1bcaeeff0a8d87e7..f20f393bfda607d84408d5a072898124365f1490 100644 (file)
@@ -1027,7 +1027,7 @@ void r852_shutdown(struct pci_dev *pci_dev)
 }
 
 #ifdef CONFIG_PM
-int r852_suspend(struct device *device)
+static int r852_suspend(struct device *device)
 {
        struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));
 
@@ -1048,7 +1048,7 @@ int r852_suspend(struct device *device)
        return 0;
 }
 
-int r852_resume(struct device *device)
+static int r852_resume(struct device *device)
 {
        struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));
 
@@ -1092,7 +1092,7 @@ static const struct pci_device_id r852_pci_id_tbl[] = {
 
 MODULE_DEVICE_TABLE(pci, r852_pci_id_tbl);
 
-SIMPLE_DEV_PM_OPS(r852_pm_ops, r852_suspend, r852_resume);
+static SIMPLE_DEV_PM_OPS(r852_pm_ops, r852_suspend, r852_resume);
 
 static struct pci_driver r852_pci_driver = {
        .name           = DRV_NAME,
index c9f9127ff7708ee06fae1bd6e159f8e0619f20e5..f309addc2fa0505137f83a7a389bcb74b4fff9e6 100644 (file)
@@ -351,7 +351,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
                return 0;
        }
 
-       /* Read the syndrom pattern from the FPGA and correct the bitorder */
+       /* Read the syndrome pattern from the FPGA and correct the bitorder */
        rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
        for (i = 0; i < 8; i++) {
                ecc[i] = bitrev8(*rs_ecc);
@@ -380,7 +380,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
        /* Let the library code do its magic. */
        res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL);
        if (res > 0) {
-               DEBUG(MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
+               pr_debug("rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res);
        }
        return res;
 }
@@ -444,7 +444,6 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
                len = mtd->writesize;
                buf = kmalloc(len, GFP_KERNEL);
                if (!buf) {
-                       printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
                        er_stat = 1;
                        goto out;
                }
index 4405468f196b076c6b97fb1366ec8fff55d684a8..868685db6712fa3c18b593b4e9a171707f68f228 100644 (file)
@@ -723,7 +723,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
 
        /* free the common resources */
 
-       if (info->clk != NULL && !IS_ERR(info->clk)) {
+       if (!IS_ERR(info->clk)) {
                s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
                clk_put(info->clk);
        }
@@ -744,26 +744,15 @@ static int s3c24xx_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
-const char *part_probes[] = { "cmdlinepart", NULL };
 static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
                                      struct s3c2410_nand_mtd *mtd,
                                      struct s3c2410_nand_set *set)
 {
-       struct mtd_partition *part_info;
-       int nr_part = 0;
+       if (set)
+               mtd->mtd.name = set->name;
 
-       if (set == NULL)
-               return mtd_device_register(&mtd->mtd, NULL, 0);
-
-       mtd->mtd.name = set->name;
-       nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0);
-
-       if (nr_part <= 0 && set->nr_partitions > 0) {
-               nr_part = set->nr_partitions;
-               part_info = set->partitions;
-       }
-
-       return mtd_device_register(&mtd->mtd, part_info, nr_part);
+       return mtd_device_parse_register(&mtd->mtd, NULL, 0,
+                       set->partitions, set->nr_partitions);
 }
 
 /**
@@ -880,8 +869,10 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
        /* If you use u-boot BBT creation code, specifying this flag will
         * let the kernel fish out the BBT from the NAND, and also skip the
         * full NAND scan that can take 1/2s or so. Little things... */
-       if (set->flash_bbt)
-               chip->options |= NAND_USE_FLASH_BBT | NAND_SKIP_BBTSCAN;
+       if (set->flash_bbt) {
+               chip->bbt_options |= NAND_BBT_USE_FLASH;
+               chip->options |= NAND_SKIP_BBTSCAN;
+       }
 }
 
 /**
index 19e24ed089ea9dd05d1bc9b4ea25dc406d5ede90..619d2a504788b050aa46cc48e0cd13c31588d921 100644 (file)
@@ -103,16 +103,12 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat,
        return readb(sharpsl->io + ECCCNTR) != 0;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /*
  * Main initialization routine
  */
 static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
 {
        struct nand_chip *this;
-       struct mtd_partition *sharpsl_partition_info;
-       int nr_partitions;
        struct resource *r;
        int err = 0;
        struct sharpsl_nand *sharpsl;
@@ -184,14 +180,9 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
 
        /* Register the partitions */
        sharpsl->mtd.name = "sharpsl-nand";
-       nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0);
-       if (nr_partitions <= 0) {
-               nr_partitions = data->nr_partitions;
-               sharpsl_partition_info = data->partitions;
-       }
 
-       err = mtd_device_register(&sharpsl->mtd, sharpsl_partition_info,
-                                 nr_partitions);
+       err = mtd_device_parse_register(&sharpsl->mtd, NULL, 0,
+                       data->partitions, data->nr_partitions);
        if (err)
                goto err_add;
 
index b6332e83b2895e798fc5220dd914b1e1a1e99602..32ae5af7444f6a28d26e02a7ff6b53efc7e31bde 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/mtd/nand.h>
+#include <linux/module.h>
 #include "sm_common.h"
 
 static struct nand_ecclayout nand_oob_sm = {
@@ -47,7 +48,7 @@ static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
 
        /* As long as this function is called on erase block boundaries
                it will work correctly for 256 byte nand */
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
        ops.oobbuf = (void *)&oob;
index ca2d0555729e466b43940043c9d044334f3719d4..0fb24f9c232772dac3c307bff2c7eb7a2d690c5f 100644 (file)
@@ -155,8 +155,6 @@ static int socrates_nand_device_ready(struct mtd_info *mtd)
        return 1;
 }
 
-static const char *part_probes[] = { "cmdlinepart", NULL };
-
 /*
  * Probe for the NAND device.
  */
@@ -166,8 +164,7 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
        struct mtd_info *mtd;
        struct nand_chip *nand_chip;
        int res;
-       struct mtd_partition *partitions = NULL;
-       int num_partitions = 0;
+       struct mtd_part_parser_data ppdata;
 
        /* Allocate memory for the device structure (and zero it) */
        host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
@@ -193,6 +190,7 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
        mtd->name = "socrates_nand";
        mtd->owner = THIS_MODULE;
        mtd->dev.parent = &ofdev->dev;
+       ppdata.of_node = ofdev->dev.of_node;
 
        /*should never be accessed directly */
        nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
@@ -225,30 +223,10 @@ static int __devinit socrates_nand_probe(struct platform_device *ofdev)
                goto out;
        }
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       num_partitions = parse_mtd_partitions(mtd, part_probes,
-                                             &partitions, 0);
-       if (num_partitions < 0) {
-               res = num_partitions;
-               goto release;
-       }
-#endif
-
-       if (num_partitions == 0) {
-               num_partitions = of_mtd_parse_partitions(&ofdev->dev,
-                                                        ofdev->dev.of_node,
-                                                        &partitions);
-               if (num_partitions < 0) {
-                       res = num_partitions;
-                       goto release;
-               }
-       }
-
-       res = mtd_device_register(mtd, partitions, num_partitions);
+       res = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
        if (!res)
                return res;
 
-release:
        nand_release(mtd);
 
 out:
index 11e8371b56834e8b0c79f64fe4d54393be849630..beebd95f76907de7e32102d0dd9a7593be99d0a7 100644 (file)
@@ -121,9 +121,6 @@ struct tmio_nand {
 
 #define mtd_to_tmio(m)                 container_of(m, struct tmio_nand, mtd)
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /*--------------------------------------------------------------------------*/
 
@@ -381,8 +378,6 @@ static int tmio_probe(struct platform_device *dev)
        struct tmio_nand *tmio;
        struct mtd_info *mtd;
        struct nand_chip *nand_chip;
-       struct mtd_partition *parts;
-       int nbparts = 0;
        int retval;
 
        if (data == NULL)
@@ -461,15 +456,9 @@ static int tmio_probe(struct platform_device *dev)
                goto err_scan;
        }
        /* Register the partitions */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-       nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
-#endif
-       if (nbparts <= 0 && data) {
-               parts = data->partition;
-               nbparts = data->num_partitions;
-       }
-
-       retval = mtd_device_register(mtd, parts, nbparts);
+       retval = mtd_device_parse_register(mtd, NULL, 0,
+                       data ? data->partition : NULL,
+                       data ? data->num_partitions : 0);
        if (!retval)
                return retval;
 
index bfba4e39a6c5cd5866d95b0fd114896489935a62..ace46fdaef58cfb3b51fc9c981e637bb7e0fd2a4 100644 (file)
@@ -74,7 +74,6 @@ struct txx9ndfmc_drvdata {
        unsigned char hold;     /* in gbusclock */
        unsigned char spw;      /* in gbusclock */
        struct nand_hw_control hw_control;
-       struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
 };
 
 static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
@@ -287,7 +286,6 @@ static int txx9ndfmc_nand_scan(struct mtd_info *mtd)
 static int __init txx9ndfmc_probe(struct platform_device *dev)
 {
        struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
-       static const char *probes[] = { "cmdlinepart", NULL };
        int hold, spw;
        int i;
        struct txx9ndfmc_drvdata *drvdata;
@@ -333,7 +331,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
                struct txx9ndfmc_priv *txx9_priv;
                struct nand_chip *chip;
                struct mtd_info *mtd;
-               int nr_parts;
 
                if (!(plat->ch_mask & (1 << i)))
                        continue;
@@ -393,9 +390,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
                }
                mtd->name = txx9_priv->mtdname;
 
-               nr_parts = parse_mtd_partitions(mtd, probes,
-                                               &drvdata->parts[i], 0);
-               mtd_device_register(mtd, drvdata->parts[i], nr_parts);
+               mtd_device_parse_register(mtd, NULL, 0, NULL, 0);
                drvdata->mtds[i] = mtd;
        }
 
@@ -421,7 +416,6 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev)
                txx9_priv = chip->priv;
 
                nand_release(mtd);
-               kfree(drvdata->parts[i]);
                kfree(txx9_priv->mtdname);
                kfree(txx9_priv);
        }
index b155666acfbe5a1c07ebfa37b1b1ec3c1140d07c..cda77b562ad43da9efd14f1cfb1ab4219583e9d8 100644 (file)
@@ -63,14 +63,12 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
        }
 
-       DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);
+       pr_debug("NFTL: add_mtd for %s\n", mtd->name);
 
        nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
 
-       if (!nftl) {
-               printk(KERN_WARNING "NFTL: out of memory for data structures\n");
+       if (!nftl)
                return;
-       }
 
        nftl->mbd.mtd = mtd;
        nftl->mbd.devnum = -1;
@@ -132,7 +130,7 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct NFTLrecord *nftl = (void *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("NFTL: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
        kfree(nftl->ReplUnitTable);
@@ -149,7 +147,7 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs & mask;
        ops.ooblen = len;
        ops.oobbuf = buf;
@@ -170,7 +168,7 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs & mask;
        ops.ooblen = len;
        ops.oobbuf = buf;
@@ -193,7 +191,7 @@ static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
        struct mtd_oob_ops ops;
        int res;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooboffs = offs & mask;
        ops.ooblen = mtd->oobsize;
        ops.oobbuf = oob;
@@ -220,7 +218,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
 
        /* Normally, we force a fold to happen before we run out of free blocks completely */
        if (!desperate && nftl->numfreeEUNs < 2) {
-               DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n");
+               pr_debug("NFTL_findfreeblock: there are too few free EUNs\n");
                return BLOCK_NIL;
        }
 
@@ -291,8 +289,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                        if (block == 2) {
                                foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
                                if (foldmark == FOLD_MARK_IN_PROGRESS) {
-                                       DEBUG(MTD_DEBUG_LEVEL1,
-                                             "Write Inhibited on EUN %d\n", thisEUN);
+                                       pr_debug("Write Inhibited on EUN %d\n", thisEUN);
                                        inplace = 0;
                                } else {
                                        /* There's no other reason not to do inplace,
@@ -357,7 +354,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                        if (BlockLastState[block] != SECTOR_FREE &&
                            BlockMap[block] != BLOCK_NIL &&
                            BlockMap[block] != targetEUN) {
-                               DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "
+                               pr_debug("Setting inplace to 0. VUC %d, "
                                      "block %d was %x lastEUN, "
                                      "and is in EUN %d (%s) %d\n",
                                      thisVUC, block, BlockLastState[block],
@@ -373,14 +370,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
                    pendingblock < ((thisVUC + 1)* (nftl->EraseSize / 512)) &&
                    BlockLastState[pendingblock - (thisVUC * (nftl->EraseSize / 512))] !=
                    SECTOR_FREE) {
-                       DEBUG(MTD_DEBUG_LEVEL1, "Pending write not free in EUN %d. "
+                       pr_debug("Pending write not free in EUN %d. "
                              "Folding out of place.\n", targetEUN);
                        inplace = 0;
                }
        }
 
        if (!inplace) {
-               DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
+               pr_debug("Cannot fold Virtual Unit Chain %d in place. "
                      "Trying out-of-place\n", thisVUC);
                /* We need to find a targetEUN to fold into. */
                targetEUN = NFTL_findfreeblock(nftl, 1);
@@ -410,7 +407,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
           and the Erase Unit into which we are supposed to be copying.
           Go for it.
        */
-       DEBUG(MTD_DEBUG_LEVEL1,"Folding chain %d into unit %d\n", thisVUC, targetEUN);
+       pr_debug("Folding chain %d into unit %d\n", thisVUC, targetEUN);
        for (block = 0; block < nftl->EraseSize / 512 ; block++) {
                unsigned char movebuf[512];
                int ret;
@@ -428,7 +425,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
 
                ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
                                512, &retlen, movebuf);
-               if (ret < 0 && ret != -EUCLEAN) {
+               if (ret < 0 && !mtd_is_bitflip(ret)) {
                        ret = mtd->read(mtd, (nftl->EraseSize * BlockMap[block])
                                        + (block * 512), 512, &retlen,
                                        movebuf);
@@ -457,7 +454,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
           has duplicate chains, we need to free one of the chains because it's not necessary any more.
        */
        thisEUN = nftl->EUNtable[thisVUC];
-       DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
+       pr_debug("Want to erase\n");
 
        /* For each block in the old chain (except the targetEUN of course),
           free it and make it available for future use */
@@ -570,7 +567,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
                                      (writeEUN * nftl->EraseSize) + blockofs,
                                      8, &retlen, (char *)&bci);
 
-                       DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
+                       pr_debug("Status of block %d in EUN %d is %x\n",
                              block , writeEUN, le16_to_cpu(bci.Status));
 
                        status = bci.Status | bci.Status1;
@@ -623,7 +620,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
                                   but they are reserved for when we're
                                   desperate. Well, now we're desperate.
                                */
-                               DEBUG(MTD_DEBUG_LEVEL1, "Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC);
+                               pr_debug("Using desperate==1 to find free EUN to accommodate write to VUC %d\n", thisVUC);
                                writeEUN = NFTL_findfreeblock(nftl, 1);
                        }
                        if (writeEUN == BLOCK_NIL) {
@@ -776,7 +773,7 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
                size_t retlen;
                int res = mtd->read(mtd, ptr, 512, &retlen, buffer);
 
-               if (res < 0 && res != -EUCLEAN)
+               if (res < 0 && !mtd_is_bitflip(res))
                        return -EIO;
        }
        return 0;
index e3cd1ffad2f624c203237068847a5643c3254941..ac4092591aea035068e169900b099ca8121c2185 100644 (file)
@@ -32,7 +32,7 @@
 
 /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
  *     various device information of the NFTL partition and Bad Unit Table. Update
- *     the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
+ *     the ReplUnitTable[] table according to the Bad Unit Table. ReplUnitTable[]
  *     is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
  */
 static int find_boot_record(struct NFTLrecord *nftl)
@@ -297,7 +297,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
  *
  * Return: 0 when succeed, -1 on error.
  *
- *  ToDo: 1. Is it neceressary to check_free_sector after erasing ??
+ *  ToDo: 1. Is it necessary to check_free_sector after erasing ??
  */
 int NFTL_formatblock(struct NFTLrecord *nftl, int block)
 {
@@ -337,7 +337,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
                nb_erases = le32_to_cpu(uci.WearInfo);
                nb_erases++;
 
-               /* wrap (almost impossible with current flashs) or free block */
+               /* wrap (almost impossible with current flash) or free block */
                if (nb_erases == 0)
                        nb_erases = 1;
 
@@ -363,10 +363,10 @@ fail:
  *     Mark as 'IGNORE' each incorrect sector. This check is only done if the chain
  *     was being folded when NFTL was interrupted.
  *
- *     The check_free_sectors in this function is neceressary. There is a possible
+ *     The check_free_sectors in this function is necessary. There is a possible
  *     situation that after writing the Data area, the Block Control Information is
  *     not updated according (due to power failure or something) which leaves the block
- *     in an umconsistent state. So we have to check if a block is really FREE in this
+ *     in an inconsistent state. So we have to check if a block is really FREE in this
  *     case. */
 static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
 {
@@ -428,7 +428,7 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
 
        for (;;) {
                length++;
-               /* avoid infinite loops, although this is guaranted not to
+               /* avoid infinite loops, although this is guaranteed not to
                   happen because of the previous checks */
                if (length >= nftl->nb_blocks) {
                        printk("nftl: length too long %d !\n", length);
@@ -447,11 +447,11 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
 /* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a
  *     Virtual Unit Chain, i.e. all the units are disconnected.
  *
- *     It is not stricly correct to begin from the first block of the chain because
+ *     It is not strictly correct to begin from the first block of the chain because
  *     if we stop the code, we may see again a valid chain if there was a first_block
  *     flag in a block inside it. But is it really a problem ?
  *
- * FixMe: Figure out what the last statesment means. What if power failure when we are
+ * FixMe: Figure out what the last statement means. What if power failure when we are
  *     in the for (;;) loop formatting blocks ??
  */
 static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
@@ -485,7 +485,7 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
  *     totally free (only 0xff).
  *
  * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the
- *     following critia:
+ *     following criteria:
  *     1. */
 static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 {
@@ -502,7 +502,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
        erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
        if (erase_mark != ERASE_MARK) {
                /* if no erase mark, the block must be totally free. This is
-                  possible in two cases : empty filsystem or interrupted erase (very unlikely) */
+                  possible in two cases : empty filesystem or interrupted erase (very unlikely) */
                if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0)
                        return -1;
 
@@ -544,7 +544,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
 /* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS
  *     to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2
  *     is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted
- *     for some reason. A clean up/check of the VUC is neceressary in this case.
+ *     for some reason. A clean up/check of the VUC is necessary in this case.
  *
  * WARNING: return 0 if read error
  */
@@ -657,7 +657,7 @@ int NFTL_mount(struct NFTLrecord *s)
                                                printk("Block %d: incorrect logical block: %d expected: %d\n",
                                                       block, logical_block, first_logical_block);
                                                /* the chain is incorrect : we must format it,
-                                                  but we need to read it completly */
+                                                  but we need to read it completely */
                                                do_format_chain = 1;
                                        }
                                        if (is_first_block) {
@@ -669,7 +669,7 @@ int NFTL_mount(struct NFTLrecord *s)
                                                        printk("Block %d: incorrectly marked as first block in chain\n",
                                                               block);
                                                        /* the chain is incorrect : we must format it,
-                                                          but we need to read it completly */
+                                                          but we need to read it completely */
                                                        do_format_chain = 1;
                                                } else {
                                                        printk("Block %d: folding in progress - ignoring first block flag\n",
index a996718fa6b06e05607dae1f86bf01a8ff024dd5..64be8f0848b075cdccb647309ff88d12b3fa547d 100644 (file)
 #include <linux/slab.h>
 #include <linux/mtd/partitions.h>
 
-int __devinit of_mtd_parse_partitions(struct device *dev,
-                                      struct device_node *node,
-                                      struct mtd_partition **pparts)
+static int parse_ofpart_partitions(struct mtd_info *master,
+                                  struct mtd_partition **pparts,
+                                  struct mtd_part_parser_data *data)
 {
+       struct device_node *node;
        const char *partname;
        struct device_node *pp;
        int nr_parts, i;
 
+
+       if (!data)
+               return 0;
+
+       node = data->of_node;
+       if (!node)
+               return 0;
+
        /* First count the subnodes */
        pp = NULL;
        nr_parts = 0;
@@ -69,7 +78,7 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
 
        if (!i) {
                of_node_put(pp);
-               dev_err(dev, "No valid partition found on %s\n", node->full_name);
+               pr_err("No valid partition found on %s\n", node->full_name);
                kfree(*pparts);
                *pparts = NULL;
                return -EINVAL;
@@ -77,6 +86,99 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
 
        return nr_parts;
 }
-EXPORT_SYMBOL(of_mtd_parse_partitions);
+
+static struct mtd_part_parser ofpart_parser = {
+       .owner = THIS_MODULE,
+       .parse_fn = parse_ofpart_partitions,
+       .name = "ofpart",
+};
+
+static int parse_ofoldpart_partitions(struct mtd_info *master,
+                                     struct mtd_partition **pparts,
+                                     struct mtd_part_parser_data *data)
+{
+       struct device_node *dp;
+       int i, plen, nr_parts;
+       const struct {
+               __be32 offset, len;
+       } *part;
+       const char *names;
+
+       if (!data)
+               return 0;
+
+       dp = data->of_node;
+       if (!dp)
+               return 0;
+
+       part = of_get_property(dp, "partitions", &plen);
+       if (!part)
+               return 0; /* No partitions found */
+
+       pr_warning("Device tree uses obsolete partition map binding: %s\n",
+                       dp->full_name);
+
+       nr_parts = plen / sizeof(part[0]);
+
+       *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
+       if (!pparts)
+               return -ENOMEM;
+
+       names = of_get_property(dp, "partition-names", &plen);
+
+       for (i = 0; i < nr_parts; i++) {
+               (*pparts)[i].offset = be32_to_cpu(part->offset);
+               (*pparts)[i].size   = be32_to_cpu(part->len) & ~1;
+               /* bit 0 set signifies read only partition */
+               if (be32_to_cpu(part->len) & 1)
+                       (*pparts)[i].mask_flags = MTD_WRITEABLE;
+
+               if (names && (plen > 0)) {
+                       int len = strlen(names) + 1;
+
+                       (*pparts)[i].name = (char *)names;
+                       plen -= len;
+                       names += len;
+               } else {
+                       (*pparts)[i].name = "unnamed";
+               }
+
+               part++;
+       }
+
+       return nr_parts;
+}
+
+static struct mtd_part_parser ofoldpart_parser = {
+       .owner = THIS_MODULE,
+       .parse_fn = parse_ofoldpart_partitions,
+       .name = "ofoldpart",
+};
+
+static int __init ofpart_parser_init(void)
+{
+       int rc;
+       rc = register_mtd_parser(&ofpart_parser);
+       if (rc)
+               goto out;
+
+       rc = register_mtd_parser(&ofoldpart_parser);
+       if (!rc)
+               return 0;
+
+       deregister_mtd_parser(&ofoldpart_parser);
+out:
+       return rc;
+}
+
+module_init(ofpart_parser_init);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree");
+MODULE_AUTHOR("Vitaly Wool, David Gibson");
+/*
+ * When MTD core cannot find the requested parser, it tries to load the module
+ * with the same name. Since we provide the ofoldpart parser, we should have
+ * the corresponding alias.
+ */
+MODULE_ALIAS("ofoldpart");
index 2d70d354d846b6d36efb334434533445c0e21270..7813095264a56192dbd13c0948da04cfdfd5f82f 100644 (file)
  */
 #define DRIVER_NAME    "onenand-flash"
 
-static const char *part_probes[] = { "cmdlinepart", NULL,  };
-
 struct onenand_info {
        struct mtd_info         mtd;
-       struct mtd_partition    *parts;
        struct onenand_chip     onenand;
 };
 
@@ -73,13 +70,9 @@ static int __devinit generic_onenand_probe(struct platform_device *pdev)
                goto out_iounmap;
        }
 
-       err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
-       if (err > 0)
-               mtd_device_register(&info->mtd, info->parts, err);
-       else if (err <= 0 && pdata && pdata->parts)
-               mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
-       else
-               err = mtd_device_register(&info->mtd, NULL, 0);
+       err = mtd_device_parse_register(&info->mtd, NULL, 0,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
 
        platform_set_drvdata(pdev, info);
 
@@ -104,7 +97,6 @@ static int __devexit generic_onenand_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (info) {
-               mtd_device_unregister(&info->mtd);
                onenand_release(&info->mtd);
                release_mem_region(res->start, size);
                iounmap(info->onenand.base);
index 6a1d6d9a2df95454fcb7a0212be53fdaf72936b1..7e9ea6852b671d3e1b09f1c259eee49be3ecb968 100644 (file)
@@ -57,7 +57,6 @@ struct omap2_onenand {
        unsigned long phys_base;
        int gpio_irq;
        struct mtd_info mtd;
-       struct mtd_partition *parts;
        struct onenand_chip onenand;
        struct completion irq_done;
        struct completion dma_done;
@@ -67,8 +66,6 @@ struct omap2_onenand {
        struct regulator *regulator;
 };
 
-static const char *part_probes[] = { "cmdlinepart", NULL,  };
-
 static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
 {
        struct omap2_onenand *c = data;
@@ -741,6 +738,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
                c->regulator = regulator_get(&pdev->dev, "vonenand");
                if (IS_ERR(c->regulator)) {
                        dev_err(&pdev->dev,  "Failed to get regulator\n");
+                       r = PTR_ERR(c->regulator);
                        goto err_release_dma;
                }
                c->onenand.enable = omap2_onenand_enable;
@@ -753,13 +751,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
        if ((r = onenand_scan(&c->mtd, 1)) < 0)
                goto err_release_regulator;
 
-       r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0);
-       if (r > 0)
-               r = mtd_device_register(&c->mtd, c->parts, r);
-       else if (pdata->parts != NULL)
-               r = mtd_device_register(&c->mtd, pdata->parts, pdata->nr_parts);
-       else
-               r = mtd_device_register(&c->mtd, NULL, 0);
+       r = mtd_device_parse_register(&c->mtd, NULL, 0,
+                       pdata ? pdata->parts : NULL,
+                       pdata ? pdata->nr_parts : 0);
        if (r)
                goto err_release_onenand;
 
@@ -786,7 +780,6 @@ err_release_mem_region:
 err_free_cs:
        gpmc_cs_free(c->gpmc_cs);
 err_kfree:
-       kfree(c->parts);
        kfree(c);
 
        return r;
@@ -809,7 +802,6 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
        iounmap(c->onenand.base);
        release_mem_region(c->phys_base, ONENAND_IO_SIZE);
        gpmc_cs_free(c->gpmc_cs);
-       kfree(c->parts);
        kfree(c);
 
        return 0;
index ac9e959802a7b113e838ecb8d6e24aee5b7df524..a8394730b4b6fc7e9e84fcdd919e9a09c0b669da 100644 (file)
@@ -1015,7 +1015,7 @@ static void onenand_release_device(struct mtd_info *mtd)
 }
 
 /**
- * onenand_transfer_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_transfer_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd          MTD device structure
  * @param buf          destination address
  * @param column       oob offset to read from
@@ -1079,7 +1079,7 @@ static int onenand_recover_lsb(struct mtd_info *mtd, loff_t addr, int status)
                return status;
 
        /* check if we failed due to uncorrectable error */
-       if (status != -EBADMSG && status != ONENAND_BBT_READ_ECC_ERROR)
+       if (!mtd_is_eccerr(status) && status != ONENAND_BBT_READ_ECC_ERROR)
                return status;
 
        /* check if address lies in MLC region */
@@ -1122,10 +1122,10 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        int ret = 0;
        int writesize = this->writesize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-             __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1159,7 +1159,7 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        if (unlikely(ret))
                                ret = onenand_recover_lsb(mtd, from, ret);
                        onenand_update_bufferram(mtd, from, !ret);
-                       if (ret == -EBADMSG)
+                       if (mtd_is_eccerr(ret))
                                ret = 0;
                        if (ret)
                                break;
@@ -1170,7 +1170,7 @@ static int onenand_mlc_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        thisooblen = oobsize - oobcolumn;
                        thisooblen = min_t(int, thisooblen, ooblen - oobread);
 
-                       if (ops->mode == MTD_OOB_AUTO)
+                       if (ops->mode == MTD_OPS_AUTO_OOB)
                                onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
                        else
                                this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
@@ -1226,10 +1226,10 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
        int ret = 0, boundary = 0;
        int writesize = this->writesize;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-                       __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1255,7 +1255,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        this->command(mtd, ONENAND_CMD_READ, from, writesize);
                        ret = this->wait(mtd, FL_READING);
                        onenand_update_bufferram(mtd, from, !ret);
-                       if (ret == -EBADMSG)
+                       if (mtd_is_eccerr(ret))
                                ret = 0;
                }
        }
@@ -1291,7 +1291,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                        thisooblen = oobsize - oobcolumn;
                        thisooblen = min_t(int, thisooblen, ooblen - oobread);
 
-                       if (ops->mode == MTD_OOB_AUTO)
+                       if (ops->mode == MTD_OPS_AUTO_OOB)
                                onenand_transfer_auto_oob(mtd, oobbuf, oobcolumn, thisooblen);
                        else
                                this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, oobcolumn, thisooblen);
@@ -1315,7 +1315,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
                /* Now wait for load */
                ret = this->wait(mtd, FL_READING);
                onenand_update_bufferram(mtd, from, !ret);
-               if (ret == -EBADMSG)
+               if (mtd_is_eccerr(ret))
                        ret = 0;
        }
 
@@ -1351,19 +1351,19 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
        struct mtd_ecc_stats stats;
        int read = 0, thislen, column, oobsize;
        size_t len = ops->ooblen;
-       mtd_oob_mode_t mode = ops->mode;
+       unsigned int mode = ops->mode;
        u_char *buf = ops->oobbuf;
        int ret = 0, readcmd;
 
        from += ops->ooboffs;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-               __func__, (unsigned int) from, (int) len);
+       pr_debug("%s: from = 0x%08x, len = %i\n", __func__, (unsigned int)from,
+                       (int)len);
 
        /* Initialize return length value */
        ops->oobretlen = 0;
 
-       if (mode == MTD_OOB_AUTO)
+       if (mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1403,13 +1403,13 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
                if (unlikely(ret))
                        ret = onenand_recover_lsb(mtd, from, ret);
 
-               if (ret && ret != -EBADMSG) {
+               if (ret && !mtd_is_eccerr(ret)) {
                        printk(KERN_ERR "%s: read failed = 0x%x\n",
                                __func__, ret);
                        break;
                }
 
-               if (mode == MTD_OOB_AUTO)
+               if (mode == MTD_OPS_AUTO_OOB)
                        onenand_transfer_auto_oob(mtd, buf, column, thislen);
                else
                        this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
@@ -1487,10 +1487,10 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
        int ret;
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
                break;
-       case MTD_OOB_RAW:
+       case MTD_OPS_RAW:
                /* Not implemented yet */
        default:
                return -EINVAL;
@@ -1576,8 +1576,8 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
        size_t len = ops->ooblen;
        u_char *buf = ops->oobbuf;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %zi\n",
-               __func__, (unsigned int) from, len);
+       pr_debug("%s: from = 0x%08x, len = %zi\n", __func__, (unsigned int)from,
+                       len);
 
        /* Initialize return value */
        ops->oobretlen = 0;
@@ -1750,8 +1750,8 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
        /* Wait for any existing operation to clear */
        onenand_panic_wait(mtd);
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        *retlen = 0;
@@ -1821,7 +1821,7 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 }
 
 /**
- * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
+ * onenand_fill_auto_oob - [INTERN] oob auto-placement transfer
  * @param mtd          MTD device structure
  * @param oob_buf      oob buffer
  * @param buf          source address
@@ -1883,8 +1883,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
        u_char *oobbuf;
        int ret = 0, cmd;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        ops->retlen = 0;
@@ -1908,7 +1908,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
        if (!len)
                return 0;
 
-       if (ops->mode == MTD_OOB_AUTO)
+       if (ops->mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -1945,7 +1945,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
                                /* We send data to spare ram with oobsize
                                 * to prevent byte access */
                                memset(oobbuf, 0xff, mtd->oobsize);
-                               if (ops->mode == MTD_OOB_AUTO)
+                               if (ops->mode == MTD_OPS_AUTO_OOB)
                                        onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
                                else
                                        memcpy(oobbuf + oobcolumn, oob, thisooblen);
@@ -2055,7 +2055,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
 
 
 /**
- * onenand_write_oob_nolock - [Internal] OneNAND write out-of-band
+ * onenand_write_oob_nolock - [INTERN] OneNAND write out-of-band
  * @param mtd          MTD device structure
  * @param to           offset to write to
  * @param len          number of bytes to write
@@ -2074,17 +2074,17 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
        u_char *oobbuf;
        size_t len = ops->ooblen;
        const u_char *buf = ops->oobbuf;
-       mtd_oob_mode_t mode = ops->mode;
+       unsigned int mode = ops->mode;
 
        to += ops->ooboffs;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n",
-               __func__, (unsigned int) to, (int) len);
+       pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
+                       (int)len);
 
        /* Initialize retlen, in case of early exit */
        ops->oobretlen = 0;
 
-       if (mode == MTD_OOB_AUTO)
+       if (mode == MTD_OPS_AUTO_OOB)
                oobsize = this->ecclayout->oobavail;
        else
                oobsize = mtd->oobsize;
@@ -2128,7 +2128,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
                /* We send data to spare ram with oobsize
                 * to prevent byte access */
                memset(oobbuf, 0xff, mtd->oobsize);
-               if (mode == MTD_OOB_AUTO)
+               if (mode == MTD_OPS_AUTO_OOB)
                        onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
                else
                        memcpy(oobbuf + column, buf, thislen);
@@ -2217,10 +2217,10 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
        int ret;
 
        switch (ops->mode) {
-       case MTD_OOB_PLACE:
-       case MTD_OOB_AUTO:
+       case MTD_OPS_PLACE_OOB:
+       case MTD_OPS_AUTO_OOB:
                break;
-       case MTD_OOB_RAW:
+       case MTD_OPS_RAW:
                /* Not implemented yet */
        default:
                return -EINVAL;
@@ -2281,7 +2281,7 @@ static int onenand_multiblock_erase_verify(struct mtd_info *mtd,
 }
 
 /**
- * onenand_multiblock_erase - [Internal] erase block(s) using multiblock erase
+ * onenand_multiblock_erase - [INTERN] erase block(s) using multiblock erase
  * @param mtd          MTD device structure
  * @param instr                erase instruction
  * @param region       erase region
@@ -2397,7 +2397,7 @@ static int onenand_multiblock_erase(struct mtd_info *mtd,
 
 
 /**
- * onenand_block_by_block_erase - [Internal] erase block(s) using regular erase
+ * onenand_block_by_block_erase - [INTERN] erase block(s) using regular erase
  * @param mtd          MTD device structure
  * @param instr                erase instruction
  * @param region       erase region
@@ -2489,8 +2489,9 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
        struct mtd_erase_region_info *region = NULL;
        loff_t region_offset = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: start=0x%012llx, len=%llu\n", __func__,
-             (unsigned long long) instr->addr, (unsigned long long) instr->len);
+       pr_debug("%s: start=0x%012llx, len=%llu\n", __func__,
+                       (unsigned long long)instr->addr,
+                       (unsigned long long)instr->len);
 
        /* Do not allow erase past end of device */
        if (unlikely((len + addr) > mtd->size)) {
@@ -2558,7 +2559,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
  */
 static void onenand_sync(struct mtd_info *mtd)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "%s: called\n", __func__);
+       pr_debug("%s: called\n", __func__);
 
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_SYNCING);
@@ -2602,7 +2603,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
        struct bbm_info *bbm = this->bbm;
        u_char buf[2] = {0, 0};
        struct mtd_oob_ops ops = {
-               .mode = MTD_OOB_PLACE,
+               .mode = MTD_OPS_PLACE_OOB,
                .ooblen = 2,
                .oobbuf = buf,
                .ooboffs = 0,
@@ -2922,7 +2923,7 @@ static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr,
 }
 
 /**
- * onenand_otp_write_oob_nolock - [Internal] OneNAND write out-of-band, specific to OTP
+ * onenand_otp_write_oob_nolock - [INTERN] OneNAND write out-of-band, specific to OTP
  * @param mtd          MTD device structure
  * @param to           offset to write to
  * @param len          number of bytes to write
@@ -3170,7 +3171,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
                this->wait(mtd, FL_RESETING);
        } else {
-               ops.mode = MTD_OOB_PLACE;
+               ops.mode = MTD_OPS_PLACE_OOB;
                ops.ooblen = len;
                ops.oobbuf = buf;
                ops.ooboffs = 0;
@@ -3429,6 +3430,19 @@ static void onenand_check_features(struct mtd_info *mtd)
                else if (numbufs == 1) {
                        this->options |= ONENAND_HAS_4KB_PAGE;
                        this->options |= ONENAND_HAS_CACHE_PROGRAM;
+                       /*
+                        * There are two different 4KiB pagesize chips
+                        * and no way to detect it by H/W config values.
+                        *
+                        * To detect the correct NOP for each chips,
+                        * It should check the version ID as workaround.
+                        *
+                        * Now it has as following
+                        * KFM4G16Q4M has NOP 4 with version ID 0x0131
+                        * KFM4G16Q5M has NOP 1 with versoin ID 0x013e
+                        */
+                       if ((this->version_id & 0xf) == 0xe)
+                               this->options |= ONENAND_HAS_NOP_1;
                }
 
        case ONENAND_DEVICE_DENSITY_2Gb:
@@ -3663,7 +3677,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int
        int i, ret;
        int block;
        struct mtd_oob_ops ops = {
-               .mode = MTD_OOB_PLACE,
+               .mode = MTD_OPS_PLACE_OOB,
                .ooboffs = 0,
                .ooblen = mtd->oobsize,
                .datbuf = NULL,
@@ -4054,6 +4068,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
                        this->ecclayout = &onenand_oob_128;
                        mtd->subpage_sft = 2;
                }
+               if (ONENAND_IS_NOP_1(this))
+                       mtd->subpage_sft = 0;
                break;
        case 64:
                this->ecclayout = &onenand_oob_64;
index fc2c16a0fd1cd4fbf4e76e33ac87578aaf0b38d7..66fe3b7e78515679bae0f8ae75ab9bfb5b509958 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
+#include <linux/export.h>
 
 /**
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
@@ -80,7 +81,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
        startblock = 0;
        from = 0;
 
-       ops.mode = MTD_OOB_PLACE;
+       ops.mode = MTD_OPS_PLACE_OOB;
        ops.ooblen = readlen;
        ops.oobbuf = buf;
        ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
@@ -153,7 +154,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
        block = (int) (onenand_block(this, offs) << 1);
        res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
-       DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
+       pr_debug("onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
                (unsigned int) offs, block >> 1, res);
 
        switch ((int) res) {
@@ -188,10 +189,8 @@ int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
        len = this->chipsize >> (this->erase_shift + 2);
        /* Allocate memory (2bit per block) and clear the memory bad block table */
        bbm->bbt = kzalloc(len, GFP_KERNEL);
-       if (!bbm->bbt) {
-               printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
+       if (!bbm->bbt)
                return -ENOMEM;
-       }
 
        /* Set the bad block position */
        bbm->badblockpos = ONENAND_BADBLOCK_POS;
index 3306b5b3c736b82206cd1e56ee5afd9e11bd5dfa..5474547eafc2fc271b2000bcf5c146a18b4a8372 100644 (file)
@@ -147,7 +147,6 @@ struct s3c_onenand {
        struct resource *dma_res;
        unsigned long   phys_base;
        struct completion       complete;
-       struct mtd_partition *parts;
 };
 
 #define CMD_MAP_00(dev, addr)          (dev->cmd_map(MAP_00, ((addr) << 1)))
@@ -157,8 +156,6 @@ struct s3c_onenand {
 
 static struct s3c_onenand *onenand;
 
-static const char *part_probes[] = { "cmdlinepart", NULL, };
-
 static inline int s3c_read_reg(int offset)
 {
        return readl(onenand->base + offset);
@@ -1017,13 +1014,9 @@ static int s3c_onenand_probe(struct platform_device *pdev)
        if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
                dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
 
-       err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0);
-       if (err > 0)
-               mtd_device_register(mtd, onenand->parts, err);
-       else if (err <= 0 && pdata && pdata->parts)
-               mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
-       else
-               err = mtd_device_register(mtd, NULL, 0);
+       err = mtd_device_parse_register(mtd, NULL, 0,
+                                       pdata ? pdata->parts : NULL,
+                                       pdata ? pdata->nr_parts : 0);
 
        platform_set_drvdata(pdev, mtd);
 
index 7a87d07cd79f4bcae8dcf11241d0b052fa765cd9..e366b1d84eade1685821dcf5021427e993656842 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/module.h>
 
 struct fis_image_desc {
     unsigned char name[16];      // Null terminated name
@@ -56,8 +57,8 @@ static inline int redboot_checksum(struct fis_image_desc *img)
 }
 
 static int parse_redboot_partitions(struct mtd_info *master,
-                             struct mtd_partition **pparts,
-                             unsigned long fis_origin)
+                                   struct mtd_partition **pparts,
+                                   struct mtd_part_parser_data *data)
 {
        int nrparts = 0;
        struct fis_image_desc *buf;
@@ -197,11 +198,10 @@ static int parse_redboot_partitions(struct mtd_info *master,
                        goto out;
                }
                new_fl->img = &buf[i];
-                if (fis_origin) {
-                        buf[i].flash_base -= fis_origin;
-                } else {
-                        buf[i].flash_base &= master->size-1;
-                }
+               if (data && data->origin)
+                       buf[i].flash_base -= data->origin;
+               else
+                       buf[i].flash_base &= master->size-1;
 
                /* I'm sure the JFFS2 code has done me permanent damage.
                 * I now think the following is _normal_
@@ -297,6 +297,9 @@ static struct mtd_part_parser redboot_parser = {
        .name = "RedBoot",
 };
 
+/* mtd parsers will request the module by parser name */
+MODULE_ALIAS("RedBoot");
+
 static int __init redboot_parser_init(void)
 {
        return register_mtd_parser(&redboot_parser);
index cc4d1805b864d3504f57b227a94b1747f2f7fe50..73ae217a4252a1b386c7c9b3b820dece4c3e65bd 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
+#include <linux/module.h>
 
 #include <asm/types.h>
 
index ed3d6cd2c6dca216e097bfd5491544283be5ac11..fddb714e323cf3ea577b40c32e4abbb2aced5f29 100644 (file)
@@ -34,7 +34,7 @@ module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 
-/* ------------------- sysfs attributtes ---------------------------------- */
+/* ------------------- sysfs attributes ---------------------------------- */
 struct sm_sysfs_attribute {
        struct device_attribute dev_attr;
        char *data;
@@ -138,7 +138,7 @@ static int sm_get_lba(uint8_t *lba)
        if ((lba[0] & 0xF8) != 0x10)
                return -2;
 
-       /* check parity - endianess doesn't matter */
+       /* check parity - endianness doesn't matter */
        if (hweight16(*(uint16_t *)lba) & 1)
                return -2;
 
@@ -147,7 +147,7 @@ static int sm_get_lba(uint8_t *lba)
 
 
 /*
- * Read LBA asscociated with block
+ * Read LBA associated with block
  * returns -1, if block is erased
  * returns -2 if error happens
  */
@@ -252,11 +252,11 @@ static int sm_read_sector(struct sm_ftl *ftl,
                return 0;
        }
 
-       /* User might not need the oob, but we do for data vertification */
+       /* User might not need the oob, but we do for data verification */
        if (!oob)
                oob = &tmp_oob;
 
-       ops.mode = ftl->smallpagenand ? MTD_OOB_RAW : MTD_OOB_PLACE;
+       ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
        ops.ooboffs = 0;
        ops.ooblen = SM_OOB_SIZE;
        ops.oobbuf = (void *)oob;
@@ -276,12 +276,12 @@ again:
                        return ret;
        }
 
-       /* Unfortunelly, oob read will _always_ succeed,
+       /* Unfortunately, oob read will _always_ succeed,
                despite card removal..... */
        ret = mtd->read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
 
        /* Test for unknown errors */
-       if (ret != 0 && ret != -EUCLEAN && ret != -EBADMSG) {
+       if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
                dbg("read of block %d at zone %d, failed due to error (%d)",
                        block, zone, ret);
                goto again;
@@ -306,7 +306,7 @@ again:
        }
 
        /* Test ECC*/
-       if (ret == -EBADMSG ||
+       if (mtd_is_eccerr(ret) ||
                (ftl->smallpagenand && sm_correct_sector(buffer, oob))) {
 
                dbg("read of block %d at zone %d, failed due to ECC error",
@@ -336,7 +336,7 @@ static int sm_write_sector(struct sm_ftl *ftl,
        if (ftl->unstable)
                return -EIO;
 
-       ops.mode = ftl->smallpagenand ? MTD_OOB_RAW : MTD_OOB_PLACE;
+       ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
        ops.len = SM_SECTOR_SIZE;
        ops.datbuf = buffer;
        ops.ooboffs = 0;
@@ -447,14 +447,14 @@ static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
 
        /* We aren't checking the return value, because we don't care */
        /* This also fails on fake xD cards, but I guess these won't expose
-               any bad blocks till fail completly */
+               any bad blocks till fail completely */
        for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
                sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
 }
 
 /*
  * Erase a block within a zone
- * If erase succedes, it updates free block fifo, otherwise marks block as bad
+ * If erase succeeds, it updates free block fifo, otherwise marks block as bad
  */
 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
                          int put_free)
@@ -510,7 +510,7 @@ static void sm_erase_callback(struct erase_info *self)
        complete(&ftl->erase_completion);
 }
 
-/* Throughtly test that block is valid. */
+/* Thoroughly test that block is valid. */
 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
 {
        int boffset;
@@ -526,7 +526,7 @@ static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
        for (boffset = 0; boffset < ftl->block_size;
                                        boffset += SM_SECTOR_SIZE) {
 
-               /* This shoudn't happen anyway */
+               /* This shouldn't happen anyway */
                if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
                        return -2;
 
index 5cd18979333296b738696d9430d79b2cd4ce2775..976e3d28b962de39870e70be8bfd3d3c29c70bff 100644 (file)
@@ -135,8 +135,7 @@ static int get_valid_cis_sector(struct mtd_info *mtd)
                                /* Found */
                                cis_sector = (int)(offset >> SECTOR_SHIFT);
                        } else {
-                               DEBUG(MTD_DEBUG_LEVEL1,
-                                       "SSFDC_RO: CIS/IDI sector not found"
+                               pr_debug("SSFDC_RO: CIS/IDI sector not found"
                                        " on %s (mtd%d)\n", mtd->name,
                                        mtd->index);
                        }
@@ -170,7 +169,7 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
        struct mtd_oob_ops ops;
        int ret;
 
-       ops.mode = MTD_OOB_RAW;
+       ops.mode = MTD_OPS_RAW;
        ops.ooboffs = 0;
        ops.ooblen = OOB_SIZE;
        ops.oobbuf = buf;
@@ -221,8 +220,7 @@ static int get_logical_address(uint8_t *oob_buf)
                        block_address >>= 1;
 
                        if (get_parity(block_address, 10) != parity) {
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                       "SSFDC_RO: logical address field%d"
+                               pr_debug("SSFDC_RO: logical address field%d"
                                        "parity error(0x%04X)\n", j+1,
                                        block_address);
                        } else {
@@ -235,7 +233,7 @@ static int get_logical_address(uint8_t *oob_buf)
        if (!ok)
                block_address = -2;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n",
+       pr_debug("SSFDC_RO: get_logical_address() %d\n",
                block_address);
 
        return block_address;
@@ -249,7 +247,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
        int ret, block_address, phys_block;
        struct mtd_info *mtd = ssfdc->mbd.mtd;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
+       pr_debug("SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
              ssfdc->map_len,
              (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024);
 
@@ -262,8 +260,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
 
                ret = read_raw_oob(mtd, offset, oob_buf);
                if (ret < 0) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                               "SSFDC_RO: mtd read_oob() failed at %lu\n",
+                       pr_debug("SSFDC_RO: mtd read_oob() failed at %lu\n",
                                offset);
                        return -1;
                }
@@ -279,8 +276,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
                        ssfdc->logic_block_map[block_address] =
                                (unsigned short)phys_block;
 
-                       DEBUG(MTD_DEBUG_LEVEL2,
-                               "SSFDC_RO: build_block_map() phys_block=%d,"
+                       pr_debug("SSFDC_RO: build_block_map() phys_block=%d,"
                                "logic_block_addr=%d, zone=%d\n",
                                phys_block, block_address, zone_index);
                }
@@ -304,11 +300,8 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                return;
 
        ssfdc = kzalloc(sizeof(struct ssfdcr_record), GFP_KERNEL);
-       if (!ssfdc) {
-               printk(KERN_WARNING
-                       "SSFDC_RO: out of memory for data structures\n");
+       if (!ssfdc)
                return;
-       }
 
        ssfdc->mbd.mtd = mtd;
        ssfdc->mbd.devnum = -1;
@@ -319,8 +312,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        ssfdc->erase_size = mtd->erasesize;
        ssfdc->map_len = (u32)mtd->size / mtd->erasesize;
 
-       DEBUG(MTD_DEBUG_LEVEL1,
-               "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
+       pr_debug("SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
                ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
                DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE));
 
@@ -331,7 +323,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        ssfdc->cylinders = (unsigned short)(((u32)mtd->size >> SECTOR_SHIFT) /
                        ((long)ssfdc->sectors * (long)ssfdc->heads));
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
+       pr_debug("SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
                ssfdc->cylinders, ssfdc->heads , ssfdc->sectors,
                (long)ssfdc->cylinders * (long)ssfdc->heads *
                (long)ssfdc->sectors);
@@ -342,11 +334,8 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        /* Allocate logical block map */
        ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) *
                                         ssfdc->map_len, GFP_KERNEL);
-       if (!ssfdc->logic_block_map) {
-               printk(KERN_WARNING
-                       "SSFDC_RO: out of memory for data structures\n");
+       if (!ssfdc->logic_block_map)
                goto out_err;
-       }
        memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) *
                ssfdc->map_len);
 
@@ -371,7 +360,7 @@ static void ssfdcr_remove_dev(struct mtd_blktrans_dev *dev)
 {
        struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
+       pr_debug("SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
        kfree(ssfdc->logic_block_map);
@@ -387,8 +376,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
        offset = (int)(logic_sect_no % sectors_per_block);
        block_address = (int)(logic_sect_no / sectors_per_block);
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-               "SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
+       pr_debug("SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
                " block_addr=%d\n", logic_sect_no, sectors_per_block, offset,
                block_address);
 
@@ -397,8 +385,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
 
        block_address = ssfdc->logic_block_map[block_address];
 
-       DEBUG(MTD_DEBUG_LEVEL3,
-               "SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
+       pr_debug("SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
                block_address);
 
        if (block_address < 0xffff) {
@@ -407,8 +394,7 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
                sect_no = (unsigned long)block_address * sectors_per_block +
                                offset;
 
-               DEBUG(MTD_DEBUG_LEVEL3,
-                       "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
+               pr_debug("SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
                        sect_no);
 
                if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0)
@@ -424,7 +410,7 @@ static int ssfdcr_getgeo(struct mtd_blktrans_dev *dev,  struct hd_geometry *geo)
 {
        struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
 
-       DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
+       pr_debug("SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
                        ssfdc->cylinders, ssfdc->heads, ssfdc->sectors);
 
        geo->heads = ssfdc->heads;
index dec92ae6111a190b0ad8493ad5098c996a7a0616..933f7e5f32d301a90f7256750b03c8a1542a9609 100644 (file)
@@ -30,7 +30,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_oobtest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -131,7 +131,7 @@ static int write_eraseblock(int ebnum)
 
        for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
                set_random_data(writebuf, use_len);
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = use_len;
@@ -184,7 +184,7 @@ static int verify_eraseblock(int ebnum)
 
        for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
                set_random_data(writebuf, use_len);
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = use_len;
@@ -211,7 +211,7 @@ static int verify_eraseblock(int ebnum)
                if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) {
                        int k;
 
-                       ops.mode      = MTD_OOB_AUTO;
+                       ops.mode      = MTD_OPS_AUTO_OOB;
                        ops.len       = 0;
                        ops.retlen    = 0;
                        ops.ooblen    = mtd->ecclayout->oobavail;
@@ -276,7 +276,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
        size_t len = mtd->ecclayout->oobavail * pgcnt;
 
        set_random_data(writebuf, len);
-       ops.mode      = MTD_OOB_AUTO;
+       ops.mode      = MTD_OPS_AUTO_OOB;
        ops.len       = 0;
        ops.retlen    = 0;
        ops.ooblen    = len;
@@ -366,6 +366,13 @@ static int __init mtd_oobtest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
@@ -507,7 +514,7 @@ static int __init mtd_oobtest_init(void)
                addr0 += mtd->erasesize;
 
        /* Attempt to write off end of OOB */
-       ops.mode      = MTD_OOB_AUTO;
+       ops.mode      = MTD_OPS_AUTO_OOB;
        ops.len       = 0;
        ops.retlen    = 0;
        ops.ooblen    = 1;
@@ -527,7 +534,7 @@ static int __init mtd_oobtest_init(void)
        }
 
        /* Attempt to read off end of OOB */
-       ops.mode      = MTD_OOB_AUTO;
+       ops.mode      = MTD_OPS_AUTO_OOB;
        ops.len       = 0;
        ops.retlen    = 0;
        ops.ooblen    = 1;
@@ -551,7 +558,7 @@ static int __init mtd_oobtest_init(void)
                       "block is bad\n");
        else {
                /* Attempt to write off end of device */
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = mtd->ecclayout->oobavail + 1;
@@ -571,7 +578,7 @@ static int __init mtd_oobtest_init(void)
                }
 
                /* Attempt to read off end of device */
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = mtd->ecclayout->oobavail + 1;
@@ -595,7 +602,7 @@ static int __init mtd_oobtest_init(void)
                        goto out;
 
                /* Attempt to write off end of device */
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = mtd->ecclayout->oobavail;
@@ -615,7 +622,7 @@ static int __init mtd_oobtest_init(void)
                }
 
                /* Attempt to read off end of device */
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = mtd->ecclayout->oobavail;
@@ -655,7 +662,7 @@ static int __init mtd_oobtest_init(void)
                addr = (i + 1) * mtd->erasesize - mtd->writesize;
                for (pg = 0; pg < cnt; ++pg) {
                        set_random_data(writebuf, sz);
-                       ops.mode      = MTD_OOB_AUTO;
+                       ops.mode      = MTD_OPS_AUTO_OOB;
                        ops.len       = 0;
                        ops.retlen    = 0;
                        ops.ooblen    = sz;
@@ -683,7 +690,7 @@ static int __init mtd_oobtest_init(void)
                        continue;
                set_random_data(writebuf, mtd->ecclayout->oobavail * 2);
                addr = (i + 1) * mtd->erasesize - mtd->writesize;
-               ops.mode      = MTD_OOB_AUTO;
+               ops.mode      = MTD_OPS_AUTO_OOB;
                ops.len       = 0;
                ops.retlen    = 0;
                ops.ooblen    = mtd->ecclayout->oobavail * 2;
index 00b937e38c1d509abcda5cbd6cfc429c06b0807b..afafb6935fd0870707d13f9b7ea12cfbbb69af56 100644 (file)
@@ -30,7 +30,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_pagetest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -128,7 +128,7 @@ static int verify_eraseblock(int ebnum)
        for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) {
                /* Do a read to set the internal dataRAMs to different data */
                err = mtd->read(mtd, addr0, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -136,7 +136,7 @@ static int verify_eraseblock(int ebnum)
                        return err;
                }
                err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -146,7 +146,7 @@ static int verify_eraseblock(int ebnum)
                memset(twopages, 0, bufsize);
                read = 0;
                err = mtd->read(mtd, addr, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -164,7 +164,7 @@ static int verify_eraseblock(int ebnum)
                unsigned long oldnext = next;
                /* Do a read to set the internal dataRAMs to different data */
                err = mtd->read(mtd, addr0, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -172,7 +172,7 @@ static int verify_eraseblock(int ebnum)
                        return err;
                }
                err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -182,7 +182,7 @@ static int verify_eraseblock(int ebnum)
                memset(twopages, 0, bufsize);
                read = 0;
                err = mtd->read(mtd, addr, bufsize, &read, twopages);
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != bufsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -231,7 +231,7 @@ static int crosstest(void)
        read = 0;
        addr = addrn - pgsize - pgsize;
        err = mtd->read(mtd, addr, pgsize, &read, pp1);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -244,7 +244,7 @@ static int crosstest(void)
        read = 0;
        addr = addrn - pgsize - pgsize - pgsize;
        err = mtd->read(mtd, addr, pgsize, &read, pp1);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -258,7 +258,7 @@ static int crosstest(void)
        addr = addr0;
        printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
        err = mtd->read(mtd, addr, pgsize, &read, pp2);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -272,7 +272,7 @@ static int crosstest(void)
        addr = addrn - pgsize;
        printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
        err = mtd->read(mtd, addr, pgsize, &read, pp3);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -286,7 +286,7 @@ static int crosstest(void)
        addr = addr0;
        printk(PRINT_PREF "reading page at %#llx\n", (long long)addr);
        err = mtd->read(mtd, addr, pgsize, &read, pp4);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -345,7 +345,7 @@ static int erasecrosstest(void)
        printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
        memset(readbuf, 0, pgsize);
        err = mtd->read(mtd, addr0, pgsize, &read, readbuf);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -383,7 +383,7 @@ static int erasecrosstest(void)
        printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
        memset(readbuf, 0, pgsize);
        err = mtd->read(mtd, addr0, pgsize, &read, readbuf);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -439,7 +439,7 @@ static int erasetest(void)
 
        printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
        err = mtd->read(mtd, addr0, pgsize, &read, twopages);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != pgsize) {
                printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -504,6 +504,13 @@ static int __init mtd_pagetest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
index afe71aa15c4b4493c5e2c5d50946d71122c35b98..550fe51225a731bcc434ac04ef8890588521b0a6 100644 (file)
@@ -29,7 +29,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_readtest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -66,7 +66,7 @@ static int read_eraseblock_by_page(int ebnum)
                if (mtd->oobsize) {
                        struct mtd_oob_ops ops;
 
-                       ops.mode      = MTD_OOB_PLACE;
+                       ops.mode      = MTD_OPS_PLACE_OOB;
                        ops.len       = 0;
                        ops.retlen    = 0;
                        ops.ooblen    = mtd->oobsize;
@@ -75,7 +75,8 @@ static int read_eraseblock_by_page(int ebnum)
                        ops.datbuf    = NULL;
                        ops.oobbuf    = oobbuf;
                        ret = mtd->read_oob(mtd, addr, &ops);
-                       if (ret || ops.oobretlen != mtd->oobsize) {
+                       if ((ret && !mtd_is_bitflip(ret)) ||
+                                       ops.oobretlen != mtd->oobsize) {
                                printk(PRINT_PREF "error: read oob failed at "
                                                  "%#llx\n", (long long)addr);
                                if (!err)
@@ -169,6 +170,12 @@ static int __init mtd_readtest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
index 627d4e2466a3bccbedd3ca27c304f2b47bd414ca..493b367bdd35211af2db7273d981398a938dd039 100644 (file)
@@ -29,7 +29,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -216,7 +216,7 @@ static int read_eraseblock(int ebnum)
 
        err = mtd->read(mtd, addr, mtd->erasesize, &read, iobuf);
        /* Ignore corrected ECC errors */
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (err || read != mtd->erasesize) {
                printk(PRINT_PREF "error: read failed at %#llx\n", addr);
@@ -237,7 +237,7 @@ static int read_eraseblock_by_page(int ebnum)
        for (i = 0; i < pgcnt; i++) {
                err = mtd->read(mtd, addr, pgsize, &read, buf);
                /* Ignore corrected ECC errors */
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != pgsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -263,7 +263,7 @@ static int read_eraseblock_by_2pages(int ebnum)
        for (i = 0; i < n; i++) {
                err = mtd->read(mtd, addr, sz, &read, buf);
                /* Ignore corrected ECC errors */
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != sz) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -278,7 +278,7 @@ static int read_eraseblock_by_2pages(int ebnum)
        if (pgcnt % 2) {
                err = mtd->read(mtd, addr, pgsize, &read, buf);
                /* Ignore corrected ECC errors */
-               if (err == -EUCLEAN)
+               if (mtd_is_bitflip(err))
                        err = 0;
                if (err || read != pgsize) {
                        printk(PRINT_PREF "error: read failed at %#llx\n",
@@ -361,6 +361,13 @@ static int __init mtd_speedtest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        if (count)
                printk(PRINT_PREF "MTD device: %d    count: %d\n", dev, count);
        else
index 531625fc9259cdd167f0ade4755cf1f71cdefaa2..52ffd9120e0ded0eaf45d262cb4b6f115aad0ada 100644 (file)
@@ -30,7 +30,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_stresstest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -154,7 +154,7 @@ static int do_read(void)
        }
        addr = eb * mtd->erasesize + offs;
        err = mtd->read(mtd, addr, len, &read, readbuf);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                err = 0;
        if (unlikely(err || read != len)) {
                printk(PRINT_PREF "error: read failed at 0x%llx\n",
@@ -250,6 +250,13 @@ static int __init mtd_stresstest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
index 334eae53a3dba64a50ce117d83883434fa53cd91..1a05bfac4eeee5f6f9406b469ab27a74760c3cc8 100644 (file)
@@ -29,7 +29,7 @@
 
 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -198,7 +198,7 @@ static int verify_eraseblock(int ebnum)
        read = 0;
        err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
        if (unlikely(err || read != subpgsize)) {
-               if (err == -EUCLEAN && read == subpgsize) {
+               if (mtd_is_bitflip(err) && read == subpgsize) {
                        printk(PRINT_PREF "ECC correction at %#llx\n",
                               (long long)addr);
                        err = 0;
@@ -226,7 +226,7 @@ static int verify_eraseblock(int ebnum)
        read = 0;
        err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
        if (unlikely(err || read != subpgsize)) {
-               if (err == -EUCLEAN && read == subpgsize) {
+               if (mtd_is_bitflip(err) && read == subpgsize) {
                        printk(PRINT_PREF "ECC correction at %#llx\n",
                               (long long)addr);
                        err = 0;
@@ -264,7 +264,7 @@ static int verify_eraseblock2(int ebnum)
                read = 0;
                err = mtd->read(mtd, addr, subpgsize * k, &read, readbuf);
                if (unlikely(err || read != subpgsize * k)) {
-                       if (err == -EUCLEAN && read == subpgsize * k) {
+                       if (mtd_is_bitflip(err) && read == subpgsize * k) {
                                printk(PRINT_PREF "ECC correction at %#llx\n",
                                       (long long)addr);
                                err = 0;
@@ -298,7 +298,7 @@ static int verify_eraseblock_ff(int ebnum)
                read = 0;
                err = mtd->read(mtd, addr, subpgsize, &read, readbuf);
                if (unlikely(err || read != subpgsize)) {
-                       if (err == -EUCLEAN && read == subpgsize) {
+                       if (mtd_is_bitflip(err) && read == subpgsize) {
                                printk(PRINT_PREF "ECC correction at %#llx\n",
                                       (long long)addr);
                                err = 0;
@@ -379,6 +379,13 @@ static int __init mtd_subpagetest_init(void)
 
        printk(KERN_INFO "\n");
        printk(KERN_INFO "=================================================\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
 
        mtd = get_mtd_device(NULL, dev);
index 5c6c3d2489014960056a5f27916a8c2924810549..03ab649a6964292f50f40f9073c45ae097a47b8e 100644 (file)
@@ -46,7 +46,7 @@ static int pgcnt;
 module_param(pgcnt, int, S_IRUGO);
 MODULE_PARM_DESC(pgcnt, "number of pages per eraseblock to torture (0 => all)");
 
-static int dev;
+static int dev = -EINVAL;
 module_param(dev, int, S_IRUGO);
 MODULE_PARM_DESC(dev, "MTD device number to use");
 
@@ -138,7 +138,7 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
 
 retry:
        err = mtd->read(mtd, addr, len, &read, check_buf);
-       if (err == -EUCLEAN)
+       if (mtd_is_bitflip(err))
                printk(PRINT_PREF "single bit flip occurred at EB %d "
                       "MTD reported that it was fixed.\n", ebnum);
        else if (err) {
@@ -213,6 +213,13 @@ static int __init tort_init(void)
        printk(KERN_INFO "=================================================\n");
        printk(PRINT_PREF "Warning: this program is trying to wear out your "
               "flash, stop it if this is not wanted.\n");
+
+       if (dev < 0) {
+               printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
+               printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
+               return -EINVAL;
+       }
+
        printk(PRINT_PREF "MTD device: %d\n", dev);
        printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n",
               ebcnt, eb, eb + ebcnt - 1, dev);
index 4be671815014ee3b054f2ba8f704781dfbc1f032..fb7f19b62d91fabe2fdc785bf08aa1a32f523497 100644 (file)
@@ -443,7 +443,7 @@ retry:
                if (err == UBI_IO_BITFLIPS) {
                        scrub = 1;
                        err = 0;
-               } else if (err == -EBADMSG) {
+               } else if (mtd_is_eccerr(err)) {
                        if (vol->vol_type == UBI_DYNAMIC_VOLUME)
                                goto out_unlock;
                        scrub = 1;
index 6ba55c2358738d3d3645f816b55c0286ee15562b..f20b6f22f240378ce6386ee8c4e59d25f81cb3de 100644 (file)
@@ -172,9 +172,9 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
 retry:
        err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
        if (err) {
-               const char *errstr = (err == -EBADMSG) ? " (ECC error)" : "";
+               const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : "";
 
-               if (err == -EUCLEAN) {
+               if (mtd_is_bitflip(err)) {
                        /*
                         * -EUCLEAN is reported if there was a bit-flip which
                         * was corrected, so this is harmless.
@@ -205,7 +205,7 @@ retry:
                 * all the requested data. But some buggy drivers might do
                 * this, so we change it to -EIO.
                 */
-               if (read != len && err == -EBADMSG) {
+               if (read != len && mtd_is_eccerr(err)) {
                        ubi_assert(0);
                        err = -EIO;
                }
@@ -469,7 +469,7 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
 
 out:
        mutex_unlock(&ubi->buf_mutex);
-       if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
+       if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) {
                /*
                 * If a bit-flip or data integrity error was detected, the test
                 * has not passed because it happened on a freshly erased
@@ -760,7 +760,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
 
        read_err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
        if (read_err) {
-               if (read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
+               if (read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err))
                        return read_err;
 
                /*
@@ -776,7 +776,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
 
        magic = be32_to_cpu(ec_hdr->magic);
        if (magic != UBI_EC_HDR_MAGIC) {
-               if (read_err == -EBADMSG)
+               if (mtd_is_eccerr(read_err))
                        return UBI_IO_BAD_HDR_EBADMSG;
 
                /*
@@ -1032,12 +1032,12 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
        p = (char *)vid_hdr - ubi->vid_hdr_shift;
        read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
                          ubi->vid_hdr_alsize);
-       if (read_err && read_err != UBI_IO_BITFLIPS && read_err != -EBADMSG)
+       if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err))
                return read_err;
 
        magic = be32_to_cpu(vid_hdr->magic);
        if (magic != UBI_VID_HDR_MAGIC) {
-               if (read_err == -EBADMSG)
+               if (mtd_is_eccerr(read_err))
                        return UBI_IO_BAD_HDR_EBADMSG;
 
                if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {
@@ -1219,7 +1219,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
                return -ENOMEM;
 
        err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
-       if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)
+       if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
                goto exit;
 
        crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);
@@ -1306,7 +1306,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
        p = (char *)vid_hdr - ubi->vid_hdr_shift;
        err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
                          ubi->vid_hdr_alsize);
-       if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)
+       if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
                goto exit;
 
        crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);
@@ -1358,7 +1358,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
        }
 
        err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf1);
-       if (err && err != -EUCLEAN)
+       if (err && !mtd_is_bitflip(err))
                goto out_free;
 
        for (i = 0; i < len; i++) {
@@ -1422,7 +1422,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
        }
 
        err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
-       if (err && err != -EUCLEAN) {
+       if (err && !mtd_is_bitflip(err)) {
                ubi_err("error %d while reading %d bytes from PEB %d:%d, "
                        "read %zd bytes", err, len, pnum, offset, read);
                goto error;
index d39716e5b204c8fce14e2383dfdc1d43c91d972d..1a35fc5e3b40a947451acc340b58b7c29f2ded41 100644 (file)
@@ -410,7 +410,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
                return 0;
 
        err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check);
-       if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) {
+       if (err && mtd_is_eccerr(err) && vol->vol_type == UBI_STATIC_VOLUME) {
                ubi_warn("mark volume %d as corrupted", vol_id);
                vol->corrupted = 1;
        }
index ff2a65c37f69a6c12e7dbbdafb0c8367e951ce49..f6a7d7ac4b98a6fb1f2dd3b8d2f0abad4b06bd45 100644 (file)
@@ -81,7 +81,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
 
                err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1);
                if (err) {
-                       if (err == -EBADMSG)
+                       if (mtd_is_eccerr(err))
                                err = 1;
                        break;
                }
index a3a198f9b98dd05ea7690f4239c6874a9a3f0526..0cb17d936b5a46581ab6360c1b8307211b3c01c0 100644 (file)
@@ -395,7 +395,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
        }
 
        err = ubi_io_read_data(ubi, buf, pnum, 0, len);
-       if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)
+       if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
                goto out_free_buf;
 
        data_crc = be32_to_cpu(vid_hdr->data_crc);
@@ -793,7 +793,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
 
        err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start,
                          ubi->leb_size);
-       if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
+       if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) {
                /*
                 * Bit-flips or integrity errors while reading the data area.
                 * It is difficult to say for sure what type of corruption is
index 97e093d196725ca2b8529221d5b3a5cbc8e47d72..863835f4aefea5aa6cd4fc481d36092d09a0509e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/err.h>
 #include <linux/math64.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG
index 4b50a3029b8467817c582eb6488007cfa3fdfd46..9ad18da1891de31d2e792de57ede91626764e431 100644 (file)
@@ -423,7 +423,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi,
 
                err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
                                       ubi->vtbl_size);
-               if (err == UBI_IO_BITFLIPS || err == -EBADMSG)
+               if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err))
                        /*
                         * Scrub the PEB later. Note, -EBADMSG indicates an
                         * uncorrectable ECC error, but we have our own CRC and
index 583f66cd5bbd63dc199468b87b96baf32582bcb1..654a5e94e0e7c4f227c93b75a7791c406c586d38 100644 (file)
@@ -245,6 +245,8 @@ source "drivers/net/ethernet/Kconfig"
 
 source "drivers/net/fddi/Kconfig"
 
+source "drivers/net/hippi/Kconfig"
+
 config NET_SB1000
        tristate "General Instruments Surfboard 1000"
        depends on PNP
index a73d9dc80ff674d7b90de88226511470b9c8c873..84fb6349a59ab7d78c2ba37fe4d06538e5d52bd8 100644 (file)
@@ -4,7 +4,7 @@
 
 menuconfig ARCNET
        depends on NETDEVICES && (ISA || PCI || PCMCIA)
-       bool "ARCnet support"
+       tristate "ARCnet support"
        ---help---
          If you have a network card of this type, say Y and check out the
          (arguably) beautiful poetry in
index b2b9109b6712ef63212600811d3b879687dbc215..7f8756825b8abf62f924d569b3e923c7f955c413 100644 (file)
@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
        u32 slave_speed;
        int res;
 
-       slave->speed = -1;
-       slave->duplex = -1;
+       slave->speed = SPEED_UNKNOWN;
+       slave->duplex = DUPLEX_UNKNOWN;
 
        res = __ethtool_get_settings(slave_dev, &ecmd);
        if (res < 0)
@@ -2553,30 +2553,6 @@ re_arm:
        }
 }
 
-static __be32 bond_glean_dev_ip(struct net_device *dev)
-{
-       struct in_device *idev;
-       struct in_ifaddr *ifa;
-       __be32 addr = 0;
-
-       if (!dev)
-               return 0;
-
-       rcu_read_lock();
-       idev = __in_dev_get_rcu(dev);
-       if (!idev)
-               goto out;
-
-       ifa = idev->ifa_list;
-       if (!ifa)
-               goto out;
-
-       addr = ifa->ifa_local;
-out:
-       rcu_read_unlock();
-       return addr;
-}
-
 static int bond_has_this_ip(struct bonding *bond, __be32 ip)
 {
        struct vlan_entry *vlan;
@@ -3322,6 +3298,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
        struct bonding *bond;
        struct vlan_entry *vlan;
 
+       /* we only care about primary address */
+       if(ifa->ifa_flags & IFA_F_SECONDARY)
+               return NOTIFY_DONE;
+
        list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (bond->dev == event_dev) {
                        switch (event) {
@@ -3329,7 +3309,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
                                bond->master_ip = ifa->ifa_local;
                                return NOTIFY_OK;
                        case NETDEV_DOWN:
-                               bond->master_ip = bond_glean_dev_ip(bond->dev);
+                               bond->master_ip = 0;
                                return NOTIFY_OK;
                        default:
                                return NOTIFY_DONE;
@@ -3345,8 +3325,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
                                        vlan->vlan_ip = ifa->ifa_local;
                                        return NOTIFY_OK;
                                case NETDEV_DOWN:
-                                       vlan->vlan_ip =
-                                               bond_glean_dev_ip(vlan_dev);
+                                       vlan->vlan_ip = 0;
                                        return NOTIFY_OK;
                                default:
                                        return NOTIFY_DONE;
index d2ff52e63cbb614ea01c817a1342a6195a4de91d..ad284baafe87df64599c3335106a31aa0d6b3ec0 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include "bonding.h"
@@ -157,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq,
        seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
        seq_printf(seq, "MII Status: %s\n",
                   (slave->link == BOND_LINK_UP) ?  "up" : "down");
-       if (slave->speed == -1)
+       if (slave->speed == SPEED_UNKNOWN)
                seq_printf(seq, "Speed: %s\n", "Unknown");
        else
                seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
 
-       if (slave->duplex == -1)
+       if (slave->duplex == DUPLEX_UNKNOWN)
                seq_printf(seq, "Duplex: %s\n", "Unknown");
        else
                seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
index 5a20804fdece8d1c281e310e49509973185a33ed..4ef7e2fd9fe6f5b577c13fc56a5b2ae45a54a0bd 100644 (file)
@@ -319,6 +319,13 @@ static ssize_t bonding_store_mode(struct device *d,
                goto out;
        }
 
+       if (bond->slave_cnt > 0) {
+               pr_err("unable to update mode of %s because it has slaves.\n",
+                       bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
        new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
                pr_err("%s: Ignoring invalid mode value %.*s.\n",
index 905bce0b3a4328bdc59243481d2624c63f55b0e8..2c7f5036f570fd70d1078c1fabef3b7336d2d89e 100644 (file)
@@ -20,7 +20,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
index 4cf835dbc1222f6c90154b601bc02b76d6efbbb6..3fb66d09ece59e463c81eb20b77ba7cfa7df9fd0 100644 (file)
@@ -608,7 +608,7 @@ static void b44_tx(struct b44 *bp)
                                 skb->len,
                                 DMA_TO_DEVICE);
                rp->skb = NULL;
-               dev_kfree_skb(skb);
+               dev_kfree_skb_irq(skb);
        }
 
        bp->tx_cons = cons;
index bce203fa4b9e274c24e06e52b133a0936328c4e5..882f48f0a03cdb47568bff2e67b95cc1cdab5cb3 100644 (file)
@@ -10327,6 +10327,43 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
        return 0;
 }
 
+
+static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
+                                      struct link_params *params, u8 mode)
+{
+       struct bnx2x *bp = params->bp;
+       u16 temp;
+
+       bnx2x_cl22_write(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               MDIO_REG_GPHY_SHADOW_LED_SEL1);
+       bnx2x_cl22_read(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               &temp);
+       temp &= 0xff00;
+
+       DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
+       switch (mode) {
+       case LED_MODE_FRONT_PANEL_OFF:
+       case LED_MODE_OFF:
+               temp |= 0x00ee;
+               break;
+       case LED_MODE_OPER:
+               temp |= 0x0001;
+               break;
+       case LED_MODE_ON:
+               temp |= 0x00ff;
+               break;
+       default:
+               break;
+       }
+       bnx2x_cl22_write(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
+       return;
+}
+
+
 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
                                     struct link_params *params)
 {
@@ -11103,7 +11140,7 @@ static struct bnx2x_phy phy_54618se = {
        .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
        .format_fw_ver  = (format_fw_ver_t)NULL,
        .hw_reset       = (hw_reset_t)NULL,
-       .set_link_led   = (set_link_led_t)NULL,
+       .set_link_led   = (set_link_led_t)bnx2x_5461x_set_link_led,
        .phy_specific_func = (phy_specific_func_t)NULL
 };
 /*****************************************************************/
index 6486ab8c8fc87d803a6e5a3d507d50796704db08..2f6361e949f0c836562ff896928cb6709abf883a 100644 (file)
@@ -10548,33 +10548,38 @@ do {                                                                  \
 
 int bnx2x_init_firmware(struct bnx2x *bp)
 {
-       const char *fw_file_name;
        struct bnx2x_fw_file_hdr *fw_hdr;
        int rc;
 
-       if (CHIP_IS_E1(bp))
-               fw_file_name = FW_FILE_NAME_E1;
-       else if (CHIP_IS_E1H(bp))
-               fw_file_name = FW_FILE_NAME_E1H;
-       else if (!CHIP_IS_E1x(bp))
-               fw_file_name = FW_FILE_NAME_E2;
-       else {
-               BNX2X_ERR("Unsupported chip revision\n");
-               return -EINVAL;
-       }
 
-       BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
+       if (!bp->firmware) {
+               const char *fw_file_name;
 
-       rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
-       if (rc) {
-               BNX2X_ERR("Can't load firmware file %s\n", fw_file_name);
-               goto request_firmware_exit;
-       }
+               if (CHIP_IS_E1(bp))
+                       fw_file_name = FW_FILE_NAME_E1;
+               else if (CHIP_IS_E1H(bp))
+                       fw_file_name = FW_FILE_NAME_E1H;
+               else if (!CHIP_IS_E1x(bp))
+                       fw_file_name = FW_FILE_NAME_E2;
+               else {
+                       BNX2X_ERR("Unsupported chip revision\n");
+                       return -EINVAL;
+               }
+               BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
 
-       rc = bnx2x_check_firmware(bp);
-       if (rc) {
-               BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
-               goto request_firmware_exit;
+               rc = request_firmware(&bp->firmware, fw_file_name,
+                                     &bp->pdev->dev);
+               if (rc) {
+                       BNX2X_ERR("Can't load firmware file %s\n",
+                                 fw_file_name);
+                       goto request_firmware_exit;
+               }
+
+               rc = bnx2x_check_firmware(bp);
+               if (rc) {
+                       BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name);
+                       goto request_firmware_exit;
+               }
        }
 
        fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
@@ -10630,6 +10635,7 @@ static void bnx2x_release_firmware(struct bnx2x *bp)
        kfree(bp->init_ops);
        kfree(bp->init_data);
        release_firmware(bp->firmware);
+       bp->firmware = NULL;
 }
 
 
@@ -10925,6 +10931,8 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
        if (bp->doorbells)
                iounmap(bp->doorbells);
 
+       bnx2x_release_firmware(bp);
+
        bnx2x_free_mem_bp(bp);
 
        free_netdev(dev);
index fc7bd0f23c0b7e656905eb590ea6d8c0d360ea44..e58073ef33b47e5dc45708d794726a7a038470a2 100644 (file)
@@ -6990,6 +6990,7 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_REG_INTR_MASK                             0x1b
 #define MDIO_REG_INTR_MASK_LINK_STATUS                 (0x1 << 1)
 #define MDIO_REG_GPHY_SHADOW                           0x1c
+#define MDIO_REG_GPHY_SHADOW_LED_SEL1                  (0x0d << 10)
 #define MDIO_REG_GPHY_SHADOW_LED_SEL2                  (0x0e << 10)
 #define MDIO_REG_GPHY_SHADOW_WR_ENA                    (0x1 << 15)
 #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED              (0x1e << 10)
index 0440425c83d6820e3ba2ad12ec57430ec9896492..14517691f8dbe9a759abe26a7e5f5debd2515eb4 100644 (file)
@@ -5380,7 +5380,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
        rc = drv->init_fw(bp);
        if (rc) {
                BNX2X_ERR("Error loading firmware\n");
-               goto fw_init_err;
+               goto init_err;
        }
 
        /* Handle the beginning of COMMON_XXX pases separatelly... */
@@ -5388,25 +5388,25 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
        case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
                rc = bnx2x_func_init_cmn_chip(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_COMMON:
                rc = bnx2x_func_init_cmn(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_PORT:
                rc = bnx2x_func_init_port(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        case FW_MSG_CODE_DRV_LOAD_FUNCTION:
                rc = bnx2x_func_init_func(bp, drv);
                if (rc)
-                       goto init_hw_err;
+                       goto init_err;
 
                break;
        default:
@@ -5414,10 +5414,7 @@ static int bnx2x_func_hw_init(struct bnx2x *bp,
                rc = -EINVAL;
        }
 
-init_hw_err:
-       drv->release_fw(bp);
-
-fw_init_err:
+init_err:
        drv->gunzip_end(bp);
 
        /* In case of success, complete the comand immediatelly: no ramrods
index 161cbbb4814ad1ae99fa75f3473a28fac8bcf768..bf4074167d6a321e8f5888c2e2909b0b71e1f62b 100644 (file)
@@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
 
 #define DRV_MODULE_NAME                "tg3"
 #define TG3_MAJ_NUM                    3
-#define TG3_MIN_NUM                    120
+#define TG3_MIN_NUM                    121
 #define DRV_MODULE_VERSION     \
        __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE     "August 18, 2011"
+#define DRV_MODULE_RELDATE     "November 2, 2011"
 
 #define RESET_KIND_SHUTDOWN    0
 #define RESET_KIND_INIT                1
@@ -628,19 +628,23 @@ static void tg3_ape_lock_init(struct tg3 *tp)
                regbase = TG3_APE_PER_LOCK_GRANT;
 
        /* Make sure the driver hasn't any stale locks. */
-       for (i = 0; i < 8; i++) {
-               if (i == TG3_APE_LOCK_GPIO)
-                       continue;
-               tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
+       for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) {
+               switch (i) {
+               case TG3_APE_LOCK_PHY0:
+               case TG3_APE_LOCK_PHY1:
+               case TG3_APE_LOCK_PHY2:
+               case TG3_APE_LOCK_PHY3:
+                       bit = APE_LOCK_GRANT_DRIVER;
+                       break;
+               default:
+                       if (!tp->pci_fn)
+                               bit = APE_LOCK_GRANT_DRIVER;
+                       else
+                               bit = 1 << tp->pci_fn;
+               }
+               tg3_ape_write32(tp, regbase + 4 * i, bit);
        }
 
-       /* Clear the correct bit of the GPIO lock too. */
-       if (!tp->pci_fn)
-               bit = APE_LOCK_GRANT_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
-       tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
 }
 
 static int tg3_ape_lock(struct tg3 *tp, int locknum)
@@ -658,6 +662,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
                        return 0;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
+               if (!tp->pci_fn)
+                       bit = APE_LOCK_REQ_DRIVER;
+               else
+                       bit = 1 << tp->pci_fn;
                break;
        default:
                return -EINVAL;
@@ -673,11 +681,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
        off = 4 * locknum;
 
-       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
-               bit = APE_LOCK_REQ_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
        tg3_ape_write32(tp, req + off, bit);
 
        /* Wait for up to 1 millisecond to acquire lock. */
@@ -710,6 +713,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
                        return;
        case TG3_APE_LOCK_GRC:
        case TG3_APE_LOCK_MEM:
+               if (!tp->pci_fn)
+                       bit = APE_LOCK_GRANT_DRIVER;
+               else
+                       bit = 1 << tp->pci_fn;
                break;
        default:
                return;
@@ -720,11 +727,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
        else
                gnt = TG3_APE_PER_LOCK_GRANT;
 
-       if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
-               bit = APE_LOCK_GRANT_DRIVER;
-       else
-               bit = 1 << tp->pci_fn;
-
        tg3_ape_write32(tp, gnt + 4 * locknum, bit);
 }
 
@@ -5927,6 +5929,18 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
        return work_done;
 }
 
+static inline void tg3_reset_task_schedule(struct tg3 *tp)
+{
+       if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags))
+               schedule_work(&tp->reset_task);
+}
+
+static inline void tg3_reset_task_cancel(struct tg3 *tp)
+{
+       cancel_work_sync(&tp->reset_task);
+       tg3_flag_clear(tp, RESET_TASK_PENDING);
+}
+
 static int tg3_poll_msix(struct napi_struct *napi, int budget)
 {
        struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
@@ -5967,7 +5981,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
 tx_recovery:
        /* work_done is guaranteed to be less than budget. */
        napi_complete(napi);
-       schedule_work(&tp->reset_task);
+       tg3_reset_task_schedule(tp);
        return work_done;
 }
 
@@ -6002,7 +6016,7 @@ static void tg3_process_error(struct tg3 *tp)
        tg3_dump_state(tp);
 
        tg3_flag_set(tp, ERROR_PROCESSED);
-       schedule_work(&tp->reset_task);
+       tg3_reset_task_schedule(tp);
 }
 
 static int tg3_poll(struct napi_struct *napi, int budget)
@@ -6049,7 +6063,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
 tx_recovery:
        /* work_done is guaranteed to be less than budget. */
        napi_complete(napi);
-       schedule_work(&tp->reset_task);
+       tg3_reset_task_schedule(tp);
        return work_done;
 }
 
@@ -6338,11 +6352,11 @@ static void tg3_reset_task(struct work_struct *work)
 {
        struct tg3 *tp = container_of(work, struct tg3, reset_task);
        int err;
-       unsigned int restart_timer;
 
        tg3_full_lock(tp, 0);
 
        if (!netif_running(tp->dev)) {
+               tg3_flag_clear(tp, RESET_TASK_PENDING);
                tg3_full_unlock(tp);
                return;
        }
@@ -6355,9 +6369,6 @@ static void tg3_reset_task(struct work_struct *work)
 
        tg3_full_lock(tp, 1);
 
-       restart_timer = tg3_flag(tp, RESTART_TIMER);
-       tg3_flag_clear(tp, RESTART_TIMER);
-
        if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
                tp->write32_tx_mbox = tg3_write32_tx_mbox;
                tp->write32_rx_mbox = tg3_write_flush_reg32;
@@ -6372,14 +6383,13 @@ static void tg3_reset_task(struct work_struct *work)
 
        tg3_netif_start(tp);
 
-       if (restart_timer)
-               mod_timer(&tp->timer, jiffies + 1);
-
 out:
        tg3_full_unlock(tp);
 
        if (!err)
                tg3_phy_start(tp);
+
+       tg3_flag_clear(tp, RESET_TASK_PENDING);
 }
 
 static void tg3_tx_timeout(struct net_device *dev)
@@ -6391,7 +6401,7 @@ static void tg3_tx_timeout(struct net_device *dev)
                tg3_dump_state(tp);
        }
 
-       schedule_work(&tp->reset_task);
+       tg3_reset_task_schedule(tp);
 }
 
 /* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
@@ -6442,31 +6452,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
                hwbug = 1;
 
        if (tg3_flag(tp, 4K_FIFO_LIMIT)) {
+               u32 prvidx = *entry;
                u32 tmp_flag = flags & ~TXD_FLAG_END;
-               while (len > TG3_TX_BD_DMA_MAX) {
+               while (len > TG3_TX_BD_DMA_MAX && *budget) {
                        u32 frag_len = TG3_TX_BD_DMA_MAX;
                        len -= TG3_TX_BD_DMA_MAX;
 
-                       if (len) {
-                               tnapi->tx_buffers[*entry].fragmented = true;
-                               /* Avoid the 8byte DMA problem */
-                               if (len <= 8) {
-                                       len += TG3_TX_BD_DMA_MAX / 2;
-                                       frag_len = TG3_TX_BD_DMA_MAX / 2;
-                               }
-                       } else
-                               tmp_flag = flags;
-
-                       if (*budget) {
-                               tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
-                                             frag_len, tmp_flag, mss, vlan);
-                               (*budget)--;
-                               *entry = NEXT_TX(*entry);
-                       } else {
-                               hwbug = 1;
-                               break;
+                       /* Avoid the 8byte DMA problem */
+                       if (len <= 8) {
+                               len += TG3_TX_BD_DMA_MAX / 2;
+                               frag_len = TG3_TX_BD_DMA_MAX / 2;
                        }
 
+                       tnapi->tx_buffers[*entry].fragmented = true;
+
+                       tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
+                                     frag_len, tmp_flag, mss, vlan);
+                       *budget -= 1;
+                       prvidx = *entry;
+                       *entry = NEXT_TX(*entry);
+
                        map += frag_len;
                }
 
@@ -6474,10 +6479,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
                        if (*budget) {
                                tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
                                              len, flags, mss, vlan);
-                               (*budget)--;
+                               *budget -= 1;
                                *entry = NEXT_TX(*entry);
                        } else {
                                hwbug = 1;
+                               tnapi->tx_buffers[prvidx].fragmented = false;
                        }
                }
        } else {
@@ -6509,7 +6515,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
                txb = &tnapi->tx_buffers[entry];
        }
 
-       for (i = 0; i < last; i++) {
+       for (i = 0; i <= last; i++) {
                const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                entry = NEXT_TX(entry);
@@ -6559,6 +6565,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
                        dev_kfree_skb(new_skb);
                        ret = -1;
                } else {
+                       u32 save_entry = *entry;
+
                        base_flags |= TXD_FLAG_END;
 
                        tnapi->tx_buffers[*entry].skb = new_skb;
@@ -6568,7 +6576,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
                        if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
                                            new_skb->len, base_flags,
                                            mss, vlan)) {
-                               tg3_tx_skb_unmap(tnapi, *entry, 0);
+                               tg3_tx_skb_unmap(tnapi, save_entry, -1);
                                dev_kfree_skb(new_skb);
                                ret = -1;
                        }
@@ -6758,11 +6766,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
                          ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
-                           mss, vlan))
+                           mss, vlan)) {
                would_hit_hwbug = 1;
-
        /* Now loop through additional data fragments, and queue them. */
-       if (skb_shinfo(skb)->nr_frags > 0) {
+       } else if (skb_shinfo(skb)->nr_frags > 0) {
                u32 tmp_mss = mss;
 
                if (!tg3_flag(tp, HW_TSO_1) &&
@@ -6784,11 +6791,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        if (dma_mapping_error(&tp->pdev->dev, mapping))
                                goto dma_error;
 
-                       if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
+                       if (!budget ||
+                           tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
                                            len, base_flags |
                                            ((i == last) ? TXD_FLAG_END : 0),
-                                           tmp_mss, vlan))
+                                           tmp_mss, vlan)) {
                                would_hit_hwbug = 1;
+                               break;
+                       }
                }
        }
 
@@ -6828,7 +6838,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_OK;
 
 dma_error:
-       tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
+       tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
        tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
 drop:
        dev_kfree_skb(skb);
@@ -7281,7 +7291,8 @@ static void tg3_free_rings(struct tg3 *tp)
                        if (!skb)
                                continue;
 
-                       tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags);
+                       tg3_tx_skb_unmap(tnapi, i,
+                                        skb_shinfo(skb)->nr_frags - 1);
 
                        dev_kfree_skb_any(skb);
                }
@@ -9200,7 +9211,7 @@ static void tg3_timer(unsigned long __opaque)
 {
        struct tg3 *tp = (struct tg3 *) __opaque;
 
-       if (tp->irq_sync)
+       if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING))
                goto restart_timer;
 
        spin_lock(&tp->lock);
@@ -9223,10 +9234,9 @@ static void tg3_timer(unsigned long __opaque)
                }
 
                if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
-                       tg3_flag_set(tp, RESTART_TIMER);
                        spin_unlock(&tp->lock);
-                       schedule_work(&tp->reset_task);
-                       return;
+                       tg3_reset_task_schedule(tp);
+                       goto restart_timer;
                }
        }
 
@@ -9674,15 +9684,14 @@ static int tg3_open(struct net_device *dev)
                struct tg3_napi *tnapi = &tp->napi[i];
                err = tg3_request_irq(tp, i);
                if (err) {
-                       for (i--; i >= 0; i--)
+                       for (i--; i >= 0; i--) {
+                               tnapi = &tp->napi[i];
                                free_irq(tnapi->irq_vec, tnapi);
-                       break;
+                       }
+                       goto err_out2;
                }
        }
 
-       if (err)
-               goto err_out2;
-
        tg3_full_lock(tp, 0);
 
        err = tg3_init_hw(tp, 1);
@@ -9783,7 +9792,7 @@ static int tg3_close(struct net_device *dev)
        struct tg3 *tp = netdev_priv(dev);
 
        tg3_napi_disable(tp);
-       cancel_work_sync(&tp->reset_task);
+       tg3_reset_task_cancel(tp);
 
        netif_tx_stop_all_queues(dev);
 
@@ -11520,7 +11529,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
                        break;
        }
 
-       tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0);
+       tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1);
        dev_kfree_skb(skb);
 
        if (tx_idx != tnapi->tx_prod)
@@ -14228,12 +14237,30 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        val = tr32(MEMARB_MODE);
        tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
-       if (tg3_flag(tp, PCIX_MODE)) {
-               pci_read_config_dword(tp->pdev,
-                                     tp->pcix_cap + PCI_X_STATUS, &val);
-               tp->pci_fn = val & 0x7;
-       } else {
-               tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+       tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+           tg3_flag(tp, 5780_CLASS)) {
+               if (tg3_flag(tp, PCIX_MODE)) {
+                       pci_read_config_dword(tp->pdev,
+                                             tp->pcix_cap + PCI_X_STATUS,
+                                             &val);
+                       tp->pci_fn = val & 0x7;
+               }
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
+               if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
+                   NIC_SRAM_CPMUSTAT_SIG) {
+                       tp->pci_fn = val & TG3_CPMU_STATUS_FMSK_5717;
+                       tp->pci_fn = tp->pci_fn ? 1 : 0;
+               }
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+               tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
+               if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
+                   NIC_SRAM_CPMUSTAT_SIG) {
+                       tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5719) >>
+                                    TG3_CPMU_STATUS_FSHFT_5719;
+               }
        }
 
        /* Get eeprom hw config before calling tg3_set_power_state().
@@ -15665,7 +15692,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
                if (tp->fw)
                        release_firmware(tp->fw);
 
-               cancel_work_sync(&tp->reset_task);
+               tg3_reset_task_cancel(tp);
 
                if (tg3_flag(tp, USE_PHYLIB)) {
                        tg3_phy_fini(tp);
@@ -15699,7 +15726,7 @@ static int tg3_suspend(struct device *device)
        if (!netif_running(dev))
                return 0;
 
-       flush_work_sync(&tp->reset_task);
+       tg3_reset_task_cancel(tp);
        tg3_phy_stop(tp);
        tg3_netif_stop(tp);
 
@@ -15812,12 +15839,10 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
        tg3_netif_stop(tp);
 
        del_timer_sync(&tp->timer);
-       tg3_flag_clear(tp, RESTART_TIMER);
 
        /* Want to make sure that the reset task doesn't run */
-       cancel_work_sync(&tp->reset_task);
+       tg3_reset_task_cancel(tp);
        tg3_flag_clear(tp, TX_RECOVERY_PENDING);
-       tg3_flag_clear(tp, RESTART_TIMER);
 
        netif_device_detach(netdev);
 
index f32f288134c7b4946334ab59099a577b95cadd36..94b4bd049a33a8e29534e423e560faedadd94fc7 100644 (file)
 #define TG3_CPMU_CLCK_ORIDE            0x00003624
 #define  CPMU_CLCK_ORIDE_MAC_ORIDE_EN   0x80000000
 
+#define TG3_CPMU_STATUS                        0x0000362c
+#define  TG3_CPMU_STATUS_FMSK_5717      0x20000000
+#define  TG3_CPMU_STATUS_FMSK_5719      0xc0000000
+#define  TG3_CPMU_STATUS_FSHFT_5719     30
+
 #define TG3_CPMU_CLCK_STAT             0x00003630
 #define  CPMU_CLCK_STAT_MAC_CLCK_MASK   0x001f0000
 #define  CPMU_CLCK_STAT_MAC_CLCK_62_5   0x00000000
 #define  NIC_SRAM_RGMII_EXT_IBND_RX_EN  0x00000008
 #define  NIC_SRAM_RGMII_EXT_IBND_TX_EN  0x00000010
 
+#define NIC_SRAM_CPMU_STATUS           0x00000e00
+#define  NIC_SRAM_CPMUSTAT_SIG         0x0000362c
+#define  NIC_SRAM_CPMUSTAT_SIG_MSK     0x0000ffff
+
 #define NIC_SRAM_RX_MINI_BUFFER_DESC   0x00001000
 
 #define NIC_SRAM_DMA_DESC_POOL_BASE    0x00002000
 #define  APE_PER_LOCK_GRANT_DRIVER      0x00001000
 
 /* APE convenience enumerations. */
-#define TG3_APE_LOCK_GRC                1
-#define TG3_APE_LOCK_MEM                4
-#define TG3_APE_LOCK_GPIO               7
+#define TG3_APE_LOCK_PHY0              0
+#define TG3_APE_LOCK_GRC               1
+#define TG3_APE_LOCK_PHY1              2
+#define TG3_APE_LOCK_PHY2              3
+#define TG3_APE_LOCK_MEM               4
+#define TG3_APE_LOCK_PHY3              5
+#define TG3_APE_LOCK_GPIO              7
 
 #define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
 
@@ -2866,7 +2879,6 @@ enum TG3_FLAGS {
        TG3_FLAG_JUMBO_CAPABLE,
        TG3_FLAG_CHIP_RESETTING,
        TG3_FLAG_INIT_COMPLETE,
-       TG3_FLAG_RESTART_TIMER,
        TG3_FLAG_TSO_BUG,
        TG3_FLAG_IS_5788,
        TG3_FLAG_MAX_RXPEND_64,
@@ -2909,6 +2921,7 @@ enum TG3_FLAGS {
        TG3_FLAG_APE_HAS_NCSI,
        TG3_FLAG_5717_PLUS,
        TG3_FLAG_4K_FIFO_LIMIT,
+       TG3_FLAG_RESET_TASK_PENDING,
 
        /* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
        TG3_FLAG_NUMBER_OF_FLAGS,       /* Last entry in enum TG3_FLAGS */
index 5d7872ecff523904ea18dfb9ce3bf5c79171fcb3..7f3091e7eb42f6c459f40b5471d3e57abacb8851 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <linux/prefetch.h>
+#include <linux/module.h>
 
 #include "bnad.h"
 #include "bna.h"
index 98849a1fc749995070dadd607175f55ef89d2fa0..b48378a41e492ce3df245214235c25b901a436c1 100644 (file)
@@ -7,6 +7,7 @@ config HAVE_NET_MACB
 
 config NET_ATMEL
        bool "Atmel devices"
+       default y
        depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
index da5a5d9b8aff1e963e53e441791c7ea3582cd1d3..90ff1318cc05fbc5ed0e08141962d8a87140c74f 100644 (file)
@@ -40,6 +40,7 @@
 #include <net/netevent.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include "common.h"
 #include "regs.h"
index 41540978a1732a8953565a0bf3d4b6083e4744cf..70fec8b1140f9239ec1975e0c768381c0fd54b92 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/if_vlan.h>
 #include <linux/jhash.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/neighbour.h>
 #include "common.h"
 #include "t3cdev.h"
index a2d323c473f8bd5789e75b0a6ae504115347e065..6ac77a62f361ab6e02e1b90645b17bc37dbb580f 100644 (file)
@@ -37,6 +37,9 @@
 #include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/jhash.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <net/neighbour.h>
 #include "cxgb4.h"
 #include "l2t.h"
@@ -503,10 +506,6 @@ struct l2t_data *t4_init_l2t(void)
        return d;
 }
 
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
 static inline void *l2t_get_idx(struct seq_file *seq, loff_t pos)
 {
        struct l2t_entry *l2tab = seq->private;
index ddc16985d0f68bf69316f7f202f51f1231b2e536..140254c7cba900aea3c80336f7033db651c957ba 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/jiffies.h>
 #include <linux/prefetch.h>
+#include <linux/export.h>
 #include <net/ipv6.h>
 #include <net/tcp.h>
 #include "cxgb4.h"
index 438f4580bf66207539761761e37c42e0ef303b78..2a22f52563532201891fa4a720d11180886b714c 100644 (file)
@@ -613,7 +613,7 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
 
                if (!dm->wake_state)
                        irq_set_irq_wake(dm->irq_wake, 1);
-               else if (dm->wake_state & !opts)
+               else if (dm->wake_state && !opts)
                        irq_set_irq_wake(dm->irq_wake, 0);
        }
 
index e0aed188c57fd09b714766f0c96aa9e2c3601f43..bf266a00c7742129fd8d86699e1756d0dc1ba070 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/prefetch.h>
+#include <linux/module.h>
 #include "be.h"
 #include "be_cmds.h"
 #include <asm/div64.h>
index bdb348a5ccf60bd6bb93b2d745546445b5f2d413..251b635fe75a1a767ff76a21aad8c243dbf21f3c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include <net/ethoc.h>
 
 static int buffer_size = 0x8000; /* 32 KBytes */
index 1cf671643d1fc13d508c13102b5424c77f3ddb1e..5272f9d4dda9448faece5a061d413c71620f6da4 100644 (file)
@@ -7,8 +7,7 @@ config NET_VENDOR_FREESCALE
        default y
        depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
                   M523x || M527x || M5272 || M528x || M520x || M532x || \
-                  ARCH_MXC || ARCH_MXS || \
-                  (PPC_MPC52xx && PPC_BESTCOMM)
+                  ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM)
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
@@ -25,6 +24,7 @@ config FEC
        bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
        depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
                   ARCH_MXC || ARCH_MXS)
+       default ARCH_MXC || ARCH_MXS if ARM
        select PHYLIB
        ---help---
          Say Y here if you want to use the built-in 10/100 Fast ethernet
index 46d690a92c0bda42990b9bd5b4b43bb18ee0af74..b5dc0273a1d1d63f213096dfd3f1057006d0b6e2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/stddef.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index 410d6a1984ed400863c7e5eabd63e7041629d101..6650068c996c48158c3b09c8975b912440e00aff 100644 (file)
@@ -61,9 +61,9 @@
 #ifdef EHEA_SMALL_QUEUES
 #define EHEA_MAX_CQE_COUNT      1023
 #define EHEA_DEF_ENTRIES_SQ     1023
-#define EHEA_DEF_ENTRIES_RQ1    4095
+#define EHEA_DEF_ENTRIES_RQ1    1023
 #define EHEA_DEF_ENTRIES_RQ2    1023
-#define EHEA_DEF_ENTRIES_RQ3    1023
+#define EHEA_DEF_ENTRIES_RQ3    511
 #else
 #define EHEA_MAX_CQE_COUNT      4080
 #define EHEA_DEF_ENTRIES_SQ     4080
index 37b70f7052b68ad9a16593cb299cf6eb380a6491..bfeccbfde236237dc0c8486d0dd1d12d192d3a02 100644 (file)
@@ -371,7 +371,8 @@ static void ehea_update_stats(struct work_struct *work)
 out_herr:
        free_page((unsigned long)cb2);
 resched:
-       schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+       schedule_delayed_work(&port->stats_work,
+                             round_jiffies_relative(msecs_to_jiffies(1000)));
 }
 
 static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
@@ -2434,7 +2435,8 @@ static int ehea_open(struct net_device *dev)
        }
 
        mutex_unlock(&port->port_lock);
-       schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+       schedule_delayed_work(&port->stats_work,
+                             round_jiffies_relative(msecs_to_jiffies(1000)));
 
        return ret;
 }
index 4326681df382ac461c24e21eb6a6ea0ee64d4426..acc31af6594a243b91d7c9f666363581f68ddf05 100644 (file)
@@ -1421,7 +1421,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
 
                /* FIXME: do we need this? */
                memset(local_list, 0, sizeof(local_list));
-               memset(remote_list, 0, sizeof(VETH_MAX_FRAMES_PER_MSG));
+               memset(remote_list, 0, sizeof(remote_list));
 
                /* a 0 address marks the end of the valid entries */
                if (senddata->addr[startchunk] == 0)
index 61029dc7fa6f82534641e03c2d432466a8a76165..76213162fbe32499869470472243b96a003afbb8 100644 (file)
@@ -5,7 +5,11 @@
 config NET_VENDOR_INTEL
        bool "Intel devices"
        default y
-       depends on PCI || PCI_MSI
+       depends on PCI || PCI_MSI || ISA || ISA_DMA_API || ARM || \
+                  ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \
+                  GSC || BVME6000 || MVME16x || ARCH_ENP2611 || \
+                  (ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR) || \
+                  EXPERIMENTAL
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
index 4dd9b63273f62eac9917d69df9a613dd3fa14e61..20e93b08e7f3c7e6e2389bea815e0b3dec227d71 100644 (file)
@@ -27,6 +27,7 @@
 *******************************************************************************/
 
 #include <linux/netdevice.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 
 #include "e1000.h"
index db95731863d75bf470ce660b13de951f50670eed..00fcd39ad666b6c289379e401800438347952dd7 100644 (file)
@@ -442,12 +442,14 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
 
 int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter)
 {
+#ifdef CONFIG_PCI_IOV
        int i;
        for (i = 0; i < adapter->num_vfs; i++) {
                if (adapter->vfinfo[i].vfdev->dev_flags &
                                PCI_DEV_FLAGS_ASSIGNED)
                        return true;
        }
+#endif
        return false;
 }
 
index 4a5d8897faab47ec93358c7a7d16c4b44d983b83..df04f1a3857c96e5e16b4098580d2904c5c33a2e 100644 (file)
@@ -42,11 +42,11 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
 int ixgbe_ndo_get_vf_config(struct net_device *netdev,
                            int vf, struct ifla_vf_info *ivi);
 void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
-#ifdef CONFIG_PCI_IOV
 void ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
+int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter);
+#ifdef CONFIG_PCI_IOV
 void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
                        const struct ixgbe_info *ii);
-int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter);
 #endif
 
 
index 7becff1f387d7c9d84fb26ab3db6f7299bb64f15..76b84573566bd850a267c02a9d533fac5b68c7c4 100644 (file)
@@ -1744,6 +1744,112 @@ jme_phy_off(struct jme_adapter *jme)
                jme_new_phy_off(jme);
 }
 
+static int
+jme_phy_specreg_read(struct jme_adapter *jme, u32 specreg)
+{
+       u32 phy_addr;
+
+       phy_addr = JM_PHY_SPEC_REG_READ | specreg;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+                       phy_addr);
+       return jme_mdio_read(jme->dev, jme->mii_if.phy_id,
+                       JM_PHY_SPEC_DATA_REG);
+}
+
+static void
+jme_phy_specreg_write(struct jme_adapter *jme, u32 ext_reg, u32 phy_data)
+{
+       u32 phy_addr;
+
+       phy_addr = JM_PHY_SPEC_REG_WRITE | ext_reg;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_DATA_REG,
+                       phy_data);
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+                       phy_addr);
+}
+
+static int
+jme_phy_calibration(struct jme_adapter *jme)
+{
+       u32 ctrl1000, phy_data;
+
+       jme_phy_off(jme);
+       jme_phy_on(jme);
+       /*  Enabel PHY test mode 1 */
+       ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+       ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+       ctrl1000 |= PHY_GAD_TEST_MODE_1;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+
+       phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+       phy_data &= ~JM_PHY_EXT_COMM_2_CALI_MODE_0;
+       phy_data |= JM_PHY_EXT_COMM_2_CALI_LATCH |
+                       JM_PHY_EXT_COMM_2_CALI_ENABLE;
+       jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+       msleep(20);
+       phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+       phy_data &= ~(JM_PHY_EXT_COMM_2_CALI_ENABLE |
+                       JM_PHY_EXT_COMM_2_CALI_MODE_0 |
+                       JM_PHY_EXT_COMM_2_CALI_LATCH);
+       jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+
+       /*  Disable PHY test mode */
+       ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+       ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+       return 0;
+}
+
+static int
+jme_phy_setEA(struct jme_adapter *jme)
+{
+       u32 phy_comm0 = 0, phy_comm1 = 0;
+       u8 nic_ctrl;
+
+       pci_read_config_byte(jme->pdev, PCI_PRIV_SHARE_NICCTRL, &nic_ctrl);
+       if ((nic_ctrl & 0x3) == JME_FLAG_PHYEA_ENABLE)
+               return 0;
+
+       switch (jme->pdev->device) {
+       case PCI_DEVICE_ID_JMICRON_JMC250:
+               if (((jme->chip_main_rev == 5) &&
+                       ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+                       (jme->chip_sub_rev == 3))) ||
+                       (jme->chip_main_rev >= 6)) {
+                       phy_comm0 = 0x008A;
+                       phy_comm1 = 0x4109;
+               }
+               if ((jme->chip_main_rev == 3) &&
+                       ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+                       phy_comm0 = 0xE088;
+               break;
+       case PCI_DEVICE_ID_JMICRON_JMC260:
+               if (((jme->chip_main_rev == 5) &&
+                       ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+                       (jme->chip_sub_rev == 3))) ||
+                       (jme->chip_main_rev >= 6)) {
+                       phy_comm0 = 0x008A;
+                       phy_comm1 = 0x4109;
+               }
+               if ((jme->chip_main_rev == 3) &&
+                       ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+                       phy_comm0 = 0xE088;
+               if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 0))
+                       phy_comm0 = 0x608A;
+               if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 2))
+                       phy_comm0 = 0x408A;
+               break;
+       default:
+               return -ENODEV;
+       }
+       if (phy_comm0)
+               jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_0_REG, phy_comm0);
+       if (phy_comm1)
+               jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_1_REG, phy_comm1);
+
+       return 0;
+}
+
 static int
 jme_open(struct net_device *netdev)
 {
@@ -1769,7 +1875,8 @@ jme_open(struct net_device *netdev)
                jme_set_settings(netdev, &jme->old_ecmd);
        else
                jme_reset_phy_processor(jme);
-
+       jme_phy_calibration(jme);
+       jme_phy_setEA(jme);
        jme_reset_link(jme);
 
        return 0;
@@ -3184,7 +3291,8 @@ jme_resume(struct device *dev)
                jme_set_settings(netdev, &jme->old_ecmd);
        else
                jme_reset_phy_processor(jme);
-
+       jme_phy_calibration(jme);
+       jme_phy_setEA(jme);
        jme_start_irq(jme);
        netif_device_attach(netdev);
 
@@ -3239,4 +3347,3 @@ MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, jme_pci_tbl);
-
index 02ea27c1dcb5a464f06d9b38d98259f6f080fd4c..4304072bd3c536e852a38cf6c37716df8500ed66 100644 (file)
@@ -760,6 +760,25 @@ enum jme_rxmcs_bits {
                                  RXMCS_CHECKSUM,
 };
 
+/*     Extern PHY common register 2    */
+
+#define PHY_GAD_TEST_MODE_1                    0x00002000
+#define PHY_GAD_TEST_MODE_MSK                  0x0000E000
+#define JM_PHY_SPEC_REG_READ                   0x00004000
+#define JM_PHY_SPEC_REG_WRITE                  0x00008000
+#define PHY_CALIBRATION_DELAY                  20
+#define JM_PHY_SPEC_ADDR_REG                   0x1E
+#define JM_PHY_SPEC_DATA_REG                   0x1F
+
+#define JM_PHY_EXT_COMM_0_REG                  0x30
+#define JM_PHY_EXT_COMM_1_REG                  0x31
+#define JM_PHY_EXT_COMM_2_REG                  0x32
+#define JM_PHY_EXT_COMM_2_CALI_ENABLE          0x01
+#define JM_PHY_EXT_COMM_2_CALI_MODE_0          0x02
+#define JM_PHY_EXT_COMM_2_CALI_LATCH           0x10
+#define PCI_PRIV_SHARE_NICCTRL                 0xF5
+#define JME_FLAG_PHYEA_ENABLE                  0x2
+
 /*
  * Wakeup Frame setup interface registers
  */
index 6bb2b9506cadfde73ddef809bc0fcf78dd202b0a..0b3567ab812151f00210544cc805815b0953a90d 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #include <asm/checksum.h>
 
index cbd026f3bc57f5ee164bc68d94bfd8197d6b1fe7..7803efa46eb26b4b9fb5465ea1cb1df15d26d8ed 100644 (file)
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.29"
+#define DRV_VERSION            "1.30"
 
 /*
  * The Yukon II chipset takes 64 bit command blocks (called list elements)
@@ -68,7 +68,7 @@
 #define MAX_SKB_TX_LE  (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
 #define TX_MIN_PENDING         (MAX_SKB_TX_LE+1)
 #define TX_MAX_PENDING         1024
-#define TX_DEF_PENDING         127
+#define TX_DEF_PENDING         63
 
 #define TX_WATCHDOG            (5 * HZ)
 #define NAPI_WEIGHT            64
@@ -366,17 +366,6 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                                gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
                        }
                } else {
-                       if (hw->chip_id >= CHIP_ID_YUKON_OPT) {
-                               u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2);
-
-                               /* enable PHY Reverse Auto-Negotiation */
-                               ctrl2 |= 1u << 13;
-
-                               /* Write PHY changes (SW-reset must follow) */
-                               gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2);
-                       }
-
-
                        /* disable energy detect */
                        ctrl &= ~PHY_M_PC_EN_DET_MSK;
 
@@ -880,6 +869,7 @@ static void sky2_wol_init(struct sky2_port *sky2)
 
        /* block receiver */
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+       sky2_read32(hw, B0_CTST);
 }
 
 static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
@@ -1285,6 +1275,14 @@ static void rx_set_checksum(struct sky2_port *sky2)
                     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 }
 
+/*
+ * Fixed initial key as seed to RSS.
+ */
+static const uint32_t rss_init_key[10] = {
+       0x7c3351da, 0x51c5cf4e, 0x44adbdd1, 0xe8d38d18, 0x48897c43,
+       0xb1d60e7e, 0x6a3dd760, 0x01a2e453, 0x16f46f13, 0x1a0e7b30
+};
+
 /* Enable/disable receive hash calculation (RSS) */
 static void rx_set_rss(struct net_device *dev, u32 features)
 {
@@ -1300,12 +1298,9 @@ static void rx_set_rss(struct net_device *dev, u32 features)
 
        /* Program RSS initial values */
        if (features & NETIF_F_RXHASH) {
-               u32 key[nkeys];
-
-               get_random_bytes(key, nkeys * sizeof(u32));
                for (i = 0; i < nkeys; i++)
                        sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
-                                    key[i]);
+                                    rss_init_key[i]);
 
                /* Need to turn on (undocumented) flag to make hashing work  */
                sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
@@ -1728,6 +1723,8 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
        if (err)
                dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
        else {
+               hw->flags |= SKY2_HW_IRQ_SETUP;
+
                napi_enable(&hw->napi);
                sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
                sky2_read32(hw, B0_IMSK);
@@ -1738,7 +1735,7 @@ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
 
 
 /* Bring up network interface. */
-static int sky2_up(struct net_device *dev)
+static int sky2_open(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
@@ -1758,6 +1755,11 @@ static int sky2_up(struct net_device *dev)
 
        sky2_hw_up(sky2);
 
+       if (hw->chip_id == CHIP_ID_YUKON_OPT ||
+           hw->chip_id == CHIP_ID_YUKON_PRM ||
+           hw->chip_id == CHIP_ID_YUKON_OP_2)
+               imask |= Y2_IS_PHY_QLNK;        /* enable PHY Quick Link */
+
        /* Enable interrupts from phy/mac for port */
        imask = sky2_read32(hw, B0_IMSK);
        imask |= portirq_msk[port];
@@ -2051,6 +2053,8 @@ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
 
        sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+       sky2_read32(hw, B0_CTST);
 }
 
 static void sky2_hw_down(struct sky2_port *sky2)
@@ -2101,7 +2105,7 @@ static void sky2_hw_down(struct sky2_port *sky2)
 }
 
 /* Network shutdown */
-static int sky2_down(struct net_device *dev)
+static int sky2_close(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
@@ -2112,15 +2116,22 @@ static int sky2_down(struct net_device *dev)
 
        netif_info(sky2, ifdown, dev, "disabling interface\n");
 
-       /* Disable port IRQ */
-       sky2_write32(hw, B0_IMSK,
-                    sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
-       sky2_read32(hw, B0_IMSK);
-
        if (hw->ports == 1) {
+               sky2_write32(hw, B0_IMSK, 0);
+               sky2_read32(hw, B0_IMSK);
+
                napi_disable(&hw->napi);
                free_irq(hw->pdev->irq, hw);
+               hw->flags &= ~SKY2_HW_IRQ_SETUP;
        } else {
+               u32 imask;
+
+               /* Disable port IRQ */
+               imask  = sky2_read32(hw, B0_IMSK);
+               imask &= ~portirq_msk[sky2->port];
+               sky2_write32(hw, B0_IMSK, imask);
+               sky2_read32(hw, B0_IMSK);
+
                synchronize_irq(hw->pdev->irq);
                napi_synchronize(&hw->napi);
        }
@@ -2598,7 +2609,7 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
        if (netif_running(dev)) {
                sky2_tx_complete(sky2, last);
 
-               /* Wake unless it's detached, and called e.g. from sky2_down() */
+               /* Wake unless it's detached, and called e.g. from sky2_close() */
                if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
                        netif_wake_queue(dev);
        }
@@ -3269,7 +3280,6 @@ static void sky2_reset(struct sky2_hw *hw)
            hw->chip_id == CHIP_ID_YUKON_PRM ||
            hw->chip_id == CHIP_ID_YUKON_OP_2) {
                u16 reg;
-               u32 msk;
 
                if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
                        /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
@@ -3292,11 +3302,6 @@ static void sky2_reset(struct sky2_hw *hw)
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
 
-               /* enable PHY Quick Link */
-               msk = sky2_read32(hw, B0_IMSK);
-               msk |= Y2_IS_PHY_QLNK;
-               sky2_write32(hw, B0_IMSK, msk);
-
                /* check if PSMv2 was running before */
                reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
                if (reg & PCI_EXP_LNKCTL_ASPMC)
@@ -3394,7 +3399,7 @@ static void sky2_detach(struct net_device *dev)
                netif_tx_lock(dev);
                netif_device_detach(dev);       /* stop txq */
                netif_tx_unlock(dev);
-               sky2_down(dev);
+               sky2_close(dev);
        }
 }
 
@@ -3404,7 +3409,7 @@ static int sky2_reattach(struct net_device *dev)
        int err = 0;
 
        if (netif_running(dev)) {
-               err = sky2_up(dev);
+               err = sky2_open(dev);
                if (err) {
                        netdev_info(dev, "could not restart %d\n", err);
                        dev_close(dev);
@@ -3421,10 +3426,13 @@ static void sky2_all_down(struct sky2_hw *hw)
 {
        int i;
 
-       sky2_read32(hw, B0_IMSK);
-       sky2_write32(hw, B0_IMSK, 0);
-       synchronize_irq(hw->pdev->irq);
-       napi_disable(&hw->napi);
+       if (hw->flags & SKY2_HW_IRQ_SETUP) {
+               sky2_read32(hw, B0_IMSK);
+               sky2_write32(hw, B0_IMSK, 0);
+
+               synchronize_irq(hw->pdev->irq);
+               napi_disable(&hw->napi);
+       }
 
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
@@ -3457,11 +3465,12 @@ static void sky2_all_up(struct sky2_hw *hw)
                netif_wake_queue(dev);
        }
 
-       sky2_write32(hw, B0_IMSK, imask);
-       sky2_read32(hw, B0_IMSK);
-
-       sky2_read32(hw, B0_Y2_SP_LISR);
-       napi_enable(&hw->napi);
+       if (hw->flags & SKY2_HW_IRQ_SETUP) {
+               sky2_write32(hw, B0_IMSK, imask);
+               sky2_read32(hw, B0_IMSK);
+               sky2_read32(hw, B0_Y2_SP_LISR);
+               napi_enable(&hw->napi);
+       }
 }
 
 static void sky2_restart(struct work_struct *work)
@@ -4082,6 +4091,16 @@ static int sky2_set_coalesce(struct net_device *dev,
        return 0;
 }
 
+/*
+ * Hardware is limited to min of 128 and max of 2048 for ring size
+ * and  rounded up to next power of two
+ * to avoid division in modulus calclation
+ */
+static unsigned long roundup_ring_size(unsigned long pending)
+{
+       return max(128ul, roundup_pow_of_two(pending+1));
+}
+
 static void sky2_get_ringparam(struct net_device *dev,
                               struct ethtool_ringparam *ering)
 {
@@ -4109,7 +4128,7 @@ static int sky2_set_ringparam(struct net_device *dev,
 
        sky2->rx_pending = ering->rx_pending;
        sky2->tx_pending = ering->tx_pending;
-       sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1);
+       sky2->tx_ring_size = roundup_ring_size(sky2->tx_pending);
 
        return sky2_reattach(dev);
 }
@@ -4567,7 +4586,7 @@ static int sky2_device_event(struct notifier_block *unused,
        struct net_device *dev = ptr;
        struct sky2_port *sky2 = netdev_priv(dev);
 
-       if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug)
+       if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)
                return NOTIFY_DONE;
 
        switch (event) {
@@ -4632,8 +4651,8 @@ static __exit void sky2_debug_cleanup(void)
    not allowing netpoll on second port */
 static const struct net_device_ops sky2_netdev_ops[2] = {
   {
-       .ndo_open               = sky2_up,
-       .ndo_stop               = sky2_down,
+       .ndo_open               = sky2_open,
+       .ndo_stop               = sky2_close,
        .ndo_start_xmit         = sky2_xmit_frame,
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -4649,8 +4668,8 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
 #endif
   },
   {
-       .ndo_open               = sky2_up,
-       .ndo_stop               = sky2_down,
+       .ndo_open               = sky2_open,
+       .ndo_stop               = sky2_close,
        .ndo_start_xmit         = sky2_xmit_frame,
        .ndo_do_ioctl           = sky2_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -4703,7 +4722,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        spin_lock_init(&sky2->phy_lock);
 
        sky2->tx_pending = TX_DEF_PENDING;
-       sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1);
+       sky2->tx_ring_size = roundup_ring_size(TX_DEF_PENDING);
        sky2->rx_pending = RX_DEF_PENDING;
 
        hw->dev[port] = dev;
index 0af31b8b5f106174b74c99cd124c758d95c71672..ff6f58bf822aa378ffa0975140733fa40bf41f5d 100644 (file)
@@ -2287,6 +2287,7 @@ struct sky2_hw {
 #define SKY2_HW_RSS_BROKEN     0x00000100
 #define SKY2_HW_VLAN_BROKEN     0x00000200
 #define SKY2_HW_RSS_CHKSUM     0x00000400      /* RSS requires chksum */
+#define SKY2_HW_IRQ_SETUP      0x00000800
 
        u8                   chip_id;
        u8                   chip_rev;
index 116cae334dadc91ca52ce774703284c9b3cd66e7..8be20e7ea3d175d2e8e31e8fd75d151ab0fd1df3 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/export.h>
 #include <linux/bitmap.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
index 32f947154c33c1f7acddb015972cb312878e9ecd..45aea9c3ae2c3f0825771a9a216ee1ccfa5765d7 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/workqueue.h>
+#include <linux/module.h>
 
 #include "mlx4.h"
 
index 23cee7b6af918c146f2f447291bf180a6af4bb58..78f5a1a0b8c8ca806ebe8e7385c822885dbf29c1 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 
index bd8ef9f2fa715deaddef7c867f48b3765645240c..499a5168892aa045399f38b11197cc9e21e6d1dd 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include <linux/hardirq.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 
 #include <linux/mlx4/cmd.h>
index b89c36dbf5b3ea7927fb46252819210bdd55ec26..c2df6c35860317e63a1473e2b69636bedaadc777 100644 (file)
@@ -581,6 +581,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                 * Packet is OK - process it.
                 */
                length = be32_to_cpu(cqe->byte_cnt);
+               length -= ring->fcs_del;
                ring->bytes += length;
                ring->packets++;
 
@@ -813,8 +814,11 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
        context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
 
        /* Cancel FCS removal if FW allows */
-       if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)
+       if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP) {
                context->param3 |= cpu_to_be32(1 << 29);
+               ring->fcs_del = ETH_FCS_LEN;
+       } else
+               ring->fcs_del = 0;
 
        err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);
        if (err) {
index 90f2cd24faac83954b07aabf0c3dc1cdcfc26c60..d901b4267537b8e9d614f57068513a95748d6e22 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/if_vlan.h>
 #include <linux/vmalloc.h>
 #include <linux/tcp.h>
+#include <linux/moduleparam.h>
 
 #include "mlx4_en.h"
 
index 869a2c220a7b4b7c6b727a1696ea94070edab334..24ee96775996dc459c03c62b537eb120538f7201 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 
index abdfbacab4a68eba2a32b1cf104f448cb09247af..435ca6e49734b3df44d213a64ff9028e7e912d1f 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/mlx4/cmd.h>
+#include <linux/module.h>
 #include <linux/cache.h>
 
 #include "fw.h"
index 73c94fcdfddf0096318e4db7649a4c5a858e9f20..ca6feb55bd94721ac4755bf3d57495a74245bb09 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "mlx4.h"
 
index cd1784593a3c9c98706240da59f922d6c3bdbc82..978688c3104685d9ec2054e987ed891b3b4646c4 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/etherdevice.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/export.h>
 
 #include "mlx4.h"
 
index 8fda331c65dfddd19a69da927444ec41be546da4..207b5add3ca848134ea44bf3fadd918ef2912c3f 100644 (file)
@@ -272,6 +272,7 @@ struct mlx4_en_rx_ring {
        u32 prod;
        u32 cons;
        u32 buf_size;
+       u8  fcs_del;
        void *buf;
        void *rx_info;
        unsigned long bytes;
index ab639cfef78ea8005f39beccd6a8f71a92ed96c9..efa3e77355e499eb365b74a0e2fabe8e79f5fa5d 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 
 #include <linux/mlx4/cmd.h>
index 3736163e30e9a6d9296e541d4756b3925c51a5df..260ed259ce9ba8afebdeabadb66a79126e5c85e3 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/io-mapping.h>
 
 #include <asm/page.h>
index a44f080fdfe59899c6d06639a63dfe43bfea8ba4..d942aea4927b1aa1b9ec67ddd703d2227a290fee 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/errno.h>
 #include <linux/if_ether.h>
+#include <linux/export.h>
 
 #include <linux/mlx4/cmd.h>
 
index 51c53898c35f89f3529e866fea994e001a828a85..15f870cb2590b778fa38a3096e19a9957d8ca29d 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/gfp.h>
+#include <linux/export.h>
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/qp.h>
 
index a20b141dbb5cf3a1ee3b8910624b9c0b58740a08..9cbf3fce0145c3f8d8518e125bbb46295669e9fb 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/mlx4/cmd.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
 
 #include "mlx4.h"
index 4a6b9fd073b6330f5d2b693c322c0c5ea2bd5c29..eb836f770f500eb68ead520eacd5b5705f798e3f 100644 (file)
@@ -5,7 +5,10 @@
 config NET_VENDOR_NATSEMI
        bool "National Semi-conductor devices"
        default y
-       depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000
+       depends on AMIGA_PCMCIA || ARM || EISA || EXPERIMENTAL || H8300 || \
+                  ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MCA || \
+                  MCA_LEGACY || MIPS || PCI || PCMCIA || SUPERH || \
+                  XTENSA_PLATFORM_XT2000 || ZORRO
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y
          and read the Ethernet-HOWTO, available from
index 671e166b5af14acc4d7c95e85de48749ef6eca6b..a83197d757c1e4557dc1b883fa341138d0fd3951 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/firmware.h>
 #include <linux/net_tstamp.h>
 #include <linux/prefetch.h>
+#include <linux/module.h>
 #include "vxge-main.h"
 #include "vxge-reg.h"
 
index 1e37eb98c4e29265030dfe930b048d91ea384295..1c61d36e657070d16ecf921992e59a883bf574c3 100644 (file)
@@ -609,7 +609,7 @@ struct nv_ethtool_str {
 };
 
 static const struct nv_ethtool_str nv_estats_str[] = {
-       { "tx_bytes" },
+       { "tx_bytes" }, /* includes Ethernet FCS CRC */
        { "tx_zero_rexmt" },
        { "tx_one_rexmt" },
        { "tx_many_rexmt" },
@@ -637,7 +637,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
        /* version 2 stats */
        { "tx_deferral" },
        { "tx_packets" },
-       { "rx_bytes" },
+       { "rx_bytes" }, /* includes Ethernet FCS CRC */
        { "tx_pause" },
        { "rx_pause" },
        { "rx_drop_frame" },
@@ -649,7 +649,7 @@ static const struct nv_ethtool_str nv_estats_str[] = {
 };
 
 struct nv_ethtool_stats {
-       u64 tx_bytes;
+       u64 tx_bytes; /* should be ifconfig->tx_bytes + 4*tx_packets */
        u64 tx_zero_rexmt;
        u64 tx_one_rexmt;
        u64 tx_many_rexmt;
@@ -670,14 +670,14 @@ struct nv_ethtool_stats {
        u64 rx_unicast;
        u64 rx_multicast;
        u64 rx_broadcast;
-       u64 rx_packets;
+       u64 rx_packets; /* should be ifconfig->rx_packets */
        u64 rx_errors_total;
        u64 tx_errors_total;
 
        /* version 2 stats */
        u64 tx_deferral;
-       u64 tx_packets;
-       u64 rx_bytes;
+       u64 tx_packets; /* should be ifconfig->tx_packets */
+       u64 rx_bytes;   /* should be ifconfig->rx_bytes + 4*rx_packets */
        u64 tx_pause;
        u64 rx_pause;
        u64 rx_drop_frame;
@@ -1682,6 +1682,7 @@ static void nv_get_hw_stats(struct net_device *dev)
                np->estats.tx_pause += readl(base + NvRegTxPause);
                np->estats.rx_pause += readl(base + NvRegRxPause);
                np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame);
+               np->estats.rx_errors_total += np->estats.rx_drop_frame;
        }
 
        if (np->driver_data & DEV_HAS_STATISTICS_V3) {
@@ -1705,12 +1706,22 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
        if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
                nv_get_hw_stats(dev);
 
+               /*
+                * Note: because HW stats are not always available and
+                * for consistency reasons, the following ifconfig
+                * stats are managed by software: rx_bytes, tx_bytes,
+                * rx_packets and tx_packets. The related hardware
+                * stats reported by ethtool should be equivalent to
+                * these ifconfig stats, with 4 additional bytes per
+                * packet (Ethernet FCS CRC).
+                */
+
                /* copy to net_device stats */
-               dev->stats.tx_bytes = np->estats.tx_bytes;
                dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
                dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
                dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
                dev->stats.rx_over_errors = np->estats.rx_over_errors;
+               dev->stats.rx_fifo_errors = np->estats.rx_drop_frame;
                dev->stats.rx_errors = np->estats.rx_errors_total;
                dev->stats.tx_errors = np->estats.tx_errors_total;
        }
@@ -2099,10 +2110,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* add fragments to entries count */
        for (i = 0; i < fragments; i++) {
-               u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
+               u32 frag_size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
 
-               entries += (size >> NV_TX2_TSO_MAX_SHIFT) +
-                          ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
+               entries += (frag_size >> NV_TX2_TSO_MAX_SHIFT) +
+                          ((frag_size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
        }
 
        spin_lock_irqsave(&np->lock, flags);
@@ -2141,13 +2152,13 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* setup the fragments */
        for (i = 0; i < fragments; i++) {
                const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-               u32 size = skb_frag_size(frag);
+               u32 frag_size = skb_frag_size(frag);
                offset = 0;
 
                do {
                        prev_tx = put_tx;
                        prev_tx_ctx = np->put_tx_ctx;
-                       bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
+                       bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size;
                        np->put_tx_ctx->dma = skb_frag_dma_map(
                                                        &np->pci_dev->dev,
                                                        frag, offset,
@@ -2159,12 +2170,12 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
                        offset += bcnt;
-                       size -= bcnt;
+                       frag_size -= bcnt;
                        if (unlikely(put_tx++ == np->last_tx.orig))
                                put_tx = np->first_tx.orig;
                        if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
                                np->put_tx_ctx = np->first_tx_ctx;
-               } while (size);
+               } while (frag_size);
        }
 
        /* set last fragment flag  */
@@ -2213,10 +2224,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
 
        /* add fragments to entries count */
        for (i = 0; i < fragments; i++) {
-               u32 size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
+               u32 frag_size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
 
-               entries += (size >> NV_TX2_TSO_MAX_SHIFT) +
-                          ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
+               entries += (frag_size >> NV_TX2_TSO_MAX_SHIFT) +
+                          ((frag_size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
        }
 
        spin_lock_irqsave(&np->lock, flags);
@@ -2257,13 +2268,13 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
        /* setup the fragments */
        for (i = 0; i < fragments; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-               u32 size = skb_frag_size(frag);
+               u32 frag_size = skb_frag_size(frag);
                offset = 0;
 
                do {
                        prev_tx = put_tx;
                        prev_tx_ctx = np->put_tx_ctx;
-                       bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
+                       bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size;
                        np->put_tx_ctx->dma = skb_frag_dma_map(
                                                        &np->pci_dev->dev,
                                                        frag, offset,
@@ -2276,12 +2287,12 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                        put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
                        offset += bcnt;
-                       size -= bcnt;
+                       frag_size -= bcnt;
                        if (unlikely(put_tx++ == np->last_tx.ex))
                                put_tx = np->first_tx.ex;
                        if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
                                np->put_tx_ctx = np->first_tx_ctx;
-               } while (size);
+               } while (frag_size);
        }
 
        /* set last fragment flag  */
@@ -2374,13 +2385,8 @@ static int nv_tx_done(struct net_device *dev, int limit)
                if (np->desc_ver == DESC_VER_1) {
                        if (flags & NV_TX_LASTPACKET) {
                                if (flags & NV_TX_ERROR) {
-                                       if (flags & NV_TX_UNDERFLOW)
-                                               dev->stats.tx_fifo_errors++;
-                                       if (flags & NV_TX_CARRIERLOST)
-                                               dev->stats.tx_carrier_errors++;
                                        if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
-                                       dev->stats.tx_errors++;
                                } else {
                                        dev->stats.tx_packets++;
                                        dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
@@ -2392,13 +2398,8 @@ static int nv_tx_done(struct net_device *dev, int limit)
                } else {
                        if (flags & NV_TX2_LASTPACKET) {
                                if (flags & NV_TX2_ERROR) {
-                                       if (flags & NV_TX2_UNDERFLOW)
-                                               dev->stats.tx_fifo_errors++;
-                                       if (flags & NV_TX2_CARRIERLOST)
-                                               dev->stats.tx_carrier_errors++;
                                        if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
-                                       dev->stats.tx_errors++;
                                } else {
                                        dev->stats.tx_packets++;
                                        dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
@@ -2434,15 +2435,16 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
                nv_unmap_txskb(np, np->get_tx_ctx);
 
                if (flags & NV_TX2_LASTPACKET) {
-                       if (!(flags & NV_TX2_ERROR))
-                               dev->stats.tx_packets++;
-                       else {
+                       if (flags & NV_TX2_ERROR) {
                                if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) {
                                        if (np->driver_data & DEV_HAS_GEAR_MODE)
                                                nv_gear_backoff_reseed(dev);
                                        else
                                                nv_legacybackoff_reseed(dev);
                                }
+                       } else {
+                               dev->stats.tx_packets++;
+                               dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                        }
 
                        dev_kfree_skb_any(np->get_tx_ctx->skb);
@@ -2636,7 +2638,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        if ((flags & NV_RX_ERROR_MASK) == NV_RX_ERROR4) {
                                                len = nv_getlen(dev, skb->data, len);
                                                if (len < 0) {
-                                                       dev->stats.rx_errors++;
                                                        dev_kfree_skb(skb);
                                                        goto next_pkt;
                                                }
@@ -2650,11 +2651,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        else {
                                                if (flags & NV_RX_MISSEDFRAME)
                                                        dev->stats.rx_missed_errors++;
-                                               if (flags & NV_RX_CRCERR)
-                                                       dev->stats.rx_crc_errors++;
-                                               if (flags & NV_RX_OVERFLOW)
-                                                       dev->stats.rx_over_errors++;
-                                               dev->stats.rx_errors++;
                                                dev_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2670,7 +2666,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) {
                                                len = nv_getlen(dev, skb->data, len);
                                                if (len < 0) {
-                                                       dev->stats.rx_errors++;
                                                        dev_kfree_skb(skb);
                                                        goto next_pkt;
                                                }
@@ -2682,11 +2677,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        }
                                        /* the rest are hard errors */
                                        else {
-                                               if (flags & NV_RX2_CRCERR)
-                                                       dev->stats.rx_crc_errors++;
-                                               if (flags & NV_RX2_OVERFLOW)
-                                                       dev->stats.rx_over_errors++;
-                                               dev->stats.rx_errors++;
                                                dev_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2787,7 +2777,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                                __vlan_hwaccel_put_tag(skb, vid);
                        }
                        napi_gro_receive(&np->napi, skb);
-
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += len;
                } else {
@@ -2962,11 +2951,11 @@ static void nv_set_multicast(struct net_device *dev)
                                struct netdev_hw_addr *ha;
 
                                netdev_for_each_mc_addr(ha, dev) {
-                                       unsigned char *addr = ha->addr;
+                                       unsigned char *hw_addr = ha->addr;
                                        u32 a, b;
 
-                                       a = le32_to_cpu(*(__le32 *) addr);
-                                       b = le16_to_cpu(*(__le16 *) (&addr[4]));
+                                       a = le32_to_cpu(*(__le32 *) hw_addr);
+                                       b = le16_to_cpu(*(__le16 *) (&hw_addr[4]));
                                        alwaysOn[0] &= a;
                                        alwaysOff[0] &= ~a;
                                        alwaysOn[1] &= b;
@@ -3398,7 +3387,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
 
        for (i = 0;; i++) {
                events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL;
-               writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus);
+               writel(events, base + NvRegMSIXIrqStatus);
+               netdev_dbg(dev, "tx irq events: %08x\n", events);
                if (!(events & np->irqmask))
                        break;
 
@@ -3509,7 +3499,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 
        for (i = 0;; i++) {
                events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
-               writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
+               writel(events, base + NvRegMSIXIrqStatus);
+               netdev_dbg(dev, "rx irq events: %08x\n", events);
                if (!(events & np->irqmask))
                        break;
 
@@ -3553,7 +3544,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
 
        for (i = 0;; i++) {
                events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER;
-               writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus);
+               writel(events, base + NvRegMSIXIrqStatus);
+               netdev_dbg(dev, "irq events: %08x\n", events);
                if (!(events & np->irqmask))
                        break;
 
@@ -3617,10 +3609,10 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data)
 
        if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
                events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
-               writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus);
+               writel(events & NVREG_IRQ_TIMER, base + NvRegIrqStatus);
        } else {
                events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
-               writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
+               writel(events & NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
        }
        pci_push(base);
        if (!(events & NVREG_IRQ_TIMER))
@@ -4566,7 +4558,7 @@ static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *e
        struct fe_priv *np = netdev_priv(dev);
 
        /* update stats */
-       nv_do_stats_poll((unsigned long)dev);
+       nv_get_hw_stats(dev);
 
        memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64));
 }
index bc1d946b7971b6c1ede4fc7616aa5609d153b26c..212f43b308a3c27ed411b21768e160e0d899a571 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/capability.h>
 #include <linux/dma-mapping.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/netdevice.h>
index b89f3a684aec4dbb1cb83d0ef7d59e0ffc567330..48406ca382f1de638e8938b4732f19406485fc83 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "pch_gbe.h"
 #include "pch_gbe_api.h"
+#include <linux/module.h>
 
 #define DRV_VERSION     "1.00"
 const char pch_driver_version[] = DRV_VERSION;
index 5b5d90a47e29419eef6cb207066403e37e855efc..9cb5f912e4891f5b832bb941bce6916c5248bdb6 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "pch_gbe.h"
+#include <linux/module.h>      /* for __MODULE_STRING */
 
 #define OPTION_UNSET   -1
 #define OPTION_DISABLED 0
index 05db5434bafc3284eb0a3b6162a64c8ed2c436d6..90497ffb1ac39d5635d258730f8cc229275aa240 100644 (file)
@@ -2,4 +2,5 @@
 # Makefile for the A Semi network device drivers.
 #
 
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o
+obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
+pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
index 8731f79c9efc40439bac7af0363225d885f42036..b8478aab050e76efa2b734572b3f866f98da321f 100644 (file)
 
 
 #define TX_DESC_PER_IOCB 8
-/* The maximum number of frags we handle is based
- * on PAGE_SIZE...
- */
-#if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 13)   /* 4k & 8k pages */
+
+#if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0
 #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2)
 #else /* all other page sizes */
 #define TX_DESC_PER_OAL 0
@@ -1353,7 +1351,7 @@ struct tx_ring_desc {
        struct ob_mac_iocb_req *queue_entry;
        u32 index;
        struct oal oal;
-       struct map_list map[MAX_SKB_FRAGS + 1];
+       struct map_list map[MAX_SKB_FRAGS + 2];
        int map_cnt;
        struct tx_ring_desc *next;
 };
index 1fc01ca72b466095b682f209b266f7209f8d3ec1..4bf68cfef39072d607420c476160944888d5fa47 100644 (file)
@@ -940,7 +940,7 @@ static void r6040_multicast_list(struct net_device *dev)
        iowrite16(lp->mcr0, ioaddr + MCR0);
 
        /* Fill the MAC hash tables with their values */
-       if (lp->mcr0 && MCR0_HASH_EN) {
+       if (lp->mcr0 & MCR0_HASH_EN) {
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
                iowrite16(hash_table[2], ioaddr + MAR2);
index 92b45f08858fab787a7ac3de3297f9b8c318ea67..67bf0781999200d656e09e990be95709700cbce1 100644 (file)
@@ -1183,11 +1183,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
        return value;
 }
 
-static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
+static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
 {
-       RTL_W16(IntrMask, 0x0000);
+       void __iomem *ioaddr = tp->mmio_addr;
 
-       RTL_W16(IntrStatus, 0xffff);
+       RTL_W16(IntrMask, 0x0000);
+       RTL_W16(IntrStatus, tp->intr_event);
+       RTL_R8(ChipCmd);
 }
 
 static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
@@ -1292,7 +1294,7 @@ static void __rtl8169_check_link_status(struct net_device *dev,
                netif_carrier_off(dev);
                netif_info(tp, ifdown, dev, "link down\n");
                if (pm)
-                       pm_schedule_suspend(&tp->pci_dev->dev, 100);
+                       pm_schedule_suspend(&tp->pci_dev->dev, 5000);
        }
        spin_unlock_irqrestore(&tp->lock, flags);
 }
@@ -3933,8 +3935,6 @@ static void rtl_hw_reset(struct rtl8169_private *tp)
                        break;
                udelay(100);
        }
-
-       rtl8169_init_ring_indexes(tp);
 }
 
 static int __devinit
@@ -4339,7 +4339,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
        void __iomem *ioaddr = tp->mmio_addr;
 
        /* Disable interrupts */
-       rtl8169_irq_mask_and_ack(ioaddr);
+       rtl8169_irq_mask_and_ack(tp);
 
        rtl_rx_close(tp);
 
@@ -4885,8 +4885,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
        RTL_W16(IntrMitigate, 0x5151);
 
        /* Work around for RxFIFO overflow. */
-       if (tp->mac_version == RTL_GIGA_MAC_VER_11 ||
-           tp->mac_version == RTL_GIGA_MAC_VER_22) {
+       if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
                tp->intr_event |= RxFIFOOver | PCSTimeout;
                tp->intr_event &= ~RxOverflow;
        }
@@ -5076,6 +5075,11 @@ static void rtl_hw_start_8101(struct net_device *dev)
        void __iomem *ioaddr = tp->mmio_addr;
        struct pci_dev *pdev = tp->pci_dev;
 
+       if (tp->mac_version >= RTL_GIGA_MAC_VER_30) {
+               tp->intr_event &= ~RxFIFOOver;
+               tp->napi_event &= ~RxFIFOOver;
+       }
+
        if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
            tp->mac_version == RTL_GIGA_MAC_VER_16) {
                int cap = pci_pcie_cap(pdev);
@@ -5342,7 +5346,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
        /* Wait for any pending NAPI task to complete */
        napi_disable(&tp->napi);
 
-       rtl8169_irq_mask_and_ack(ioaddr);
+       rtl8169_irq_mask_and_ack(tp);
 
        tp->intr_mask = 0xffff;
        RTL_W16(IntrMask, tp->intr_event);
@@ -5389,14 +5393,16 @@ static void rtl8169_reset_task(struct work_struct *work)
        if (!netif_running(dev))
                goto out_unlock;
 
+       rtl8169_hw_reset(tp);
+
        rtl8169_wait_for_quiescence(dev);
 
        for (i = 0; i < NUM_RX_DESC; i++)
                rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);
 
        rtl8169_tx_clear(tp);
+       rtl8169_init_ring_indexes(tp);
 
-       rtl8169_hw_reset(tp);
        rtl_hw_start(dev);
        netif_wake_queue(dev);
        rtl8169_check_link_status(dev, tp, tp->mmio_addr);
@@ -5407,11 +5413,6 @@ out_unlock:
 
 static void rtl8169_tx_timeout(struct net_device *dev)
 {
-       struct rtl8169_private *tp = netdev_priv(dev);
-
-       rtl8169_hw_reset(tp);
-
-       /* Let's wait a bit while any (async) irq lands on */
        rtl8169_schedule_work(dev, rtl8169_reset_task);
 }
 
@@ -5804,6 +5805,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
         */
        status = RTL_R16(IntrStatus);
        while (status && status != 0xffff) {
+               status &= tp->intr_event;
+               if (!status)
+                       break;
+
                handled = 1;
 
                /* Handle all of the error cases first. These will reset
@@ -5818,27 +5823,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                        switch (tp->mac_version) {
                        /* Work around for rx fifo overflow */
                        case RTL_GIGA_MAC_VER_11:
-                       case RTL_GIGA_MAC_VER_22:
-                       case RTL_GIGA_MAC_VER_26:
                                netif_stop_queue(dev);
                                rtl8169_tx_timeout(dev);
                                goto done;
-                       /* Testers needed. */
-                       case RTL_GIGA_MAC_VER_17:
-                       case RTL_GIGA_MAC_VER_19:
-                       case RTL_GIGA_MAC_VER_20:
-                       case RTL_GIGA_MAC_VER_21:
-                       case RTL_GIGA_MAC_VER_23:
-                       case RTL_GIGA_MAC_VER_24:
-                       case RTL_GIGA_MAC_VER_27:
-                       case RTL_GIGA_MAC_VER_28:
-                       case RTL_GIGA_MAC_VER_31:
-                       /* Experimental science. Pktgen proof. */
-                       case RTL_GIGA_MAC_VER_12:
-                       case RTL_GIGA_MAC_VER_25:
-                               if (status == RxFIFOOver)
-                                       goto done;
-                               break;
                        default:
                                break;
                        }
index adbda182f15997b41da7609aa9997dc2f0608f45..752d521c09b1a15400ada2d8ce6fce786f1c42c9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/prefetch.h>
+#include <linux/moduleparam.h>
 #include <net/ip.h>
 #include <net/checksum.h>
 #include "net_driver.h"
index d2be42aafbef201e48ea5d1fb177564aaeaacf31..8843071fe987bd1543b91387f6da9c3c9a8d0800 100644 (file)
@@ -1937,6 +1937,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
 {
        struct smsc911x_data *pdata = netdev_priv(dev);
        unsigned int byte_test;
+       unsigned int to = 100;
 
        SMSC_TRACE(pdata, probe, "Driver Parameters:");
        SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
@@ -1952,6 +1953,17 @@ static int __devinit smsc911x_init(struct net_device *dev)
                return -ENODEV;
        }
 
+       /*
+        * poll the READY bit in PMT_CTRL. Any other access to the device is
+        * forbidden while this bit isn't set. Try for 100ms
+        */
+       while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+               udelay(1000);
+       if (to == 0) {
+               pr_err("Device not READY in 100ms aborting\n");
+               return -ENODEV;
+       }
+
        /* Check byte ordering */
        byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
        SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
index 4f15680849ffcc51a95c31425167011d1b0e277f..edb24b0e337be8d27af132519d771e1f58aa36ac 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/crc32.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 #include "smsc9420.h"
 
index ac6f190743dd3227e269d8e05f9df894681e626f..22745d7bf530d3e4865c869a671f981d4758019d 100644 (file)
@@ -29,15 +29,6 @@ config STMMAC_DA
          By default, the DMA arbitration scheme is based on Round-robin
          (rx:tx priority is 1:1).
 
-config STMMAC_DUAL_MAC
-       bool "STMMAC: dual mac support (EXPERIMENTAL)"
-       default n
-        depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
-       ---help---
-         Some ST SoCs (for example the stx7141 and stx7200c2) have two
-         Ethernet Controllers. This option turns on the second Ethernet
-         device on this kind of platforms.
-
 config STMMAC_TIMER
        bool "STMMAC Timer optimisation"
        default n
index da66ac511c4c60df8dabe849cd02ba9ae2d76dad..4d5402a1d262976bdede2fed63875000d81e17fb 100644 (file)
@@ -39,10 +39,11 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
        /* DMA SW reset */
        value |= DMA_BUS_MODE_SFT_RESET;
        writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
+       limit = 10;
        while (limit--) {
                if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
                        break;
+               mdelay(10);
        }
        if (limit < 0)
                return -EBUSY;
index 627f656b0f3c581bbb20a45084b7c1fd87a22194..bc17fd08b55dc9085a9ea66cefe1f388fd3ce985 100644 (file)
@@ -41,10 +41,11 @@ static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
        /* DMA SW reset */
        value |= DMA_BUS_MODE_SFT_RESET;
        writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
+       limit = 10;
        while (limit--) {
                if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
                        break;
+               mdelay(10);
        }
        if (limit < 0)
                return -EBUSY;
index 9bafa6cf9e8b5af13b262e1efc28809ff9a9c910..a140a8fbf0515c70e2471639907239f34b55f036 100644 (file)
@@ -72,7 +72,6 @@ struct stmmac_priv {
        spinlock_t lock;
        spinlock_t tx_lock;
        int wolopts;
-       int wolenabled;
        int wol_irq;
 #ifdef CONFIG_STMMAC_TIMER
        struct stmmac_timer *tm;
@@ -80,6 +79,7 @@ struct stmmac_priv {
        struct plat_stmmacenet_data *plat;
        struct stmmac_counters mmc;
        struct dma_features dma_cap;
+       int hw_cap_support;
 };
 
 extern int stmmac_mdio_unregister(struct net_device *ndev);
index e8eff09bbbd73c7b036f5cd9520d030c949fddc1..0395f9eba801e9281f6af9a9fca8dc12057b55e4 100644 (file)
@@ -430,6 +430,12 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        struct stmmac_priv *priv = netdev_priv(dev);
        u32 support = WAKE_MAGIC | WAKE_UCAST;
 
+       /* By default almost all GMAC devices support the WoL via
+        * magic frame but we can disable it if the HW capability
+        * register shows no support for pmt_magic_frame. */
+       if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
+               wol->wolopts &= ~WAKE_MAGIC;
+
        if (!device_can_wakeup(priv->device))
                return -EINVAL;
 
index 20546bbbb8db04744d39b2e4a4e5710f04fa6538..72cd190b9c1a0734d401b193e1bd7b12cb49b3af 100644 (file)
@@ -321,12 +321,10 @@ static int stmmac_init_phy(struct net_device *dev)
        }
 
        /* Stop Advertising 1000BASE Capability if interface is not GMII */
-       if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
-           (interface == PHY_INTERFACE_MODE_RMII))) {
-               phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-                                     SUPPORTED_Asym_Pause);
-               phydev->advertising = phydev->supported;
-       }
+       if ((interface == PHY_INTERFACE_MODE_MII) ||
+           (interface == PHY_INTERFACE_MODE_RMII))
+               phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
+                                        SUPPORTED_1000baseT_Full);
 
        /*
         * Broken HW is sometimes missing the pull-up resistor on the
@@ -783,10 +781,15 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
        unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
                            MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
 
-       /* Do not manage MMC IRQ (FIXME) */
+       /* Mask MMC irq, counters are managed in SW and registers
+        * are cleared on each READ eventually. */
        dwmac_mmc_intr_all_mask(priv->ioaddr);
-       dwmac_mmc_ctrl(priv->ioaddr, mode);
-       memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+
+       if (priv->dma_cap.rmon) {
+               dwmac_mmc_ctrl(priv->ioaddr, mode);
+               memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+       } else
+               pr_info(" No MAC Management Counters available");
 }
 
 static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
@@ -807,8 +810,29 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
        return 0;
 }
 
-/* New GMAC chips support a new register to indicate the
- * presence of the optional feature/functions.
+/**
+ * stmmac_selec_desc_mode
+ * @dev : device pointer
+ * Description: select the Enhanced/Alternate or Normal descriptors */
+static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
+{
+       if (priv->plat->enh_desc) {
+               pr_info(" Enhanced/Alternate descriptors\n");
+               priv->hw->desc = &enh_desc_ops;
+       } else {
+               pr_info(" Normal descriptors\n");
+               priv->hw->desc = &ndesc_ops;
+       }
+}
+
+/**
+ * stmmac_get_hw_features
+ * @priv : private device pointer
+ * Description:
+ *  new GMAC chip generations have a new register to indicate the
+ *  presence of the optional feature/functions.
+ *  This can be also used to override the value passed through the
+ *  platform and necessary for old MAC10/100 and GMAC chips.
  */
 static int stmmac_get_hw_features(struct stmmac_priv *priv)
 {
@@ -829,7 +853,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
                        (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
                priv->dma_cap.pmt_magic_frame =
                        (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
-               /*MMC*/
+               /* MMC */
                priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
                /* IEEE 1588-2002*/
                priv->dma_cap.time_stamp =
@@ -857,8 +881,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
                priv->dma_cap.enh_desc =
                        (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
 
-       } else
-               pr_debug("\tNo HW DMA feature register supported");
+       }
 
        return hw_cap;
 }
@@ -913,6 +936,44 @@ static int stmmac_open(struct net_device *dev)
                goto open_error;
        }
 
+       stmmac_get_synopsys_id(priv);
+
+       priv->hw_cap_support = stmmac_get_hw_features(priv);
+
+       if (priv->hw_cap_support) {
+               pr_info(" Support DMA HW capability register");
+
+               /* We can override some gmac/dma configuration fields: e.g.
+                * enh_desc, tx_coe (e.g. that are passed through the
+                * platform) with the values from the HW capability
+                * register (if supported).
+                */
+               priv->plat->enh_desc = priv->dma_cap.enh_desc;
+               priv->plat->tx_coe = priv->dma_cap.tx_coe;
+               priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
+
+               /* By default disable wol on magic frame if not supported */
+               if (!priv->dma_cap.pmt_magic_frame)
+                       priv->wolopts &= ~WAKE_MAGIC;
+
+       } else
+               pr_info(" No HW DMA feature register supported");
+
+       /* Select the enhnaced/normal descriptor structures */
+       stmmac_selec_desc_mode(priv);
+
+       /* PMT module is not integrated in all the MAC devices. */
+       if (priv->plat->pmt) {
+               pr_info(" Remote wake-up capable\n");
+               device_set_wakeup_capable(priv->device, 1);
+       }
+
+       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+       if (priv->rx_coe)
+               pr_info(" Checksum Offload Engine supported\n");
+       if (priv->plat->tx_coe)
+               pr_info(" Checksum insertion supported\n");
+
        /* Create and initialize the TX/RX descriptors chains. */
        priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
        priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
@@ -935,15 +996,6 @@ static int stmmac_open(struct net_device *dev)
        /* Initialize the MAC Core */
        priv->hw->mac->core_init(priv->ioaddr);
 
-       stmmac_get_synopsys_id(priv);
-
-       stmmac_get_hw_features(priv);
-
-       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
-       if (priv->rx_coe)
-               pr_info("stmmac: Rx Checksum Offload Engine supported\n");
-       if (priv->plat->tx_coe)
-               pr_info("\tTX Checksum insertion supported\n");
        netdev_update_features(dev);
 
        /* Request the IRQ lines */
@@ -965,8 +1017,7 @@ static int stmmac_open(struct net_device *dev)
        memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
        priv->xstats.threshold = tc;
 
-       if (priv->dma_cap.rmon)
-               stmmac_mmc_setup(priv);
+       stmmac_mmc_setup(priv);
 
        /* Start the ball rolling... */
        DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
@@ -1489,9 +1540,7 @@ static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        if (!priv->phydev)
                return -EINVAL;
 
-       spin_lock(&priv->lock);
        ret = phy_mii_ioctl(priv->phydev, rq, cmd);
-       spin_unlock(&priv->lock);
 
        return ret;
 }
@@ -1558,7 +1607,7 @@ static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
        struct net_device *dev = seq->private;
        struct stmmac_priv *priv = netdev_priv(dev);
 
-       if (!stmmac_get_hw_features(priv)) {
+       if (!priv->hw_cap_support) {
                seq_printf(seq, "DMA HW features not supported\n");
                return 0;
        }
@@ -1766,12 +1815,6 @@ static int stmmac_mac_device_setup(struct net_device *dev)
        if (!device)
                return -ENOMEM;
 
-       if (priv->plat->enh_desc) {
-               device->desc = &enh_desc_ops;
-               pr_info("\tEnhanced descriptor structure\n");
-       } else
-               device->desc = &ndesc_ops;
-
        priv->hw = device;
        priv->hw->ring = &ring_mode_ops;
 
@@ -1845,11 +1888,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
 
        priv->ioaddr = addr;
 
-       /* PMT module is not integrated in all the MAC devices. */
-       if (plat_dat->pmt) {
-               pr_info("\tPMT module supported\n");
-               device_set_wakeup_capable(&pdev->dev, 1);
-       }
        /*
         * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
         * The external wake up irq can be passed through the platform code
@@ -1862,7 +1900,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
        if (priv->wol_irq == -ENXIO)
                priv->wol_irq = ndev->irq;
 
-
        platform_set_drvdata(pdev, ndev);
 
        /* Set the I/O base addr */
@@ -1875,7 +1912,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
                        goto out_free_ndev;
        }
 
-       /* MAC HW revice detection */
+       /* MAC HW device detection */
        ret = stmmac_mac_device_setup(ndev);
        if (ret < 0)
                goto out_plat_exit;
@@ -1978,12 +2015,13 @@ static int stmmac_suspend(struct device *dev)
        if (!ndev || !netif_running(ndev))
                return 0;
 
+       if (priv->phydev)
+               phy_stop(priv->phydev);
+
        spin_lock(&priv->lock);
 
        netif_device_detach(ndev);
        netif_stop_queue(ndev);
-       if (priv->phydev)
-               phy_stop(priv->phydev);
 
 #ifdef CONFIG_STMMAC_TIMER
        priv->tm->timer_stop();
@@ -2041,12 +2079,13 @@ static int stmmac_resume(struct device *dev)
 #endif
        napi_enable(&priv->napi);
 
-       if (priv->phydev)
-               phy_start(priv->phydev);
-
        netif_start_queue(ndev);
 
        spin_unlock(&priv->lock);
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
        return 0;
 }
 
index c517dac02ae1837343ff48465274f7b3e54caae3..cf14ab9db5768f7781f7b9983120c01644fad0aa 100644 (file)
@@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i
        sbus_dp = op->dev.parent->of_node;
 
        /* We can match PCI devices too, do not accept those here. */
-       if (strcmp(sbus_dp->name, "sbus"))
+       if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))
                return err;
 
        if (is_qfe) {
index 10826d8a2a2df36b3731051b2d4abb504c15ce39..1187a1169eb21b50351599939cc4cb9728ad3b57 100644 (file)
@@ -926,7 +926,7 @@ static int tile_net_poll(struct napi_struct *napi, int budget)
                goto done;
 
        /* Re-enable the ingress interrupt. */
-       enable_percpu_irq(priv->intr_id);
+       enable_percpu_irq(priv->intr_id, 0);
 
        /* HACK: Avoid the "rotting packet" problem (see above). */
        if (qup->__packet_receive_read !=
@@ -1296,7 +1296,7 @@ static void tile_net_open_enable(void *dev_ptr)
        info->napi_enabled = true;
 
        /* Enable the ingress interrupt. */
-       enable_percpu_irq(priv->intr_id);
+       enable_percpu_irq(priv->intr_id, 0);
 }
 
 
@@ -1697,7 +1697,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
        for (i = 0; i < sh->nr_frags; i++) {
 
                skb_frag_t *f = &sh->frags[i];
-               unsigned long pfn = page_to_pfn(f->page);
+               unsigned long pfn = page_to_pfn(skb_frag_page(f));
 
                /* FIXME: Compute "hash_for_home" properly. */
                /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */
@@ -1706,7 +1706,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
                /* FIXME: Hmmm. */
                if (!hash_default) {
                        void *va = pfn_to_kaddr(pfn) + f->page_offset;
-                       BUG_ON(PageHighMem(f->page));
+                       BUG_ON(PageHighMem(skb_frag_page(f)));
                        finv_buffer_remote(va, f->size, 0);
                }
 
index ddb33cfd3543d6a16c8e469454ba5666d05945ae..7bf1e2015784722765d94c0065ac1c5615dc3765 100644 (file)
@@ -1674,6 +1674,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
        int result;
 
        pr_debug("%s: called\n", __func__);
+
+       udbg_shutdown_ps3gelic();
+
        result = ps3_open_hv_device(dev);
 
        if (result) {
index d3fadfbc3bcc1f5b4e154ae717f2f96d56fd81af..a93df6ac190980f697aaf3c20c47970113359f1e 100644 (file)
@@ -359,6 +359,12 @@ static inline void *port_priv(struct gelic_port *port)
        return port->priv;
 }
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
+extern void udbg_shutdown_ps3gelic(void);
+#else
+static inline void udbg_shutdown_ps3gelic(void) {}
+#endif
+
 extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
 /* shared netdev ops */
 extern void gelic_card_up(struct gelic_card *card);
index caf3659e173cda3a04735cb1ecad7cfd94de27c7..2681b53820eefaf3edaa8e6e336b9b6de12d8bf0 100644 (file)
@@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
                return;
        temac_iow(lp, XTE_LSW0_OFFSET, value);
        temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+       temac_indirect_busywait(lp);
 }
 
 /**
@@ -203,6 +204,9 @@ static void temac_dma_bd_release(struct net_device *ndev)
        struct temac_local *lp = netdev_priv(ndev);
        int i;
 
+       /* Reset Local Link (DMA) */
+       lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+
        for (i = 0; i < RX_BD_NUM; i++) {
                if (!lp->rx_skb[i])
                        break;
@@ -860,6 +864,8 @@ static int temac_open(struct net_device *ndev)
                phy_start(lp->phy_dev);
        }
 
+       temac_device_reset(ndev);
+
        rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
        if (rc)
                goto err_tx_irq;
@@ -867,7 +873,6 @@ static int temac_open(struct net_device *ndev)
        if (rc)
                goto err_rx_irq;
 
-       temac_device_reset(ndev);
        return 0;
 
  err_rx_irq:
index ec96d910e9a3e6528172329f730465d2bda4caac..f45c85a8426125be667c80cd4e8408bb58fc7337 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/platform_device.h>
 #include <linux/ptp_classify.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <mach/ixp46x_ts.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
index 7393eb732ee6737b31fa28c70f5baf1c4e1f3499..95eb34fdbba7b2ac1996303675bc9b0b262cbadf 100644 (file)
@@ -36,4 +36,4 @@ config ROADRUNNER_LARGE_RINGS
          kernel code or by user space programs. Say Y here only if you have
          the memory.
 
-endif /* HIPPI */
+endif # HIPPI
index a3ce3d4561eda101d9f54168d03d383b991aeac3..74134970b7095c4faae3f9f627358bd69617353d 100644 (file)
@@ -192,6 +192,13 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
                         */
                        macvlan_broadcast(skb, port, src->dev,
                                          MACVLAN_MODE_VEPA);
+               else {
+                       /* forward to original port. */
+                       vlan = src;
+                       ret = macvlan_broadcast_one(skb, vlan, eth, 0);
+                       goto out;
+               }
+
                return RX_HANDLER_PASS;
        }
 
index bb88e12101c78b86b91def144677e4ecb10d8091..a70244306c9462830c4ebde0b87334ef7667fa0e 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 menuconfig PHYLIB
-       bool "PHY Device support and infrastructure"
+       tristate "PHY Device support and infrastructure"
        depends on !S390
        depends on NETDEVICES
        help
index a4eae750a4145084b0cf45e90b875f1eb2c019c3..f414ffb5b728130591530cfaa350eb78fb03251b 100644 (file)
@@ -14,6 +14,7 @@
  *
  */
 #include <linux/phy.h>
+#include <linux/module.h>
 
 #define RTL821x_PHYSR          0x11
 #define RTL821x_PHYSR_DUPLEX   0x2000
index e81e22e3d1d2fcf84be504403002b52d492a01d8..e6fed4d4cb77f70c8c6d62af16d53a57ed31c99c 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/slab.h>
 
-#define DRIVER_VERSION "26-Sep-2011"
+#define DRIVER_VERSION "08-Nov-2011"
 #define DRIVER_NAME "asix"
 
 /* ASIX AX8817X based USB 2.0 Ethernet Devices */
 #define MARVELL_CTRL_TXDELAY   0x0002
 #define MARVELL_CTRL_RXDELAY   0x0080
 
-#define        PHY_MODE_RTL8211CL      0x0004
+#define        PHY_MODE_RTL8211CL      0x000C
 
 /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
 struct asix_data {
@@ -652,9 +652,17 @@ static u32 asix_get_phyid(struct usbnet *dev)
 {
        int phy_reg;
        u32 phy_id;
+       int i;
 
-       phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
-       if (phy_reg < 0)
+       /* Poll for the rare case the FW or phy isn't ready yet.  */
+       for (i = 0; i < 100; i++) {
+               phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
+               if (phy_reg != 0 && phy_reg != 0xFFFF)
+                       break;
+               mdelay(1);
+       }
+
+       if (phy_reg <= 0 || phy_reg == 0xFFFF)
                return 0;
 
        phy_id = (phy_reg & 0xffff) << 16;
@@ -1075,7 +1083,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
 
 static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
 {
-       int ret;
+       int ret, embd_phy;
        struct asix_data *data = (struct asix_data *)&dev->data;
        u8 buf[ETH_ALEN];
        u32 phyid;
@@ -1100,16 +1108,36 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->mii.reg_num_mask = 0x1f;
        dev->mii.phy_id = asix_get_phy_addr(dev);
 
-       phyid = asix_get_phyid(dev);
-       dbg("PHYID=0x%08x", phyid);
-
        dev->net->netdev_ops = &ax88772_netdev_ops;
        dev->net->ethtool_ops = &ax88772_ethtool_ops;
 
-       ret = ax88772_reset(dev);
+       embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
+
+       /* Reset the PHY to normal operation mode */
+       ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
+       if (ret < 0) {
+               dbg("Select PHY #1 failed: %d", ret);
+               return ret;
+       }
+
+       ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
+       if (ret < 0)
+               return ret;
+
+       msleep(150);
+
+       ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
        if (ret < 0)
                return ret;
 
+       msleep(150);
+
+       ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE);
+
+       /* Read PHYID register *AFTER* the PHY was reset properly */
+       phyid = asix_get_phyid(dev);
+       dbg("PHYID=0x%08x", phyid);
+
        /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
        if (dev->driver_info->flags & FLAG_FRAMING_AX) {
                /* hard_mtu  is still the default - the device does not support
@@ -1220,6 +1248,7 @@ static int ax88178_reset(struct usbnet *dev)
        __le16 eeprom;
        u8 status;
        int gpio0 = 0;
+       u32 phyid;
 
        asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
        dbg("GPIO Status: 0x%04x", status);
@@ -1235,12 +1264,13 @@ static int ax88178_reset(struct usbnet *dev)
                data->ledmode = 0;
                gpio0 = 1;
        } else {
-               data->phymode = le16_to_cpu(eeprom) & 7;
+               data->phymode = le16_to_cpu(eeprom) & 0x7F;
                data->ledmode = le16_to_cpu(eeprom) >> 8;
                gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
        }
        dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
 
+       /* Power up external GigaPHY through AX88178 GPIO pin */
        asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
        if ((le16_to_cpu(eeprom) >> 8) != 1) {
                asix_write_gpio(dev, 0x003c, 30);
@@ -1252,6 +1282,13 @@ static int ax88178_reset(struct usbnet *dev)
                asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
        }
 
+       /* Read PHYID register *AFTER* powering up PHY */
+       phyid = asix_get_phyid(dev);
+       dbg("PHYID=0x%08x", phyid);
+
+       /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
+       asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL);
+
        asix_sw_reset(dev, 0);
        msleep(150);
 
@@ -1396,7 +1433,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int ret;
        u8 buf[ETH_ALEN];
-       u32 phyid;
        struct asix_data *data = (struct asix_data *)&dev->data;
 
        data->eeprom_len = AX88772_EEPROM_LEN;
@@ -1423,12 +1459,12 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->netdev_ops = &ax88178_netdev_ops;
        dev->net->ethtool_ops = &ax88178_ethtool_ops;
 
-       phyid = asix_get_phyid(dev);
-       dbg("PHYID=0x%08x", phyid);
+       /* Blink LEDS so users know driver saw dongle */
+       asix_sw_reset(dev, 0);
+       msleep(150);
 
-       ret = ax88178_reset(dev);
-       if (ret < 0)
-               return ret;
+       asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
+       msleep(150);
 
        /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
        if (dev->driver_info->flags & FLAG_FRAMING_AX) {
index c924ea2bce07a4c06aa8d6ab5d9c23620b446915..99ed6eb4dfaf6b8b1153dbe9bfcb4e5917500986 100644 (file)
@@ -567,7 +567,7 @@ static const struct usb_device_id   products [] = {
 {
        USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long)&wwan_info,
+       .driver_info = 0,
 },
 
 /*
index 1e7221951056304162e9d173dea85827234f16c0..9c26c6390d69a72abffbf47dc91d9aea96ec1ba0 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
+#include <linux/module.h>
 
 /*
  * The device has a CDC ACM port for modem control (it claims to be
@@ -143,10 +144,11 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        }
 
        frame = (struct vl600_frame_hdr *) buf->data;
-       /* NOTE: Should check that frame->magic == 0x53544448?
-        * Otherwise if we receive garbage at the beginning of the frame
-        * we may end up allocating a huge buffer and saving all the
-        * future incoming data into it.  */
+       /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
+        * otherwise we may run out of memory w/a bad packet */
+       if (ntohl(frame->magic) != 0x53544448 &&
+                       ntohl(frame->magic) != 0x44544d48)
+               goto error;
 
        if (buf->len < sizeof(*frame) ||
                        buf->len != le32_to_cpup(&frame->len)) {
@@ -295,6 +297,11 @@ encapsulate:
         * overwrite the remaining fields.
         */
        packet = (struct vl600_pkt_hdr *) skb->data;
+       /* The VL600 wants IPv6 packets to have an IPv4 ethertype
+        * Since this modem only supports IPv4 and IPv6, just set all
+        * frames to 0x0800 (ETH_P_IP)
+        */
+       packet->h_proto = htons(ETH_P_IP);
        memset(&packet->dummy, 0, sizeof(packet->dummy));
        packet->len = cpu_to_le32(orig_len);
 
@@ -307,21 +314,12 @@ encapsulate:
        if (skb->len < full_len) /* Pad */
                skb_put(skb, full_len - skb->len);
 
-       /* The VL600 wants IPv6 packets to have an IPv4 ethertype
-        * Check if this is an IPv6 packet, and set the ethertype
-        * to 0x800
-        */
-       if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
-               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
-               skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
-       }
-
        return skb;
 }
 
 static const struct driver_info        vl600_info = {
        .description    = "LG VL600 modem",
-       .flags          = FLAG_ETHER | FLAG_RX_ASSEMBLE,
+       .flags          = FLAG_RX_ASSEMBLE | FLAG_WWAN,
        .bind           = vl600_bind,
        .unbind         = vl600_unbind,
        .status         = usbnet_cdc_status,
index 22a7cf951e728132b6f55d0d99584fc50e374eaa..a5b9b12ef268134fef1e978d8e19ce5468c16135 100644 (file)
@@ -51,6 +51,7 @@
 #define USB_VENDOR_ID_SMSC             (0x0424)
 #define USB_PRODUCT_ID_LAN7500         (0x7500)
 #define USB_PRODUCT_ID_LAN7505         (0x7505)
+#define RXW_PADDING                    2
 
 #define check_warn(ret, fmt, args...) \
        ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
@@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 
                memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
                le32_to_cpus(&rx_cmd_b);
-               skb_pull(skb, 4 + NET_IP_ALIGN);
+               skb_pull(skb, 4 + RXW_PADDING);
 
                packet = skb->data;
 
                /* get the packet length */
-               size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
-               align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+               size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
+               align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
 
                if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
                        netif_dbg(dev, rx_err, dev->net,
index 7d6082160bcc42377a51ba2b8be6f60a37eec093..fae0fbd8bc887a99ca0e068bbc4d06bed884775c 100644 (file)
@@ -1057,7 +1057,8 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
        unsigned long           flags;
        int retval;
 
-       skb_tx_timestamp(skb);
+       if (skb)
+               skb_tx_timestamp(skb);
 
        // some devices want funky USB-level framing, for
        // win32 driver (usually) and/or hardware quirks
index 5b23767ea817232a24b33a479f9b2014e895d1b6..ef883e97cee08a557fd3dcc2546535c1ca487372 100644 (file)
@@ -17,6 +17,7 @@
 #include <net/dst.h>
 #include <net/xfrm.h>
 #include <linux/veth.h>
+#include <linux/module.h>
 
 #define DRV_NAME       "veth"
 #define DRV_VERSION    "1.0"
index b771ebac0f014ffcaacb978e50101b2c6532b8ee..d96bfb1ac20b161f10b19e362b5ad934110072cd 100644 (file)
@@ -24,6 +24,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <net/ip6_checksum.h>
 
 #include "vmxnet3_int.h"
index 727d728649b7dd49d260ddf9471c8202d541a75c..2fea02b35b2dacba5188fb3be9d235c7239cbac4 100644 (file)
@@ -78,6 +78,8 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/wimax/i2400m.h>
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 
 
 #define D_SUBMODULE control
index 9c70b5fa3f51e03b0ea51c84d844df4c22089ad3..129ba36bd04d6a52c205aa60c44d042c2003401b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include "i2400m.h"
 
 
index 85dadd5bf4beec09cb0ce10a7912c21773ccd4e0..7cbd7d231e11f4efde628650bc4e6843939fbe25 100644 (file)
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/export.h>
 #include "i2400m.h"
 
 
index 2edd8fe1c1f31c409cef10fedd62c5e9be7cc5b1..64a110604ad3d19213102d13f86a75d2ed2dedba 100644 (file)
@@ -76,6 +76,7 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/export.h>
 #include "i2400m.h"
 
 
index 2f94a872101f64097ec6a58ba8af708bf5277819..37becfcc98f2783dbd74c75a42ad8bd365f498eb 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
 #include <linux/workqueue.h>
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 #include "i2400m.h"
 
 
index be428cae28d895f81f4a2db559bf6e3c4f577726..21a9edd6e75d5826e7a30026f57647f990e32216 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/mmc/sdio_func.h>
 #include "i2400m-sdio.h"
 #include <linux/wimax/i2400m.h>
+#include <linux/module.h>
 
 #define D_SUBMODULE main
 #include "sdio-debug-levels.h"
index 4b30ed11d7857f7ec5461ef0196d2182d39f3c10..4b9ecb20deec28f5710ba4f82c78502be1b23d50 100644 (file)
  */
 #include <linux/netdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "i2400m.h"
 
 
index 9a644d052f1e01482acd0c199b23c76513704c1a..2c1b8b687646eedb0ac795a706c34cc32fa5ab29 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/wimax/i2400m.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 
 #define D_SUBMODULE usb
index 3b752d9fb3cd7bd9f72264cdf8f003cecebacaaf..f5ce5623da990db9941699cae0bbba8ec74d238d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 
 #include "adm8211.h"
index fce8c904eea9e70e2656c0b0d9d8f9ddc65d4033..8c5ce8b0c7346873a64c6ee9e8f358a2d5a565c6 100644 (file)
@@ -57,8 +57,9 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGES.
  */
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 
-#include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/list.h>
 #include "debug.h"
index c1dff2ced0446b0869a4c226b66e2deb1404d970..dfa48eb7d953eca530b4ceba9e3e62b25b74c63f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 #include <linux/etherdevice.h>
+#include <linux/module.h>
 #include "../ath.h"
 #include "ath5k.h"
 #include "debug.h"
index 3aff36bad5d3a64194d08c312701ad26ae9a430d..f517eb8f7b44b6ba13e07bc02a4de80586ef6444 100644 (file)
@@ -14,6 +14,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/moduleparam.h>
+
 #include "core.h"
 #include "cfg80211.h"
 #include "debug.h"
index ba3f23d71150ee0bf0054efbc42530cac4ac3569..7879b5314285492dc0ccbffd61098bf5d909af65 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/circ_buf.h>
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include "debug.h"
 #include "target.h"
index f1dc311ee0c7b041bdbcac42b5bc29b867e7cdd4..066d4f88807faf6d4af8f3fae753901b3df9f92f 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/module.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
index 85a54cd2b0831c4a5f24f93c2dccb1bd2f1e1a0f..5e47ca6d16a826e71176c3dd5e7efa01586c4375 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/nl80211.h>
 #include <linux/platform_device.h>
 #include <linux/ath9k_platform.h>
+#include <linux/module.h>
 #include "ath9k.h"
 
 static const struct platform_device_id ath9k_platform_id_table[] = {
index 2776c3c1f506286639d0db1e54dd2bd003d2fec1..a639b94f764301792a23765333b1509f64fec39a 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include "hw.h"
 #include "hw-ops.h"
 
index e0ab0657cc3a8808379ae0cc93e32e0863e13305..88279e325dcac0037ba3b6ed6b13a22bf23bc752 100644 (file)
@@ -868,10 +868,6 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
        /* Do PA Calibration */
        ar9002_hw_pa_cal(ah, true);
 
-       /* Do NF Calibration after DC offset and other calibrations */
-       ath9k_hw_loadnf(ah, chan);
-       ath9k_hw_start_nfcal(ah, true);
-
        if (ah->caldata)
                ah->caldata->nfcal_pending = true;
 
index 626d547d2f0666f452a64be7ab6066ed495be1d7..11f192a1ceb72d332ccde32cf98f0ef7c3ff41c3 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/moduleparam.h>
 #include "hw.h"
 #include "ar5008_initvals.h"
 #include "ar9001_initvals.h"
index f7d8e516a2a9ee4770243b49b8d36a802461bd34..b5920168606dea8b47226dc1e9d554f9f5fecdae 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "hw.h"
+#include <linux/export.h>
 
 #define AR_BufLen           0x00000fff
 
index 16851cb109a6302d492e6b4ce1a5f6f143d3433e..12a730dcb500912ad81bfeebfe6b8f9119cdfa33 100644 (file)
@@ -908,12 +908,15 @@ static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
        int i;
        bool restore;
 
-       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata)
+       if (!ah->caldata)
                return false;
 
        hist = &ah->caldata->rtt_hist;
+       if (!hist->num_readings)
+               return false;
+
        ar9003_hw_rtt_enable(ah);
-       ar9003_hw_rtt_set_mask(ah, 0x10);
+       ar9003_hw_rtt_set_mask(ah, 0x00);
        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
                if (!(ah->rxchainmask & (1 << i)))
                        continue;
@@ -1070,6 +1073,7 @@ skip_tx_iqcal:
                if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
                        u32 *table;
 
+                       hist->num_readings++;
                        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
                                if (!(ah->rxchainmask & (1 << i)))
                                        continue;
@@ -1081,9 +1085,6 @@ skip_tx_iqcal:
                ar9003_hw_rtt_disable(ah);
        }
 
-       ath9k_hw_loadnf(ah, chan);
-       ath9k_hw_start_nfcal(ah, true);
-
        /* Initialize list pointers */
        ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
        ah->supp_cals = IQ_MISMATCH_CAL;
index b363cc06cfd950cd08cf42334658d9cafced6598..ccde784a842f0c06441b266cad140be4435a6213 100644 (file)
@@ -13,6 +13,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include <linux/export.h>
 #include "hw.h"
 #include "ar9003_mac.h"
 
index 0c462c904cbea7a3603641c70f0013dfdfbb7e81..a4450cba065375509e241e7397730e9e6c4c04ad 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "hw.h"
 #include "ar9003_phy.h"
 
index fe96997921d322bb96b1f4dc42a551769e722f7d..2330e7ede19946a88cacdd7359e52192da45bf01 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "hw.h"
 #include "ar9003_phy.h"
 
index 2f4023e660810c53aca60314d6668c7e3f857455..4114fe752c6b4f85485ef13024350dc6b9d55f8f 100644 (file)
 
 #define AR_PHY_TXGAIN_TABLE      (AR_SM_BASE + 0x300)
 
-#define AR_PHY_TX_IQCAL_CONTROL_0   (AR_SM_BASE + AR_SREV_9485(ah) ? \
-                                                0x3c4 : 0x444)
-#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + AR_SREV_9485(ah) ? \
-                                                0x3c8 : 0x448)
-#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + AR_SREV_9485(ah) ? \
-                                                0x3c4 : 0x440)
-#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + AR_SREV_9485(ah) ? \
-                                                0x3f0 : 0x48c)
+#define AR_PHY_TX_IQCAL_CONTROL_0   (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+                                                0x3c4 : 0x444))
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+                                                0x3c8 : 0x448))
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+                                                0x3c4 : 0x440))
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+                                                0x3f0 : 0x48c))
 #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i)    (AR_SM_BASE + \
                                             (AR_SREV_9485(ah) ? \
                                              0x3d0 : 0x450) + ((_i) << 2))
 #define AR_SWITCH_TABLE_ALL_S (0)
 
 #define AR_PHY_65NM_CH0_THERM       (AR_SREV_9300(ah) ? 0x16290 :\
-                                       (AR_SREV_9485(ah) ? 0x1628c : 0x16294))
+                                       (AR_SREV_9462(ah) ? 0x16294 : 0x1628c))
 
 #define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000
 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
 #define AR_PHY_65NM_CH2_RXTX2       0x16904
 
 #define AR_CH0_TOP2            (AR_SREV_9300(ah) ? 0x1628c : \
-                                       (AR_SREV_9485(ah) ? 0x16284 : 0x16290))
+                                       (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
 #define AR_CH0_TOP2_XPABIASLVL         0xf000
 #define AR_CH0_TOP2_XPABIASLVL_S       12
 
 #define AR_CH0_XTAL            (AR_SREV_9300(ah) ? 0x16294 : \
-                                       (AR_SREV_9485(ah) ? 0x16290 : 0x16298))
+                                       (AR_SREV_9462(ah) ? 0x16298 : 0x16290))
 #define AR_CH0_XTAL_CAPINDAC   0x7f000000
 #define AR_CH0_XTAL_CAPINDAC_S 24
 #define AR_CH0_XTAL_CAPOUTDAC  0x00fe0000
 #define AR_PHY_TPC_5_B1         (AR_SM1_BASE + 0x208)
 #define AR_PHY_TPC_6_B1         (AR_SM1_BASE + 0x20c)
 #define AR_PHY_TPC_11_B1        (AR_SM1_BASE + 0x220)
-#define AR_PHY_PDADC_TAB_1     (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \
-                                       0x240 : 0x280))
+#define AR_PHY_PDADC_TAB_1     (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \
+                                       0x280 : 0x240))
 #define AR_PHY_TPC_19_B1       (AR_SM1_BASE + 0x240)
 #define AR_PHY_TPC_19_B1_ALPHA_THERM           0xff
 #define AR_PHY_TPC_19_B1_ALPHA_THERM_S         0
 #define AR_PHY_AIC_SRAM_ADDR_B1        (AR_SM1_BASE + 0x5f0)
 #define AR_PHY_AIC_SRAM_DATA_B1        (AR_SM1_BASE + 0x5f4)
 
-#define AR_PHY_RTT_TABLE_SW_INTF_B(i)  (0x384 + (i) ? \
-                                       AR_SM1_BASE : AR_SM_BASE)
-#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i)        (0x388 + (i) ? \
-                                       AR_SM1_BASE : AR_SM_BASE)
+#define AR_PHY_RTT_TABLE_SW_INTF_B(i)  (0x384 + ((i) ? \
+                                       AR_SM1_BASE : AR_SM_BASE))
+#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i)        (0x388 + ((i) ? \
+                                       AR_SM1_BASE : AR_SM_BASE))
 /*
  * Channel 2 Register Map
  */
index 611ea6ce8508dfb760a1172ea46793e6716c48e3..d16d029f81a9db1d45dbd7f0115e057d3be3bf1d 100644 (file)
@@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = {
        {0x000160ac, 0x24611800},
        {0x000160b0, 0x03284f3e},
        {0x0001610c, 0x00170000},
-       {0x00016140, 0x10804008},
+       {0x00016140, 0x50804008},
 };
 
 static const u32 ar9485_1_1_mac_postamble[][5] = {
@@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = {
 
 static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
        /* Addr        allmodes */
-       {0x00018c00, 0x10052e5e},
+       {0x00018c00, 0x18052e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
@@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
 
 static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
        /* Addr        allmodes */
-       {0x00018c00, 0x10013e5e},
+       {0x00018c00, 0x18013e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
@@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
 
 static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
        /* Addr        allmodes  */
-       {0x00018c00, 0x10012e5e},
+       {0x00018c00, 0x18012e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
@@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
 
 static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
        /* Addr        allmodes */
-       {0x00018c00, 0x10053e5e},
+       {0x00018c00, 0x18053e5e},
        {0x00018c04, 0x000801d8},
        {0x00018c08, 0x0000080c},
 };
index 6635c377dc00e8d977b2094b345a4d287f721ec3..012263968d64f75245e5f993a0b37c9123e08874 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "hw.h"
 
 enum ath_bt_mode {
index ebaf304f464bc2aa0efc58bd1997251acfee90c7..99538810a3120a87ba8bdb3f94f72e6bce09e40a 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "hw.h"
 #include "hw-ops.h"
+#include <linux/export.h>
 
 /* Common calibration code */
 
index 327aa28f60307a6609d6a8d8030ba9d3203c3322..2741203e803f2dadb4204eefae82dd2896e11649 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include "ath9k.h"
index f16d2033081f3ea8df6b30a8ee74258772a2d500..8873c6e6fb9627c02c41d4b1d36ffb340da3eacf 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 
 #include "hw.h"
@@ -1724,6 +1725,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (!ath9k_hw_init_cal(ah, chan))
                return -EIO;
 
+       ath9k_hw_loadnf(ah, chan);
+       ath9k_hw_start_nfcal(ah, true);
+
        ENABLE_REGWRITE_BUFFER(ah);
 
        ath9k_hw_restore_chainmask(ah);
@@ -1823,7 +1827,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
        }
 
        /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
-       REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
 }
 
 /*
index af1b325495319aeb7398b4045b4995534d24da97..d4c909f8e474d793d71d52af3bd8d34a9c0f9843 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/ath9k_platform.h>
+#include <linux/module.h>
 
 #include "ath9k.h"
 
index 6a8fdf33a5273704a61767cf0dd4c4aecd703d5b..ecdb6fd2907909bcbddb4b3c6bfce5d7d022c6b3 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "hw.h"
 #include "hw-ops.h"
+#include <linux/export.h>
 
 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
                                        struct ath9k_tx_queue_info *qi)
index edb0b4b3da3ad4563533d13aa94245832aa2e3cd..2dcdf63cb390bfa894c1017972b53b296c2475d9 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 #include <linux/ath9k_platform.h>
+#include <linux/module.h>
 #include "ath9k.h"
 
 static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
index 8448281dd0691f53cfa41fb260ff7e60f83e64e0..888abc2be3a547d6f85ad32723fd2d2910c5582e 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "ath9k.h"
 
index f4cae1cccbfff879f2e5859989f3e524be1b9f86..cba9d0435dc41813fc4f39be979223ef8dd6aea4 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/firmware.h>
 #include <linux/crc32.h>
+#include <linux/module.h>
 #include "carl9170.h"
 #include "fwcmd.h"
 #include "version.h"
index d20946939cd8cae0968abfb096dbe3321c0e63eb..59472e1605cd89779e06c299937ba950968b3daf 100644 (file)
@@ -296,7 +296,8 @@ static void carl9170_tx_release(struct kref *ref)
                        super = (void *)skb->data;
                        txinfo->status.ampdu_len = super->s.rix;
                        txinfo->status.ampdu_ack_len = super->s.cnt;
-               } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
+               } else if ((txinfo->flags & IEEE80211_TX_STAT_ACK) &&
+                          !(txinfo->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
                        /*
                         * drop redundant tx_status reports:
                         *
@@ -308,15 +309,17 @@ static void carl9170_tx_release(struct kref *ref)
                         *
                         * 3. minstrel_ht is picky, it only accepts
                         *    reports of frames with the TX_STATUS_AMPDU flag.
+                        *
+                        * 4. mac80211 is not particularly interested in
+                        *    feedback either [CTL_REQ_TX_STATUS not set]
                         */
 
                        dev_kfree_skb_any(skb);
                        return;
                } else {
                        /*
-                        * Frame has failed, but we want to keep it in
-                        * case it was lost due to a power-state
-                        * transition.
+                        * Either the frame transmission has failed or
+                        * mac80211 requested tx status.
                         */
                }
        }
index 5367b1086e09254bccf82f0fa220bde9d0bdabc8..508eccf5d982c8d821edec4fc4b8a578bf2e01e2 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include "ath.h"
 
 const char *ath_opmode_to_string(enum nl80211_iftype opmode)
index 3f508e59f146b412246f34becab5862117bfd765..19befb33107348e949cf958c05ee2683f9ba28d9 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include "ath.h"
index 17b0efd86f9a49d7b5e049e950a9fcf7802ddaad..4cf7c5eb4813420c4908539f99ba8373c915d10c 100644 (file)
@@ -15,6 +15,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <linux/export.h>
 #include <asm/unaligned.h>
 #include <net/mac80211.h>
 
index 028310f263c81c01060f5d551496cca88519b3b9..65ecb5bab25a2a0a0c1e64d5122397238ab1e0ca 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 #include <net/mac80211.h>
 #include "regd.h"
@@ -253,6 +254,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
        int r;
 
        sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+       if (!sband)
+               return;
 
        /*
         * If no country IE has been received always enable active scan
index 7cf4125a16241f79d344a365f00f5c4ef0f13421..5634d9a9965bcd91addc69408224caccee7a7746 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
index 12b6b4067a398e7b6958a76af9b48f7d81831172..714cad649c45b68281ae7c2c1e7f66e7c317c52c 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ciscode.h>
index c73e8600d218673b28838e898bba1d903a6c493b..5f77cbe0b6aaeb5d6e121ad5e37b70a3b8596d62 100644 (file)
@@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
        }
 }
 
+/* TODO: verify if needed for SSLPN or LCN  */
 static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
 {
        const struct b43_phy *phy = &dev->phy;
@@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        unsigned int plcp_fragment_len;
        u32 mac_ctl = 0;
        u16 phy_ctl = 0;
+       bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP ||
+                             phy->type == B43_PHYTYPE_N ||
+                             phy->type == B43_PHYTYPE_HT);
        u8 extra_ft = 0;
        struct ieee80211_rate *txrate;
        struct ieee80211_tx_rate *rates;
@@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                        extra_ft |= B43_TXH_EFT_RTSFB_CCK;
 
                if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
-                   phy->type == B43_PHYTYPE_N) {
+                   fill_phy_ctl1) {
                        txhdr->phy_ctl1_rts = cpu_to_le16(
                                b43_generate_tx_phy_ctl1(dev, rts_rate));
                        txhdr->phy_ctl1_rts_fb = cpu_to_le16(
@@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                break;
        }
 
-       if (phy->type == B43_PHYTYPE_N) {
+       if (fill_phy_ctl1) {
                txhdr->phy_ctl1 =
                        cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
                txhdr->phy_ctl1_fb =
@@ -736,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 
        /* Link quality statistics */
        switch (chanstat & B43_RX_CHAN_PHYTYPE) {
+       case B43_PHYTYPE_HT:
+               /* TODO: is max the right choice? */
+               status.signal = max_t(__s8,
+                       max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1),
+                       rxhdr->phy_ht_power2);
+               break;
        case B43_PHYTYPE_N:
+               /* Broadcom has code for min and avg, but always uses max */
                if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
                        status.signal = max(rxhdr->power1, rxhdr->power2);
                else
@@ -827,7 +838,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 #endif
        return;
 drop:
-       b43dbg(dev->wl, "RX: Packet dropped\n");
        dev_kfree_skb_any(skb);
 }
 
index 16c514d54afabb6be6f57c078e631e5a7d4c8647..98d90747836a482fa836f6e30c8fc173e1c935e5 100644 (file)
@@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 {
                } __packed;
        } __packed;
        union {
+               /* HT-PHY */
+               struct {
+                       PAD_BYTES(1);
+                       __s8 phy_ht_power0;
+               } __packed;
+
                /* RSSI for N-PHYs */
                struct {
                        __s8 power2;
@@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 {
 
                __le16 phy_status2;     /* PHY RX Status 2 */
        } __packed;
-       __le16 phy_status3;     /* PHY RX Status 3 */
+       union {
+               /* HT-PHY */
+               struct {
+                       __s8 phy_ht_power1;
+                       __s8 phy_ht_power2;
+               } __packed;
+
+               __le16 phy_status3;     /* PHY RX Status 3 */
+       } __packed;
        union {
                /* Tested with 598.314, 644.1001 and 666.2 */
                struct {
index a3b72cd72c6664a12fbf271fe51bd23f78972e43..20f02437af8c73c4416987112abd6c75a91bc301 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
index bff9dcd6fadcbb68f91ce4b6409e3539be5b785d..89ff94da556aa08ee08b3d4a2f859f07c671a792 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/types.h>
 #include <linux/netdevice.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/sched.h>
index b56a30297c269712840a8696f77d1d84daab358a..6ebec8f42846977439c07844cba9a6f7e429801c 100644 (file)
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
 
 static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
 {
-       uint dmactrlflags = di->dma.dmactrlflags;
+       uint dmactrlflags;
 
        if (di == NULL) {
-               DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+               DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
                return 0;
        }
 
+       dmactrlflags = di->dma.dmactrlflags;
        dmactrlflags &= ~mask;
        dmactrlflags |= flags;
 
index ac8d02bd34f233fc2b2634cf1acc5953b01685a7..0d8a9cdf897afe3569ea412256a17cf301ffb8b4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/firmware.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 #include <defs.h>
 #include "nicpci.h"
index e0b3e8d406b36f692ebc996024ae79885c5a1096..df7050abe717d9c09a6167ade588553a16041e79 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/lib80211.h>
 #include <linux/if_arp.h>
 
index c34a3b7f12924db3cbc2c75b3b173bcfc4da3d73..344a981a052e630a4daf5c6e6630d8703a2fb617 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "hostap_80211.h"
 #include "hostap_common.h"
index 3d05dc15c6b8a3d63f69afbc37654401cfacee2e..e1f4102772426032f9ccd5c060f39118d9bb25c3 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/random.h>
 #include <linux/if_arp.h>
 #include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
index d737091cf6acc1c4abd45d0a8d058e3e3b9799d3..47932b28aac101217ee56d1db2dc736e7d8d1d5b 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/if_arp.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "hostap_wlan.h"
 #include "hostap.h"
 #include "hostap_ap.h"
index 12de46407c71ae42b7eb99e6f4e9d44888af2430..045a93645a3dede213af0a68855bf0889a5be26b 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/sched.h>
 #include <linux/ethtool.h>
 #include <linux/if_arp.h>
+#include <linux/module.h>
 #include <net/lib80211.h>
 
 #include "hostap_wlan.h"
index 005ff25a405f2bfde34adf66d4e9e85f85c44f2a..75ef8f04aabe3889b11f69908ebcec485bab1c01 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 #include <net/lib80211.h>
 
 #include "hostap_wlan.h"
index 996996a71657f86e6ed1d64531dd649ef9f1f7d0..1407dca70deff07a6c88582222c9892692b1907d 100644 (file)
@@ -26,6 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
 #include <linux/ieee80211.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 
 
index 9b5d0abe8be9f13de56a5e82c5ae75a77ec946b4..f4d21ec22497a8d2cf6508aebd5becfa9805c872 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 #include "iwl-eeprom.h"
index a6b5222fc59e09bba9e3b9ae527e155ea5b68ede..521b73b527d3486271e0a54bac4dfe239d2c1081 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
index 66f0fb2bbe00a6d66c726d620ee8b4efe388edba..f10df3e2813a0c63f86429dd1344c8519222e369 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
 #include <linux/lockdep.h>
+#include <linux/export.h>
 
 #include "iwl-dev.h"
 #include "iwl-core.h"
index ef9e268bf8a074ea3707b04992e758f52dc0eb8d..c0dfb1a4e968f1d6dd5533d58e158f6062dbd93d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
index e12b48c2cff6ab71e097d38c9632eeb11044bed0..dd008b0e6417a3b3e15679399252c53af9af990d 100644 (file)
@@ -191,6 +191,7 @@ static struct iwl_base_params iwl1000_base_params = {
        .chain_noise_scale = 1000,
        .wd_timeout = IWL_DEF_WD_TIMEOUT,
        .max_event_log_size = 128,
+       .wd_disable = true,
 };
 static struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
index c511c98a89a81284e03f621705cbd09736616297..f55fb2d1af52f3891e8d29bc7a21ab193b7f243f 100644 (file)
@@ -364,6 +364,7 @@ static struct iwl_base_params iwl5000_base_params = {
        .wd_timeout = IWL_LONG_WD_TIMEOUT,
        .max_event_log_size = 512,
        .no_idle_support = true,
+       .wd_disable = true,
 };
 static struct iwl_ht_params iwl5000_ht_params = {
        .ht_greenfield_support = true,
index 58a381c01c89c9a367c7b592d65a49eb02457be0..a7a6def40d05aa29fe6d739daf1f0d247bf45a80 100644 (file)
@@ -528,6 +528,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        return 0;
 }
 
+void iwlagn_config_ht40(struct ieee80211_conf *conf,
+       struct iwl_rxon_context *ctx)
+{
+       if (conf_is_ht40_minus(conf)) {
+               ctx->ht.extension_chan_offset =
+                       IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+               ctx->ht.is_40mhz = true;
+       } else if (conf_is_ht40_plus(conf)) {
+               ctx->ht.extension_chan_offset =
+                       IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+               ctx->ht.is_40mhz = true;
+       } else {
+               ctx->ht.extension_chan_offset =
+                       IEEE80211_HT_PARAM_CHA_SEC_NONE;
+               ctx->ht.is_40mhz = false;
+       }
+}
+
 int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct iwl_priv *priv = hw->priv;
@@ -586,19 +604,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                                ctx->ht.enabled = conf_is_ht(conf);
 
                        if (ctx->ht.enabled) {
-                               if (conf_is_ht40_minus(conf)) {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-                                       ctx->ht.is_40mhz = true;
-                               } else if (conf_is_ht40_plus(conf)) {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-                                       ctx->ht.is_40mhz = true;
-                               } else {
-                                       ctx->ht.extension_chan_offset =
-                                               IEEE80211_HT_PARAM_CHA_SEC_NONE;
-                                       ctx->ht.is_40mhz = false;
-                               }
+                               /* if HT40 is used, it should not change
+                                * after associated except channel switch */
+                               if (iwl_is_associated_ctx(ctx) &&
+                                    !ctx->ht.is_40mhz)
+                                       iwlagn_config_ht40(conf, ctx);
                        } else
                                ctx->ht.is_40mhz = false;
 
index ed6283623932e2436ddc364d8429ee085df28249..4b2aa1da09532a98e4505afe70f2ec3114fa6510 100644 (file)
@@ -1268,9 +1268,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
 
        switch (keyconf->cipher) {
        case WLAN_CIPHER_SUITE_TKIP:
-               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-
                if (sta)
                        addr = sta->addr;
                else /* station mode case only */
@@ -1283,8 +1280,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
                                          seq.tkip.iv32, p1k, CMD_SYNC);
                break;
        case WLAN_CIPHER_SUITE_CCMP:
-               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-               /* fall through */
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
                ret = iwlagn_send_sta_key(priv, keyconf, sta_id,
index ccba69b7f8a78f9b54635328bee5c3e3d4d4553a..bacc06c95e7ac798449e11ca883e5b5dc1def717 100644 (file)
@@ -2316,6 +2316,17 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                return -EOPNOTSUPP;
        }
 
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_TKIP:
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               /* fall through */
+       case WLAN_CIPHER_SUITE_CCMP:
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               break;
+       default:
+               break;
+       }
+
        /*
         * We could program these keys into the hardware as well, but we
         * don't expect much multicast traffic in IBSS and having keys
@@ -2599,21 +2610,9 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
 
        /* Configure HT40 channels */
        ctx->ht.enabled = conf_is_ht(conf);
-       if (ctx->ht.enabled) {
-               if (conf_is_ht40_minus(conf)) {
-                       ctx->ht.extension_chan_offset =
-                               IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-                       ctx->ht.is_40mhz = true;
-               } else if (conf_is_ht40_plus(conf)) {
-                       ctx->ht.extension_chan_offset =
-                               IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-                       ctx->ht.is_40mhz = true;
-               } else {
-                       ctx->ht.extension_chan_offset =
-                               IEEE80211_HT_PARAM_CHA_SEC_NONE;
-                       ctx->ht.is_40mhz = false;
-               }
-       } else
+       if (ctx->ht.enabled)
+               iwlagn_config_ht40(conf, ctx);
+       else
                ctx->ht.is_40mhz = false;
 
        if ((le16_to_cpu(ctx->staging.channel) != ch))
@@ -3499,9 +3498,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
 module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
 MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
 
-module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO);
+module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
 MODULE_PARM_DESC(wd_disable,
-               "Disable stuck queue watchdog timer (default: 0 [enabled])");
+               "Disable stuck queue watchdog timer 0=system default, "
+               "1=disable, 2=enable (default: 0)");
 
 /*
  * set bt_coex_active to true, uCode will do kill/defer
index 5b936ec1a541ecc1ecd213771f7d4e75f7960136..3856abaea50792885442b78b084e4c328ace3fc6 100644 (file)
@@ -86,6 +86,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif,
                             struct ieee80211_bss_conf *bss_conf,
                             u32 changes);
+void iwlagn_config_ht40(struct ieee80211_conf *conf,
+                       struct iwl_rxon_context *ctx);
 
 /* uCode */
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
index b247a56d51354775b5cbc4cd16c54ee05d6deedf..fcf54160e4ed51b3f89a84447898c7948acaaf59 100644 (file)
@@ -1755,16 +1755,6 @@ static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
 {
        if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
                int ret;
-               if (txq == priv->shrd->cmd_queue) {
-                       /*
-                        * validate command queue still working
-                        * by sending "ECHO" command
-                        */
-                       if (!iwl_cmd_echo_test(priv))
-                               return 0;
-                       else
-                               IWL_DEBUG_HC(priv, "echo testing fail\n");
-               }
                ret = iwl_force_reset(priv, IWL_FW_RESET, false);
                return (ret == -EAGAIN) ? 0 : 1;
        }
@@ -1820,11 +1810,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv)
 {
        unsigned int timeout = priv->cfg->base_params->wd_timeout;
 
-       if (timeout && !iwlagn_mod_params.wd_disable)
-               mod_timer(&priv->watchdog,
-                         jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout)));
-       else
-               del_timer(&priv->watchdog);
+       if (!iwlagn_mod_params.wd_disable) {
+               /* use system default */
+               if (timeout && !priv->cfg->base_params->wd_disable)
+                       mod_timer(&priv->watchdog,
+                               jiffies +
+                               msecs_to_jiffies(IWL_WD_TICK(timeout)));
+               else
+                       del_timer(&priv->watchdog);
+       } else {
+               /* module parameter overwrite default configuration */
+               if (timeout && iwlagn_mod_params.wd_disable == 2)
+                       mod_timer(&priv->watchdog,
+                               jiffies +
+                               msecs_to_jiffies(IWL_WD_TICK(timeout)));
+               else
+                       del_timer(&priv->watchdog);
+       }
 }
 
 /**
index 137da33807044bedd162a501a65454037abce49f..f2fc288f3dd31f5068e1bb29fbe3307fa1d2045d 100644 (file)
@@ -113,6 +113,7 @@ struct iwl_lib_ops {
  * @shadow_reg_enable: HW shadhow register bit
  * @no_idle_support: do not support idle mode
  * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
+ * wd_disable: disable watchdog timer
  */
 struct iwl_base_params {
        int eeprom_size;
@@ -134,6 +135,7 @@ struct iwl_base_params {
        const bool shadow_reg_enable;
        const bool no_idle_support;
        const bool hd_v2;
+       const bool wd_disable;
 };
 /*
  * @advanced_bt_coexist: support advanced bt coexist
index 3b6cc66365e5b56bea8df3ad7875946ebbd44d31..1800029911adfa1e21dfc8d3c6b0d59614daf88f 100644 (file)
@@ -60,6 +60,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 
@@ -445,10 +446,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
        err = pci_enable_msi(pdev);
-       if (err) {
-               dev_printk(KERN_ERR, &pdev->dev, "pci_enable_msi failed");
-               goto out_iounmap;
-       }
+       if (err)
+               dev_printk(KERN_ERR, &pdev->dev,
+                       "pci_enable_msi failed(0X%x)", err);
 
        /* TODO: Move this away, not needed if not MSI */
        /* enable rfkill interrupt: hw bug w/a */
@@ -469,7 +469,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 out_disable_msi:
        pci_disable_msi(pdev);
-out_iounmap:
        pci_iounmap(pdev, pci_bus->hw_base);
 out_pci_release_regions:
        pci_set_drvdata(pdev, NULL);
index 1f7a93c67c45ed67998389ac406917875e826125..14eaf37ce3b1c6a06fdad12d9cc74371274ba894 100644 (file)
@@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params;
  * @restart_fw: restart firmware, default = 1
  * @plcp_check: enable plcp health check, default = true
  * @ack_check: disable ack health check, default = false
- * @wd_disable: enable stuck queue check, default = false
+ * @wd_disable: enable stuck queue check, default = 0
  * @bt_coex_active: enable bt coex, default = true
  * @led_mode: system default, default = 0
  * @no_sleep_autoadjust: disable autoadjust, default = true
@@ -141,7 +141,7 @@ struct iwl_mod_params {
        int restart_fw;
        bool plcp_check;
        bool ack_check;
-       bool wd_disable;
+       int  wd_disable;
        bool bt_coex_active;
        int led_mode;
        bool no_sleep_autoadjust;
index 8e8c75c997eef2e4ca576189e1fd265a7a3ac0bd..ce918980e97799a51fc3b0b9a732d28fe706c84a 100644 (file)
@@ -407,6 +407,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_queue *q = &txq->q;
        enum dma_data_direction dma_dir;
        unsigned long flags;
+       spinlock_t *lock;
 
        if (!q->n_bd)
                return;
@@ -414,19 +415,22 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        /* In the command queue, all the TBs are mapped as BIDI
         * so unmap them as such.
         */
-       if (txq_id == trans->shrd->cmd_queue)
+       if (txq_id == trans->shrd->cmd_queue) {
                dma_dir = DMA_BIDIRECTIONAL;
-       else
+               lock = &trans->hcmd_lock;
+       } else {
                dma_dir = DMA_TO_DEVICE;
+               lock = &trans->shrd->sta_lock;
+       }
 
-       spin_lock_irqsave(&trans->shrd->sta_lock, flags);
+       spin_lock_irqsave(lock, flags);
        while (q->write_ptr != q->read_ptr) {
                /* The read_ptr needs to bound by q->n_window */
                iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
                                    dma_dir);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
-       spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
+       spin_unlock_irqrestore(lock, flags);
 }
 
 /**
@@ -986,29 +990,16 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        return 0;
 }
 
-static void iwl_trans_pcie_disable_sync_irq(struct iwl_trans *trans)
+static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 {
        unsigned long flags;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
+       /* tell the device to stop sending interrupts */
        spin_lock_irqsave(&trans->shrd->lock, flags);
        iwl_disable_interrupts(trans);
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
 
-       /* wait to make sure we flush pending tasklet*/
-       synchronize_irq(bus(trans)->irq);
-       tasklet_kill(&trans_pcie->irq_tasklet);
-}
-
-static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
-{
-       /* stop and reset the on-board processor */
-       iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
-       /* tell the device to stop sending interrupts */
-       iwl_trans_pcie_disable_sync_irq(trans);
-
        /* device going down, Stop using ICT table */
        iwl_disable_ict(trans);
 
@@ -1035,6 +1026,20 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 
        /* Stop the device, and put it in low power state */
        iwl_apm_stop(priv(trans));
+
+       /* Upon stop, the APM issues an interrupt if HW RF kill is set.
+        * Clean again the interrupt here
+        */
+       spin_lock_irqsave(&trans->shrd->lock, flags);
+       iwl_disable_interrupts(trans);
+       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+
+       /* wait to make sure we flush pending tasklet*/
+       synchronize_irq(bus(trans)->irq);
+       tasklet_kill(&trans_pcie->irq_tasklet);
+
+       /* stop and reset the on-board processor */
+       iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
 
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
index 50dee6a0a5cac07af17e2f8ba60d088badc02c06..bd75078c454b552d8df71758b3eba0d99c045578 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/ieee80211.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/moduleparam.h>
 
 #include "iwm.h"
 #include "bus.h"
index 0a0cc9667cd667c6468e7a749d0ab2de9fa89991..87eef5773a02e35203319f53fa4ff1da58cdf60b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 
 #include "iwm.h"
 #include "bus.h"
index 362002735b12f63694366c433f1e3f2fbd8b3b8e..98a179f98ea14c6bf7ddde509079a977d64257bb 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
 #include <linux/slab.h>
+#include <linux/moduleparam.h>
 
 #include "iwm.h"
 #include "debug.h"
index 56383e7be8350757dca6f7cafcd7b81a657e7529..764b40dd24adad66722756dd3833b9c191969f1a 100644 (file)
@@ -63,6 +63,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/debugfs.h>
index ff6378276ff08d5f06f29ac604304466aff37aac..a7f1ab28940d3ae6ad8e4fbda26b18087b4c21b4 100644 (file)
@@ -634,7 +634,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
                        if (channel &&
                            !(channel->flags & IEEE80211_CHAN_DISABLED))
                                cfg80211_inform_bss(wiphy, channel,
-                                       bssid, le64_to_cpu(*(__le64 *)tsfdesc),
+                                       bssid, get_unaligned_le64(tsfdesc),
                                        capa, intvl, ie, ielen,
                                        LBS_SCAN_RSSI_TO_MBM(rssi),
                                        GFP_KERNEL);
@@ -728,15 +728,9 @@ static void lbs_scan_worker(struct work_struct *work)
                le16_to_cpu(scan_cmd->hdr.size),
                lbs_ret_scan, 0);
 
-       if (priv->scan_channel >= priv->scan_req->n_channels) {
+       if (priv->scan_channel >= priv->scan_req->n_channels)
                /* Mark scan done */
-               if (priv->internal_scan)
-                       kfree(priv->scan_req);
-               else
-                       cfg80211_scan_done(priv->scan_req, false);
-
-               priv->scan_req = NULL;
-       }
+               lbs_scan_done(priv);
 
        /* Restart network */
        if (carrier)
@@ -774,6 +768,21 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal,
        lbs_deb_leave(LBS_DEB_CFG80211);
 }
 
+/*
+ * Clean up priv->scan_req.  Should be used to handle the allocation details.
+ */
+void lbs_scan_done(struct lbs_private *priv)
+{
+       WARN_ON(!priv->scan_req);
+
+       if (priv->internal_scan)
+               kfree(priv->scan_req);
+       else
+               cfg80211_scan_done(priv->scan_req, false);
+
+       priv->scan_req = NULL;
+}
+
 static int lbs_cfg_scan(struct wiphy *wiphy,
        struct net_device *dev,
        struct cfg80211_scan_request *request)
index a02ee151710e36a1f401912a7f1873ee09f9af37..558168ce634d519d67201d92c1992163550f4b4b 100644 (file)
@@ -16,6 +16,7 @@ int lbs_reg_notifier(struct wiphy *wiphy,
 void lbs_send_disconnect_notification(struct lbs_private *priv);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 
+void lbs_scan_done(struct lbs_private *priv);
 void lbs_scan_deinit(struct lbs_private *priv);
 int lbs_disconnect(struct lbs_private *priv, u16 reason);
 
index e08ab1de3d9d3bd126eb0a0c821bd46d82cee903..d798bcc0d83a9561f8a8fdb68826d720de9fc970 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/if_arp.h>
+#include <linux/export.h>
 
 #include "decl.h"
 #include "cfg.h"
index 1af182778844c04d47e5f070fa853cff0c6c2925..d8d8f0d0899faaebb5f2efa857267c3259f27612 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "decl.h"
 #include "cmd.h"
index c962e21762dc19012a0784f2bdd990921242b3d8..9804ebc892d46dab0171bb90f964391146825831 100644 (file)
@@ -29,7 +29,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
index 622ae6de0d8bfc31161ba687f0e4f35a0976b08d..728baa445259c5ead043fa2540017c6d9ee19135 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <linux/hardirq.h>
 #include <linux/interrupt.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
@@ -995,6 +995,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
                spin_unlock_irqrestore(&card->buffer_lock, flags);
                break;
        default:
+               kfree(packet);
                netdev_err(priv->dev, "can't transfer buffer of type %d\n",
                           type);
                err = -EINVAL;
index 8147f1e2a0b0d4a15521f66a82369450bb58af05..db879c364ebf93e93c218e65d344a78ebb3aee92 100644 (file)
@@ -5,7 +5,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/delay.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
index b03779bcd5479d6ddc83076a5b257821295a1cf1..957681dede1776b1a9ee94ab87626bb9e0f9ee63 100644 (file)
@@ -6,7 +6,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/hardirq.h>
@@ -255,10 +255,8 @@ static int lbs_eth_stop(struct net_device *dev)
 
        lbs_update_mcast(priv);
        cancel_delayed_work_sync(&priv->scan_work);
-       if (priv->scan_req) {
-               cfg80211_scan_done(priv->scan_req, false);
-               priv->scan_req = NULL;
-       }
+       if (priv->scan_req)
+               lbs_scan_done(priv);
 
        netif_carrier_off(priv->dev);
 
index 62e10eeadd7e11339ff4ee2b67cdf04d097a6bbf..c7366b07b568ab303985c651679b3bcdb409e051 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/hardirq.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 
 #include "defs.h"
index 8f127520d7863f6ff5eb09b49272d7227b75c5ab..c025f9c1828234ebbac20396c76ae69c05af05da 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 
 #include "host.h"
index 13557fe0bf952be7bb18f28e4ffa3d199e473c71..909ac3685010f116d160063a5e95ebcb2f34f358 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/hardirq.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "libertas_tf.h"
 
index ba7d96584cb6695120e548763dc4be8a976066ec..68202e63873a00172b672365e694e3f9823bbae6 100644 (file)
@@ -15,7 +15,7 @@
 #include "if_usb.h"
 
 #include <linux/delay.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
index acc461aa385e180656cf76a0f6d69990e0b74f6e..ceb51b6e67026bb434c1db67259ffd27129917ff 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 
 #include <linux/etherdevice.h>
+#include <linux/module.h>
 #include "libertas_tf.h"
 
 #define DRIVER_RELEASE_VERSION "004.p0"
index 68455a2307cb54ba99611cb6618ed16169b9f0df..523ad55a288501af3931b03ae56eef98756bbeb7 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
 #include <linux/debugfs.h>
+#include <linux/module.h>
 #include <net/genetlink.h>
 #include "mac80211_hwsim.h"
 
index dae8dbb24a03e83352742b20c3320c9819019889..8d3ab378662b77ac4c55c40bceba1b8a53715552 100644 (file)
@@ -819,8 +819,10 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                        wildcard_ssid_tlv->header.len = cpu_to_le16(
                                (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
                                                         max_ssid_length)));
-                       wildcard_ssid_tlv->max_ssid_length =
-                               user_scan_in->ssid_list[ssid_idx].max_len;
+
+                       /* max_ssid_length = 0 tells firmware to perform
+                          specific scan for the SSID filled */
+                       wildcard_ssid_tlv->max_ssid_length = 0;
 
                        memcpy(wildcard_ssid_tlv->ssid,
                               user_scan_in->ssid_list[ssid_idx].ssid,
@@ -1469,7 +1471,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
                               s32 rssi, const u8 *ie_buf, size_t ie_len,
                               u16 beacon_period, u16 cap_info_bitmap, u8 band)
 {
-       struct mwifiex_bssdescriptor *bss_desc = NULL;
+       struct mwifiex_bssdescriptor *bss_desc;
        int ret;
        unsigned long flags;
        u8 *beacon_ie;
@@ -1484,6 +1486,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
 
        beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
        if (!beacon_ie) {
+               kfree(bss_desc);
                dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
                return -ENOMEM;
        }
index 527cf5333db5d9a815afc3ef8856b032cb3030ea..4df8cf64b56ce553d1c1a537741d2f995d414b4c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
+#include <linux/module.h>
 
 #include "hermes.h"
 #include "hermes_dld.h"
index 8b6f363b3f7db581d47fdac99d4da01658187120..fa8ce510478143f6d8eaa55f2e70eaf959b08bf4 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <net/mac80211.h>
 #include <linux/crc-ccitt.h>
+#include <linux/export.h>
 
 #include "p54.h"
 #include "eeprom.h"
index 53a3408931be3b94394e71de3ba8ac7051c969a6..18e82b31afa61243554e21e9808e47bada65d5b0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 
 #include <net/mac80211.h>
 
index ad9ae04d07aaa0666133cb52c8c8930a7683b05b..db4d9a02f264eb6877face19cd892ac9e7d363fa 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
+#include <linux/module.h>
 
 #include <net/mac80211.h>
 
index 1b753173680fe4ca2c02c7251c3e8e80f544f17c..b1f51a215792028783223984dec8f0b0ac1a8f17 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 
 #include "p54.h"
index f18df82eeb92caccedb8381bb95e4f55cd4d1901..78d0d6988553d40354b9fbf2396e1657eaefd9c6 100644 (file)
@@ -588,8 +588,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
        WARN_ON(priv->fw_state != FW_STATE_READY);
 
-       cancel_work_sync(&priv->work);
-
        p54spi_power_off(priv);
        spin_lock_irqsave(&priv->tx_lock, flags);
        INIT_LIST_HEAD(&priv->tx_pending);
@@ -597,6 +595,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
        priv->fw_state = FW_STATE_OFF;
        mutex_unlock(&priv->mutex);
+
+       cancel_work_sync(&priv->work);
 }
 
 static int __devinit p54spi_probe(struct spi_device *spi)
@@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        init_completion(&priv->fw_comp);
        INIT_LIST_HEAD(&priv->tx_pending);
        mutex_init(&priv->mutex);
+       spin_lock_init(&priv->tx_lock);
        SET_IEEE80211_DEV(hw, &spi->dev);
        priv->common.open = p54spi_op_start;
        priv->common.stop = p54spi_op_stop;
index a8f3bc740dfaf8354abff344f5ab7665bd8faf58..9b60968664279c310eb88abba9500931199d481b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/crc32.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 
 #include "p54.h"
index f485784a60aeb0a903871464e6db494c71dc2bf6..6ed9c323e3cb866c1b69dc7294b71f82f7cc8878 100644 (file)
@@ -16,6 +16,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
index d97a2caf582b3997f2378434117758a928cefbd3..bc2ba80c47bb9ff0105d8ed2c119ab3b3589364e 100644 (file)
@@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
                dwrq->flags = 0;
                dwrq->length = 0;
        }
-       essid->octets[essid->length] = '\0';
+       essid->octets[dwrq->length] = '\0';
        memcpy(extra, essid->octets, dwrq->length);
        kfree(essid);
 
index 3f183a15186e09b5e05a2e296c5c66bd94426b23..1ba079dffb11573e86f1b547ac8868e313840f26 100644 (file)
@@ -3771,7 +3771,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
        /* Apparently the data is read from end to start */
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
        /* The returned value is in CPU order, but eeprom is le */
-       rt2x00dev->eeprom[i] = cpu_to_le32(reg);
+       *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
        *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
index f1565792f2701c6285b202456c831341f6f5e181..377876315b8d4a9bcdcc91b228b14bed45bef943 100644 (file)
@@ -919,6 +919,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x050d, 0x935b) },
        /* Buffalo */
        { USB_DEVICE(0x0411, 0x00e8) },
+       { USB_DEVICE(0x0411, 0x0158) },
        { USB_DEVICE(0x0411, 0x016f) },
        { USB_DEVICE(0x0411, 0x01a2) },
        /* Corega */
index 2ec5c00235e612941fca457a20a9f16b1b8718b9..99ff12d0c29dfce934719f304cd66511fc30d514 100644 (file)
@@ -943,6 +943,7 @@ struct rt2x00_dev {
         * Powersaving work
         */
        struct delayed_work autowakeup_work;
+       struct work_struct sleep_work;
 
        /*
         * Data queue arrays for RX, TX, Beacon and ATIM.
index e1fb2a8569be292d0f26f5347b0bfa828737bd39..edd317fa7c0aafb06658d06616cc74a5e73c0bd0 100644 (file)
@@ -465,6 +465,23 @@ static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
        return NULL;
 }
 
+static void rt2x00lib_sleep(struct work_struct *work)
+{
+       struct rt2x00_dev *rt2x00dev =
+           container_of(work, struct rt2x00_dev, sleep_work);
+
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return;
+
+       /*
+        * Check again is powersaving is enabled, to prevent races from delayed
+        * work execution.
+        */
+       if (!test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
+               rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
+                                IEEE80211_CONF_CHANGE_PS);
+}
+
 static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
                                      struct sk_buff *skb,
                                      struct rxdone_entry_desc *rxdesc)
@@ -512,8 +529,7 @@ static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
        cam |= (tim_ie->bitmap_ctrl & 0x01);
 
        if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
-               rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
-                                IEEE80211_CONF_CHANGE_PS);
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->sleep_work);
 }
 
 static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
@@ -1141,6 +1157,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 
        INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
+       INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
 
        /*
         * Let the driver probe the device to detect the capabilities.
@@ -1197,6 +1214,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
         */
        cancel_work_sync(&rt2x00dev->intf_work);
        cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+       cancel_work_sync(&rt2x00dev->sleep_work);
        if (rt2x00_is_usb(rt2x00dev)) {
                del_timer_sync(&rt2x00dev->txstatus_timer);
                cancel_work_sync(&rt2x00dev->rxdone_work);
index 0082015ff664e9e5af45298dd804f46cf028d4a4..2f14a5fb0cbb97007880b4cbf76fba2449500ac1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 
 #include "rtl8180.h"
index 24873b55b55c31cd43e5fe7a3d00ff124f62c977..4a78f9e39dfa985614721f810b3085d00da29168 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 
 #include "rtl8187.h"
index d4fdd2a5a7392a24f1a15b47f3f5aaa14d36a7cc..b4ce93436d2e705a3661e616c3b7111fa5f64641 100644 (file)
@@ -30,6 +30,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/ip.h>
+#include <linux/module.h>
 #include "wifi.h"
 #include "rc.h"
 #include "base.h"
index 7babb6acd9575639f0bc84d0faeccfec819da0c6..dc36d7461caaaecd07a8f60a93941b843c094ff2 100644 (file)
@@ -29,6 +29,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/export.h>
 #include "wifi.h"
 #include "cam.h"
 
index 3fc21f60bb0494d8cb49c0f2cc4e2a60cc62c49d..ed1058b7158700c6eb65cc1f373472577b85ab1f 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/export.h>
 #include "wifi.h"
 #include "efuse.h"
 
index 177a8e669241b834dbdab05a4ec872e415812c58..eb61061821e40cc2f3f1d25ac678bbd4b813e1b2 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/export.h>
 #include "core.h"
 #include "wifi.h"
 #include "pci.h"
index a693feffbe72913a28411ffbff05d07a1748fce7..55c8e50f45fd143b7e606894c71e072c97480f2a 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/export.h>
 #include "wifi.h"
 #include "base.h"
 #include "ps.h"
@@ -394,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        if (mac->link_state != MAC80211_LINKED)
                return;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
 
        /* Idle for a while if we connect to AP a while ago. */
        if (mac->cnt_after_linked >= 2) {
@@ -406,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
                }
        }
 
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 
 /*Leave the leisure power save mode.*/
@@ -415,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       unsigned long flags;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags);
 
        if (ppsc->fwctrl_lps) {
                if (ppsc->dot11_psmode != EACTIVE) {
@@ -437,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
                        rtl_lps_set_psmode(hw, EACTIVE);
                }
        }
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags);
 }
 
 /* For sw LPS*/
@@ -538,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
                RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
        }
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 
 void rtl_swlps_rfon_wq_callback(void *data)
@@ -573,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
        if (rtlpriv->link_info.busytraffic)
                return;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 
        if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
                !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
index a00774e7090d58fc9d783c56a5184e56db18c2d0..72a98cab6f699e124ac18cb0bf0a3c4d7f778634 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/export.h>
 #include "dm_common.h"
 #include "phy_common.h"
 #include "../pci.h"
index 49a064bdbce6d26225674eab7e8540b29a747607..950c65a15b8a7fa0521471f5124cd89ee111268b 100644 (file)
@@ -30,6 +30,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/firmware.h>
+#include <linux/export.h>
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
index 2f624fc2749923ce3a0d22d24394d10bcea9b0d3..605ff191aeb7f437c756aba158c3a5daa49726ce 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/module.h>
 #include "../wifi.h"
 
 
index 3b11642d3f7dd9d44e038559d543bb5ba35ed6db..1f07558debf2b05b41bad4391b8fbccae9a19c68 100644 (file)
@@ -27,6 +27,7 @@
  *
  *****************************************************************************/
 
+#include <linux/export.h>
 #include "../wifi.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
index a48404cc2b962d0bff172a836c8410737f3705b0..f2aa33dc4d7806d89c80ac5ac3471e753c626173 100644 (file)
@@ -28,6 +28,7 @@
  *****************************************************************************/
 
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 
 #include "../wifi.h"
 #include "../core.h"
index feed1ed8d9b68f1d690f571bc7842d03a392eddf..c244f2f1b83fb6658569cd545ac37ec3a2772a18 100644 (file)
@@ -42,6 +42,7 @@
 #include "led.h"
 #include "hw.h"
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Georgia         <georgia@realtek.com>");
 MODULE_AUTHOR("Ziv Huang       <ziv_huang@realtek.com>");
index 691f800921852ce439b66ee84535ef6b6276e53c..149493f4c25c650ab2cf5ebcadc78d5d743997da 100644 (file)
@@ -30,6 +30,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 
 #include "../wifi.h"
 #include "../core.h"
index 3ec9a0d41bafde750d478a2b7ffbc8f69a6c8ec4..92f49d522c56dbc2b81f54b1850c00df6b92e9a2 100644 (file)
@@ -30,6 +30,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 
 #include "../wifi.h"
 #include "../core.h"
index b42c2e2b2055463089c0de2a6cc1882f13d9e5c0..54cb8a60514d582e6bf5ae07fdf3d2b212aa2c2c 100644 (file)
@@ -28,6 +28,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/usb.h>
+#include <linux/export.h>
 #include "core.h"
 #include "wifi.h"
 #include "usb.h"
index d4e628db76b03be00406f1e1629251d3700c2909..6813379149767ea4c6236d6b43a0f1f0c219c8d1 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/slab.h>
 #include <linux/wl12xx.h>
+#include <linux/export.h>
 
 #include "acx.h"
 #include "reg.h"
index 128ccb79318c86c7e0a8bc4a65c61389b58e959f..fc29c671cf3b34db3fc695fbd70209720a3c52e8 100644 (file)
@@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
                                                break;
                                        }
                                /* Fail if SSID isn't present in the filters */
-                               if (j == req->n_ssids) {
+                               if (j == cmd->n_ssids) {
                                        ret = -EINVAL;
                                        goto out_free;
                                }
index cf0d69dd7be56ae84be4ab98a38bd68309d7655e..785bdbe38f2a0cb6f67d6ad56a3c0ad2d5980490 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/skbuff.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
index 161f207786a42b53b9f5fd2bd66481220882c0c9..94b79c3338c4260200306f180ff053b87006faa6 100644 (file)
@@ -58,10 +58,6 @@ struct xenvif {
        u8               fe_dev_addr[6];
 
        /* Physical parameters of the comms window. */
-       grant_handle_t   tx_shmem_handle;
-       grant_ref_t      tx_shmem_ref;
-       grant_handle_t   rx_shmem_handle;
-       grant_ref_t      rx_shmem_ref;
        unsigned int     irq;
 
        /* List of frontends to notify after a batch of frames sent. */
@@ -70,8 +66,6 @@ struct xenvif {
        /* The shared rings and indexes. */
        struct xen_netif_tx_back_ring tx;
        struct xen_netif_rx_back_ring rx;
-       struct vm_struct *tx_comms_area;
-       struct vm_struct *rx_comms_area;
 
        /* Frontend feature information. */
        u8 can_sg:1;
@@ -106,6 +100,11 @@ struct xenvif {
        wait_queue_head_t waiting_to_free;
 };
 
+static inline struct xenbus_device *xenvif_to_xenbus_device(struct xenvif *vif)
+{
+       return to_xenbus_device(vif->dev->dev.parent);
+}
+
 #define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
 #define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 
index d5508957200e0a28e010fa358bf677ad3a308eaa..15e332d08c8d7825382e21bfba8c868636c2c1f6 100644 (file)
@@ -1021,7 +1021,7 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
                pending_idx = *((u16 *)skb->data);
                xen_netbk_idx_release(netbk, pending_idx);
                for (j = start; j < i; j++) {
-                       pending_idx = frag_get_pending_idx(&shinfo->frags[i]);
+                       pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
                        xen_netbk_idx_release(netbk, pending_idx);
                }
 
@@ -1589,88 +1589,42 @@ static int xen_netbk_kthread(void *data)
 
 void xen_netbk_unmap_frontend_rings(struct xenvif *vif)
 {
-       struct gnttab_unmap_grant_ref op;
-
-       if (vif->tx.sring) {
-               gnttab_set_unmap_op(&op, (unsigned long)vif->tx_comms_area->addr,
-                                   GNTMAP_host_map, vif->tx_shmem_handle);
-
-               if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
-                       BUG();
-       }
-
-       if (vif->rx.sring) {
-               gnttab_set_unmap_op(&op, (unsigned long)vif->rx_comms_area->addr,
-                                   GNTMAP_host_map, vif->rx_shmem_handle);
-
-               if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
-                       BUG();
-       }
-       if (vif->rx_comms_area)
-               free_vm_area(vif->rx_comms_area);
-       if (vif->tx_comms_area)
-               free_vm_area(vif->tx_comms_area);
+       if (vif->tx.sring)
+               xenbus_unmap_ring_vfree(xenvif_to_xenbus_device(vif),
+                                       vif->tx.sring);
+       if (vif->rx.sring)
+               xenbus_unmap_ring_vfree(xenvif_to_xenbus_device(vif),
+                                       vif->rx.sring);
 }
 
 int xen_netbk_map_frontend_rings(struct xenvif *vif,
                                 grant_ref_t tx_ring_ref,
                                 grant_ref_t rx_ring_ref)
 {
-       struct gnttab_map_grant_ref op;
+       void *addr;
        struct xen_netif_tx_sring *txs;
        struct xen_netif_rx_sring *rxs;
 
        int err = -ENOMEM;
 
-       vif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
-       if (vif->tx_comms_area == NULL)
+       err = xenbus_map_ring_valloc(xenvif_to_xenbus_device(vif),
+                                    tx_ring_ref, &addr);
+       if (err)
                goto err;
 
-       vif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
-       if (vif->rx_comms_area == NULL)
-               goto err;
-
-       gnttab_set_map_op(&op, (unsigned long)vif->tx_comms_area->addr,
-                         GNTMAP_host_map, tx_ring_ref, vif->domid);
-
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
-
-       if (op.status) {
-               netdev_warn(vif->dev,
-                           "failed to map tx ring. err=%d status=%d\n",
-                           err, op.status);
-               err = op.status;
-               goto err;
-       }
-
-       vif->tx_shmem_ref    = tx_ring_ref;
-       vif->tx_shmem_handle = op.handle;
-
-       txs = (struct xen_netif_tx_sring *)vif->tx_comms_area->addr;
+       txs = (struct xen_netif_tx_sring *)addr;
        BACK_RING_INIT(&vif->tx, txs, PAGE_SIZE);
 
-       gnttab_set_map_op(&op, (unsigned long)vif->rx_comms_area->addr,
-                         GNTMAP_host_map, rx_ring_ref, vif->domid);
-
-       if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
-               BUG();
-
-       if (op.status) {
-               netdev_warn(vif->dev,
-                           "failed to map rx ring. err=%d status=%d\n",
-                           err, op.status);
-               err = op.status;
+       err = xenbus_map_ring_valloc(xenvif_to_xenbus_device(vif),
+                                    rx_ring_ref, &addr);
+       if (err)
                goto err;
-       }
-
-       vif->rx_shmem_ref     = rx_ring_ref;
-       vif->rx_shmem_handle  = op.handle;
-       vif->rx_req_cons_peek = 0;
 
-       rxs = (struct xen_netif_rx_sring *)vif->rx_comms_area->addr;
+       rxs = (struct xen_netif_rx_sring *)addr;
        BACK_RING_INIT(&vif->rx, rxs, PAGE_SIZE);
 
+       vif->rx_req_cons_peek = 0;
+
        return 0;
 
 err:
@@ -1714,7 +1668,7 @@ static int __init netback_init(void)
                                             "netback/%u", group);
 
                if (IS_ERR(netbk->task)) {
-                       printk(KERN_ALERT "kthread_run() fails at netback\n");
+                       printk(KERN_ALERT "kthread_create() fails at netback\n");
                        del_timer(&netbk->net_timer);
                        rc = PTR_ERR(netbk->task);
                        goto failed_init;
index 5b0f1ff8036133c50a4427dfa90e08ec9d54cde7..06c3642e5bdb0f1525c6bde54bf2c73058e1b26e 100644 (file)
@@ -27,6 +27,7 @@
  *
  */
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/nfc.h>
 #include <net/nfc/nci.h>
 #include <net/nfc/nci_core.h>
index aeec35bc3789662f350de2ffdd5ebd6e9f0acf8d..fd85fa298e0f053eb666fc0c6060e3779731545f 100644 (file)
@@ -681,9 +681,14 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
        if (p != NULL && l > 0)
                strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
 
+       /*
+        * CONFIG_CMDLINE is meant to be a default in case nothing else
+        * managed to set the command line, unless CONFIG_CMDLINE_FORCE
+        * is set in which case we override whatever was found earlier.
+        */
 #ifdef CONFIG_CMDLINE
 #ifndef CONFIG_CMDLINE_FORCE
-       if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+       if (!((char *)data)[0])
 #endif
                strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 #endif /* CONFIG_CMDLINE */
index 6d3dd3988d0f2891e65514a2bac68b184409ac1d..0f0cfa3bca301e2d824ad64ebdaba23d6c617825 100644 (file)
 #include <linux/string.h>
 #include <linux/slab.h>
 
-/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
-#ifndef NO_IRQ
-#define NO_IRQ 0
-#endif
-
 /**
  * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
  * @device: Device node of the device whose interrupt is to be mapped
@@ -44,7 +39,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
        struct of_irq oirq;
 
        if (of_irq_map_one(dev, index, &oirq))
-               return NO_IRQ;
+               return 0;
 
        return irq_create_of_mapping(oirq.controller, oirq.specifier,
                                     oirq.size);
@@ -60,27 +55,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
  */
 struct device_node *of_irq_find_parent(struct device_node *child)
 {
-       struct device_node *p, *c = child;
+       struct device_node *p;
        const __be32 *parp;
 
-       if (!of_node_get(c))
+       if (!of_node_get(child))
                return NULL;
 
        do {
-               parp = of_get_property(c, "interrupt-parent", NULL);
+               parp = of_get_property(child, "interrupt-parent", NULL);
                if (parp == NULL)
-                       p = of_get_parent(c);
+                       p = of_get_parent(child);
                else {
                        if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
                                p = of_node_get(of_irq_dflt_pic);
                        else
                                p = of_find_node_by_phandle(be32_to_cpup(parp));
                }
-               of_node_put(c);
-               c = p;
+               of_node_put(child);
+               child = p;
        } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
 
-       return (p == child) ? NULL : p;
+       return p;
 }
 
 /**
@@ -345,7 +340,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 
        /* Only dereference the resource if both the
         * resource and the irq are valid. */
-       if (r && irq != NO_IRQ) {
+       if (r && irq) {
                r->start = r->end = irq;
                r->flags = IORESOURCE_IRQ;
                r->name = dev->full_name;
@@ -363,7 +358,7 @@ int of_irq_count(struct device_node *dev)
 {
        int nr = 0;
 
-       while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ)
+       while (of_irq_to_resource(dev, nr, NULL))
                nr++;
 
        return nr;
@@ -383,7 +378,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
        int i;
 
        for (i = 0; i < nr_irqs; i++, res++)
-               if (of_irq_to_resource(dev, i, res) == NO_IRQ)
+               if (!of_irq_to_resource(dev, i, res))
                        break;
 
        return i;
@@ -424,6 +419,8 @@ void __init of_irq_init(const struct of_device_id *matches)
 
                desc->dev = np;
                desc->interrupt_parent = of_irq_find_parent(np);
+               if (desc->interrupt_parent == np)
+                       desc->interrupt_parent = NULL;
                list_add_tail(&desc->list, &intc_desc_list);
        }
 
index bb184717588fe019e7bf039bfb73e651c5960ec6..ffab033d207e199113e4772e345c7968fc027744 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/of_net.h>
 #include <linux/phy.h>
+#include <linux/export.h>
 
 /**
  * It maps 'enum phy_interface_t' found in include/linux/phy.h
index 3701b62c1d5eeb5197351125f95cf7511a072ab1..13e37e2d8ec16ba8b4179198cfbf759015628da9 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/of.h>
 #include <linux/of_pci.h>
 #include <asm/prom.h>
index ac1ec54e4fd50eea60d123004fe735636518722c..93125163dea21fc16bcf2dd0243c7426cd351708 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/kernel.h>
 #include <linux/of_pci.h>
 #include <linux/of_irq.h>
+#include <linux/export.h>
 #include <asm/prom.h>
 
 /**
index 1dbce58a58b01eecc8ebe48d7a9d802cfa90193f..6dbc074e4876afc809a5de9e73c0d35e7fcf5987 100644 (file)
@@ -6,6 +6,7 @@
  * tree.
  */
 
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
index dccd8636095cb361e2e0e1e2bb8fb7fdd57ecee2..f8c752e408a663d55adf7e84ca4fb42aa93d1d02 100644 (file)
@@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val)
        return err;
 }
 
+static int timer_mode;
+
 static int __init oprofile_init(void)
 {
        int err;
 
+       /* always init architecture to setup backtrace support */
        err = oprofile_arch_init(&oprofile_ops);
-       if (err < 0 || timer) {
-               printk(KERN_INFO "oprofile: using timer interrupt.\n");
+
+       timer_mode = err || timer;      /* fall back to timer mode on errors */
+       if (timer_mode) {
+               if (!err)
+                       oprofile_arch_exit();
                err = oprofile_timer_init(&oprofile_ops);
                if (err)
                        return err;
        }
-       return oprofilefs_register();
+
+       err = oprofilefs_register();
+       if (!err)
+               return 0;
+
+       /* failed */
+       if (timer_mode)
+               oprofile_timer_exit();
+       else
+               oprofile_arch_exit();
+
+       return err;
 }
 
 
 static void __exit oprofile_exit(void)
 {
-       oprofile_timer_exit();
        oprofilefs_unregister();
-       oprofile_arch_exit();
+       if (timer_mode)
+               oprofile_timer_exit();
+       else
+               oprofile_arch_exit();
 }
 
 
index 3ef44624f5103ddaf405e76fcafd0afe6b27a132..878fba1265829cdab586a145d86a332b5ce32874 100644 (file)
@@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops)
        ops->start = oprofile_hrtimer_start;
        ops->stop = oprofile_hrtimer_stop;
        ops->cpu_type = "timer";
+       printk(KERN_INFO "oprofile: using timer interrupt.\n");
        return 0;
 }
 
index 75a80e46b391103673da0f5b62f48d1cf384ee72..8b490d77054f547c2a83f10e52529ff15f85eeb4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/scatterlist.h>
 #include <linux/iommu-helper.h>
+#include <linux/export.h>
 
 #include <asm/byteorder.h>
 #include <asm/cache.h>         /* for L1_CACHE_BYTES */
index a6f762188bc331ed958dc3aec7fb225b1a8cad95..8644d5372e7ff328f5f0fe10079648088d4634bd 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 
 #include <asm/ropes.h>
 #include <asm/mckinley.h>      /* for proc_mckinley_root */
index cec66064ee4b51a65be8d940b719c2d67760e4bf..f02b5235056d938ac2713c4534ff0bd3d89d7c8f 100644 (file)
@@ -51,17 +51,6 @@ config XEN_PCIDEV_FRONTEND
           The PCI device frontend driver allows the kernel to import arbitrary
           PCI devices from a PCI backend to support PCI driver domains.
 
-config XEN_PCIDEV_FE_DEBUG
-        bool "Xen PCI Frontend debugging"
-        depends on XEN_PCIDEV_FRONTEND && PCI_DEBUG
-       help
-         Say Y here if you want the Xen PCI frontend to produce a bunch of debug
-         messages to the system log.  Select this if you are having a
-         problem with Xen PCI frontend support and want to see more of what is
-         going on.
-
-         When in doubt, say N.
-
 config HT_IRQ
        bool "Interrupts on hypertransport devices"
        default y
@@ -87,6 +76,7 @@ config PCI_IOV
 
 config PCI_PRI
        bool "PCI PRI support"
+       depends on PCI
        select PCI_ATS
        help
          PRI is the PCI Page Request Interface. It allows PCI devices that are
index f727a09eb72fc9a04ffe0481eb7330d778d4f3d9..7ec56fb0bd78aca5aec916aefd8788cc1b101027 100644 (file)
@@ -10,6 +10,7 @@
  *   PASID support added by Joerg Roedel <joerg.roedel@amd.com>
  */
 
+#include <linux/export.h>
 #include <linux/pci-ats.h>
 #include <linux/pci.h>
 
index 4d4a64478404650a9640c852b3cf708937fc5ff0..d3509cdeb554913dddb68fc5b956c63bd77a1abf 100644 (file)
@@ -1,6 +1,7 @@
 /* Core PCI functionality used only by PCI hotplug */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include "pci.h"
 
 
index 596172b4ae955802a5778dd0c375b870b9a11909..fce1c54a0c8d8acf480c4b208ced89fb060ac95a 100644 (file)
@@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle)
 {
        acpi_status status;
        unsigned long long tmp;
+       struct acpi_pci_root *root;
        acpi_handle dummy_handle;
 
+       /*
+        * We shouldn't use this bridge if PCIe native hotplug control has been
+        * granted by the BIOS for it.
+        */
+       root = acpi_pci_find_root(handle);
+       if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL))
+               return -ENODEV;
+
        /* if the bridge doesn't have _STA, we assume it is always there */
        status = acpi_get_handle(handle, "_STA", &dummy_handle);
        if (ACPI_SUCCESS(status)) {
@@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
 static acpi_status
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
+       struct acpi_pci_root *root;
        int *count = (int *)context;
 
-       if (acpi_is_root_bridge(handle)) {
-               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-                               handle_hotplug_event_bridge, NULL);
-                       (*count)++;
-       }
+       if (!acpi_is_root_bridge(handle))
+               return AE_OK;
+
+       root = acpi_pci_find_root(handle);
+       if (!root)
+               return AE_OK;
+
+       if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
+               return AE_OK;
+
+       (*count)++;
+       acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                                   handle_hotplug_event_bridge, NULL);
+
        return AE_OK ;
 }
 
index 5f7226223a62c9067bcc4a47f1b3e6bd47b69c40..376d70d17176577cae942ecbe345ced41987e297 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "pciehp.h"
 
 #define PCIEHP_DETECT_PCIE     (0)
index 1e9c9aacc3a6c82363b39602c5f6bab1b4bbd30d..085dbb5fc168be33de77d0ced5c411c807ffc2ef 100644 (file)
@@ -213,9 +213,6 @@ static int board_added(struct slot *p_slot)
                goto err_exit;
        }
 
-       /* Wait for 1 second after checking link training status */
-       msleep(1000);
-
        /* Check for a power fault */
        if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
                ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
index 96dc4734e4affcc6c7f763a9853342678df8a7c6..7b1414810ae3e0e0a5ccbcd9bec0f21051cf95db 100644 (file)
@@ -280,6 +280,14 @@ int pciehp_check_link_status(struct controller *ctrl)
         else
                 msleep(1000);
 
+       /*
+        * Need to wait for 1000 ms after Data Link Layer Link Active
+        * (DLLLA) bit reads 1b before sending configuration request.
+        * We need it before checking Link Training (LT) bit becuase
+        * LT is still set even after DLLLA bit is set on some platform.
+        */
+       msleep(1000);
+
        retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
        if (retval) {
                ctrl_err(ctrl, "Cannot read LNKSTATUS register\n");
@@ -294,6 +302,16 @@ int pciehp_check_link_status(struct controller *ctrl)
                return retval;
        }
 
+       /*
+        * If the port supports Link speeds greater than 5.0 GT/s, we
+        * must wait for 100 ms after Link training completes before
+        * sending configuration request.
+        */
+       if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT)
+               msleep(100);
+
+       pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
+
        return retval;
 }
 
@@ -484,7 +502,6 @@ int pciehp_power_on_slot(struct slot * slot)
        u16 slot_cmd;
        u16 cmd_mask;
        u16 slot_status;
-       u16 lnk_status;
        int retval = 0;
 
        /* Clear sticky power-fault bit from previous power failures */
@@ -516,14 +533,6 @@ int pciehp_power_on_slot(struct slot * slot)
        ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
                 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
-       retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
-       if (retval) {
-               ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n",
-                               __func__);
-               return retval;
-       }
-       pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
-
        return retval;
 }
 
index 3ffd9c1acc0a33e0146f992fccc695444799b726..8c05a18c9770f1859a9cad86353d72f1af94ba2e 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <linux/pci_hotplug.h>
 
 static struct hpp_type0 pci_default_type0 = {
index 1d002b1c2bf4b1f1366b19eb8ded4943660654b2..c56a9413e1afc62596c98cdbd54ddfdd345429a9 100644 (file)
@@ -18,6 +18,7 @@
 #undef DEBUG
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
index aca972bbfb4c8ba04e7fc74efd74636ebe49ea65..dd7e0c51a33e5e5f79eb9f11b444fe4667d2ba2d 100644 (file)
@@ -278,8 +278,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int is_shpc_capable(struct pci_dev *dev)
 {
-       if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device ==
-                                               PCI_DEVICE_ID_AMD_GOLAM_7450))
+       if (dev->vendor == PCI_VENDOR_ID_AMD &&
+           dev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)
                return 1;
        if (!pci_find_capability(dev, PCI_CAP_ID_SHPC))
                return 0;
index 36547f0ce305e987c7a414a47d6a4e5806b239cb..75ba2311b54f3f37b62176a37e032c480be9f3f1 100644 (file)
@@ -944,8 +944,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
        ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
        ctrl_dbg(ctrl, "Hotplug Controller:\n");
 
-       if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
-                               PCI_DEVICE_ID_AMD_GOLAM_7450)) {
+       if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+           pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450) {
                /* amd shpc driver doesn't use Base Offset; assume 0 */
                ctrl->mmio_base = pci_resource_start(pdev, 0);
                ctrl->mmio_size = pci_resource_len(pdev, 0);
index db057b6fe0c8bccf12710cee1c488d77def872f9..6e373ea57b32834df2076b26b4f0d72941933644 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/irq.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/htirq.h>
 
index 203508b227b7ca383498a485947dbd482da98b7d..5775638ac0170fbb9c77b68653593e1594b92529 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
 #include <acpi/acpi_bus.h>
index 9b4e88c636f8573049c43cacd54d6c017fa21cc7..b82c155d7b37f539eb85ce28512219a6b701cf52 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/pci-ats.h>
index de01174aff067a2868817b5d64deea03cd040d55..e5f69a43b1b18e0961ff05ddc29ae3872be962fc 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 
 static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
index 2f10328bf661234437c1e862f7d4e1a96afeabb3..0e6d04d7ba4f7c0a2f8494f3e99aceaed1eecacb 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
index 7bcf12adced7249674ec931ea034066fb6ef3d64..106be0d08f81ff7b9306d0ad364b86786349a5fe 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/stat.h>
+#include <linux/export.h>
 #include <linux/topology.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
index 7285145ac1c917a5513376aba72321374f7e9eab..64765474676f6ddd37f893cac1be69d1c07bed91 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 36864a935d687bb732f9c09b45f2c647d6dca54c..48ebdb237f3f73d1e37e6e2022940ea5262d459c 100644 (file)
@@ -7,6 +7,7 @@
  * PCI ROM access routines
  */
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 
index 51a9095c7da4812ddfd843c615083eca61ea9889..5717509becbea42ab3f0c8e44b9ae76893b2cd4c 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
index 968cfea04f749ea76ffcb33bb62f114ecfd9a6ef..ac6412fb8d6fea4a03fe77f23530fb558b44230c 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/kobject.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/err.h>
 #include "pci.h"
index a5a5ca17cfe6bd9bb28afc0248546f80dca6cf99..39b79070335db7f0a5ae040b083bdc457c2f0f44 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 
 int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
 {
index 01757f18a2083fb19cd15018cc1af9bff16f7207..3e49df6d5e3b0dec58ef7fab3ce0a74d0e37e965 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
 #include <linux/slab.h>
index 2c540542b5af7fb183a57f8ea66b230649c16c2e..a87e2728b2c3a19cd50df8b6ae19de643296cceb 100644 (file)
@@ -231,6 +231,7 @@ void pxa2xx_configure_sockets(struct device *dev)
 
        __raw_writel(mecr, MECR);
 }
+EXPORT_SYMBOL(pxa2xx_configure_sockets);
 
 static const char *skt_names[] = {
        "PCMCIA socket 0",
index 63f4d5211ed2b9bf31650840195010bb10dc3889..0b4f946cf13aa6126f9b55a371cd9279fe5a8c3e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 
 #include <asm/mach-types.h>
 
index 6ee42b4c3e68b902248b4a2416c6d0add4fcb7f3..923f315926ef478dc4793924f7349074baed8d5a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/export.h>
 
 #include <asm/mach-types.h>
 
index 4f09506ad8d49398d03918227303dda202b674fe..6e7dcfd22ede8c5696cb68b80528bb94ddf9b2f1 100644 (file)
@@ -12,9 +12,8 @@
 
 #include <linux/module.h>
 
-#include <asm/system.h>
 #include <asm/mach-types.h>
-#include <mach/system.h>
+#include <mach/hardware.h>
 
 int cmx255_pcmcia_init(void);
 int cmx270_pcmcia_init(void);
index ef566443f945253ed94c6dab7d27bf81fcf46d7c..e17e2f8001d2a6ebb770d4e20c6aa0a3cd2576cd 100644 (file)
@@ -2,23 +2,17 @@
 # PINCTRL infrastructure and drivers
 #
 
-menuconfig PINCTRL
-       bool "PINCTRL Support"
+config PINCTRL
+       bool
        depends on EXPERIMENTAL
-       help
-         This enables the PINCTRL subsystem for controlling pins
-         on chip packages, for example multiplexing pins on primarily
-         PGA and BGA packages for systems on chip.
-
-         If unsure, say N.
 
 if PINCTRL
 
+menu "Pin controllers"
+       depends on PINCTRL
+
 config PINMUX
        bool "Support pinmux controllers"
-       help
-         Say Y here if you want the pincontrol subsystem to handle pin
-         multiplexing drivers.
 
 config DEBUG_PINCTRL
        bool "Debug PINCTRL calls"
@@ -30,14 +24,12 @@ config PINMUX_SIRF
        bool "CSR SiRFprimaII pinmux driver"
        depends on ARCH_PRIMA2
        select PINMUX
-       help
-         Say Y here to enable the SiRFprimaII pinmux driver
 
 config PINMUX_U300
        bool "U300 pinmux driver"
        depends on ARCH_U300
        select PINMUX
-       help
-         Say Y here to enable the U300 pinmux driver
+
+endmenu
 
 endif
index 423522d87313b583620ddbad5d85272793e0e794..eadef9e191ea59d5f59b9453894a1d3d1824b4bf 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) "pinctrl core: " fmt
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/slab.h>
index f4e3d82379d7869f39f479b74484e3b28dda5140..7f43cf86d77602675297aaea32932c9a176f4c07 100644 (file)
@@ -83,8 +83,10 @@ config DELL_LAPTOP
        depends on EXPERIMENTAL
        depends on BACKLIGHT_CLASS_DEVICE
        depends on RFKILL || RFKILL = n
-       depends on POWER_SUPPLY
        depends on SERIO_I8042
+       select POWER_SUPPLY
+       select LEDS_CLASS
+       select NEW_LEDS
        default n
        ---help---
        This driver adds support for rfkill and backlight control to Dell
index a43cfd906c6d678759d241a3fae9363889e1c15d..d93e962f26100c7e0498f80f7dac437c6f0e87f5 100644 (file)
@@ -589,14 +589,14 @@ static const struct backlight_ops dell_ops = {
        .update_status  = dell_send_intensity,
 };
 
-static void touchpad_led_on()
+static void touchpad_led_on(void)
 {
        int command = 0x97;
        char data = 1;
        i8042_command(&data, command | 1 << 12);
 }
 
-static void touchpad_led_off()
+static void touchpad_led_off(void)
 {
        int command = 0x97;
        char data = 2;
index c86665369a22d4b24a23707d5b7f24d955dc2a1a..48870e504231cb30e856c9f79190c3bf34c3c14d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/sfi.h>
+#include <linux/module.h>
 #include <asm/mrst.h>
 #include <asm/intel_scu_ipc.h>
 
index 6f40bf202dc7cf9e6baa80a329a3ea1810fcb5ed..2264331bd48e22b1178e64f87f861188a9104304 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/acpi.h>
 #include <linux/backlight.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
 MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver");
index 13ef8c37471d0a6575fed59d6cf92dece74c34ba..dcdc1f4a4624d782d35f3776d1a69bbfdf983cdb 100644 (file)
@@ -121,6 +121,7 @@ struct toshiba_acpi_dev {
        int illumination_supported:1;
        int video_supported:1;
        int fan_supported:1;
+       int system_event_supported:1;
 
        struct mutex mutex;
 };
@@ -724,7 +725,7 @@ static int keys_proc_show(struct seq_file *m, void *v)
        u32 hci_result;
        u32 value;
 
-       if (!dev->key_event_valid) {
+       if (!dev->key_event_valid && dev->system_event_supported) {
                hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result);
                if (hci_result == HCI_SUCCESS) {
                        dev->key_event_valid = 1;
@@ -964,6 +965,8 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
 
        /* enable event fifo */
        hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result);
+       if (hci_result == HCI_SUCCESS)
+               dev->system_event_supported = 1;
 
        props.type = BACKLIGHT_PLATFORM;
        props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
@@ -1032,12 +1035,15 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
 {
        struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
        u32 hci_result, value;
+       int retries = 3;
 
-       if (event != 0x80)
+       if (!dev->system_event_supported || event != 0x80)
                return;
+
        do {
                hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result);
-               if (hci_result == HCI_SUCCESS) {
+               switch (hci_result) {
+               case HCI_SUCCESS:
                        if (value == 0x100)
                                continue;
                        /* act on key press; ignore key release */
@@ -1049,14 +1055,19 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
                                pr_info("Unknown key %x\n",
                                       value);
                        }
-               } else if (hci_result == HCI_NOT_SUPPORTED) {
+                       break;
+               case HCI_NOT_SUPPORTED:
                        /* This is a workaround for an unresolved issue on
                         * some machines where system events sporadically
                         * become disabled. */
                        hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result);
                        pr_notice("Re-enabled hotkeys\n");
+                       /* fall through */
+               default:
+                       retries--;
+                       break;
                }
-       } while (hci_result != HCI_EMPTY);
+       } while (retries && hci_result != HCI_EMPTY);
 }
 
 
index 9b88be42b6cd3a43ba9b2c1d1563446c7df43f16..a134c26870b0d048929fc9eb6fe07e1e7172e35c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/list.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
index ca84d5099ce7c5fa654a39fa38427f8209b9a03d..b00c17612a89441752938de2c424d51eec6c941b 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/pnp.h>
 #include <linux/slab.h>
index bbf3edd85beb0c404b4e5b7791cfd1b79908dc3a..5be4a392a3aea39b0205baabad87f3535524c5e6 100644 (file)
@@ -509,15 +509,12 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
                                            struct acpi_resource_dma *p)
 {
        int i;
-       unsigned char map = 0, flags = 0;
-
-       if (p->channel_count == 0)
-               flags |= IORESOURCE_DISABLED;
+       unsigned char map = 0, flags;
 
        for (i = 0; i < p->channel_count; i++)
                map |= 1 << p->channels[i];
 
-       flags |= dma_flags(dev, p->type, p->bus_master, p->transfer);
+       flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
        pnp_register_dma_resource(dev, option_flags, map, flags);
 }
 
@@ -527,17 +524,14 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
 {
        int i;
        pnp_irq_mask_t map;
-       unsigned char flags = 0;
-
-       if (p->interrupt_count == 0)
-               flags |= IORESOURCE_DISABLED;
+       unsigned char flags;
 
        bitmap_zero(map.bits, PNP_IRQ_NR);
        for (i = 0; i < p->interrupt_count; i++)
                if (p->interrupts[i])
                        __set_bit(p->interrupts[i], map.bits);
 
-       flags |= irq_flags(p->triggering, p->polarity, p->sharable);
+       flags = irq_flags(p->triggering, p->polarity, p->sharable);
        pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
@@ -547,10 +541,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
 {
        int i;
        pnp_irq_mask_t map;
-       unsigned char flags = 0;
-
-       if (p->interrupt_count == 0)
-               flags |= IORESOURCE_DISABLED;
+       unsigned char flags;
 
        bitmap_zero(map.bits, PNP_IRQ_NR);
        for (i = 0; i < p->interrupt_count; i++) {
@@ -564,7 +555,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
                }
        }
 
-       flags |= irq_flags(p->triggering, p->polarity, p->sharable);
+       flags = irq_flags(p->triggering, p->polarity, p->sharable);
        pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
@@ -574,11 +565,8 @@ static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
 {
        unsigned char flags = 0;
 
-       if (io->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (io->io_decode == ACPI_DECODE_16)
-               flags |= IORESOURCE_IO_16BIT_ADDR;
+               flags = IORESOURCE_IO_16BIT_ADDR;
        pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
                                   io->alignment, io->address_length, flags);
 }
@@ -587,13 +575,8 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
                                        unsigned int option_flags,
                                        struct acpi_resource_fixed_io *io)
 {
-       unsigned char flags = 0;
-
-       if (io->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        pnp_register_port_resource(dev, option_flags, io->address, io->address,
-                                  0, io->address_length, flags | IORESOURCE_IO_FIXED);
+                                  0, io->address_length, IORESOURCE_IO_FIXED);
 }
 
 static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
@@ -602,11 +585,8 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
 {
        unsigned char flags = 0;
 
-       if (p->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
-               flags |= IORESOURCE_MEM_WRITEABLE;
+               flags = IORESOURCE_MEM_WRITEABLE;
        pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
                                  p->alignment, p->address_length, flags);
 }
@@ -617,11 +597,8 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
 {
        unsigned char flags = 0;
 
-       if (p->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
-               flags |= IORESOURCE_MEM_WRITEABLE;
+               flags = IORESOURCE_MEM_WRITEABLE;
        pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
                                  p->alignment, p->address_length, flags);
 }
@@ -632,11 +609,8 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
 {
        unsigned char flags = 0;
 
-       if (p->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
-               flags |= IORESOURCE_MEM_WRITEABLE;
+               flags = IORESOURCE_MEM_WRITEABLE;
        pnp_register_mem_resource(dev, option_flags, p->address, p->address,
                                  0, p->address_length, flags);
 }
@@ -656,19 +630,16 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
                return;
        }
 
-       if (p->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (p->resource_type == ACPI_MEMORY_RANGE) {
                if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
-                       flags |= IORESOURCE_MEM_WRITEABLE;
+                       flags = IORESOURCE_MEM_WRITEABLE;
                pnp_register_mem_resource(dev, option_flags, p->minimum,
                                          p->minimum, 0, p->address_length,
                                          flags);
        } else if (p->resource_type == ACPI_IO_RANGE)
                pnp_register_port_resource(dev, option_flags, p->minimum,
                                           p->minimum, 0, p->address_length,
-                                          flags | IORESOURCE_IO_FIXED);
+                                          IORESOURCE_IO_FIXED);
 }
 
 static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
@@ -678,19 +649,16 @@ static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
        struct acpi_resource_extended_address64 *p = &r->data.ext_address64;
        unsigned char flags = 0;
 
-       if (p->address_length == 0)
-               flags |= IORESOURCE_DISABLED;
-
        if (p->resource_type == ACPI_MEMORY_RANGE) {
                if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
-                       flags |= IORESOURCE_MEM_WRITEABLE;
+                       flags = IORESOURCE_MEM_WRITEABLE;
                pnp_register_mem_resource(dev, option_flags, p->minimum,
                                          p->minimum, 0, p->address_length,
                                          flags);
        } else if (p->resource_type == ACPI_IO_RANGE)
                pnp_register_port_resource(dev, option_flags, p->minimum,
                                           p->minimum, 0, p->address_length,
-                                          flags | IORESOURCE_IO_FIXED);
+                                          IORESOURCE_IO_FIXED);
 }
 
 struct acpipnp_parse_option_s {
index cffcb7c00b0068da7b32a467358b7e71a0388e13..01fa671ec97f6af9a31bf1a8c39ceef86691617b 100644 (file)
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(debug, "Flag to enable PMIC Battery debug messages.");
 #define PMIC_BATT_CHR_SBATDET_MASK     (1 << 5)
 #define PMIC_BATT_CHR_SDCLMT_MASK      (1 << 6)
 #define PMIC_BATT_CHR_SUSBOVP_MASK     (1 << 7)
-#define PMIC_BATT_CHR_EXCPT_MASK       0xC6
+#define PMIC_BATT_CHR_EXCPT_MASK       0x86
+
 #define PMIC_BATT_ADC_ACCCHRG_MASK     (1 << 31)
 #define PMIC_BATT_ADC_ACCCHRGVAL_MASK  0x7FFFFFFF
 
@@ -304,11 +305,6 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi)
                        pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
                        pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT);
                        batt_exception = 1;
-               } else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
-                       pbi->batt_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
-                       pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
-                       pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT);
-                       batt_exception = 1;
                } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) {
                        pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT;
                        pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
@@ -316,6 +312,10 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi)
                        batt_exception = 1;
                } else {
                        pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD;
+                       if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) {
+                               /* PMIC will change charging current automatically */
+                               pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT);
+                       }
                }
        }
 
index 98bfab35b8e99ab4c020e9dad91b8f6475b79ac2..9f0183c73076852b213b10ea2832bc7e9d74cd3e 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/mod_devicetable.h>
index a9b0209a2f55042a572fc18b2d34b2cee979ad78..2595145f3bffad80d9cdfba4d50b83df3f41ffa6 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/power_supply.h>
 #include <linux/platform_device.h>
index ffc5033ea9c92fcbad8957cad81674a376cb1909..a23317d75c5a80e65bec82fdf89bdb1f6499f0a1 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index ef8efadb58cb1778306e3b977dffc2b585b5c42e..93e3bb47a3a817ac7d1fbf0aa712bb77b0c181fd 100644 (file)
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/slab.h>
index 605514afc29f20029032ef2ab94cc1b006e8ffa3..e15d4c9d398842bf4609942da61e02448516da68 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/ctype.h>
 #include <linux/power_supply.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 
 #include "power_supply.h"
 
index d9fb729535a1691b976d475c5b089bab6fa60cfe..fb7300837feef25a6b2a80de582baf01031bf22a 100644 (file)
@@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void)
        }
 
        result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
-               IRQF_DISABLED, "vuart", &vuart_bus_priv);
+               0, "vuart", &vuart_bus_priv);
 
        if (result) {
                pr_debug("%s:%d: request_irq failed (%d)\n",
index af0afa1db4a8b3261dfba62b2d13cb680f3b3c9a..8c3f5adf1bc65378565406b8cb6567f5fd38e894 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
@@ -166,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
                goto fail_close_device;
        }
 
-       error = request_irq(dev->irq, handler, IRQF_DISABLED,
+       error = request_irq(dev->irq, handler, 0,
                            dev->sbd.core.driver->name, dev);
        if (error) {
                dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n",
index 474225852b63689500c87c6631677a502ed471e2..0e41737ea835a66d862f3b3f490be9f52dca68a1 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <asm/lv1call.h>
 #include <asm/ps3.h>
 
index cf3f9997546dc41d10a143390e834d0926720964..10451a15e8284f33be26996363c5ffd6c79ad56a 100644 (file)
@@ -101,7 +101,9 @@ static s32 scaled_ppm_to_ppb(long ppm)
 
 static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp)
 {
-       return 1; /* always round timer functions to one nanosecond */
+       tp->tv_sec = 0;
+       tp->tv_nsec = 1;
+       return 0;
 }
 
 static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp)
index 5225930a10cd24fd5003d553bfd65ada9e10eebc..691b1ab1a3d0499d85815bd03551e9d22518e494 100644 (file)
@@ -851,14 +851,12 @@ static int tsi721_doorbell_init(struct tsi721_device *priv)
        INIT_WORK(&priv->idb_work, tsi721_db_dpc);
 
        /* Allocate buffer for inbound doorbells queue */
-       priv->idb_base = dma_alloc_coherent(&priv->pdev->dev,
+       priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev,
                                IDB_QSIZE * TSI721_IDB_ENTRY_SIZE,
                                &priv->idb_dma, GFP_KERNEL);
        if (!priv->idb_base)
                return -ENOMEM;
 
-       memset(priv->idb_base, 0, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE);
-
        dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n",
                priv->idb_base, (unsigned long long)priv->idb_dma);
 
@@ -904,7 +902,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum)
         */
 
        /* Allocate space for DMA descriptors */
-       bd_ptr = dma_alloc_coherent(&priv->pdev->dev,
+       bd_ptr = dma_zalloc_coherent(&priv->pdev->dev,
                                        bd_num * sizeof(struct tsi721_dma_desc),
                                        &bd_phys, GFP_KERNEL);
        if (!bd_ptr)
@@ -913,8 +911,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum)
        priv->bdma[chnum].bd_phys = bd_phys;
        priv->bdma[chnum].bd_base = bd_ptr;
 
-       memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc));
-
        dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n",
                bd_ptr, (unsigned long long)bd_phys);
 
@@ -922,7 +918,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum)
        sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ?
                                        bd_num : TSI721_DMA_MINSTSSZ;
        sts_size = roundup_pow_of_two(sts_size);
-       sts_ptr = dma_alloc_coherent(&priv->pdev->dev,
+       sts_ptr = dma_zalloc_coherent(&priv->pdev->dev,
                                     sts_size * sizeof(struct tsi721_dma_sts),
                                     &sts_phys, GFP_KERNEL);
        if (!sts_ptr) {
@@ -938,8 +934,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum)
        priv->bdma[chnum].sts_base = sts_ptr;
        priv->bdma[chnum].sts_size = sts_size;
 
-       memset(sts_ptr, 0, sts_size);
-
        dev_dbg(&priv->pdev->dev,
                "desc status FIFO @ %p (phys = %llx) size=0x%x\n",
                sts_ptr, (unsigned long long)sts_phys, sts_size);
@@ -1400,7 +1394,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
 
        /* Outbound message descriptor status FIFO allocation */
        priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1);
-       priv->omsg_ring[mbox].sts_base = dma_alloc_coherent(&priv->pdev->dev,
+       priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev,
                        priv->omsg_ring[mbox].sts_size *
                                                sizeof(struct tsi721_dma_sts),
                        &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL);
@@ -1412,9 +1406,6 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
                goto out_desc;
        }
 
-       memset(priv->omsg_ring[mbox].sts_base, 0,
-               entries * sizeof(struct tsi721_dma_sts));
-
        /*
         * Configure Outbound Messaging Engine
         */
@@ -2116,8 +2107,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv)
        INIT_LIST_HEAD(&mport->dbells);
 
        rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
-       rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
-       rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+       rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
+       rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
        strcpy(mport->name, "Tsi721 mport");
 
        /* Hook up interrupt handler */
@@ -2163,7 +2154,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *id)
 {
        struct tsi721_device *priv;
-       int i;
+       int i, cap;
        int err;
        u32 regval;
 
@@ -2271,10 +2262,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
                        dev_info(&pdev->dev, "Unable to set consistent DMA mask\n");
        }
 
-       /* Clear "no snoop" and "relaxed ordering" bits. */
-       pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, &regval);
-       regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN);
-       pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval);
+       cap = pci_pcie_cap(pdev);
+       BUG_ON(cap == 0);
+
+       /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
+       pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &regval);
+       regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
+                   PCI_EXP_DEVCTL_NOSNOOP_EN);
+       regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT;
+       pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval);
+
+       /* Adjust PCIe completion timeout. */
+       pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, &regval);
+       regval &= ~(0x0f);
+       pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2);
 
        /*
         * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
index 58be4deb1402ad9f2a119c196e208a8b0d2f2593..822e54c394d5cd0690ee80d2c5173eb05140018f 100644 (file)
@@ -72,6 +72,8 @@
 #define TSI721_MSIXPBA_OFFSET  0x2a000
 #define TSI721_PCIECFG_EPCTL   0x400
 
+#define MAX_READ_REQUEST_SZ_SHIFT      12
+
 /*
  * Event Management Registers
  */
index 043ee3136e408412c6d9a92db354bafce1ac78fe..809b7a3336baa40e654f296feeaa8ebb5067411e 100644 (file)
@@ -10,6 +10,7 @@
  * option) any later version.
  */
 
+#include <linux/stat.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
 #include <linux/rio_ids.h>
index e821b2159b4b72a93ef0225d0db2a35b86bc4efa..ca0d608f8248c4b29dc599f2c7048f9f45d8c21a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/module.h>
 
 struct pm8607_regulator_info {
        struct regulator_desc   desc;
index 5abeb3ac3e8da43df3d58bf677c3ac0e3d17116e..298c6c6a279574561eb24f329b115fe134d274a1 100644 (file)
@@ -160,7 +160,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
                        break;
        }
 
-       if (!ri)
+       if (i == ARRAY_SIZE(aat2870_regulators))
                return NULL;
 
        ri->enable_addr = AAT2870_LDO_EN;
index 02f3c2333c8374d81f3bec3a1e2fb714f4c71095..6e1ae69646b396778660a8d3cf665f40e0d8e07e 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ab8500.h>
index 068d488a4f714a310528a5e1dcc1b9016cc59caa..e24d1b7d97a84c4f5ded6aaf672ba3f317be838c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/regulator/bq24022.h>
 #include <linux/regulator/driver.h>
index 67fa2a3297adc14afa059709d899defbb7aed9ba..938398f3e869c57814fc130b9133ac435118214e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/module.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/regulator.h>
@@ -2798,8 +2799,8 @@ void regulator_unregister(struct regulator_dev *rdev)
        list_del(&rdev->list);
        if (rdev->supply)
                regulator_put(rdev->supply);
-       device_unregister(&rdev->dev);
        kfree(rdev->constraints);
+       device_unregister(&rdev->dev);
        mutex_unlock(&regulator_list_mutex);
 }
 EXPORT_SYMBOL_GPL(regulator_unregister);
index 362e08221085825ddb2e01d8a9a9283729a86c78..e23ddfa8b2c6d2f2241e6813e2d6ff660dfeff02 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index 2d014a144365a6bdc0d3ebe60e76a7867cfb83fb..78329751af542dc36d80fc58d0c085ab24b99401 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/db8500-prcmu.h>
+#include <linux/module.h>
 
 /*
  * power state reference count
index f6ef6694ab9896687074c9224e4e60fea919acbc..b8f520513ce74b47beac3ed234fda7ad17cbb50c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index 2fe9d99c9f23107366ab8d485831bd65bce0663f..21ecf212a5227643abcad804c855f699be32f338 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/fixed.h>
index 0f22ef12601c2204170edb3d00eb38c0319e0976..72b16b5f3db6fca2f7a2ded2ce55344256ba327f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/lp3971.h>
 #include <linux/slab.h>
index 6aa1b506fb5dd0f2c508bfa7bc9ce0413ea0261f..fbc5e3741befffc8dbd097e0653881ff3c149459 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/bug.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/lp3972.h>
index e4dbd667c043577b2cfe250df38fbbdcf3869eb1..cc9ec0e0327183bb58aa81a69343905e2765db02 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
index ad6628ca94f41378bdddbe11f1286d54a64f4fd0..6176129a27e531e20c8921537798648c723f78ec 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
index cb2841feeefd373416f978f89cc587f380a0552c..8479082e1aeaaafa1d0ca5780101855c00863df7 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include "mc13xxx.h"
 
 #define MC13783_REG_SWITCHERS5                 29
index 3285d41842f281d4433cbab2e5752d5b50c1632c..023d17d022cf7ba329068b61a7d3b69695c44a82 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include "mc13xxx.h"
 
 #define MC13892_REVISION                       7
index bc27ab1363784db2788dc6e158a6c68f63b9362c..6532853a6ef5e2e92beb3174c13f1b430e071dc5 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include "mc13xxx.h"
 
 static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
index dbcf09d5080c654bef77c7b725f12bc88729d45a..14b9389dd52abf719552d7e084b5776d791d45c6 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index 66d2d60b436a3e7a28092d64a499fd203db764a5..b552aae55b417c7cd9aa97fba33bd61ad0b7e787 100644 (file)
@@ -664,10 +664,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
 
        switch (id) {
        case TPS65910_REG_VDD1:
-               dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                if (dcdc_mult == 1)
                        dcdc_mult--;
-               vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+               vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
 
                tps65910_modify_bits(pmic, TPS65910_VDD1,
                                (dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
@@ -675,10 +675,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
                tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
                break;
        case TPS65910_REG_VDD2:
-               dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                if (dcdc_mult == 1)
                        dcdc_mult--;
-               vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+               vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3;
 
                tps65910_modify_bits(pmic, TPS65910_VDD2,
                                (dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
@@ -756,9 +756,9 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
        switch (id) {
        case TPS65910_REG_VDD1:
        case TPS65910_REG_VDD2:
-               mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+               mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
                volt = VDD1_2_MIN_VOLT +
-                               (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
+                               (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
                break;
        case TPS65911_REG_VDDCTRL:
                volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
@@ -947,6 +947,8 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 
                if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
                        pmic->desc[i].ops = &tps65910_ops_dcdc;
+                       pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE *
+                                                       VDD1_2_NUM_VOLT_COARSE;
                } else if (i == TPS65910_REG_VDD3) {
                        if (tps65910_chip_id(tps65910) == TPS65910)
                                pmic->desc[i].ops = &tps65910_ops_vdd3;
index ee8747f4fa08b187ef2f79dbb51e3f69a770bc21..11cc308d66e925db83fa8c50697e734608aac1b8 100644 (file)
@@ -71,6 +71,7 @@ struct twlreg_info {
 #define VREG_TYPE              1
 #define VREG_REMAP             2
 #define VREG_DEDICATED         3       /* LDO control */
+#define VREG_VOLTAGE_SMPS_4030 9
 /* TWL6030 register offsets */
 #define VREG_TRANS             1
 #define VREG_STATE             2
@@ -514,6 +515,32 @@ static struct regulator_ops twl4030ldo_ops = {
        .get_status     = twl4030reg_get_status,
 };
 
+static int
+twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+                       unsigned *selector)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
+
+       twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
+               vsel);
+       return 0;
+}
+
+static int twl4030smps_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info *info = rdev_get_drvdata(rdev);
+       int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
+               VREG_VOLTAGE_SMPS_4030);
+
+       return vsel * 12500 + 600000;
+}
+
+static struct regulator_ops twl4030smps_ops = {
+       .set_voltage    = twl4030smps_set_voltage,
+       .get_voltage    = twl4030smps_get_voltage,
+};
+
 static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
@@ -856,6 +883,21 @@ static struct regulator_ops twlsmps_ops = {
                }, \
        }
 
+#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
+       { \
+       .base = offset, \
+       .id = num, \
+       .delay = turnon_delay, \
+       .remap = remap_conf, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL4030_REG_##label, \
+               .ops = &twl4030smps_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
 #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
        .base = offset, \
        .min_mV = min_mVolts, \
@@ -947,8 +989,8 @@ static struct twlreg_info twl_regs[] = {
        TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08),
        TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08),
        TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08),
-       TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08),
+       TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08),
        TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08),
        TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08),
index 9d5ba93575975f22e8d00a620613cc1848ffb8fe..fc66551469996a6fa05775fa1d1d1decbae38f8a 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/userspace-consumer.h>
index 69e550f57638cbde4ebde30990318cb21816ad0a..858c1f861ba596d134c253d74ba7d06d330ea0ff 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct virtual_consumer_data {
        struct mutex lock;
index 0f12c70bebc9cd49ec51dc5f6e64997e0366aaff..71632ddc37813a2cd3ba4b9a107781456335ae81 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/bug.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/regulator/driver.h>
 #include <linux/mfd/wm8400-private.h>
 
index e8326f26fa2f5c5ca11d26901f5e70052a1ffea6..dc4c2748bbc38bfac593cc47a2ff7bac6a34c8fe 100644 (file)
@@ -63,7 +63,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg)
         */
        delta = timespec_sub(old_system, old_rtc);
        delta_delta = timespec_sub(delta, old_delta);
-       if (abs(delta_delta.tv_sec)  >= 2) {
+       if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
                /*
                 * if delta_delta is too large, assume time correction
                 * has occured and set old_delta to the current delta.
@@ -97,9 +97,8 @@ static int rtc_resume(struct device *dev)
        rtc_tm_to_time(&tm, &new_rtc.tv_sec);
        new_rtc.tv_nsec = 0;
 
-       if (new_rtc.tv_sec <= old_rtc.tv_sec) {
-               if (new_rtc.tv_sec < old_rtc.tv_sec)
-                       pr_debug("%s:  time travel!\n", dev_name(&rtc->dev));
+       if (new_rtc.tv_sec < old_rtc.tv_sec) {
+               pr_debug("%s:  time travel!\n", dev_name(&rtc->dev));
                return 0;
        }
 
@@ -116,7 +115,8 @@ static int rtc_resume(struct device *dev)
        sleep_time = timespec_sub(sleep_time,
                        timespec_sub(new_system, old_system));
 
-       timekeeping_inject_sleeptime(&sleep_time);
+       if (sleep_time.tv_sec >= 0)
+               timekeeping_inject_sleeptime(&sleep_time);
        return 0;
 }
 
index 44e91e598f8d975ae7570b80366a67540611c8da..fa4d9f324189a8cb876692764b5eed7601cb1950 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/rtc.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/log2.h>
 #include <linux/workqueue.h>
 
@@ -318,6 +319,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 }
 EXPORT_SYMBOL_GPL(rtc_read_alarm);
 
+static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
+{
+       int err;
+
+       if (!rtc->ops)
+               err = -ENODEV;
+       else if (!rtc->ops->set_alarm)
+               err = -EINVAL;
+       else
+               err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
+
+       return err;
+}
+
 static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 {
        struct rtc_time tm;
@@ -341,14 +356,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
         * over right here, before we set the alarm.
         */
 
-       if (!rtc->ops)
-               err = -ENODEV;
-       else if (!rtc->ops->set_alarm)
-               err = -EINVAL;
-       else
-               err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
-
-       return err;
+       return ___rtc_set_alarm(rtc, alarm);
 }
 
 int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -762,6 +770,20 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
        return 0;
 }
 
+static void rtc_alarm_disable(struct rtc_device *rtc)
+{
+       struct rtc_wkalrm alarm;
+       struct rtc_time tm;
+
+       __rtc_read_time(rtc, &tm);
+
+       alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm),
+                                    ktime_set(300, 0)));
+       alarm.enabled = 0;
+
+       ___rtc_set_alarm(rtc, &alarm);
+}
+
 /**
  * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
  * @rtc rtc device
@@ -783,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
                struct rtc_wkalrm alarm;
                int err;
                next = timerqueue_getnext(&rtc->timerqueue);
-               if (!next)
+               if (!next) {
+                       rtc_alarm_disable(rtc);
                        return;
+               }
                alarm.time = rtc_ktime_to_tm(next->expires);
                alarm.enabled = 1;
                err = __rtc_set_alarm(rtc, &alarm);
@@ -846,7 +870,8 @@ again:
                err = __rtc_set_alarm(rtc, &alarm);
                if (err == -ETIME)
                        goto again;
-       }
+       } else
+               rtc_alarm_disable(rtc);
 
        mutex_unlock(&rtc->ops_lock);
 }
index 58d4e18530da1ca4020c1046709b7d8cdadc639c..2322c43af201bd23d0725e184c9bb5cced228996 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 
 #include <linux/i2c/dm355evm_msp.h>
+#include <linux/module.h>
 
 
 /*
index 57fbcc149ba7323cde2166b00d9b43f6d2fe296d..3a33b1fdbe0f84e54539a5c5383c26c6bcc9c04a 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ds1305.h>
+#include <linux/module.h>
 
 
 /*
index 568ad30617e7dad58f38f7a6583b8c73630a4aa7..586c244a05d854ab593b8310bd9e8a66991def14 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.6"
 
index fee41b97c9e89e3835734454a720fb772ed17202..1350029044e6247247c3220efa362dd3bb832e63 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.3"
 
index 06dfb54f99b6a6579424ec36627020311dca80cb..a319402a54479bd633a0bfdbb4710996316b1839 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/i2c.h>
 #include <linux/rtc.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.4"
 
index d84a448dd754b32203ace25e336df50e5710f43f..e3e0f92b60f0d97012f723e3a11a56b9054568d3 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.4"
 
index d8e1c2578553cd949f2afc4c2d6de4af642c6c91..8414dea5fb1410da0e39d5b446223e8c60927c85 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/i2c.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/module.h>
 
 /* Registers */
 #define EM3027_REG_ON_OFF_CTRL 0x00
index ddbc797ea6cd68f370301e165294760c24b60c07..6186833973eef194598f3786ff3d2151edb8e4ff 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.1"
 
index d33544802a2ea5fc023390a069bcbc1f9d147a41..bb21f443fb7038719458d03c97e4b4eb00a225a1 100644 (file)
@@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void)
 /*
  * rtc_time's year contains the increment over 1900, but vRTC's YEAR
  * register can't be programmed to value larger than 0x64, so vRTC
- * driver chose to use 1960 (1970 is UNIX time start point) as the base,
+ * driver chose to use 1972 (1970 is UNIX time start point) as the base,
  * and does the translation at read/write time.
  *
- * Why not just use 1970 as the offset? it's because using 1960 will
+ * Why not just use 1970 as the offset? it's because using 1972 will
  * make it consistent in leap year setting for both vrtc and low-level
- * physical rtc devices.
+ * physical rtc devices. Then why not use 1960 as the offset? If we use
+ * 1960, for a device's first use, its YEAR register is 0 and the system
+ * year will be parsed as 1960 which is not a valid UNIX time and will
+ * cause many applications to fail mysteriously.
  */
 static int mrst_read_time(struct device *dev, struct rtc_time *time)
 {
@@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
        time->tm_year = vrtc_cmos_read(RTC_YEAR);
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       /* Adjust for the 1960/1900 */
-       time->tm_year += 60;
+       /* Adjust for the 1972/1900 */
+       time->tm_year += 72;
        time->tm_mon--;
-       return RTC_24H;
+       return rtc_valid_tm(time);
 }
 
 static int mrst_set_time(struct device *dev, struct rtc_time *time)
@@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time)
        min = time->tm_min;
        sec = time->tm_sec;
 
-       if (yrs < 70 || yrs > 138)
+       if (yrs < 72 || yrs > 138)
                return -EINVAL;
-       yrs -= 60;
+       yrs -= 72;
 
        spin_lock_irqsave(&rtc_lock, flags);
 
index 60627a7645143721459cd78eb97f5addc885856e..768e2edb96780d2c232c3308cc015e57c16d0d8e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
+#include <linux/module.h>
 
 
 #define RTC_TIME_REG_OFFS      0
index 71bab0ef54436bd19be3882f95df4f62dbbd96a4..2ee3bbf7e5ea03df488233c61b659c4909219335 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.6"
 
index b42c0c6792667cb163d397e6f10ab8eced5f4999..606fdfab34e2735f148910fd6578b47d896959a4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.4.3"
 
index b3eba3cddd42658f76cb7ec84a3c13187993d1b4..e4b6880aabd05492b2a08c0511f400340b9fc0fa 100644 (file)
@@ -220,7 +220,7 @@ static void puv3_rtc_enable(struct platform_device *pdev, int en)
        }
 }
 
-static int puv3_rtc_remove(struct platform_device *dev)
+static int __devexit puv3_rtc_remove(struct platform_device *dev)
 {
        struct rtc_device *rtc = platform_get_drvdata(dev);
 
@@ -236,7 +236,7 @@ static int puv3_rtc_remove(struct platform_device *dev)
        return 0;
 }
 
-static int puv3_rtc_probe(struct platform_device *pdev)
+static int __devinit puv3_rtc_probe(struct platform_device *pdev)
 {
        struct rtc_device *rtc;
        struct resource *res;
index 368d0e63cf836a3f054a56adcc7f86f12fcc278a..971bc8e08da66008fecd1d16f29508bafc40d482 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rtc.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.2"
 
index 85c1b848dd72383b6253fbef04d2fa870719d076..d29f5432c6e87d017411e50b3c1c2219cf9e1f08 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.6"
 
index 7639ab906f02e35ceec0a75bfaddd418e17478e8..5b979d9cc3324ffccd455da21e09a35b88f753ad 100644 (file)
@@ -202,7 +202,6 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
        void __iomem *base = s3c_rtc_base;
        int year = tm->tm_year - 100;
 
-       clk_enable(rtc_clk);
        pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n",
                 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
                 tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -214,6 +213,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
                return -EINVAL;
        }
 
+       clk_enable(rtc_clk);
        writeb(bin2bcd(tm->tm_sec),  base + S3C2410_RTCSEC);
        writeb(bin2bcd(tm->tm_min),  base + S3C2410_RTCMIN);
        writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);
index 3b943673cd3e293c5c889078fd32a2f1bb01ecaa..ed3e9b5990315cc2389208768ab38b2332735fe1 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "0.1"
 
index ec6313d153599d5f745550760b5ad1990d7e7b3c..aac0ffed4345d5cabb1f26d2e7e3bd4927aecc4e 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <asm/txx9/tx4939.h>
index b00aad2620d4f81aa80d79192175dcde950d7fb2..8c051d3179db01c4e6a03ec6e80cb6f5107b1fe5 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #define DRV_VERSION "1.0.8"
 
index f6489eb7e976a8c0aa1851ebbb21901d689030c1..e71298158f9eaa83a0531269a7da5c83c0c1d14a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/types.h>
index 4a51e3f096894d0151326bfac6ecef7b5c1c73d8..bd1b9c9190514188b9c1469e8f2d2fb23a82c606 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
+#include <linux/export.h>
 #include <asm/ebcdic.h>
 #include <asm/sclp.h>
 
index 31a3ccbb6495c2e8efcdd34bbd8b3cacfbbf9154..75bde6a8b7dc9277332b40be961bbc4888d1d497 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/compat.h>
 #include <asm/cpcmd.h>
 #include <asm/debug.h>
index d291a54acfad5f94ec127cfdbff6e37d5b8cf85d..85f4a9a5d12e5d00a7e445bd1e1e0a784eaf7cd0 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/cdev.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/cio.h>
index 43068fbd0baacfe8beb7d353cda35a8c06c371e2..1b6d9247fdc78a4237d5e7048347a0a66875d140 100644 (file)
@@ -641,6 +641,8 @@ static int __init zcore_init(void)
 
        if (ipl_info.type != IPL_TYPE_FCP_DUMP)
                return -ENODATA;
+       if (OLDMEM_BASE)
+               return -ENODATA;
 
        zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
        debug_register_view(zcore_dbf, &debug_sprintf_view);
index 2d32233943a917c7f6ae9949122a78e3f962a60c..e792436c92701fc684fc830c0656666c5a73c95c 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/bug.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
+#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/wait.h>
index 75c3f1f8fd434301c3ba4a07a632e0ffefa6aac3..a84631a7391d3ed50c680b939129d159fc25daa3 100644 (file)
@@ -529,10 +529,7 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
 int chsc_chp_vary(struct chp_id chpid, int on)
 {
        struct channel_path *chp = chpid_to_chp(chpid);
-       struct chp_link link;
 
-       memset(&link, 0, sizeof(struct chp_link));
-       link.chpid = chpid;
        /* Wait until previous actions have settled. */
        css_wait_for_slow_path();
        /*
@@ -542,10 +539,10 @@ int chsc_chp_vary(struct chp_id chpid, int on)
                /* Try to update the channel path descritor. */
                chsc_determine_base_channel_path_desc(chpid, &chp->desc);
                for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
-                                          __s390_vary_chpid_on, &link);
+                                          __s390_vary_chpid_on, &chpid);
        } else
                for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
-                                          NULL, &link);
+                                          NULL, &chpid);
 
        return 0;
 }
index 155a82bcb9e545e2888430337d0b1c2b50239acd..4a1ff5c2eb881355204ffe8e047cfbe3bb8e3706 100644 (file)
@@ -68,8 +68,13 @@ struct schib {
        __u8 mda[4];             /* model dependent area */
 } __attribute__ ((packed,aligned(4)));
 
+/*
+ * When rescheduled, todo's with higher values will overwrite those
+ * with lower values.
+ */
 enum sch_todo {
        SCH_TODO_NOTHING,
+       SCH_TODO_EVAL,
        SCH_TODO_UNREG,
 };
 
index 92d7324acb1c78fbab348a2ea190c8901351df9d..21908e67bf6745d8dc91f791347a9d9cee538aa1 100644 (file)
@@ -195,51 +195,6 @@ void css_sch_device_unregister(struct subchannel *sch)
 }
 EXPORT_SYMBOL_GPL(css_sch_device_unregister);
 
-static void css_sch_todo(struct work_struct *work)
-{
-       struct subchannel *sch;
-       enum sch_todo todo;
-
-       sch = container_of(work, struct subchannel, todo_work);
-       /* Find out todo. */
-       spin_lock_irq(sch->lock);
-       todo = sch->todo;
-       CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
-                     sch->schid.sch_no, todo);
-       sch->todo = SCH_TODO_NOTHING;
-       spin_unlock_irq(sch->lock);
-       /* Perform todo. */
-       if (todo == SCH_TODO_UNREG)
-               css_sch_device_unregister(sch);
-       /* Release workqueue ref. */
-       put_device(&sch->dev);
-}
-
-/**
- * css_sched_sch_todo - schedule a subchannel operation
- * @sch: subchannel
- * @todo: todo
- *
- * Schedule the operation identified by @todo to be performed on the slow path
- * workqueue. Do nothing if another operation with higher priority is already
- * scheduled. Needs to be called with subchannel lock held.
- */
-void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
-{
-       CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
-                     sch->schid.ssid, sch->schid.sch_no, todo);
-       if (sch->todo >= todo)
-               return;
-       /* Get workqueue ref. */
-       if (!get_device(&sch->dev))
-               return;
-       sch->todo = todo;
-       if (!queue_work(cio_work_q, &sch->todo_work)) {
-               /* Already queued, release workqueue ref. */
-               put_device(&sch->dev);
-       }
-}
-
 static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
 {
        int i;
@@ -466,6 +421,65 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
                css_schedule_eval(schid);
 }
 
+/**
+ * css_sched_sch_todo - schedule a subchannel operation
+ * @sch: subchannel
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with subchannel lock held.
+ */
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
+{
+       CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
+                     sch->schid.ssid, sch->schid.sch_no, todo);
+       if (sch->todo >= todo)
+               return;
+       /* Get workqueue ref. */
+       if (!get_device(&sch->dev))
+               return;
+       sch->todo = todo;
+       if (!queue_work(cio_work_q, &sch->todo_work)) {
+               /* Already queued, release workqueue ref. */
+               put_device(&sch->dev);
+       }
+}
+
+static void css_sch_todo(struct work_struct *work)
+{
+       struct subchannel *sch;
+       enum sch_todo todo;
+       int ret;
+
+       sch = container_of(work, struct subchannel, todo_work);
+       /* Find out todo. */
+       spin_lock_irq(sch->lock);
+       todo = sch->todo;
+       CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
+                     sch->schid.sch_no, todo);
+       sch->todo = SCH_TODO_NOTHING;
+       spin_unlock_irq(sch->lock);
+       /* Perform todo. */
+       switch (todo) {
+       case SCH_TODO_NOTHING:
+               break;
+       case SCH_TODO_EVAL:
+               ret = css_evaluate_known_subchannel(sch, 1);
+               if (ret == -EAGAIN) {
+                       spin_lock_irq(sch->lock);
+                       css_sched_sch_todo(sch, todo);
+                       spin_unlock_irq(sch->lock);
+               }
+               break;
+       case SCH_TODO_UNREG:
+               css_sch_device_unregister(sch);
+               break;
+       }
+       /* Release workqueue ref. */
+       put_device(&sch->dev);
+}
+
 static struct idset *slow_subchannel_set;
 static spinlock_t slow_subchannel_lock;
 static wait_queue_head_t css_eval_wq;
index d734f4a0ecac23cea1d821b316a563b71087ccc6..47269858ecb662af862c38a5e96fc4f9aacfe2ca 100644 (file)
@@ -1868,9 +1868,9 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev)
         */
        cdev->private->flags.resuming = 1;
        cdev->private->path_new_mask = LPM_ANYPATH;
-       css_schedule_eval(sch->schid);
+       css_sched_sch_todo(sch, SCH_TODO_EVAL);
        spin_unlock_irq(sch->lock);
-       css_complete_work();
+       css_wait_for_slow_path();
 
        /* cdev may have been moved to a different subchannel. */
        sch = to_subchannel(cdev->dev.parent);
index 52c233fa2b1281d14a2881618465606447bef365..1b853513c891ca2f010f8703b110f49c6f65afb3 100644 (file)
@@ -496,8 +496,26 @@ static void ccw_device_reset_path_events(struct ccw_device *cdev)
        cdev->private->pgid_reset_mask = 0;
 }
 
-void
-ccw_device_verify_done(struct ccw_device *cdev, int err)
+static void create_fake_irb(struct irb *irb, int type)
+{
+       memset(irb, 0, sizeof(*irb));
+       if (type == FAKE_CMD_IRB) {
+               struct cmd_scsw *scsw = &irb->scsw.cmd;
+               scsw->cc = 1;
+               scsw->fctl = SCSW_FCTL_START_FUNC;
+               scsw->actl = SCSW_ACTL_START_PEND;
+               scsw->stctl = SCSW_STCTL_STATUS_PEND;
+       } else if (type == FAKE_TM_IRB) {
+               struct tm_scsw *scsw = &irb->scsw.tm;
+               scsw->x = 1;
+               scsw->cc = 1;
+               scsw->fctl = SCSW_FCTL_START_FUNC;
+               scsw->actl = SCSW_ACTL_START_PEND;
+               scsw->stctl = SCSW_STCTL_STATUS_PEND;
+       }
+}
+
+void ccw_device_verify_done(struct ccw_device *cdev, int err)
 {
        struct subchannel *sch;
 
@@ -520,12 +538,8 @@ callback:
                ccw_device_done(cdev, DEV_STATE_ONLINE);
                /* Deliver fake irb to device driver, if needed. */
                if (cdev->private->flags.fake_irb) {
-                       memset(&cdev->private->irb, 0, sizeof(struct irb));
-                       cdev->private->irb.scsw.cmd.cc = 1;
-                       cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
-                       cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
-                       cdev->private->irb.scsw.cmd.stctl =
-                               SCSW_STCTL_STATUS_PEND;
+                       create_fake_irb(&cdev->private->irb,
+                                       cdev->private->flags.fake_irb);
                        cdev->private->flags.fake_irb = 0;
                        if (cdev->handler)
                                cdev->handler(cdev, cdev->private->intparm,
index f98698d5735e887e0fb6cc46f00a63012ecdccb5..ec7fb6d3b479a25a32bfad67ecc36a3539782b39 100644 (file)
@@ -198,7 +198,7 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        if (cdev->private->state == DEV_STATE_VERIFY) {
                /* Remember to fake irb when finished. */
                if (!cdev->private->flags.fake_irb) {
-                       cdev->private->flags.fake_irb = 1;
+                       cdev->private->flags.fake_irb = FAKE_CMD_IRB;
                        cdev->private->intparm = intparm;
                        return 0;
                } else
@@ -213,9 +213,9 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        ret = cio_set_options (sch, flags);
        if (ret)
                return ret;
-       /* Adjust requested path mask to excluded varied off paths. */
+       /* Adjust requested path mask to exclude unusable paths. */
        if (lpm) {
-               lpm &= sch->opm;
+               lpm &= sch->lpm;
                if (lpm == 0)
                        return -EACCES;
        }
@@ -605,11 +605,21 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
        sch = to_subchannel(cdev->dev.parent);
        if (!sch->schib.pmcw.ena)
                return -EINVAL;
+       if (cdev->private->state == DEV_STATE_VERIFY) {
+               /* Remember to fake irb when finished. */
+               if (!cdev->private->flags.fake_irb) {
+                       cdev->private->flags.fake_irb = FAKE_TM_IRB;
+                       cdev->private->intparm = intparm;
+                       return 0;
+               } else
+                       /* There's already a fake I/O around. */
+                       return -EBUSY;
+       }
        if (cdev->private->state != DEV_STATE_ONLINE)
                return -EIO;
-       /* Adjust requested path mask to excluded varied off paths. */
+       /* Adjust requested path mask to exclude unusable paths. */
        if (lpm) {
-               lpm &= sch->opm;
+               lpm &= sch->lpm;
                if (lpm == 0)
                        return -EACCES;
        }
index 2ebb492a5c17dcb8a9e05fb23209162edb43d849..76253dfcc1be86a18eba7ac7ea4d6f53c134bc7e 100644 (file)
@@ -111,6 +111,9 @@ enum cdev_todo {
        CDEV_TODO_UNREG_EVAL,
 };
 
+#define FAKE_CMD_IRB   1
+#define FAKE_TM_IRB    2
+
 struct ccw_device_private {
        struct ccw_device *cdev;
        struct subchannel *sch;
@@ -138,7 +141,7 @@ struct ccw_device_private {
                unsigned int doverify:1;    /* delayed path verification */
                unsigned int donotify:1;    /* call notify function */
                unsigned int recog_done:1;  /* dev. recog. complete */
-               unsigned int fake_irb:1;    /* deliver faked irb */
+               unsigned int fake_irb:2;    /* deliver faked irb */
                unsigned int resuming:1;    /* recognition while resume */
                unsigned int pgroup:1;      /* pathgroup is set up */
                unsigned int mpath:1;       /* multipathing is set up */
index ed68245f9741612f5826a5a244907758f9f36901..29021f4e96b6409bc5dffc12b9717871a652bb49 100644 (file)
@@ -7,6 +7,8 @@
  */
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/export.h>
 #include <asm/debug.h>
 #include "qdio_debug.h"
 #include "qdio.h"
index d9a46a429bccf8213f4dd6c6fea8032c1d127070..2acc01f90a6ab138dce075d2bfd08dca6866caee 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <asm/qdio.h>
 
 #include "cio.h"
index b77ae519d79c4eea8c6d87a1e08609dc70ae0276..96bbe9d12a79fbef17fa9b4df331adf5a24a96c3 100644 (file)
@@ -1271,18 +1271,16 @@ ap_config_timeout(unsigned long ptr)
 }
 
 /**
- * ap_schedule_poll_timer(): Schedule poll timer.
+ * __ap_schedule_poll_timer(): Schedule poll timer.
  *
  * Set up the timer to run the poll tasklet
  */
-static inline void ap_schedule_poll_timer(void)
+static inline void __ap_schedule_poll_timer(void)
 {
        ktime_t hr_time;
 
        spin_lock_bh(&ap_poll_timer_lock);
-       if (ap_using_interrupts() || ap_suspend_flag)
-               goto out;
-       if (hrtimer_is_queued(&ap_poll_timer))
+       if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
                goto out;
        if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
                hr_time = ktime_set(0, poll_timeout);
@@ -1293,6 +1291,18 @@ out:
        spin_unlock_bh(&ap_poll_timer_lock);
 }
 
+/**
+ * ap_schedule_poll_timer(): Schedule poll timer.
+ *
+ * Set up the timer to run the poll tasklet
+ */
+static inline void ap_schedule_poll_timer(void)
+{
+       if (ap_using_interrupts())
+               return;
+       __ap_schedule_poll_timer();
+}
+
 /**
  * ap_poll_read(): Receive pending reply messages from an AP device.
  * @ap_dev: pointer to the AP device
@@ -1374,8 +1384,9 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
                        *flags |= 1;
                *flags |= 2;
                break;
-       case AP_RESPONSE_Q_FULL:
        case AP_RESPONSE_RESET_IN_PROGRESS:
+               __ap_schedule_poll_timer();
+       case AP_RESPONSE_Q_FULL:
                *flags |= 2;
                break;
        case AP_RESPONSE_MESSAGE_TOO_BIG:
@@ -1541,6 +1552,8 @@ static void ap_reset(struct ap_device *ap_dev)
        rc = ap_init_queue(ap_dev->qid);
        if (rc == -ENODEV)
                ap_dev->unregistered = 1;
+       else
+               __ap_schedule_poll_timer();
 }
 
 static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
index 3c2c923d5c0ae6d77a61ec7cac392b4aee4a8f71..94f49ffa70ba22e5e27508c93d139a2b85983ab2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/virtio_console.h>
 #include <linux/interrupt.h>
 #include <linux/virtio_ring.h>
+#include <linux/export.h>
 #include <linux/pfn.h>
 #include <asm/io.h>
 #include <asm/kvm_para.h>
index fa80ba1f0344318a30697cf09af4a44cb135f857..9b66d2d1809b30647c2db82c88ba62306f2061b3 100644 (file)
@@ -4,7 +4,7 @@ menu "S/390 network device drivers"
 config LCS
        def_tristate m
        prompt "Lan Channel Station Interface"
-       depends on CCW && NETDEVICES && (NET_ETHERNET || TR || FDDI)
+       depends on CCW && NETDEVICES && (ETHERNET || TR || FDDI)
        help
           Select this option if you want to use LCS networking on IBM System z.
           This device driver supports Token Ring (IEEE 802.5),
index c28713da1ec5d380f9e904bab6f2946016cb76ec..863fc2197155c36c0f956cd9d3bb7781d8b46778 100644 (file)
@@ -50,7 +50,7 @@
 #include "lcs.h"
 
 
-#if !defined(CONFIG_NET_ETHERNET) && \
+#if !defined(CONFIG_ETHERNET) && \
     !defined(CONFIG_TR) && !defined(CONFIG_FDDI)
 #error Cannot compile lcs.c without some net devices switched on.
 #endif
@@ -1634,7 +1634,7 @@ lcs_startlan_auto(struct lcs_card *card)
        int rc;
 
        LCS_DBF_TEXT(2, trace, "strtauto");
-#ifdef CONFIG_NET_ETHERNET
+#ifdef CONFIG_ETHERNET
        card->lan_type = LCS_FRAME_TYPE_ENET;
        rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
        if (rc == 0)
@@ -2166,7 +2166,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
                goto netdev_out;
        }
        switch (card->lan_type) {
-#ifdef CONFIG_NET_ETHERNET
+#ifdef CONFIG_ETHERNET
        case LCS_FRAME_TYPE_ENET:
                card->lan_type_trans = eth_type_trans;
                dev = alloc_etherdev(0);
index 3251333a23df18b6e8f378f0f681ac818145f0e1..b6a6356d09b3a52857a1f47f14d1a2241b04e142 100644 (file)
@@ -1994,6 +1994,8 @@ static struct net_device *netiucv_init_netdevice(char *username)
                           netiucv_setup_netdevice);
        if (!dev)
                return NULL;
+       if (dev_alloc_name(dev, dev->name) < 0)
+               goto out_netdev;
 
        privptr = netdev_priv(dev);
        privptr->fsm = init_fsm("netiucvdev", dev_state_names,
index b77c65ed13812f9d7e5462c0bcb5bcb9c1fa33f1..4abc79d3963f86ee2dc7dfd14c1fb240bf2eb540 100644 (file)
@@ -236,8 +236,7 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
 #define QETH_IN_BUF_COUNT_MAX 128
 #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
 #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
-               ((card)->ssqd.qdioac1 & AC1_SIGA_INPUT_NEEDED ? 1 : \
-                ((card)->qdio.in_buf_pool.buf_count / 2))
+                ((card)->qdio.in_buf_pool.buf_count / 2)
 
 /* buffers we have to be behind before we get a PCI */
 #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
index 81534437373a3c1209c914db4fb2a32d45860e44..fff57de78943c6d55cda3ece38a22f69bcda76b1 100644 (file)
@@ -881,7 +881,6 @@ EXPORT_SYMBOL_GPL(qeth_do_run_thread);
 void qeth_schedule_recovery(struct qeth_card *card)
 {
        QETH_CARD_TEXT(card, 2, "startrec");
-       WARN_ON(1);
        if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
                schedule_work(&card->kernel_thread_starter);
 }
index e4c1176ee25b2fd9942cfad447826611bbc7037f..4d5307ddbe55b03ce78b89e423369927c171c2c1 100644 (file)
@@ -2756,11 +2756,13 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
        struct neighbour *n = NULL;
        struct dst_entry *dst;
 
+       rcu_read_lock();
        dst = skb_dst(skb);
        if (dst)
                n = dst_get_neighbour(dst);
        if (n) {
                cast_type = n->type;
+               rcu_read_unlock();
                if ((cast_type == RTN_BROADCAST) ||
                    (cast_type == RTN_MULTICAST) ||
                    (cast_type == RTN_ANYCAST))
@@ -2768,6 +2770,8 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
                else
                        return RTN_UNSPEC;
        }
+       rcu_read_unlock();
+
        /* try something else */
        if (skb->protocol == ETH_P_IPV6)
                return (skb_network_header(skb)[24] == 0xff) ?
@@ -2847,6 +2851,8 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
        }
 
        hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
+
+       rcu_read_lock();
        dst = skb_dst(skb);
        if (dst)
                n = dst_get_neighbour(dst);
@@ -2893,6 +2899,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                                QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
                }
        }
+       rcu_read_unlock();
 }
 
 static inline void qeth_l3_hdr_csum(struct qeth_card *card,
index 0ea2fbfe0e993a42932221d52f0040aaf52b96db..d979bb26522ff8348df72caa8d2c5871deb7f5b4 100644 (file)
@@ -335,10 +335,10 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
                                        QETH_IN_BUF_COUNT_MAX)
                                qeth_realloc_buffer_pool(card,
                                        QETH_IN_BUF_COUNT_MAX);
-                       break;
                } else
                        rc = -EPERM;
-       default:   /* fall through */
+               break;
+       default:
                rc = -EINVAL;
        }
 out:
index 645b0fcbb370aa76b5bc816e4509330b67f73146..08601810966252a1b2815f600724c0c90785fb2b 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/miscdevice.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "zfcp_ext.h"
 #include "zfcp_fc.h"
 #include "zfcp_reqlist.h"
index e8b7cee62046e994187499139eda8333d766bca2..96f13ad88123408b51698023a977e90eb3261d97 100644 (file)
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/module.h>
 #include "zfcp_ext.h"
 #include "zfcp_reqlist.h"
 
index 967e7b70e9779d7c26c58cbe65dd2329c358e0a1..a9a816e4aa55f5c2ad8eadfe4302cba48609e421 100644 (file)
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <asm/debug.h>
index df9e69f5474204220d54f7498c724e56ae41f383..e14da5751d32674fa089fe6ffae6ed93da843262 100644 (file)
@@ -10,6 +10,7 @@
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "zfcp_ext.h"
 #include "zfcp_qdio.h"
 
index 09126a9d62ff8942fe3246cc2d8b5a3c9074c768..11f07f888223d92748e684b4000155b7e37eae9c 100644 (file)
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <scsi/fc/fc_fcp.h>
index aa573c39f59626da03692aea19bb34ad3ac80123..06ea3bcfdd2a3064f462592bbed67ca4b24e9c7e 100644 (file)
@@ -617,20 +617,6 @@ config SCSI_ARCMSR
          To compile this driver as a module, choose M here: the
          module will be called arcmsr (modprobe arcmsr).
 
-config SCSI_ARCMSR_AER
-       bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)"
-       depends on SCSI_ARCMSR && PCIEAER
-       default n
-       help
-         The advanced error reporting(AER) capability is "NOT" provided by
-         ARC1200/1201/1202 SATA RAID controllers cards.
-         If your card is one of ARC1200/1201/1202, please use the default setting, n.
-         If your card is other models, you could pick it
-         on condition that the kernel version is greater than 2.6.19.
-         This function is maintained driver by Nick Cheng. If you have any
-         problems or suggestion, you are welcome to contact with <nick.cheng@areca.com.tw>.
-         To enable this function, choose Y here.
-
 source "drivers/scsi/megaraid/Kconfig.megaraid"
 source "drivers/scsi/mpt2sas/Kconfig"
 
index 1bb5d3f0e260f1a94a74b15deb47301212784d19..79a30633d4aa1d9af1cf69f5ae27c2ee666e4d87 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/zorro.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index d9468027fb6150caed5a9854623b5673ddff58a4..e29fe0e708f8f4e63fbcc0f9f20142ce06d6517f 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index 061995741444b379b007886f7fe0bd2acb7b8ac1..409f5805bdd63e06459906a04a7592eebeea9aae 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/blkdev.h>
 #include <asm/uaccess.h>
 #include <linux/highmem.h> /* For flush_kernel_dcache_page */
+#include <linux/module.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 4aa76d6f11dfed870db05bb098f13cf4aa3d361a..705e13e470af18850ae4375533ae4f85495b592c 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
@@ -1109,6 +1110,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
                unique_id++;
        }
 
+       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+                              PCIE_LINK_STATE_CLKPM);
+
        error = pci_enable_device(pdev);
        if (error)
                goto out;
index 7b0a8ab710494c120d0d7b2338ebe218e6883cbf..379c696dac19cb31f6c2cb43f9bcc0e647a89725 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/semaphore.h>
 #include <linux/iscsi_boot_sysfs.h>
+#include <linux/module.h>
 
 #include <scsi/libiscsi.h>
 #include <scsi/scsi_transport_iscsi.h>
index b412e0300dd4756cc6549974ec9368c9c50eb794..dee1a094c2c2a6af5a80871785afea81a60e5833 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/export.h>
 
 #include "bfad_drv.h"
 #include "bfad_im.h"
index 01312381639f74415d1ebd2ca10c1752308fb922..e5db649e8eb757dbe79241645c024734d76dd21a 100644 (file)
@@ -19,6 +19,8 @@
  *  bfad_im.c Linux driver IM module.
  */
 
+#include <linux/export.h>
+
 #include "bfad_drv.h"
 #include "bfad_im.h"
 #include "bfa_fcs.h"
index 63de1c7cd0cb7b8b847809a661d5f378abc97bce..049ea907e04acd287640441b27b4ff666b0b7d31 100644 (file)
@@ -62,7 +62,7 @@
 #include "bnx2fc_constants.h"
 
 #define BNX2FC_NAME            "bnx2fc"
-#define BNX2FC_VERSION         "1.0.8"
+#define BNX2FC_VERSION         "1.0.9"
 
 #define PFX                    "bnx2fc: "
 
 #define REC_RETRY_COUNT                        1
 #define BNX2FC_NUM_ERR_BITS            63
 
+#define BNX2FC_RELOGIN_WAIT_TIME       200
+#define BNX2FC_RELOGIN_WAIT_CNT                10
+
 /* bnx2fc driver uses only one instance of fcoe_percpu_s */
 extern struct fcoe_percpu_s bnx2fc_global;
 
index fd382fe33f6ef108362debbf0d8a5f872947c560..ce0ce3e32f336aaf711d6129a781c0aa035120fa 100644 (file)
@@ -268,17 +268,6 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
 
        orig_io_req = cb_arg->aborted_io_req;
        srr_req = cb_arg->io_req;
-       if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
-               BNX2FC_IO_DBG(srr_req, "srr_compl: xid - 0x%x completed",
-                       orig_io_req->xid);
-               goto srr_compl_done;
-       }
-       if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
-               BNX2FC_IO_DBG(srr_req, "rec abts in prog "
-                      "orig_io - 0x%x\n",
-                       orig_io_req->xid);
-               goto srr_compl_done;
-       }
        if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) {
                /* SRR timedout */
                BNX2FC_IO_DBG(srr_req, "srr timed out, abort "
@@ -290,6 +279,12 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
                                "failed. issue cleanup\n");
                        bnx2fc_initiate_cleanup(srr_req);
                }
+               if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
+                   test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
+                       BNX2FC_IO_DBG(srr_req, "srr_compl:xid 0x%x flags = %lx",
+                                     orig_io_req->xid, orig_io_req->req_flags);
+                       goto srr_compl_done;
+               }
                orig_io_req->srr_retry++;
                if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
                        struct bnx2fc_rport *tgt = orig_io_req->tgt;
@@ -311,6 +306,12 @@ void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
                }
                goto srr_compl_done;
        }
+       if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
+           test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
+               BNX2FC_IO_DBG(srr_req, "srr_compl:xid - 0x%x flags = %lx",
+                             orig_io_req->xid, orig_io_req->req_flags);
+               goto srr_compl_done;
+       }
        mp_req = &(srr_req->mp_req);
        fc_hdr = &(mp_req->resp_fc_hdr);
        resp_len = mp_req->resp_len;
index 85bcc4b5596593c1732d4cd04c738f89fe999221..8c6156a10d90233a45bee5f27f343a33c7311929 100644 (file)
@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
 
 #define DRV_MODULE_NAME                "bnx2fc"
 #define DRV_MODULE_VERSION     BNX2FC_VERSION
-#define DRV_MODULE_RELDATE     "Oct 02, 2011"
+#define DRV_MODULE_RELDATE     "Oct 21, 2011"
 
 
 static char version[] __devinitdata =
index 0c64d184d7313ba01c1688b3da8e9a7ebb50b597..84a78af83f906e169739aac47a5d4d3635fda323 100644 (file)
@@ -1103,7 +1103,10 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
        struct fc_rport_libfc_priv *rp = rport->dd_data;
        struct bnx2fc_cmd *io_req;
        struct fc_lport *lport;
+       struct fc_rport_priv *rdata;
        struct bnx2fc_rport *tgt;
+       int logo_issued;
+       int wait_cnt = 0;
        int rc = FAILED;
 
 
@@ -1192,8 +1195,40 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
        } else {
                printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
                                "already in abts processing\n", io_req->xid);
+               if (cancel_delayed_work(&io_req->timeout_work))
+                       kref_put(&io_req->refcount,
+                                bnx2fc_cmd_release); /* drop timer hold */
+               bnx2fc_initiate_cleanup(io_req);
+
+               spin_unlock_bh(&tgt->tgt_lock);
+
+               wait_for_completion(&io_req->tm_done);
+
+               spin_lock_bh(&tgt->tgt_lock);
+               io_req->wait_for_comp = 0;
+               rdata = io_req->tgt->rdata;
+               logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO,
+                                              &tgt->flags);
                kref_put(&io_req->refcount, bnx2fc_cmd_release);
                spin_unlock_bh(&tgt->tgt_lock);
+
+               if (!logo_issued) {
+                       BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n",
+                                     tgt->flags);
+                       mutex_lock(&lport->disc.disc_mutex);
+                       lport->tt.rport_logoff(rdata);
+                       mutex_unlock(&lport->disc.disc_mutex);
+                       do {
+                               msleep(BNX2FC_RELOGIN_WAIT_TIME);
+                               /*
+                                * If session not recovered, let SCSI-ml
+                                * escalate error recovery.
+                                */
+                               if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT)
+                                       return FAILED;
+                       } while (!test_bit(BNX2FC_FLAG_SESSION_READY,
+                                          &tgt->flags));
+               }
                return SUCCESS;
        }
        if (rc == FAILED) {
@@ -1275,6 +1310,8 @@ void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req,
                   io_req->refcount.refcount.counter, io_req->cmd_type);
        bnx2fc_scsi_done(io_req, DID_ERROR);
        kref_put(&io_req->refcount, bnx2fc_cmd_release);
+       if (io_req->wait_for_comp)
+               complete(&io_req->tm_done);
 }
 
 void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
index c363a4b260fd7292279c938a5d1a0489eabda007..c10f74a566f2d58741e0c2012b15017e8ce07a5f 100644 (file)
@@ -25,6 +25,7 @@
 #include <net/dst.h>
 #include <net/route.h>
 #include <linux/inetdevice.h>  /* ip_dev_find */
+#include <linux/module.h>
 #include <net/tcp.h>
 
 static unsigned int dbg_level;
index 7c05fd9dccfd1259133adaa1691df648cff56521..23149b9e297c29ae82dff0330498f09423a0e557 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <scsi/scsi_dh.h>
 #include "../scsi_priv.h"
 
@@ -441,7 +442,15 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
 
        spin_lock_irqsave(q->queue_lock, flags);
        sdev = q->queuedata;
-       if (sdev && sdev->scsi_dh_data)
+       if (!sdev) {
+               spin_unlock_irqrestore(q->queue_lock, flags);
+               err = SCSI_DH_NOSYS;
+               if (fn)
+                       fn(data, err);
+               return err;
+       }
+
+       if (sdev->scsi_dh_data)
                scsi_dh = sdev->scsi_dh_data->scsi_dh;
        dev = get_device(&sdev->sdev_gendev);
        if (!scsi_dh || !dev ||
index 627f4b5e5176b16e9cc969c0b98ac80a85c4afb1..4ef021291a4d06d2ecd4340f5ba1c35658a5c9d1 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
@@ -507,7 +508,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
        int len, k, off, valid_states = 0;
        unsigned char *ucp;
        unsigned err;
-       unsigned long expiry, interval = 1;
+       unsigned long expiry, interval = 1000;
 
        expiry = round_jiffies_up(jiffies + ALUA_FAILOVER_TIMEOUT);
  retry:
@@ -734,6 +735,7 @@ static int alua_bus_attach(struct scsi_device *sdev)
        spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
        sdev->scsi_dh_data = scsi_dh_data;
        spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+       sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME);
 
        return 0;
 
index 48441f6908a4c2f3fa040f9dd54313ae55fb82be..591186cf1896abbd0031e4a2bd45682e2b6d5191 100644 (file)
@@ -21,6 +21,7 @@
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_dh.h>
index b479f1eef96878ae71f73c2e2d5f1c2bf6f52f51..0f86a18b157de47dc7dd8028ee727aa7d56a8b18 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_eh.h>
index 82d612f0c49dc1d422e0f3efc817bab2c947ffff..1d31279200639074b87aa075475d1e84f77bf2eb 100644 (file)
@@ -24,6 +24,7 @@
 #include <scsi/scsi_dh.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define RDAC_NAME "rdac"
 #define RDAC_RETRY_COUNT 5
index 61384ee4049b39364ec9481fffaaf3155efb77d7..cefbe44bb84a1293db665510543ab8cccaec1622 100644 (file)
@@ -2347,14 +2347,11 @@ static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
                goto done;
 
        mac = fr_cb(fp)->granted_mac;
-       if (is_zero_ether_addr(mac)) {
-               /* pre-FIP */
-               if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
-                       fc_frame_free(fp);
-                       return;
-               }
-       }
-       fcoe_update_src_mac(lport, mac);
+       /* pre-FIP */
+       if (is_zero_ether_addr(mac))
+               fcoe_ctlr_recv_flogi(fip, lport, fp);
+       if (!is_zero_ether_addr(mac))
+               fcoe_update_src_mac(lport, mac);
 done:
        fc_lport_flogi_resp(seq, fp, lport);
 }
index 50bb54150a7899d015c75e403545ecfb78b619c1..488fbc648656409be4bfb77167171d53b5e1839f 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/zorro.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index 4f7a5829ea4c0cbca2c7f5e76cb497b2c1708457..351dc0b86fab72dd788807589f7a699e49f480ae 100644 (file)
@@ -286,6 +286,7 @@ static void scsi_host_dev_release(struct device *dev)
 {
        struct Scsi_Host *shost = dev_to_shost(dev);
        struct device *parent = dev->parent;
+       struct request_queue *q;
 
        scsi_proc_hostdir_rm(shost->hostt);
 
@@ -293,9 +294,11 @@ static void scsi_host_dev_release(struct device *dev)
                kthread_stop(shost->ehandler);
        if (shost->work_q)
                destroy_workqueue(shost->work_q);
-       if (shost->uspace_req_q) {
-               kfree(shost->uspace_req_q->queuedata);
-               scsi_free_queue(shost->uspace_req_q);
+       q = shost->uspace_req_q;
+       if (q) {
+               kfree(q->queuedata);
+               q->queuedata = NULL;
+               scsi_free_queue(q);
        }
 
        scsi_destroy_command_freelist(shost);
index bbdc9f960a66fd7105a314f89e900e5b17492af9..865d452542be923ef7c02bc0f4eea816dfc898b3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -48,6 +49,7 @@
 #include <linux/bitmap.h>
 #include <linux/atomic.h>
 #include <linux/kthread.h>
+#include <linux/jiffies.h>
 #include "hpsa_cmd.h"
 #include "hpsa.h"
 
@@ -127,6 +129,10 @@ static struct board_type products[] = {
 
 static int number_of_controllers;
 
+static struct list_head hpsa_ctlr_list = LIST_HEAD_INIT(hpsa_ctlr_list);
+static spinlock_t lockup_detector_lock;
+static struct task_struct *hpsa_lockup_detector;
+
 static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
 static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id);
 static int hpsa_ioctl(struct scsi_device *dev, int cmd, void *arg);
@@ -484,6 +490,7 @@ static struct scsi_host_template hpsa_driver_template = {
 #endif
        .sdev_attrs = hpsa_sdev_attrs,
        .shost_attrs = hpsa_shost_attrs,
+       .max_sectors = 8192,
 };
 
 
@@ -566,16 +573,16 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
         * assumes h->devlock is held
         */
        int i, found = 0;
-       DECLARE_BITMAP(lun_taken, HPSA_MAX_SCSI_DEVS_PER_HBA);
+       DECLARE_BITMAP(lun_taken, HPSA_MAX_DEVICES);
 
-       memset(&lun_taken[0], 0, HPSA_MAX_SCSI_DEVS_PER_HBA >> 3);
+       memset(&lun_taken[0], 0, HPSA_MAX_DEVICES >> 3);
 
        for (i = 0; i < h->ndevices; i++) {
                if (h->dev[i]->bus == bus && h->dev[i]->target != -1)
                        set_bit(h->dev[i]->target, lun_taken);
        }
 
-       for (i = 0; i < HPSA_MAX_SCSI_DEVS_PER_HBA; i++) {
+       for (i = 0; i < HPSA_MAX_DEVICES; i++) {
                if (!test_bit(i, lun_taken)) {
                        /* *bus = 1; */
                        *target = i;
@@ -598,7 +605,7 @@ static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
        unsigned char addr1[8], addr2[8];
        struct hpsa_scsi_dev_t *sd;
 
-       if (n >= HPSA_MAX_SCSI_DEVS_PER_HBA) {
+       if (n >= HPSA_MAX_DEVICES) {
                dev_err(&h->pdev->dev, "too many devices, some will be "
                        "inaccessible.\n");
                return -1;
@@ -673,7 +680,7 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
        struct hpsa_scsi_dev_t *removed[], int *nremoved)
 {
        /* assumes h->devlock is held */
-       BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
+       BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
        removed[*nremoved] = h->dev[entry];
        (*nremoved)++;
 
@@ -702,7 +709,7 @@ static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
        int i;
        struct hpsa_scsi_dev_t *sd;
 
-       BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
+       BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
 
        sd = h->dev[entry];
        removed[*nremoved] = h->dev[entry];
@@ -814,10 +821,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        int nadded, nremoved;
        struct Scsi_Host *sh = NULL;
 
-       added = kzalloc(sizeof(*added) * HPSA_MAX_SCSI_DEVS_PER_HBA,
-               GFP_KERNEL);
-       removed = kzalloc(sizeof(*removed) * HPSA_MAX_SCSI_DEVS_PER_HBA,
-               GFP_KERNEL);
+       added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
+       removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
 
        if (!added || !removed) {
                dev_warn(&h->pdev->dev, "out of memory in "
@@ -1338,6 +1343,22 @@ static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
        wait_for_completion(&wait);
 }
 
+static void hpsa_scsi_do_simple_cmd_core_if_no_lockup(struct ctlr_info *h,
+       struct CommandList *c)
+{
+       unsigned long flags;
+
+       /* If controller lockup detected, fake a hardware error. */
+       spin_lock_irqsave(&h->lock, flags);
+       if (unlikely(h->lockup_detected)) {
+               spin_unlock_irqrestore(&h->lock, flags);
+               c->err_info->CommandStatus = CMD_HARDWARE_ERR;
+       } else {
+               spin_unlock_irqrestore(&h->lock, flags);
+               hpsa_scsi_do_simple_cmd_core(h, c);
+       }
+}
+
 static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
        struct CommandList *c, int data_direction)
 {
@@ -1735,7 +1756,6 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
        if (is_scsi_rev_5(h))
                return 0; /* p1210m doesn't need to do this. */
 
-#define MAX_MSA2XXX_ENCLOSURES 32
        if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
                dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
                        "enclosures exceeded.  Check your hardware "
@@ -1846,8 +1866,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
        int raid_ctlr_position;
        DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
 
-       currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_SCSI_DEVS_PER_HBA,
-               GFP_KERNEL);
+       currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
        physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
        logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
        tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
@@ -1870,6 +1889,13 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 
        /* Allocate the per device structures */
        for (i = 0; i < ndevs_to_allocate; i++) {
+               if (i >= HPSA_MAX_DEVICES) {
+                       dev_warn(&h->pdev->dev, "maximum devices (%d) exceeded."
+                               "  %d devices ignored.\n", HPSA_MAX_DEVICES,
+                               ndevs_to_allocate - HPSA_MAX_DEVICES);
+                       break;
+               }
+
                currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL);
                if (!currentsd[i]) {
                        dev_warn(&h->pdev->dev, "out of memory at %s:%d\n",
@@ -1956,7 +1982,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                default:
                        break;
                }
-               if (ncurrent >= HPSA_MAX_SCSI_DEVS_PER_HBA)
+               if (ncurrent >= HPSA_MAX_DEVICES)
                        break;
        }
        adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
@@ -2048,8 +2074,14 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd,
        }
        memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
 
-       /* Need a lock as this is being allocated from the pool */
        spin_lock_irqsave(&h->lock, flags);
+       if (unlikely(h->lockup_detected)) {
+               spin_unlock_irqrestore(&h->lock, flags);
+               cmd->result = DID_ERROR << 16;
+               done(cmd);
+               return 0;
+       }
+       /* Need a lock as this is being allocated from the pool */
        c = cmd_alloc(h);
        spin_unlock_irqrestore(&h->lock, flags);
        if (c == NULL) {                        /* trouble... */
@@ -2601,7 +2633,7 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                c->SG[0].Len = iocommand.buf_size;
                c->SG[0].Ext = 0; /* we are not chaining*/
        }
-       hpsa_scsi_do_simple_cmd_core(h, c);
+       hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
        if (iocommand.buf_size > 0)
                hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
        check_ioctl_unit_attention(h, c);
@@ -2724,7 +2756,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                        c->SG[i].Ext = 0;
                }
        }
-       hpsa_scsi_do_simple_cmd_core(h, c);
+       hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
        if (sg_used)
                hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
        check_ioctl_unit_attention(h, c);
@@ -2872,6 +2904,8 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
                        c->Request.Timeout = 0;
                        c->Request.CDB[0] = BMIC_WRITE;
                        c->Request.CDB[6] = BMIC_CACHE_FLUSH;
+                       c->Request.CDB[7] = (size >> 8) & 0xFF;
+                       c->Request.CDB[8] = size & 0xFF;
                        break;
                case TEST_UNIT_READY:
                        c->Request.CDBLen = 6;
@@ -3091,6 +3125,7 @@ static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id)
        if (interrupt_not_for_us(h))
                return IRQ_NONE;
        spin_lock_irqsave(&h->lock, flags);
+       h->last_intr_timestamp = get_jiffies_64();
        while (interrupt_pending(h)) {
                raw_tag = get_next_completion(h);
                while (raw_tag != FIFO_EMPTY)
@@ -3110,6 +3145,7 @@ static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id)
                return IRQ_NONE;
 
        spin_lock_irqsave(&h->lock, flags);
+       h->last_intr_timestamp = get_jiffies_64();
        raw_tag = get_next_completion(h);
        while (raw_tag != FIFO_EMPTY)
                raw_tag = next_command(h);
@@ -3126,6 +3162,7 @@ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
        if (interrupt_not_for_us(h))
                return IRQ_NONE;
        spin_lock_irqsave(&h->lock, flags);
+       h->last_intr_timestamp = get_jiffies_64();
        while (interrupt_pending(h)) {
                raw_tag = get_next_completion(h);
                while (raw_tag != FIFO_EMPTY) {
@@ -3146,6 +3183,7 @@ static irqreturn_t do_hpsa_intr_msi(int irq, void *dev_id)
        u32 raw_tag;
 
        spin_lock_irqsave(&h->lock, flags);
+       h->last_intr_timestamp = get_jiffies_64();
        raw_tag = get_next_completion(h);
        while (raw_tag != FIFO_EMPTY) {
                if (hpsa_tag_contains_index(raw_tag))
@@ -3885,6 +3923,10 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)
                dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
                return -ENODEV;
        }
+
+       pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
+                              PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
+
        err = pci_enable_device(h->pdev);
        if (err) {
                dev_warn(&h->pdev->dev, "unable to enable PCI device\n");
@@ -4090,6 +4132,149 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
        kfree(h);
 }
 
+static void remove_ctlr_from_lockup_detector_list(struct ctlr_info *h)
+{
+       assert_spin_locked(&lockup_detector_lock);
+       if (!hpsa_lockup_detector)
+               return;
+       if (h->lockup_detected)
+               return; /* already stopped the lockup detector */
+       list_del(&h->lockup_list);
+}
+
+/* Called when controller lockup detected. */
+static void fail_all_cmds_on_list(struct ctlr_info *h, struct list_head *list)
+{
+       struct CommandList *c = NULL;
+
+       assert_spin_locked(&h->lock);
+       /* Mark all outstanding commands as failed and complete them. */
+       while (!list_empty(list)) {
+               c = list_entry(list->next, struct CommandList, list);
+               c->err_info->CommandStatus = CMD_HARDWARE_ERR;
+               finish_cmd(c, c->Header.Tag.lower);
+       }
+}
+
+static void controller_lockup_detected(struct ctlr_info *h)
+{
+       unsigned long flags;
+
+       assert_spin_locked(&lockup_detector_lock);
+       remove_ctlr_from_lockup_detector_list(h);
+       h->access.set_intr_mask(h, HPSA_INTR_OFF);
+       spin_lock_irqsave(&h->lock, flags);
+       h->lockup_detected = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+       spin_unlock_irqrestore(&h->lock, flags);
+       dev_warn(&h->pdev->dev, "Controller lockup detected: 0x%08x\n",
+                       h->lockup_detected);
+       pci_disable_device(h->pdev);
+       spin_lock_irqsave(&h->lock, flags);
+       fail_all_cmds_on_list(h, &h->cmpQ);
+       fail_all_cmds_on_list(h, &h->reqQ);
+       spin_unlock_irqrestore(&h->lock, flags);
+}
+
+#define HEARTBEAT_SAMPLE_INTERVAL (10 * HZ)
+#define HEARTBEAT_CHECK_MINIMUM_INTERVAL (HEARTBEAT_SAMPLE_INTERVAL / 2)
+
+static void detect_controller_lockup(struct ctlr_info *h)
+{
+       u64 now;
+       u32 heartbeat;
+       unsigned long flags;
+
+       assert_spin_locked(&lockup_detector_lock);
+       now = get_jiffies_64();
+       /* If we've received an interrupt recently, we're ok. */
+       if (time_after64(h->last_intr_timestamp +
+                               (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
+               return;
+
+       /*
+        * If we've already checked the heartbeat recently, we're ok.
+        * This could happen if someone sends us a signal. We
+        * otherwise don't care about signals in this thread.
+        */
+       if (time_after64(h->last_heartbeat_timestamp +
+                               (HEARTBEAT_CHECK_MINIMUM_INTERVAL), now))
+               return;
+
+       /* If heartbeat has not changed since we last looked, we're not ok. */
+       spin_lock_irqsave(&h->lock, flags);
+       heartbeat = readl(&h->cfgtable->HeartBeat);
+       spin_unlock_irqrestore(&h->lock, flags);
+       if (h->last_heartbeat == heartbeat) {
+               controller_lockup_detected(h);
+               return;
+       }
+
+       /* We're ok. */
+       h->last_heartbeat = heartbeat;
+       h->last_heartbeat_timestamp = now;
+}
+
+static int detect_controller_lockup_thread(void *notused)
+{
+       struct ctlr_info *h;
+       unsigned long flags;
+
+       while (1) {
+               struct list_head *this, *tmp;
+
+               schedule_timeout_interruptible(HEARTBEAT_SAMPLE_INTERVAL);
+               if (kthread_should_stop())
+                       break;
+               spin_lock_irqsave(&lockup_detector_lock, flags);
+               list_for_each_safe(this, tmp, &hpsa_ctlr_list) {
+                       h = list_entry(this, struct ctlr_info, lockup_list);
+                       detect_controller_lockup(h);
+               }
+               spin_unlock_irqrestore(&lockup_detector_lock, flags);
+       }
+       return 0;
+}
+
+static void add_ctlr_to_lockup_detector_list(struct ctlr_info *h)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&lockup_detector_lock, flags);
+       list_add_tail(&h->lockup_list, &hpsa_ctlr_list);
+       spin_unlock_irqrestore(&lockup_detector_lock, flags);
+}
+
+static void start_controller_lockup_detector(struct ctlr_info *h)
+{
+       /* Start the lockup detector thread if not already started */
+       if (!hpsa_lockup_detector) {
+               spin_lock_init(&lockup_detector_lock);
+               hpsa_lockup_detector =
+                       kthread_run(detect_controller_lockup_thread,
+                                               NULL, "hpsa");
+       }
+       if (!hpsa_lockup_detector) {
+               dev_warn(&h->pdev->dev,
+                       "Could not start lockup detector thread\n");
+               return;
+       }
+       add_ctlr_to_lockup_detector_list(h);
+}
+
+static void stop_controller_lockup_detector(struct ctlr_info *h)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&lockup_detector_lock, flags);
+       remove_ctlr_from_lockup_detector_list(h);
+       /* If the list of ctlr's to monitor is empty, stop the thread */
+       if (list_empty(&hpsa_ctlr_list)) {
+               kthread_stop(hpsa_lockup_detector);
+               hpsa_lockup_detector = NULL;
+       }
+       spin_unlock_irqrestore(&lockup_detector_lock, flags);
+}
+
 static int __devinit hpsa_init_one(struct pci_dev *pdev,
                                    const struct pci_device_id *ent)
 {
@@ -4127,7 +4312,6 @@ reinit_after_soft_reset:
                return -ENOMEM;
 
        h->pdev = pdev;
-       h->busy_initializing = 1;
        h->intr_mode = hpsa_simple_mode ? SIMPLE_MODE_INT : PERF_MODE_INT;
        INIT_LIST_HEAD(&h->cmpQ);
        INIT_LIST_HEAD(&h->reqQ);
@@ -4236,7 +4420,7 @@ reinit_after_soft_reset:
 
        hpsa_hba_inquiry(h);
        hpsa_register_scsi(h);  /* hook ourselves into SCSI subsystem */
-       h->busy_initializing = 0;
+       start_controller_lockup_detector(h);
        return 1;
 
 clean4:
@@ -4245,7 +4429,6 @@ clean4:
        free_irq(h->intr[h->intr_mode], h);
 clean2:
 clean1:
-       h->busy_initializing = 0;
        kfree(h);
        return rc;
 }
@@ -4300,10 +4483,11 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
        struct ctlr_info *h;
 
        if (pci_get_drvdata(pdev) == NULL) {
-               dev_err(&pdev->dev, "unable to remove device \n");
+               dev_err(&pdev->dev, "unable to remove device\n");
                return;
        }
        h = pci_get_drvdata(pdev);
+       stop_controller_lockup_detector(h);
        hpsa_unregister_scsi(h);        /* unhook from SCSI subsystem */
        hpsa_shutdown(pdev);
        iounmap(h->vaddr);
index 7f53ceaa7239144523c0bc1c9c2685327bfb6198..91edafb8c7e6a257b5c13d7ed7f082b95bb95685 100644 (file)
@@ -95,8 +95,6 @@ struct ctlr_info {
        unsigned long           *cmd_pool_bits;
        int                     nr_allocs;
        int                     nr_frees;
-       int                     busy_initializing;
-       int                     busy_scanning;
        int                     scan_finished;
        spinlock_t              scan_lock;
        wait_queue_head_t       scan_wait_queue;
@@ -104,8 +102,7 @@ struct ctlr_info {
        struct Scsi_Host *scsi_host;
        spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
        int ndevices; /* number of used elements in .dev[] array. */
-#define HPSA_MAX_SCSI_DEVS_PER_HBA 256
-       struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA];
+       struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES];
        /*
         * Performant mode tables.
         */
@@ -124,6 +121,11 @@ struct ctlr_info {
        unsigned char reply_pool_wraparound;
        u32 *blockFetchTable;
        unsigned char *hba_inquiry_data;
+       u64 last_intr_timestamp;
+       u32 last_heartbeat;
+       u64 last_heartbeat_timestamp;
+       u32 lockup_detected;
+       struct list_head lockup_list;
 };
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
index 55d741b019db22cf49b374f9c8a6994f7ccfcae7..3fd4715935c27658a74ea1e14db98e56e17b4d99 100644 (file)
@@ -123,8 +123,11 @@ union u64bit {
 
 /* FIXME this is a per controller value (barf!) */
 #define HPSA_MAX_TARGETS_PER_CTLR 16
-#define HPSA_MAX_LUN 256
+#define HPSA_MAX_LUN 1024
 #define HPSA_MAX_PHYS_LUN 1024
+#define MAX_MSA2XXX_ENCLOSURES 32
+#define HPSA_MAX_DEVICES (HPSA_MAX_PHYS_LUN + HPSA_MAX_LUN + \
+       MAX_MSA2XXX_ENCLOSURES + 1) /* + 1 is for the controller itself */
 
 /* SCSI-3 Commands */
 #pragma pack(1)
index 73e24b48dced4d10a6f1139f75ebfab1fcebba5e..fd860d952b288f3cacf6066253f4d75936e0c53e 100644 (file)
@@ -9122,6 +9122,8 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C3, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C4, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
index 6d257e0dd6a57e8b7b7c6448e5430ba3bb483568..ac84736c1b9c414530d358fe4fda9235d00ac235 100644 (file)
@@ -82,6 +82,7 @@
 
 #define IPR_SUBS_DEV_ID_57B4    0x033B
 #define IPR_SUBS_DEV_ID_57B2    0x035F
+#define IPR_SUBS_DEV_ID_57C3    0x0353
 #define IPR_SUBS_DEV_ID_57C4    0x0354
 #define IPR_SUBS_DEV_ID_57C6    0x0357
 #define IPR_SUBS_DEV_ID_57CC    0x035C
index f07f30fada1bc1d66bd274cdb54d8582569c1ef5..e7fe9c4c85b84d7098850eb16288caaae8b20578 100644 (file)
@@ -1350,7 +1350,7 @@ static void isci_user_parameters_get(struct sci_user_parameters *u)
        u->stp_max_occupancy_timeout = stp_max_occ_to;
        u->ssp_max_occupancy_timeout = ssp_max_occ_to;
        u->no_outbound_task_timeout = no_outbound_task_to;
-       u->max_number_concurrent_device_spin_up = max_concurr_spinup;
+       u->max_concurr_spinup = max_concurr_spinup;
 }
 
 static 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
        ihost->oem_parameters.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
 
        /* Default to APC mode. */
-       ihost->oem_parameters.controller.max_concurrent_dev_spin_up = 1;
+       ihost->oem_parameters.controller.max_concurr_spin_up = 1;
 
        /* Default to no SSC operation. */
        ihost->oem_parameters.controller.do_enable_ssc = false;
@@ -1787,7 +1787,8 @@ int sci_oem_parameters_validate(struct sci_oem_params *oem)
        } else
                return -EINVAL;
 
-       if (oem->controller.max_concurrent_dev_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT)
+       if (oem->controller.max_concurr_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT ||
+           oem->controller.max_concurr_spin_up < 1)
                return -EINVAL;
 
        return 0;
@@ -1810,6 +1811,16 @@ static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
        return SCI_FAILURE_INVALID_STATE;
 }
 
+static u8 max_spin_up(struct isci_host *ihost)
+{
+       if (ihost->user_parameters.max_concurr_spinup)
+               return min_t(u8, ihost->user_parameters.max_concurr_spinup,
+                            MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT);
+       else
+               return min_t(u8, ihost->oem_parameters.controller.max_concurr_spin_up,
+                            MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT);
+}
+
 static void power_control_timeout(unsigned long data)
 {
        struct sci_timer *tmr = (struct sci_timer *)data;
@@ -1839,8 +1850,7 @@ static void power_control_timeout(unsigned long data)
                if (iphy == NULL)
                        continue;
 
-               if (ihost->power_control.phys_granted_power >=
-                   ihost->oem_parameters.controller.max_concurrent_dev_spin_up)
+               if (ihost->power_control.phys_granted_power >= max_spin_up(ihost))
                        break;
 
                ihost->power_control.requesters[i] = NULL;
@@ -1865,8 +1875,7 @@ void sci_controller_power_control_queue_insert(struct isci_host *ihost,
 {
        BUG_ON(iphy == NULL);
 
-       if (ihost->power_control.phys_granted_power <
-           ihost->oem_parameters.controller.max_concurrent_dev_spin_up) {
+       if (ihost->power_control.phys_granted_power < max_spin_up(ihost)) {
                ihost->power_control.phys_granted_power++;
                sci_phy_consume_power_handler(iphy);
 
index 43fe840fbe9c3427127ad0eac99a0f3b4b45aacb..a97edabcb85a29e96e1741171fcce2ea4c7cb4c0 100644 (file)
@@ -118,7 +118,7 @@ unsigned char phy_gen = 3;
 module_param(phy_gen, byte, 0);
 MODULE_PARM_DESC(phy_gen, "PHY generation (1: 1.5Gbps 2: 3.0Gbps 3: 6.0Gbps)");
 
-unsigned char max_concurr_spinup = 1;
+unsigned char max_concurr_spinup;
 module_param(max_concurr_spinup, byte, 0);
 MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
 
index 8e59c8865dcdc06911bdda139088825230e95692..ac7f27749f975761a1beefc7f1b1741a5c02e0bc 100644 (file)
@@ -145,48 +145,15 @@ static void sci_port_bcn_enable(struct isci_port *iport)
        }
 }
 
-/* called under sci_lock to stabilize phy:port associations */
-void isci_port_bcn_enable(struct isci_host *ihost, struct isci_port *iport)
-{
-       int i;
-
-       clear_bit(IPORT_BCN_BLOCKED, &iport->flags);
-       wake_up(&ihost->eventq);
-
-       if (!test_and_clear_bit(IPORT_BCN_PENDING, &iport->flags))
-               return;
-
-       for (i = 0; i < ARRAY_SIZE(iport->phy_table); i++) {
-               struct isci_phy *iphy = iport->phy_table[i];
-
-               if (!iphy)
-                       continue;
-
-               ihost->sas_ha.notify_port_event(&iphy->sas_phy,
-                                               PORTE_BROADCAST_RCVD);
-               break;
-       }
-}
-
 static void isci_port_bc_change_received(struct isci_host *ihost,
                                         struct isci_port *iport,
                                         struct isci_phy *iphy)
 {
-       if (iport && test_bit(IPORT_BCN_BLOCKED, &iport->flags)) {
-               dev_dbg(&ihost->pdev->dev,
-                       "%s: disabled BCN; isci_phy = %p, sas_phy = %p\n",
-                       __func__, iphy, &iphy->sas_phy);
-               set_bit(IPORT_BCN_PENDING, &iport->flags);
-               atomic_inc(&iport->event);
-               wake_up(&ihost->eventq);
-       } else {
-               dev_dbg(&ihost->pdev->dev,
-                       "%s: isci_phy = %p, sas_phy = %p\n",
-                       __func__, iphy, &iphy->sas_phy);
+       dev_dbg(&ihost->pdev->dev,
+               "%s: isci_phy = %p, sas_phy = %p\n",
+               __func__, iphy, &iphy->sas_phy);
 
-               ihost->sas_ha.notify_port_event(&iphy->sas_phy,
-                                               PORTE_BROADCAST_RCVD);
-       }
+       ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
        sci_port_bcn_enable(iport);
 }
 
@@ -278,9 +245,6 @@ static void isci_port_link_down(struct isci_host *isci_host,
                /* check to see if this is the last phy on this port. */
                if (isci_phy->sas_phy.port &&
                    isci_phy->sas_phy.port->num_phys == 1) {
-                       atomic_inc(&isci_port->event);
-                       isci_port_bcn_enable(isci_host, isci_port);
-
                        /* change the state for all devices on this port.  The
                         * next task sent to this device will be returned as
                         * SAS_TASK_UNDELIVERED, and the scsi mid layer will
@@ -350,6 +314,34 @@ static void isci_port_stop_complete(struct isci_host *ihost,
        dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
 }
 
+
+static bool is_port_ready_state(enum sci_port_states state)
+{
+       switch (state) {
+       case SCI_PORT_READY:
+       case SCI_PORT_SUB_WAITING:
+       case SCI_PORT_SUB_OPERATIONAL:
+       case SCI_PORT_SUB_CONFIGURING:
+               return true;
+       default:
+               return false;
+       }
+}
+
+/* flag dummy rnc hanling when exiting a ready state */
+static void port_state_machine_change(struct isci_port *iport,
+                                     enum sci_port_states state)
+{
+       struct sci_base_state_machine *sm = &iport->sm;
+       enum sci_port_states old_state = sm->current_state_id;
+
+       if (is_port_ready_state(old_state) && !is_port_ready_state(state))
+               iport->ready_exit = true;
+
+       sci_change_state(sm, state);
+       iport->ready_exit = false;
+}
+
 /**
  * isci_port_hard_reset_complete() - This function is called by the sci core
  *    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,
        /* Save the status of the hard reset from the port. */
        isci_port->hard_reset_status = completion_status;
 
+       if (completion_status != SCI_SUCCESS) {
+
+               /* The reset failed.  The port state is now SCI_PORT_FAILED. */
+               if (isci_port->active_phy_mask == 0) {
+
+                       /* Generate the link down now to the host, since it
+                        * was intercepted by the hard reset state machine when
+                        * it really happened.
+                        */
+                       isci_port_link_down(isci_port->isci_host,
+                                           &isci_port->isci_host->phys[
+                                                  isci_port->last_active_phy],
+                                           isci_port);
+               }
+               /* Advance the port state so that link state changes will be
+               * noticed.
+               */
+               port_state_machine_change(isci_port, SCI_PORT_SUB_WAITING);
+
+       }
        complete_all(&isci_port->hard_reset_complete);
 }
 
@@ -657,6 +669,8 @@ void sci_port_deactivate_phy(struct isci_port *iport, struct isci_phy *iphy,
        struct isci_host *ihost = iport->owning_controller;
 
        iport->active_phy_mask &= ~(1 << iphy->phy_index);
+       if (!iport->active_phy_mask)
+               iport->last_active_phy = iphy->phy_index;
 
        iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
 
@@ -683,33 +697,6 @@ static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *i
        }
 }
 
-static bool is_port_ready_state(enum sci_port_states state)
-{
-       switch (state) {
-       case SCI_PORT_READY:
-       case SCI_PORT_SUB_WAITING:
-       case SCI_PORT_SUB_OPERATIONAL:
-       case SCI_PORT_SUB_CONFIGURING:
-               return true;
-       default:
-               return false;
-       }
-}
-
-/* flag dummy rnc hanling when exiting a ready state */
-static void port_state_machine_change(struct isci_port *iport,
-                                     enum sci_port_states state)
-{
-       struct sci_base_state_machine *sm = &iport->sm;
-       enum sci_port_states old_state = sm->current_state_id;
-
-       if (is_port_ready_state(old_state) && !is_port_ready_state(state))
-               iport->ready_exit = true;
-
-       sci_change_state(sm, state);
-       iport->ready_exit = false;
-}
-
 /**
  * sci_port_general_link_up_handler - phy can be assigned to port?
  * @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,
        iport->logical_port_index  = SCIC_SDS_DUMMY_PORT;
        iport->physical_port_index = index;
        iport->active_phy_mask     = 0;
-       iport->ready_exit             = false;
+       iport->last_active_phy     = 0;
+       iport->ready_exit          = false;
 
        iport->owning_controller = ihost;
 
@@ -1648,7 +1636,6 @@ void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
        init_completion(&iport->start_complete);
        iport->isci_host = ihost;
        isci_port_change_state(iport, isci_freed);
-       atomic_set(&iport->event, 0);
 }
 
 /**
@@ -1676,7 +1663,7 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 {
        unsigned long flags;
        enum sci_status status;
-       int idx, ret = TMF_RESP_FUNC_COMPLETE;
+       int ret = TMF_RESP_FUNC_COMPLETE;
 
        dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
                __func__, iport);
@@ -1697,8 +1684,13 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
                        "%s: iport = %p; hard reset completion\n",
                        __func__, iport);
 
-               if (iport->hard_reset_status != SCI_SUCCESS)
+               if (iport->hard_reset_status != SCI_SUCCESS) {
                        ret = TMF_RESP_FUNC_FAILED;
+
+                       dev_err(&ihost->pdev->dev,
+                               "%s: iport = %p; hard reset failed (0x%x)\n",
+                               __func__, iport, iport->hard_reset_status);
+               }
        } else {
                ret = TMF_RESP_FUNC_FAILED;
 
@@ -1718,18 +1710,6 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
                        "%s: iport = %p; hard reset failed "
                        "(0x%x) - driving explicit link fail for all phys\n",
                        __func__, iport, iport->hard_reset_status);
-
-               /* Down all phys in the port. */
-               spin_lock_irqsave(&ihost->scic_lock, flags);
-               for (idx = 0; idx < SCI_MAX_PHYS; ++idx) {
-                       struct isci_phy *iphy = iport->phy_table[idx];
-
-                       if (!iphy)
-                               continue;
-                       sci_phy_stop(iphy);
-                       sci_phy_start(iphy);
-               }
-               spin_unlock_irqrestore(&ihost->scic_lock, flags);
        }
        return ret;
 }
index b50ecd4e8f9ce2c8588e6acbb8f8573c1005a5a7..cb5ffbc386038136812da1e596ca5059ff391615 100644 (file)
@@ -77,7 +77,6 @@ enum isci_status {
 
 /**
  * struct isci_port - isci direct attached sas port object
- * @event: counts bcns and port stop events (for bcn filtering)
  * @ready_exit: several states constitute 'ready'. When exiting ready we
  *              need to take extra port-teardown actions that are
  *              skipped when exiting to another 'ready' state.
@@ -92,10 +91,6 @@ enum isci_status {
  */
 struct isci_port {
        enum isci_status status;
-       #define IPORT_BCN_BLOCKED 0
-       #define IPORT_BCN_PENDING 1
-       unsigned long flags;
-       atomic_t event;
        struct isci_host *isci_host;
        struct asd_sas_port sas_port;
        struct list_head remote_dev_list;
@@ -109,6 +104,7 @@ struct isci_port {
        u8 logical_port_index;
        u8 physical_port_index;
        u8 active_phy_mask;
+       u8 last_active_phy;
        u16 reserved_rni;
        u16 reserved_tag;
        u32 started_request_count;
index dc007e692f4e038135e62e03048fad63707c0576..2c75248ca326ea38e3a9256da8e966fddd516d41 100644 (file)
@@ -112,7 +112,7 @@ struct sci_user_parameters {
         * This field specifies the maximum number of direct attached devices
         * that can have power supplied to them simultaneously.
         */
-       u8 max_number_concurrent_device_spin_up;
+       u8 max_concurr_spinup;
 
        /**
         * This field specifies the number of seconds to allow a phy to consume
@@ -219,7 +219,7 @@ struct sci_bios_oem_param_block_hdr {
 struct sci_oem_params {
        struct {
                uint8_t mode_type;
-               uint8_t max_concurrent_dev_spin_up;
+               uint8_t max_concurr_spin_up;
                uint8_t do_enable_ssc;
                uint8_t reserved;
        } controller;
index fbf9ce28c3f5f92774e0ec1465ad4688e4c8b7d8..b207cd3b15a0514da4579e9e869556d6b95dc961 100644 (file)
@@ -1438,88 +1438,3 @@ int isci_remote_device_found(struct domain_device *domain_dev)
 
        return status == SCI_SUCCESS ? 0 : -ENODEV;
 }
-/**
- * isci_device_is_reset_pending() - This function will check if there is any
- *    pending reset condition on the device.
- * @request: This parameter is the isci_device object.
- *
- * true if there is a reset pending for the device.
- */
-bool isci_device_is_reset_pending(
-       struct isci_host *isci_host,
-       struct isci_remote_device *isci_device)
-{
-       struct isci_request *isci_request;
-       struct isci_request *tmp_req;
-       bool reset_is_pending = false;
-       unsigned long flags;
-
-       dev_dbg(&isci_host->pdev->dev,
-               "%s: isci_device = %p\n", __func__, isci_device);
-
-       spin_lock_irqsave(&isci_host->scic_lock, flags);
-
-       /* Check for reset on all pending requests. */
-       list_for_each_entry_safe(isci_request, tmp_req,
-                                &isci_device->reqs_in_process, dev_node) {
-               dev_dbg(&isci_host->pdev->dev,
-                       "%s: isci_device = %p request = %p\n",
-                       __func__, isci_device, isci_request);
-
-               if (isci_request->ttype == io_task) {
-                       struct sas_task *task = isci_request_access_task(
-                               isci_request);
-
-                       spin_lock(&task->task_state_lock);
-                       if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
-                               reset_is_pending = true;
-                       spin_unlock(&task->task_state_lock);
-               }
-       }
-
-       spin_unlock_irqrestore(&isci_host->scic_lock, flags);
-
-       dev_dbg(&isci_host->pdev->dev,
-               "%s: isci_device = %p reset_is_pending = %d\n",
-               __func__, isci_device, reset_is_pending);
-
-       return reset_is_pending;
-}
-
-/**
- * isci_device_clear_reset_pending() - This function will clear if any pending
- *    reset condition flags on the device.
- * @request: This parameter is the isci_device object.
- *
- * true if there is a reset pending for the device.
- */
-void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev)
-{
-       struct isci_request *isci_request;
-       struct isci_request *tmp_req;
-       unsigned long flags = 0;
-
-       dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n",
-                __func__, idev, ihost);
-
-       spin_lock_irqsave(&ihost->scic_lock, flags);
-
-       /* Clear reset pending on all pending requests. */
-       list_for_each_entry_safe(isci_request, tmp_req,
-                                &idev->reqs_in_process, dev_node) {
-               dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n",
-                        __func__, idev, isci_request);
-
-               if (isci_request->ttype == io_task) {
-
-                       unsigned long flags2;
-                       struct sas_task *task = isci_request_access_task(
-                               isci_request);
-
-                       spin_lock_irqsave(&task->task_state_lock, flags2);
-                       task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
-                       spin_unlock_irqrestore(&task->task_state_lock, flags2);
-               }
-       }
-       spin_unlock_irqrestore(&ihost->scic_lock, flags);
-}
index e1747ea0d0ea13ae42713a2d18ed0c1ea07574f3..483ee50152f3694dc18a27b5a3fdfc76169961ea 100644 (file)
@@ -132,10 +132,7 @@ void isci_remote_device_nuke_requests(struct isci_host *ihost,
                                      struct isci_remote_device *idev);
 void isci_remote_device_gone(struct domain_device *domain_dev);
 int isci_remote_device_found(struct domain_device *domain_dev);
-bool isci_device_is_reset_pending(struct isci_host *ihost,
-                                 struct isci_remote_device *idev);
-void isci_device_clear_reset_pending(struct isci_host *ihost,
-                                    struct isci_remote_device *idev);
+
 /**
  * sci_remote_device_stop() - This method will stop both transmission and
  *    reception of link activity for the supplied remote device.  This method
index 565a9f0a9bc2d176ea669f68a9cedcef703fd911..192cb48d849ac6429673d9529505bac2608d87d2 100644 (file)
@@ -191,7 +191,7 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
 
        task_iu->task_func = isci_tmf->tmf_code;
        task_iu->task_tag =
-               (ireq->ttype == tmf_task) ?
+               (test_bit(IREQ_TMF, &ireq->flags)) ?
                isci_tmf->io_tag :
                SCI_CONTROLLER_INVALID_IO_TAG;
 }
@@ -516,7 +516,7 @@ sci_io_request_construct_sata(struct isci_request *ireq,
        struct domain_device *dev = ireq->target_device->domain_dev;
 
        /* check for management protocols */
-       if (ireq->ttype == tmf_task) {
+       if (test_bit(IREQ_TMF, &ireq->flags)) {
                struct isci_tmf *tmf = isci_request_access_tmf(ireq);
 
                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)
        enum sci_status status = SCI_SUCCESS;
 
        /* check for management protocols */
-       if (ireq->ttype == tmf_task) {
+       if (test_bit(IREQ_TMF, &ireq->flags)) {
                struct isci_tmf *tmf = isci_request_access_tmf(ireq);
 
                if (tmf->tmf_code == isci_tmf_sata_srst_high ||
@@ -2630,14 +2630,8 @@ static void isci_task_save_for_upper_layer_completion(
        switch (task_notification_selection) {
 
        case isci_perform_normal_io_completion:
-
                /* Normal notification (task_done) */
-               dev_dbg(&host->pdev->dev,
-                       "%s: Normal - task = %p, response=%d (%d), status=%d (%d)\n",
-                       __func__,
-                       task,
-                       task->task_status.resp, response,
-                       task->task_status.stat, status);
+
                /* Add to the completed list. */
                list_add(&request->completed_node,
                         &host->requests_to_complete);
@@ -2650,13 +2644,6 @@ static void isci_task_save_for_upper_layer_completion(
                /* No notification to libsas because this request is
                 * already in the abort path.
                 */
-               dev_dbg(&host->pdev->dev,
-                        "%s: Aborted - task = %p, response=%d (%d), status=%d (%d)\n",
-                        __func__,
-                        task,
-                        task->task_status.resp, response,
-                        task->task_status.stat, status);
-
                /* Wake up whatever process was waiting for this
                 * request to complete.
                 */
@@ -2673,30 +2660,22 @@ static void isci_task_save_for_upper_layer_completion(
 
        case isci_perform_error_io_completion:
                /* Use sas_task_abort */
-               dev_dbg(&host->pdev->dev,
-                        "%s: Error - task = %p, response=%d (%d), status=%d (%d)\n",
-                        __func__,
-                        task,
-                        task->task_status.resp, response,
-                        task->task_status.stat, status);
                /* Add to the aborted list. */
                list_add(&request->completed_node,
                         &host->requests_to_errorback);
                break;
 
        default:
-               dev_dbg(&host->pdev->dev,
-                        "%s: Unknown - task = %p, response=%d (%d), status=%d (%d)\n",
-                        __func__,
-                        task,
-                        task->task_status.resp, response,
-                        task->task_status.stat, status);
-
                /* Add to the error to libsas list. */
                list_add(&request->completed_node,
                         &host->requests_to_errorback);
                break;
        }
+       dev_dbg(&host->pdev->dev,
+               "%s: %d - task = %p, response=%d (%d), status=%d (%d)\n",
+               __func__, task_notification_selection, task,
+               (task) ? task->task_status.resp : 0, response,
+               (task) ? task->task_status.stat : 0, status);
 }
 
 static 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,
        struct sas_task *task = isci_request_access_task(request);
        struct ssp_response_iu *resp_iu;
        unsigned long task_flags;
-       struct isci_remote_device *idev = isci_lookup_device(task->dev);
-       enum service_response response       = SAS_TASK_UNDELIVERED;
-       enum exec_status status         = SAS_ABORTED_TASK;
+       struct isci_remote_device *idev = request->target_device;
+       enum service_response response = SAS_TASK_UNDELIVERED;
+       enum exec_status status = SAS_ABORTED_TASK;
        enum isci_request_status request_status;
        enum isci_completion_selection complete_to_host
                = isci_perform_normal_io_completion;
@@ -3061,7 +3040,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
 
        /* complete the io request to the core. */
        sci_controller_complete_io(ihost, request->target_device, request);
-       isci_put_device(idev);
 
        /* set terminated handle so it cannot be completed or
         * 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)
        /* XXX as hch said always creating an internal sas_task for tmf
         * requests would simplify the driver
         */
-       task = ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL;
+       task = (test_bit(IREQ_TMF, &ireq->flags)) ? NULL : isci_request_access_task(ireq);
 
        /* all unaccelerated request types (non ssp or ncq) handled with
         * substates
@@ -3564,7 +3542,7 @@ static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost,
 
        ireq = isci_request_from_tag(ihost, tag);
        ireq->ttype_ptr.io_task_ptr = task;
-       ireq->ttype = io_task;
+       clear_bit(IREQ_TMF, &ireq->flags);
        task->lldd_task = ireq;
 
        return ireq;
@@ -3578,7 +3556,7 @@ struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
 
        ireq = isci_request_from_tag(ihost, tag);
        ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
-       ireq->ttype = tmf_task;
+       set_bit(IREQ_TMF, &ireq->flags);
 
        return ireq;
 }
index f720b97b7bb5c9982afda972af51aab1f9be4b25..be38933dd6dff5a2362a2f9074a7b9491f542354 100644 (file)
@@ -77,11 +77,6 @@ enum isci_request_status {
        dead        = 0x07
 };
 
-enum task_type {
-       io_task  = 0,
-       tmf_task = 1
-};
-
 enum sci_request_protocol {
        SCIC_NO_PROTOCOL,
        SCIC_SMP_PROTOCOL,
@@ -116,7 +111,6 @@ struct isci_request {
        #define IREQ_ACTIVE 3
        unsigned long flags;
        /* XXX kill ttype and ttype_ptr, allocate full sas_task */
-       enum task_type ttype;
        union ttype_ptr_union {
                struct sas_task *io_task_ptr;   /* When ttype==io_task  */
                struct isci_tmf *tmf_task_ptr;  /* When ttype==tmf_task */
index e2d9418683ce66ce45f2522eff72556287064464..66ad3dc89498a3ab305de95bc179ecaf42afa2f3 100644 (file)
@@ -212,16 +212,27 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
                                        task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
                                        spin_unlock_irqrestore(&task->task_state_lock, flags);
 
-                                       /* Indicate QUEUE_FULL so that the scsi
-                                       * midlayer retries. if the request
-                                       * failed for remote device reasons,
-                                       * it gets returned as
-                                       * SAS_TASK_UNDELIVERED next time
-                                       * through.
-                                       */
-                                       isci_task_refuse(ihost, task,
-                                                        SAS_TASK_COMPLETE,
-                                                        SAS_QUEUE_FULL);
+                                       if (test_bit(IDEV_GONE, &idev->flags)) {
+
+                                               /* Indicate that the device
+                                                * is gone.
+                                                */
+                                               isci_task_refuse(ihost, task,
+                                                       SAS_TASK_UNDELIVERED,
+                                                       SAS_DEVICE_UNKNOWN);
+                                       } else {
+                                               /* Indicate QUEUE_FULL so that
+                                                * the scsi midlayer retries.
+                                                * If the request failed for
+                                                * remote device reasons, it
+                                                * gets returned as
+                                                * SAS_TASK_UNDELIVERED next
+                                                * time through.
+                                                */
+                                               isci_task_refuse(ihost, task,
+                                                       SAS_TASK_COMPLETE,
+                                                       SAS_QUEUE_FULL);
+                                       }
                                }
                        }
                }
@@ -243,7 +254,7 @@ static enum sci_status isci_sata_management_task_request_build(struct isci_reque
        struct isci_tmf *isci_tmf;
        enum sci_status status;
 
-       if (tmf_task != ireq->ttype)
+       if (!test_bit(IREQ_TMF, &ireq->flags))
                return SCI_FAILURE;
 
        isci_tmf = isci_request_access_tmf(ireq);
@@ -327,6 +338,60 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
        return ireq;
 }
 
+/**
+* isci_request_mark_zombie() - This function must be called with scic_lock held.
+*/
+static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq)
+{
+       struct completion *tmf_completion = NULL;
+       struct completion *req_completion;
+
+       /* Set the request state to "dead". */
+       ireq->status = dead;
+
+       req_completion = ireq->io_request_completion;
+       ireq->io_request_completion = NULL;
+
+       if (test_bit(IREQ_TMF, &ireq->flags)) {
+               /* Break links with the TMF request. */
+               struct isci_tmf *tmf = isci_request_access_tmf(ireq);
+
+               /* In the case where a task request is dying,
+                * the thread waiting on the complete will sit and
+                * timeout unless we wake it now.  Since the TMF
+                * has a default error status, complete it here
+                * to wake the waiting thread.
+                */
+               if (tmf) {
+                       tmf_completion = tmf->complete;
+                       tmf->complete = NULL;
+               }
+               ireq->ttype_ptr.tmf_task_ptr = NULL;
+               dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n",
+                       __func__, tmf->tmf_code, tmf->io_tag);
+       } else {
+               /* Break links with the sas_task - the callback is done
+                * elsewhere.
+                */
+               struct sas_task *task = isci_request_access_task(ireq);
+
+               if (task)
+                       task->lldd_task = NULL;
+
+               ireq->ttype_ptr.io_task_ptr = NULL;
+       }
+
+       dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n",
+                ireq->io_tag);
+
+       /* Don't force waiting threads to timeout. */
+       if (req_completion)
+               complete(req_completion);
+
+       if (tmf_completion != NULL)
+               complete(tmf_completion);
+}
+
 static int isci_task_execute_tmf(struct isci_host *ihost,
                                 struct isci_remote_device *idev,
                                 struct isci_tmf *tmf, unsigned long timeout_ms)
@@ -364,6 +429,7 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
 
        /* Assign the pointer to the TMF's completion kernel wait structure. */
        tmf->complete = &completion;
+       tmf->status = SCI_FAILURE_TIMEOUT;
 
        ireq = isci_task_request_build(ihost, idev, tag, tmf);
        if (!ireq)
@@ -399,18 +465,35 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
                                               msecs_to_jiffies(timeout_ms));
 
        if (timeleft == 0) {
+               /* The TMF did not complete - this could be because
+                * of an unplug.  Terminate the TMF request now.
+                */
                spin_lock_irqsave(&ihost->scic_lock, flags);
 
                if (tmf->cb_state_func != NULL)
-                       tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data);
+                       tmf->cb_state_func(isci_tmf_timed_out, tmf,
+                                          tmf->cb_data);
 
-               sci_controller_terminate_request(ihost,
-                                                 idev,
-                                                 ireq);
+               sci_controller_terminate_request(ihost, idev, ireq);
 
                spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
-               wait_for_completion(tmf->complete);
+               timeleft = wait_for_completion_timeout(
+                       &completion,
+                       msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
+
+               if (!timeleft) {
+                       /* Strange condition - the termination of the TMF
+                        * request timed-out.
+                        */
+                       spin_lock_irqsave(&ihost->scic_lock, flags);
+
+                       /* If the TMF status has not changed, kill it. */
+                       if (tmf->status == SCI_FAILURE_TIMEOUT)
+                               isci_request_mark_zombie(ihost, ireq);
+
+                       spin_unlock_irqrestore(&ihost->scic_lock, flags);
+               }
        }
 
        isci_print_tmf(tmf);
@@ -501,48 +584,17 @@ static enum isci_request_status isci_task_validate_request_to_abort(
        return old_state;
 }
 
-/**
-* isci_request_cleanup_completed_loiterer() - This function will take care of
-*    the final cleanup on any request which has been explicitly terminated.
-* @isci_host: This parameter specifies the ISCI host object
-* @isci_device: This is the device to which the request is pending.
-* @isci_request: This parameter specifies the terminated request object.
-* @task: This parameter is the libsas I/O request.
-*/
-static void isci_request_cleanup_completed_loiterer(
-       struct isci_host          *isci_host,
-       struct isci_remote_device *isci_device,
-       struct isci_request       *isci_request,
-       struct sas_task           *task)
+static int isci_request_is_dealloc_managed(enum isci_request_status stat)
 {
-       unsigned long flags;
-
-       dev_dbg(&isci_host->pdev->dev,
-               "%s: isci_device=%p, request=%p, task=%p\n",
-               __func__, isci_device, isci_request, task);
-
-       if (task != NULL) {
-
-               spin_lock_irqsave(&task->task_state_lock, flags);
-               task->lldd_task = NULL;
-
-               task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
-
-               isci_set_task_doneflags(task);
-
-               /* If this task is not in the abort path, call task_done. */
-               if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
-
-                       spin_unlock_irqrestore(&task->task_state_lock, flags);
-                       task->task_done(task);
-               } else
-                       spin_unlock_irqrestore(&task->task_state_lock, flags);
-       }
-
-       if (isci_request != NULL) {
-               spin_lock_irqsave(&isci_host->scic_lock, flags);
-               list_del_init(&isci_request->dev_node);
-               spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+       switch (stat) {
+       case aborted:
+       case aborting:
+       case terminating:
+       case completed:
+       case dead:
+               return true;
+       default:
+               return false;
        }
 }
 
@@ -563,11 +615,9 @@ static void isci_terminate_request_core(struct isci_host *ihost,
        enum sci_status status      = SCI_SUCCESS;
        bool was_terminated         = false;
        bool needs_cleanup_handling = false;
-       enum isci_request_status request_status;
        unsigned long     flags;
        unsigned long     termination_completed = 1;
        struct completion *io_request_completion;
-       struct sas_task   *task;
 
        dev_dbg(&ihost->pdev->dev,
                "%s: device = %p; request = %p\n",
@@ -577,10 +627,6 @@ static void isci_terminate_request_core(struct isci_host *ihost,
 
        io_request_completion = isci_request->io_request_completion;
 
-       task = (isci_request->ttype == io_task)
-               ? isci_request_access_task(isci_request)
-               : NULL;
-
        /* Note that we are not going to control
         * the target to abort the request.
         */
@@ -619,42 +665,27 @@ static void isci_terminate_request_core(struct isci_host *ihost,
                                __func__, isci_request, io_request_completion);
 
                        /* Wait here for the request to complete. */
-                       #define TERMINATION_TIMEOUT_MSEC 500
                        termination_completed
                                = wait_for_completion_timeout(
                                   io_request_completion,
-                                  msecs_to_jiffies(TERMINATION_TIMEOUT_MSEC));
+                                  msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
 
                        if (!termination_completed) {
 
                                /* The request to terminate has timed out.  */
-                               spin_lock_irqsave(&ihost->scic_lock,
-                                                 flags);
+                               spin_lock_irqsave(&ihost->scic_lock, flags);
 
                                /* Check for state changes. */
-                               if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) {
+                               if (!test_bit(IREQ_TERMINATED,
+                                             &isci_request->flags)) {
 
                                        /* The best we can do is to have the
                                         * request die a silent death if it
                                         * ever really completes.
-                                        *
-                                        * Set the request state to "dead",
-                                        * and clear the task pointer so that
-                                        * an actual completion event callback
-                                        * doesn't do anything.
                                         */
-                                       isci_request->status = dead;
-                                       isci_request->io_request_completion
-                                               = NULL;
-
-                                       if (isci_request->ttype == io_task) {
-
-                                               /* Break links with the
-                                               * sas_task.
-                                               */
-                                               isci_request->ttype_ptr.io_task_ptr
-                                                       = NULL;
-                                       }
+                                       isci_request_mark_zombie(ihost,
+                                                                isci_request);
+                                       needs_cleanup_handling = true;
                                } else
                                        termination_completed = 1;
 
@@ -691,29 +722,28 @@ static void isci_terminate_request_core(struct isci_host *ihost,
                         * needs to be detached and freed here.
                         */
                        spin_lock_irqsave(&isci_request->state_lock, flags);
-                       request_status = isci_request->status;
-
-                       if ((isci_request->ttype == io_task) /* TMFs are in their own thread */
-                           && ((request_status == aborted)
-                               || (request_status == aborting)
-                               || (request_status == terminating)
-                               || (request_status == completed)
-                               || (request_status == dead)
-                               )
-                           ) {
-
-                               /* The completion routine won't free a request in
-                                * the aborted/aborting/etc. states, so we do
-                                * it here.
-                                */
-                               needs_cleanup_handling = true;
-                       }
+
+                       needs_cleanup_handling
+                               = isci_request_is_dealloc_managed(
+                                       isci_request->status);
+
                        spin_unlock_irqrestore(&isci_request->state_lock, flags);
 
                }
-               if (needs_cleanup_handling)
-                       isci_request_cleanup_completed_loiterer(
-                               ihost, idev, isci_request, task);
+               if (needs_cleanup_handling) {
+
+                       dev_dbg(&ihost->pdev->dev,
+                               "%s: cleanup isci_device=%p, request=%p\n",
+                               __func__, idev, isci_request);
+
+                       if (isci_request != NULL) {
+                               spin_lock_irqsave(&ihost->scic_lock, flags);
+                               isci_free_tag(ihost, isci_request->io_tag);
+                               isci_request_change_state(isci_request, unallocated);
+                               list_del_init(&isci_request->dev_node);
+                               spin_unlock_irqrestore(&ihost->scic_lock, flags);
+                       }
+               }
        }
 }
 
@@ -772,7 +802,9 @@ void isci_terminate_pending_requests(struct isci_host *ihost,
                dev_dbg(&ihost->pdev->dev,
                         "%s: idev=%p request=%p; task=%p old_state=%d\n",
                         __func__, idev, ireq,
-                       ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL,
+                       (!test_bit(IREQ_TMF, &ireq->flags)
+                               ? isci_request_access_task(ireq)
+                               : NULL),
                        old_state);
 
                /* If the old_state is started:
@@ -889,22 +921,14 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
                "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
                 __func__, domain_device, isci_host, isci_device);
 
-       if (isci_device)
-               set_bit(IDEV_EH, &isci_device->flags);
+       if (!isci_device) {
+               /* If the device is gone, stop the escalations. */
+               dev_dbg(&isci_host->pdev->dev, "%s: No dev\n", __func__);
 
-       /* If there is a device reset pending on any request in the
-        * device's list, fail this LUN reset request in order to
-        * escalate to the device reset.
-        */
-       if (!isci_device ||
-           isci_device_is_reset_pending(isci_host, isci_device)) {
-               dev_dbg(&isci_host->pdev->dev,
-                        "%s: No dev (%p), or "
-                        "RESET PENDING: domain_device=%p\n",
-                        __func__, isci_device, domain_device);
-               ret = TMF_RESP_FUNC_FAILED;
+               ret = TMF_RESP_FUNC_COMPLETE;
                goto out;
        }
+       set_bit(IDEV_EH, &isci_device->flags);
 
        /* Send the task management part of the reset. */
        if (sas_protocol_ata(domain_device->tproto)) {
@@ -1013,7 +1037,7 @@ int isci_task_abort_task(struct sas_task *task)
        struct isci_tmf           tmf;
        int                       ret = TMF_RESP_FUNC_FAILED;
        unsigned long             flags;
-       bool                      any_dev_reset = false;
+       int                       perform_termination = 0;
 
        /* Get the isci_request reference from the task.  Note that
         * this check does not depend on the pending request list
@@ -1035,89 +1059,34 @@ int isci_task_abort_task(struct sas_task *task)
        spin_unlock_irqrestore(&isci_host->scic_lock, flags);
 
        dev_dbg(&isci_host->pdev->dev,
-               "%s: task = %p\n", __func__, task);
-
-       if (!isci_device || !old_request)
-               goto out;
-
-       set_bit(IDEV_EH, &isci_device->flags);
-
-       /* This version of the driver will fail abort requests for
-        * SATA/STP.  Failing the abort request this way will cause the
-        * SCSI error handler thread to escalate to LUN reset
-        */
-       if (sas_protocol_ata(task->task_proto)) {
-               dev_dbg(&isci_host->pdev->dev,
-                           " task %p is for a STP/SATA device;"
-                           " returning TMF_RESP_FUNC_FAILED\n"
-                           " to cause a LUN reset...\n", task);
-               goto out;
-       }
+               "%s: dev = %p, task = %p, old_request == %p\n",
+               __func__, isci_device, task, old_request);
 
-       dev_dbg(&isci_host->pdev->dev,
-               "%s: old_request == %p\n", __func__, old_request);
-
-       any_dev_reset = isci_device_is_reset_pending(isci_host, isci_device);
-
-       spin_lock_irqsave(&task->task_state_lock, flags);
-
-       any_dev_reset = any_dev_reset || (task->task_state_flags & SAS_TASK_NEED_DEV_RESET);
+       if (isci_device)
+               set_bit(IDEV_EH, &isci_device->flags);
 
-       /* If the extraction of the request reference from the task
-        * failed, then the request has been completed (or if there is a
-        * pending reset then this abort request function must be failed
-        * in order to escalate to the target reset).
+       /* Device reset conditions signalled in task_state_flags are the
+        * responsbility of libsas to observe at the start of the error
+        * handler thread.
         */
-       if ((old_request == NULL) || any_dev_reset) {
-
-               /* If the device reset task flag is set, fail the task
-                * management request.  Otherwise, the original request
-                * has completed.
-                */
-               if (any_dev_reset) {
-
-                       /* Turn off the task's DONE to make sure this
-                        * task is escalated to a target reset.
-                        */
-                       task->task_state_flags &= ~SAS_TASK_STATE_DONE;
-
-                       /* Make the reset happen as soon as possible. */
-                       task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
-
-                       spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-                       /* Fail the task management request in order to
-                        * escalate to the target reset.
-                        */
-                       ret = TMF_RESP_FUNC_FAILED;
-
-                       dev_dbg(&isci_host->pdev->dev,
-                               "%s: Failing task abort in order to "
-                               "escalate to target reset because\n"
-                               "SAS_TASK_NEED_DEV_RESET is set for "
-                               "task %p on dev %p\n",
-                               __func__, task, isci_device);
-
-
-               } else {
-                       /* The request has already completed and there
-                        * is nothing to do here other than to set the task
-                        * done bit, and indicate that the task abort function
-                        * was sucessful.
-                        */
-                       isci_set_task_doneflags(task);
-
-                       spin_unlock_irqrestore(&task->task_state_lock, flags);
+       if (!isci_device || !old_request) {
+               /* The request has already completed and there
+               * is nothing to do here other than to set the task
+               * done bit, and indicate that the task abort function
+               * was sucessful.
+               */
+               spin_lock_irqsave(&task->task_state_lock, flags);
+               task->task_state_flags |= SAS_TASK_STATE_DONE;
+               task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
+                                           SAS_TASK_STATE_PENDING);
+               spin_unlock_irqrestore(&task->task_state_lock, flags);
 
-                       ret = TMF_RESP_FUNC_COMPLETE;
+               ret = TMF_RESP_FUNC_COMPLETE;
 
-                       dev_dbg(&isci_host->pdev->dev,
-                               "%s: abort task not needed for %p\n",
-                               __func__, task);
-               }
+               dev_dbg(&isci_host->pdev->dev,
+                       "%s: abort task not needed for %p\n",
+                       __func__, task);
                goto out;
-       } else {
-               spin_unlock_irqrestore(&task->task_state_lock, flags);
        }
 
        spin_lock_irqsave(&isci_host->scic_lock, flags);
@@ -1146,24 +1115,44 @@ int isci_task_abort_task(struct sas_task *task)
                goto out;
        }
        if (task->task_proto == SAS_PROTOCOL_SMP ||
+           sas_protocol_ata(task->task_proto) ||
            test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) {
 
                spin_unlock_irqrestore(&isci_host->scic_lock, flags);
 
                dev_dbg(&isci_host->pdev->dev,
-                       "%s: SMP request (%d)"
+                       "%s: %s request"
                        " or complete_in_target (%d), thus no TMF\n",
-                       __func__, (task->task_proto == SAS_PROTOCOL_SMP),
+                       __func__,
+                       ((task->task_proto == SAS_PROTOCOL_SMP)
+                               ? "SMP"
+                               : (sas_protocol_ata(task->task_proto)
+                                       ? "SATA/STP"
+                                       : "<other>")
+                        ),
                        test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags));
 
-               /* Set the state on the task. */
-               isci_task_all_done(task);
-
-               ret = TMF_RESP_FUNC_COMPLETE;
+               if (test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) {
+                       spin_lock_irqsave(&task->task_state_lock, flags);
+                       task->task_state_flags |= SAS_TASK_STATE_DONE;
+                       task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
+                                                   SAS_TASK_STATE_PENDING);
+                       spin_unlock_irqrestore(&task->task_state_lock, flags);
+                       ret = TMF_RESP_FUNC_COMPLETE;
+               } else {
+                       spin_lock_irqsave(&task->task_state_lock, flags);
+                       task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
+                                                   SAS_TASK_STATE_PENDING);
+                       spin_unlock_irqrestore(&task->task_state_lock, flags);
+               }
 
-               /* Stopping and SMP devices are not sent a TMF, and are not
-                * reset, but the outstanding I/O request is terminated below.
+               /* STP and SMP devices are not sent a TMF, but the
+                * outstanding I/O request is terminated below.  This is
+                * because SATA/STP and SMP discovery path timeouts directly
+                * call the abort task interface for cleanup.
                 */
+               perform_termination = 1;
+
        } else {
                /* Fill in the tmf stucture */
                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)
 
                spin_unlock_irqrestore(&isci_host->scic_lock, flags);
 
-               #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* half second timeout. */
+               #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */
                ret = isci_task_execute_tmf(isci_host, isci_device, &tmf,
                                            ISCI_ABORT_TASK_TIMEOUT_MS);
 
-               if (ret != TMF_RESP_FUNC_COMPLETE)
+               if (ret == TMF_RESP_FUNC_COMPLETE)
+                       perform_termination = 1;
+               else
                        dev_dbg(&isci_host->pdev->dev,
-                               "%s: isci_task_send_tmf failed\n",
-                               __func__);
+                               "%s: isci_task_send_tmf failed\n", __func__);
        }
-       if (ret == TMF_RESP_FUNC_COMPLETE) {
+       if (perform_termination) {
                set_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags);
 
                /* Clean up the request on our side, and wait for the aborted
                 * I/O to complete.
                 */
-               isci_terminate_request_core(isci_host, isci_device, old_request);
+               isci_terminate_request_core(isci_host, isci_device,
+                                           old_request);
        }
 
        /* Make sure we do not leave a reference to aborted_io_completion */
@@ -1288,7 +1279,8 @@ isci_task_request_complete(struct isci_host *ihost,
                           enum sci_task_status completion_status)
 {
        struct isci_tmf *tmf = isci_request_access_tmf(ireq);
-       struct completion *tmf_complete;
+       struct completion *tmf_complete = NULL;
+       struct completion *request_complete = ireq->io_request_completion;
 
        dev_dbg(&ihost->pdev->dev,
                "%s: request = %p, status=%d\n",
@@ -1296,255 +1288,53 @@ isci_task_request_complete(struct isci_host *ihost,
 
        isci_request_change_state(ireq, completed);
 
-       tmf->status = completion_status;
        set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);
 
-       if (tmf->proto == SAS_PROTOCOL_SSP) {
-               memcpy(&tmf->resp.resp_iu,
-                      &ireq->ssp.rsp,
-                      SSP_RESP_IU_MAX_SIZE);
-       } else if (tmf->proto == SAS_PROTOCOL_SATA) {
-               memcpy(&tmf->resp.d2h_fis,
-                      &ireq->stp.rsp,
-                      sizeof(struct dev_to_host_fis));
+       if (tmf) {
+               tmf->status = completion_status;
+
+               if (tmf->proto == SAS_PROTOCOL_SSP) {
+                       memcpy(&tmf->resp.resp_iu,
+                              &ireq->ssp.rsp,
+                              SSP_RESP_IU_MAX_SIZE);
+               } else if (tmf->proto == SAS_PROTOCOL_SATA) {
+                       memcpy(&tmf->resp.d2h_fis,
+                              &ireq->stp.rsp,
+                              sizeof(struct dev_to_host_fis));
+               }
+               /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
+               tmf_complete = tmf->complete;
        }
-
-       /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
-       tmf_complete = tmf->complete;
-
        sci_controller_complete_io(ihost, ireq->target_device, ireq);
        /* set the 'terminated' flag handle to make sure it cannot be terminated
         *  or completed again.
         */
        set_bit(IREQ_TERMINATED, &ireq->flags);
 
-       isci_request_change_state(ireq, unallocated);
-       list_del_init(&ireq->dev_node);
-
-       /* The task management part completes last. */
-       complete(tmf_complete);
-}
-
-static void isci_smp_task_timedout(unsigned long _task)
-{
-       struct sas_task *task = (void *) _task;
-       unsigned long flags;
-
-       spin_lock_irqsave(&task->task_state_lock, flags);
-       if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
-               task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-       spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-       complete(&task->completion);
-}
-
-static void isci_smp_task_done(struct sas_task *task)
-{
-       if (!del_timer(&task->timer))
-               return;
-       complete(&task->completion);
-}
-
-static int isci_smp_execute_task(struct isci_host *ihost,
-                                struct domain_device *dev, void *req,
-                                int req_size, void *resp, int resp_size)
-{
-       int res, retry;
-       struct sas_task *task = NULL;
-
-       for (retry = 0; retry < 3; retry++) {
-               task = sas_alloc_task(GFP_KERNEL);
-               if (!task)
-                       return -ENOMEM;
-
-               task->dev = dev;
-               task->task_proto = dev->tproto;
-               sg_init_one(&task->smp_task.smp_req, req, req_size);
-               sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
-
-               task->task_done = isci_smp_task_done;
-
-               task->timer.data = (unsigned long) task;
-               task->timer.function = isci_smp_task_timedout;
-               task->timer.expires = jiffies + 10*HZ;
-               add_timer(&task->timer);
-
-               res = isci_task_execute_task(task, 1, GFP_KERNEL);
-
-               if (res) {
-                       del_timer(&task->timer);
-                       dev_dbg(&ihost->pdev->dev,
-                               "%s: executing SMP task failed:%d\n",
-                               __func__, res);
-                       goto ex_err;
-               }
-
-               wait_for_completion(&task->completion);
-               res = -ECOMM;
-               if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
-                       dev_dbg(&ihost->pdev->dev,
-                               "%s: smp task timed out or aborted\n",
-                               __func__);
-                       isci_task_abort_task(task);
-                       if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
-                               dev_dbg(&ihost->pdev->dev,
-                                       "%s: SMP task aborted and not done\n",
-                                       __func__);
-                               goto ex_err;
-                       }
-               }
-               if (task->task_status.resp == SAS_TASK_COMPLETE &&
-                   task->task_status.stat == SAM_STAT_GOOD) {
-                       res = 0;
-                       break;
-               }
-               if (task->task_status.resp == SAS_TASK_COMPLETE &&
-                     task->task_status.stat == SAS_DATA_UNDERRUN) {
-                       /* no error, but return the number of bytes of
-                       * underrun */
-                       res = task->task_status.residual;
-                       break;
-               }
-               if (task->task_status.resp == SAS_TASK_COMPLETE &&
-                     task->task_status.stat == SAS_DATA_OVERRUN) {
-                       res = -EMSGSIZE;
-                       break;
-               } else {
-                       dev_dbg(&ihost->pdev->dev,
-                               "%s: task to dev %016llx response: 0x%x "
-                               "status 0x%x\n", __func__,
-                               SAS_ADDR(dev->sas_addr),
-                               task->task_status.resp,
-                               task->task_status.stat);
-                       sas_free_task(task);
-                       task = NULL;
-               }
-       }
-ex_err:
-       BUG_ON(retry == 3 && task != NULL);
-       sas_free_task(task);
-       return res;
-}
-
-#define DISCOVER_REQ_SIZE  16
-#define DISCOVER_RESP_SIZE 56
-
-int isci_smp_get_phy_attached_dev_type(struct isci_host *ihost,
-                                      struct domain_device *dev,
-                                      int phy_id, int *adt)
-{
-       struct smp_resp *disc_resp;
-       u8 *disc_req;
-       int res;
-
-       disc_resp = kzalloc(DISCOVER_RESP_SIZE, GFP_KERNEL);
-       if (!disc_resp)
-               return -ENOMEM;
-
-       disc_req = kzalloc(DISCOVER_REQ_SIZE, GFP_KERNEL);
-       if (disc_req) {
-               disc_req[0] = SMP_REQUEST;
-               disc_req[1] = SMP_DISCOVER;
-               disc_req[9] = phy_id;
-       } else {
-               kfree(disc_resp);
-               return -ENOMEM;
-       }
-       res = isci_smp_execute_task(ihost, dev, disc_req, DISCOVER_REQ_SIZE,
-                                   disc_resp, DISCOVER_RESP_SIZE);
-       if (!res) {
-               if (disc_resp->result != SMP_RESP_FUNC_ACC)
-                       res = disc_resp->result;
-               else
-                       *adt = disc_resp->disc.attached_dev_type;
+       /* As soon as something is in the terminate path, deallocation is
+        * managed there.  Note that the final non-managed state of a task
+        * request is "completed".
+        */
+       if ((ireq->status == completed) ||
+           !isci_request_is_dealloc_managed(ireq->status)) {
+               isci_request_change_state(ireq, unallocated);
+               isci_free_tag(ihost, ireq->io_tag);
+               list_del_init(&ireq->dev_node);
        }
-       kfree(disc_req);
-       kfree(disc_resp);
-
-       return res;
-}
-
-static void isci_wait_for_smp_phy_reset(struct isci_remote_device *idev, int phy_num)
-{
-       struct domain_device *dev = idev->domain_dev;
-       struct isci_port *iport = idev->isci_port;
-       struct isci_host *ihost = iport->isci_host;
-       int res, iteration = 0, attached_device_type;
-       #define STP_WAIT_MSECS 25000
-       unsigned long tmo = msecs_to_jiffies(STP_WAIT_MSECS);
-       unsigned long deadline = jiffies + tmo;
-       enum {
-               SMP_PHYWAIT_PHYDOWN,
-               SMP_PHYWAIT_PHYUP,
-               SMP_PHYWAIT_DONE
-       } phy_state = SMP_PHYWAIT_PHYDOWN;
-
-       /* While there is time, wait for the phy to go away and come back */
-       while (time_is_after_jiffies(deadline) && phy_state != SMP_PHYWAIT_DONE) {
-               int event = atomic_read(&iport->event);
-
-               ++iteration;
-
-               tmo = wait_event_timeout(ihost->eventq,
-                                        event != atomic_read(&iport->event) ||
-                                        !test_bit(IPORT_BCN_BLOCKED, &iport->flags),
-                                        tmo);
-               /* link down, stop polling */
-               if (!test_bit(IPORT_BCN_BLOCKED, &iport->flags))
-                       break;
 
-               dev_dbg(&ihost->pdev->dev,
-                       "%s: iport %p, iteration %d,"
-                       " phase %d: time_remaining %lu, bcns = %d\n",
-                       __func__, iport, iteration, phy_state,
-                       tmo, test_bit(IPORT_BCN_PENDING, &iport->flags));
-
-               res = isci_smp_get_phy_attached_dev_type(ihost, dev, phy_num,
-                                                        &attached_device_type);
-               tmo = deadline - jiffies;
-
-               if (res) {
-                       dev_dbg(&ihost->pdev->dev,
-                                "%s: iteration %d, phase %d:"
-                                " SMP error=%d, time_remaining=%lu\n",
-                                __func__, iteration, phy_state, res, tmo);
-                       break;
-               }
-               dev_dbg(&ihost->pdev->dev,
-                       "%s: iport %p, iteration %d,"
-                       " phase %d: time_remaining %lu, bcns = %d, "
-                       "attdevtype = %x\n",
-                       __func__, iport, iteration, phy_state,
-                       tmo, test_bit(IPORT_BCN_PENDING, &iport->flags),
-                       attached_device_type);
-
-               switch (phy_state) {
-               case SMP_PHYWAIT_PHYDOWN:
-                       /* Has the device gone away? */
-                       if (!attached_device_type)
-                               phy_state = SMP_PHYWAIT_PHYUP;
-
-                       break;
-
-               case SMP_PHYWAIT_PHYUP:
-                       /* Has the device come back? */
-                       if (attached_device_type)
-                               phy_state = SMP_PHYWAIT_DONE;
-                       break;
-
-               case SMP_PHYWAIT_DONE:
-                       break;
-               }
+       /* "request_complete" is set if the task was being terminated. */
+       if (request_complete)
+               complete(request_complete);
 
-       }
-       dev_dbg(&ihost->pdev->dev, "%s: done\n",  __func__);
+       /* The task management part completes last. */
+       if (tmf_complete)
+               complete(tmf_complete);
 }
 
 static int isci_reset_device(struct isci_host *ihost,
                             struct isci_remote_device *idev)
 {
        struct sas_phy *phy = sas_find_local_phy(idev->domain_dev);
-       struct isci_port *iport = idev->isci_port;
        enum sci_status status;
        unsigned long flags;
        int rc;
@@ -1564,13 +1354,6 @@ static int isci_reset_device(struct isci_host *ihost,
        }
        spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
-       /* Make sure all pending requests are able to be fully terminated. */
-       isci_device_clear_reset_pending(ihost, idev);
-
-       /* If this is a device on an expander, disable BCN processing. */
-       if (!scsi_is_sas_phy_local(phy))
-               set_bit(IPORT_BCN_BLOCKED, &iport->flags);
-
        rc = sas_phy_reset(phy, true);
 
        /* Terminate in-progress I/O now. */
@@ -1581,21 +1364,6 @@ static int isci_reset_device(struct isci_host *ihost,
        status = sci_remote_device_reset_complete(idev);
        spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
-       /* If this is a device on an expander, bring the phy back up. */
-       if (!scsi_is_sas_phy_local(phy)) {
-               /* A phy reset will cause the device to go away then reappear.
-                * Since libsas will take action on incoming BCNs (eg. remove
-                * a device going through an SMP phy-control driven reset),
-                * we need to wait until the phy comes back up before letting
-                * discovery proceed in libsas.
-                */
-               isci_wait_for_smp_phy_reset(idev, phy->number);
-
-               spin_lock_irqsave(&ihost->scic_lock, flags);
-               isci_port_bcn_enable(ihost, idev->isci_port);
-               spin_unlock_irqrestore(&ihost->scic_lock, flags);
-       }
-
        if (status != SCI_SUCCESS) {
                dev_dbg(&ihost->pdev->dev,
                         "%s: sci_remote_device_reset_complete(%p) "
index 15b18d1589936dcdeef39a8a336f055aa549dd16..bc78c0a41d5cac86df69d6a23af08e6dac949552 100644 (file)
@@ -58,6 +58,8 @@
 #include <scsi/sas_ata.h>
 #include "host.h"
 
+#define ISCI_TERMINATION_TIMEOUT_MSEC 500
+
 struct isci_request;
 
 /**
@@ -224,35 +226,6 @@ enum isci_completion_selection {
        isci_perform_error_io_completion        /* Use sas_task_abort */
 };
 
-static inline void isci_set_task_doneflags(
-       struct sas_task *task)
-{
-       /* Since no futher action will be taken on this task,
-        * make sure to mark it complete from the lldd perspective.
-        */
-       task->task_state_flags |= SAS_TASK_STATE_DONE;
-       task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
-       task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
-}
-/**
- * isci_task_all_done() - This function clears the task bits to indicate the
- *    LLDD is done with the task.
- *
- *
- */
-static inline void isci_task_all_done(
-       struct sas_task *task)
-{
-       unsigned long flags;
-
-       /* Since no futher action will be taken on this task,
-        * make sure to mark it complete from the lldd perspective.
-        */
-       spin_lock_irqsave(&task->task_state_lock, flags);
-       isci_set_task_doneflags(task);
-       spin_unlock_irqrestore(&task->task_state_lock, flags);
-}
-
 /**
  * isci_task_set_completion_status() - This function sets the completion status
  *    for the request.
@@ -334,7 +307,9 @@ isci_task_set_completion_status(
                /* Fall through to the normal case... */
        case isci_perform_normal_io_completion:
                /* Normal notification (task_done) */
-               isci_set_task_doneflags(task);
+               task->task_state_flags |= SAS_TASK_STATE_DONE;
+               task->task_state_flags &= ~(SAS_TASK_AT_INITIATOR |
+                                           SAS_TASK_STATE_PENDING);
                break;
        default:
                WARN_ONCE(1, "unknown task_notification_selection: %d\n",
index 23e706673d066117cbcf673d8f495987a69754b5..7c34d8e7cc7552f3c8e30a23279d1a78923f7e2b 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
+#include <linux/module.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
index b9cb8140b398220c384820029dc5cac3efdae393..7269e928824a07f93efb1e570eb136f6cbedfbeb 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include <scsi/fc/fc_gs.h>
index 9b25969e2ad02f86e712582ddf3b52c6b25188d1..fb9161dc4ca67411f07413018562286fcaeff017 100644 (file)
@@ -21,6 +21,7 @@
  * Provide interface to send ELS/CT FC frames
  */
 
+#include <linux/export.h>
 #include <asm/unaligned.h>
 #include <scsi/fc/fc_gs.h>
 #include <scsi/fc/fc_ns.h>
index 7c055fdca45de91ae3c2682ab217e34ee32f4f54..9de9db27e87401b1f5cf244a15e9320011faa276 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/export.h>
 
 #include <scsi/fc/fc_fc2.h>
 
@@ -469,6 +470,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
        struct fc_frame_header *fh = fc_frame_header_get(fp);
        int error;
        u32 f_ctl;
+       u8 fh_type = fh->fh_type;
 
        ep = fc_seq_exch(sp);
        WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT);
@@ -493,7 +495,7 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
         */
        error = lport->tt.frame_send(lport, fp);
 
-       if (fh->fh_type == FC_TYPE_BLS)
+       if (fh_type == FC_TYPE_BLS)
                return error;
 
        /*
@@ -1792,6 +1794,9 @@ restart:
                        goto restart;
                }
        }
+       pool->next_index = 0;
+       pool->left = FC_XID_UNKNOWN;
+       pool->right = FC_XID_UNKNOWN;
        spin_unlock_bh(&pool->lock);
 }
 
@@ -2280,6 +2285,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport,
                goto free_mempool;
        for_each_possible_cpu(cpu) {
                pool = per_cpu_ptr(mp->pool, cpu);
+               pool->next_index = 0;
                pool->left = FC_XID_UNKNOWN;
                pool->right = FC_XID_UNKNOWN;
                spin_lock_init(&pool->lock);
index b7735129f1f36ed3b90eff3c3db900659fd42c84..1bf9841ef154c6cc5fb3322cfa097689fe84fd8a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 #include <linux/scatterlist.h>
 #include <linux/crc32.h>
+#include <linux/module.h>
 
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
index 628f347404f9b355e1fbe14bd58fdae3f0d7171d..e77094a587ed62aa17e1c1479d6a1ba04ad2af06 100644 (file)
@@ -89,6 +89,7 @@
 
 #include <linux/timer.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 
@@ -1030,16 +1031,8 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
                           FCH_EVT_LIPRESET, 0);
        fc_vports_linkchange(lport);
        fc_lport_reset_locked(lport);
-       if (lport->link_up) {
-               /*
-                * Wait upto resource allocation time out before
-                * doing re-login since incomplete FIP exchanged
-                * from last session may collide with exchanges
-                * in new session.
-                */
-               msleep(lport->r_a_tov);
+       if (lport->link_up)
                fc_lport_enter_flogi(lport);
-       }
 }
 
 /**
@@ -1481,6 +1474,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
                         void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
+       struct fc_frame_header *fh;
        struct fc_els_flogi *flp;
        u32 did;
        u16 csp_flags;
@@ -1508,49 +1502,56 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
                goto err;
        }
 
+       fh = fc_frame_header_get(fp);
        did = fc_frame_did(fp);
-       if (fc_frame_payload_op(fp) == ELS_LS_ACC && did) {
-               flp = fc_frame_payload_get(fp, sizeof(*flp));
-               if (flp) {
-                       mfs = ntohs(flp->fl_csp.sp_bb_data) &
-                               FC_SP_BB_DATA_MASK;
-                       if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
-                           mfs < lport->mfs)
-                               lport->mfs = mfs;
-                       csp_flags = ntohs(flp->fl_csp.sp_features);
-                       r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
-                       e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
-                       if (csp_flags & FC_SP_FT_EDTR)
-                               e_d_tov /= 1000000;
-
-                       lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
-
-                       if ((csp_flags & FC_SP_FT_FPORT) == 0) {
-                               if (e_d_tov > lport->e_d_tov)
-                                       lport->e_d_tov = e_d_tov;
-                               lport->r_a_tov = 2 * e_d_tov;
-                               fc_lport_set_port_id(lport, did, fp);
-                               printk(KERN_INFO "host%d: libfc: "
-                                      "Port (%6.6x) entered "
-                                      "point-to-point mode\n",
-                                      lport->host->host_no, did);
-                               fc_lport_ptp_setup(lport, fc_frame_sid(fp),
-                                                  get_unaligned_be64(
-                                                          &flp->fl_wwpn),
-                                                  get_unaligned_be64(
-                                                          &flp->fl_wwnn));
-                       } else {
-                               lport->e_d_tov = e_d_tov;
-                               lport->r_a_tov = r_a_tov;
-                               fc_host_fabric_name(lport->host) =
-                                       get_unaligned_be64(&flp->fl_wwnn);
-                               fc_lport_set_port_id(lport, did, fp);
-                               fc_lport_enter_dns(lport);
-                       }
-               }
-       } else {
-               FC_LPORT_DBG(lport, "FLOGI RJT or bad response\n");
+       if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
+           fc_frame_payload_op(fp) != ELS_LS_ACC) {
+               FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
                fc_lport_error(lport, fp);
+               goto err;
+       }
+
+       flp = fc_frame_payload_get(fp, sizeof(*flp));
+       if (!flp) {
+               FC_LPORT_DBG(lport, "FLOGI bad response\n");
+               fc_lport_error(lport, fp);
+               goto err;
+       }
+
+       mfs = ntohs(flp->fl_csp.sp_bb_data) &
+               FC_SP_BB_DATA_MASK;
+       if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
+           mfs < lport->mfs)
+               lport->mfs = mfs;
+       csp_flags = ntohs(flp->fl_csp.sp_features);
+       r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
+       e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
+       if (csp_flags & FC_SP_FT_EDTR)
+               e_d_tov /= 1000000;
+
+       lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
+
+       if ((csp_flags & FC_SP_FT_FPORT) == 0) {
+               if (e_d_tov > lport->e_d_tov)
+                       lport->e_d_tov = e_d_tov;
+               lport->r_a_tov = 2 * e_d_tov;
+               fc_lport_set_port_id(lport, did, fp);
+               printk(KERN_INFO "host%d: libfc: "
+                      "Port (%6.6x) entered "
+                      "point-to-point mode\n",
+                      lport->host->host_no, did);
+               fc_lport_ptp_setup(lport, fc_frame_sid(fp),
+                                  get_unaligned_be64(
+                                          &flp->fl_wwpn),
+                                  get_unaligned_be64(
+                                          &flp->fl_wwnn));
+       } else {
+               lport->e_d_tov = e_d_tov;
+               lport->r_a_tov = r_a_tov;
+               fc_host_fabric_name(lport->host) =
+                       get_unaligned_be64(&flp->fl_wwnn);
+               fc_lport_set_port_id(lport, did, fp);
+               fc_lport_enter_dns(lport);
        }
 
 out:
index f33b897e4784153da1e829cc2733306aab485528..9fbf78ed821b3ceeb36a941e5fddd3142d0300cf 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <scsi/libfc.h>
+#include <linux/export.h>
 
 /**
  * fc_vport_create() - Create a new NPIV vport instance
index 760db7619446f6bc86fedfcd1a7511c62c262057..b9e434844a69bb93fe12e153896973a1c8df2968 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/rcupdate.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include <scsi/libfc.h>
index d7c76f2eb6368eac8f6b1d0e50f51fe6f087e53c..143bbe448bec6b7e4a22f52eeb3c718c64815473 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
index 09b232fd9a1bb6c59764ac35f64e7838b5469c4c..5715a3d0a3d3e7db2b8a1b4c4de6ac983c4f6f48 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
+#include <linux/module.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
index e1aa17840c5bf2e0a2d41784114c3f41cdd5aeb1..bb8f49269a68dfc307ca178e1effd95fd72ef3ee 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/scatterlist.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "sas_internal.h"
 
index b2c4a773165699e8a46544c1aeb522a1d8e318e1..b6e233d9a0a15f98bb7a8760fbe5ab0102b6ebaf 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kthread.h>
 #include <linux/firmware.h>
+#include <linux/export.h>
 #include <linux/ctype.h>
 
 #include "sas_internal.h"
index b13a3346894cb1348dcf03ce183edee6ef8464fc..a78e5bd3e514592a7986b91d5b1efd224e073194 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <scsi/sas.h>
 #include <scsi/libsas.h>
 
index ff6a28ce9b6900f647145120830cb7de96b439b7..0707ecdbaa32d271b923caa9cea38da9b13a1881 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_tcq.h>
index 4b0333ee2d948be0eaabcb225cd9c4ed0115e51c..d0ebaeb7ef60e96857c18999a6048a39247126e2 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/aer.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
index 2cd844f7058f0ec20745485fc14f71afd33ee670..28382596fb9a929545ae6bb9e4984b5d385aa274 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
 #include <linux/interrupt.h>
index 907c94b9245dc0989ae6184506a449543e4ccef0..55bc4fc7376f5a753f08e2d8aa44b3846cc377e6 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
index 5b8790b3cf4bba7a2791da9acdd68ed8f7c7cbaa..2e1e54e5c3ae89514ef1de659fe8963237ee41c9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <asm/unaligned.h>
 
index 6c42dff0f4d30d77e68dbfc445e961bfb55a786a..e6173376605d4d9f52bb01727f6d078f3da26ab9 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/stat.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
index 8883ca36f932826e76a5e6995ac5dab7494a6f4d..35bd13879fed613de539b0719e2191da7956cedd 100644 (file)
@@ -71,6 +71,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "megaraid_mbox.h"
 
 static int megaraid_init(void);
index 3105d5e8d9082c675e3b040d8c9bffd8565deb93..8dc1b32918dd6d064027fd32159859864bc96e87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000-2010 LSI Corporation.
+ *  Copyright (c) 2000-2011 LSI Corporation.
  *
  *
  *           Name:  mpi2.h
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.18
+ *  mpi2.h Version:  02.00.20
  *
  *  Version History
  *  ---------------
@@ -66,6 +66,9 @@
  *  08-11-10  02.00.17  Bumped MPI2_HEADER_VERSION_UNIT.
  *  11-10-10  02.00.18  Bumped MPI2_HEADER_VERSION_UNIT.
  *                      Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define.
+ *  02-23-11  02.00.19  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                      Added MPI2_FUNCTION_SEND_HOST_MESSAGE.
+ *  03-09-11  02.00.20  Bumped MPI2_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
@@ -91,7 +94,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x12)
+#define MPI2_HEADER_VERSION_UNIT            (0x14)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -515,6 +518,8 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
 #define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION   (0x2F)
 /* Power Management Control */
 #define MPI2_FUNCTION_PWR_MGMT_CONTROL              (0x30)
+/* Send Host Message */
+#define MPI2_FUNCTION_SEND_HOST_MESSAGE             (0x31)
 /* beginning of product-specific range */
 #define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC          (0xF0)
 /* end of product-specific range */
index 61475a6480e3299d0922e6b6faabc93d71374938..cfd95b4e3004705da33d9e27c4ac9b1d899a034a 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2010 LSI Corporation.
+ *  Copyright (c) 2000-2011 LSI Corporation.
  *
  *
  *           Name:  mpi2_cnfg.h
  *          Title:  MPI Configuration messages and pages
  *  Creation Date:  November 10, 2006
  *
- *    mpi2_cnfg.h Version:  02.00.17
+ *    mpi2_cnfg.h Version:  02.00.19
  *
  *  Version History
  *  ---------------
  *                      to MPI2_CONFIG_PAGE_IO_UNIT_7.
  *                      Added MPI2_CONFIG_EXTPAGETYPE_EXT_MANUFACTURING define
  *                      and MPI2_CONFIG_PAGE_EXT_MAN_PS structure.
+ *  02-23-11  02.00.18  Added ProxyVF_ID field to MPI2_CONFIG_REQUEST.
+ *                      Added IO Unit Page 8, IO Unit Page 9,
+ *                      and IO Unit Page 10.
+ *                      Added SASNotifyPrimitiveMasks field to
+ *                      MPI2_CONFIG_PAGE_IOC_7.
+ *  03-09-11  02.00.19  Fixed IO Unit Page 10 (to match the spec).
  *  --------------------------------------------------------------------------
  */
 
@@ -329,7 +335,9 @@ typedef struct _MPI2_CONFIG_REQUEST
     U8                      VP_ID;                      /* 0x08 */
     U8                      VF_ID;                      /* 0x09 */
     U16                     Reserved1;                  /* 0x0A */
-    U32                     Reserved2;                  /* 0x0C */
+       U8                      Reserved2;                  /* 0x0C */
+       U8                      ProxyVF_ID;                 /* 0x0D */
+       U16                     Reserved4;                  /* 0x0E */
     U32                     Reserved3;                  /* 0x10 */
     MPI2_CONFIG_PAGE_HEADER Header;                     /* 0x14 */
     U32                     PageAddress;                /* 0x18 */
@@ -915,6 +923,120 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
 #define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT      (0x01)
 #define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS         (0x02)
 
+/* IO Unit Page 8 */
+
+#define MPI2_IOUNIT8_NUM_THRESHOLDS     (4)
+
+typedef struct _MPI2_IOUNIT8_SENSOR {
+       U16                     Flags;                /* 0x00 */
+       U16                     Reserved1;            /* 0x02 */
+       U16
+               Threshold[MPI2_IOUNIT8_NUM_THRESHOLDS]; /* 0x04 */
+       U32                     Reserved2;            /* 0x0C */
+       U32                     Reserved3;            /* 0x10 */
+       U32                     Reserved4;            /* 0x14 */
+} MPI2_IOUNIT8_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT8_SENSOR,
+Mpi2IOUnit8Sensor_t, MPI2_POINTER pMpi2IOUnit8Sensor_t;
+
+/* defines for IO Unit Page 8 Sensor Flags field */
+#define MPI2_IOUNIT8_SENSOR_FLAGS_T3_ENABLE         (0x0008)
+#define MPI2_IOUNIT8_SENSOR_FLAGS_T2_ENABLE         (0x0004)
+#define MPI2_IOUNIT8_SENSOR_FLAGS_T1_ENABLE         (0x0002)
+#define MPI2_IOUNIT8_SENSOR_FLAGS_T0_ENABLE         (0x0001)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check the value returned for NumSensors at runtime.
+ */
+#ifndef MPI2_IOUNITPAGE8_SENSOR_ENTRIES
+#define MPI2_IOUNITPAGE8_SENSOR_ENTRIES     (1)
+#endif
+
+typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_8 {
+       MPI2_CONFIG_PAGE_HEADER Header;               /* 0x00 */
+       U32                     Reserved1;            /* 0x04 */
+       U32                     Reserved2;            /* 0x08 */
+       U8                      NumSensors;           /* 0x0C */
+       U8                      PollingInterval;      /* 0x0D */
+       U16                     Reserved3;            /* 0x0E */
+       MPI2_IOUNIT8_SENSOR
+                       Sensor[MPI2_IOUNITPAGE8_SENSOR_ENTRIES];/* 0x10 */
+} MPI2_CONFIG_PAGE_IO_UNIT_8, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_8,
+Mpi2IOUnitPage8_t, MPI2_POINTER pMpi2IOUnitPage8_t;
+
+#define MPI2_IOUNITPAGE8_PAGEVERSION                    (0x00)
+
+
+/* IO Unit Page 9 */
+
+typedef struct _MPI2_IOUNIT9_SENSOR {
+       U16                     CurrentTemperature;     /* 0x00 */
+       U16                     Reserved1;              /* 0x02 */
+       U8                      Flags;                  /* 0x04 */
+       U8                      Reserved2;              /* 0x05 */
+       U16                     Reserved3;              /* 0x06 */
+       U32                     Reserved4;              /* 0x08 */
+       U32                     Reserved5;              /* 0x0C */
+} MPI2_IOUNIT9_SENSOR, MPI2_POINTER PTR_MPI2_IOUNIT9_SENSOR,
+Mpi2IOUnit9Sensor_t, MPI2_POINTER pMpi2IOUnit9Sensor_t;
+
+/* defines for IO Unit Page 9 Sensor Flags field */
+#define MPI2_IOUNIT9_SENSOR_FLAGS_TEMP_VALID        (0x01)
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check the value returned for NumSensors at runtime.
+ */
+#ifndef MPI2_IOUNITPAGE9_SENSOR_ENTRIES
+#define MPI2_IOUNITPAGE9_SENSOR_ENTRIES     (1)
+#endif
+
+typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_9 {
+       MPI2_CONFIG_PAGE_HEADER Header;                /* 0x00 */
+       U32                     Reserved1;             /* 0x04 */
+       U32                     Reserved2;             /* 0x08 */
+       U8                      NumSensors;            /* 0x0C */
+       U8                      Reserved4;             /* 0x0D */
+       U16                     Reserved3;             /* 0x0E */
+       MPI2_IOUNIT9_SENSOR
+                       Sensor[MPI2_IOUNITPAGE9_SENSOR_ENTRIES];/* 0x10 */
+} MPI2_CONFIG_PAGE_IO_UNIT_9, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_9,
+Mpi2IOUnitPage9_t, MPI2_POINTER pMpi2IOUnitPage9_t;
+
+#define MPI2_IOUNITPAGE9_PAGEVERSION                    (0x00)
+
+
+/* IO Unit Page 10 */
+
+typedef struct _MPI2_IOUNIT10_FUNCTION {
+       U8                      CreditPercent;      /* 0x00 */
+       U8                      Reserved1;          /* 0x01 */
+       U16                     Reserved2;          /* 0x02 */
+} MPI2_IOUNIT10_FUNCTION, MPI2_POINTER PTR_MPI2_IOUNIT10_FUNCTION,
+Mpi2IOUnit10Function_t, MPI2_POINTER pMpi2IOUnit10Function_t;
+
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check the value returned for NumFunctions at runtime.
+ */
+#ifndef MPI2_IOUNITPAGE10_FUNCTION_ENTRIES
+#define MPI2_IOUNITPAGE10_FUNCTION_ENTRIES      (1)
+#endif
+
+typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_10 {
+       MPI2_CONFIG_PAGE_HEADER Header;                    /* 0x00 */
+       U8                      NumFunctions;             /* 0x04 */
+       U8                      Reserved1;              /* 0x05 */
+       U16                     Reserved2;              /* 0x06 */
+       U32                     Reserved3;              /* 0x08 */
+       U32                     Reserved4;              /* 0x0C */
+       MPI2_IOUNIT10_FUNCTION
+               Function[MPI2_IOUNITPAGE10_FUNCTION_ENTRIES];/* 0x10 */
+} MPI2_CONFIG_PAGE_IO_UNIT_10, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_10,
+Mpi2IOUnitPage10_t, MPI2_POINTER pMpi2IOUnitPage10_t;
+
+#define MPI2_IOUNITPAGE10_PAGEVERSION                   (0x01)
+
 
 
 /****************************************************************************
@@ -1022,12 +1144,12 @@ typedef struct _MPI2_CONFIG_PAGE_IOC_7
     U32                     Reserved1;                  /* 0x04 */
     U32                     EventMasks[MPI2_IOCPAGE7_EVENTMASK_WORDS];/* 0x08 */
     U16                     SASBroadcastPrimitiveMasks; /* 0x18 */
-    U16                     Reserved2;                  /* 0x1A */
+       U16                     SASNotifyPrimitiveMasks;    /* 0x1A */
     U32                     Reserved3;                  /* 0x1C */
 } MPI2_CONFIG_PAGE_IOC_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IOC_7,
   Mpi2IOCPage7_t, MPI2_POINTER pMpi2IOCPage7_t;
 
-#define MPI2_IOCPAGE7_PAGEVERSION                       (0x01)
+#define MPI2_IOCPAGE7_PAGEVERSION                       (0x02)
 
 
 /* IOC Page 8 */
@@ -2070,16 +2192,16 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_8 {
 #define MPI2_SASIOUNITPAGE8_PAGEVERSION     (0x00)
 
 /* defines for PowerManagementCapabilities field */
-#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD          (0x000001000)
-#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE        (0x000000800)
-#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE        (0x000000400)
-#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE       (0x000000200)
-#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE       (0x000000100)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD        (0x000000010)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE      (0x000000008)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE      (0x000000004)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE     (0x000000002)
-#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE     (0x000000001)
+#define MPI2_SASIOUNIT8_PM_HOST_PORT_WIDTH_MOD          (0x00001000)
+#define MPI2_SASIOUNIT8_PM_HOST_SAS_SLUMBER_MODE        (0x00000800)
+#define MPI2_SASIOUNIT8_PM_HOST_SAS_PARTIAL_MODE        (0x00000400)
+#define MPI2_SASIOUNIT8_PM_HOST_SATA_SLUMBER_MODE       (0x00000200)
+#define MPI2_SASIOUNIT8_PM_HOST_SATA_PARTIAL_MODE       (0x00000100)
+#define MPI2_SASIOUNIT8_PM_IOUNIT_PORT_WIDTH_MOD        (0x00000010)
+#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_SLUMBER_MODE      (0x00000008)
+#define MPI2_SASIOUNIT8_PM_IOUNIT_SAS_PARTIAL_MODE      (0x00000004)
+#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_SLUMBER_MODE     (0x00000002)
+#define MPI2_SASIOUNIT8_PM_IOUNIT_SATA_PARTIAL_MODE     (0x00000001)
 
 
 
@@ -2266,6 +2388,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0
 /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */
 
 /* values for SAS Device Page 0 Flags field */
+#define MPI2_SAS_DEVICE0_FLAGS_UNAUTHORIZED_DEVICE          (0x8000)
 #define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE           (0x1000)
 #define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE           (0x0800)
 #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY     (0x0400)
index 1f0c190d336e8825ec31d57c6e99e7d754d95f1d..93d9b6956d052380e15453044f9a065a1c8842bd 100644 (file)
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2010 LSI Corporation.
+ *  Copyright (c) 2000-2011 LSI Corporation.
  *
  *
  *           Name:  mpi2_ioc.h
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  October 11, 2006
  *
- *  mpi2_ioc.h Version:  02.00.16
+ *  mpi2_ioc.h Version:  02.00.17
  *
  *  Version History
  *  ---------------
  *  05-12-10  02.00.15  Marked Task Set Full Event as obsolete.
  *                      Added MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY define.
  *  11-10-10  02.00.16  Added MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC.
+ *  02-23-11  02.00.17  Added SAS NOTIFY Primitive event, and added
+ *                      SASNotifyPrimitiveMasks field to
+ *                      MPI2_EVENT_NOTIFICATION_REQUEST.
+ *                      Added Temperature Threshold Event.
+ *                      Added Host Message Event.
+ *                      Added Send Host Message request and reply.
  *  --------------------------------------------------------------------------
  */
 
@@ -421,7 +427,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REQUEST
     U32                     Reserved6;                      /* 0x10 */
     U32                     EventMasks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];/* 0x14 */
     U16                     SASBroadcastPrimitiveMasks;     /* 0x24 */
-    U16                     Reserved7;                      /* 0x26 */
+        U16                     SASNotifyPrimitiveMasks;        /* 0x26 */
     U32                     Reserved8;                      /* 0x28 */
 } MPI2_EVENT_NOTIFICATION_REQUEST,
   MPI2_POINTER PTR_MPI2_EVENT_NOTIFICATION_REQUEST,
@@ -476,6 +482,9 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
 #define MPI2_EVENT_GPIO_INTERRUPT                   (0x0023)
 #define MPI2_EVENT_HOST_BASED_DISCOVERY_PHY         (0x0024)
 #define MPI2_EVENT_SAS_QUIESCE                      (0x0025)
+#define MPI2_EVENT_SAS_NOTIFY_PRIMITIVE             (0x0026)
+#define MPI2_EVENT_TEMP_THRESHOLD                   (0x0027)
+#define MPI2_EVENT_HOST_MESSAGE                     (0x0028)
 
 
 /* Log Entry Added Event data */
@@ -507,6 +516,39 @@ typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT {
   MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT,
   Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t;
 
+/* Temperature Threshold Event data */
+
+typedef struct _MPI2_EVENT_DATA_TEMPERATURE {
+       U16         Status;                             /* 0x00 */
+       U8          SensorNum;                          /* 0x02 */
+       U8          Reserved1;                          /* 0x03 */
+       U16         CurrentTemperature;                 /* 0x04 */
+       U16         Reserved2;                          /* 0x06 */
+       U32         Reserved3;                          /* 0x08 */
+       U32         Reserved4;                          /* 0x0C */
+} MPI2_EVENT_DATA_TEMPERATURE,
+MPI2_POINTER PTR_MPI2_EVENT_DATA_TEMPERATURE,
+Mpi2EventDataTemperature_t, MPI2_POINTER pMpi2EventDataTemperature_t;
+
+/* Temperature Threshold Event data Status bits */
+#define MPI2_EVENT_TEMPERATURE3_EXCEEDED            (0x0008)
+#define MPI2_EVENT_TEMPERATURE2_EXCEEDED            (0x0004)
+#define MPI2_EVENT_TEMPERATURE1_EXCEEDED            (0x0002)
+#define MPI2_EVENT_TEMPERATURE0_EXCEEDED            (0x0001)
+
+
+/* Host Message Event data */
+
+typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE {
+       U8          SourceVF_ID;                        /* 0x00 */
+       U8          Reserved1;                          /* 0x01 */
+       U16         Reserved2;                          /* 0x02 */
+       U32         Reserved3;                          /* 0x04 */
+       U32         HostData[1];                        /* 0x08 */
+} MPI2_EVENT_DATA_HOST_MESSAGE, MPI2_POINTER PTR_MPI2_EVENT_DATA_HOST_MESSAGE,
+Mpi2EventDataHostMessage_t, MPI2_POINTER pMpi2EventDataHostMessage_t;
+
+
 /* Hard Reset Received Event data */
 
 typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED
@@ -749,6 +791,24 @@ typedef struct _MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE
 #define MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED               (0x07)
 #define MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED               (0x08)
 
+/* SAS Notify Primitive Event data */
+
+typedef struct _MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE {
+       U8                      PhyNum;                     /* 0x00 */
+       U8                      Port;                       /* 0x01 */
+       U8                      Reserved1;                  /* 0x02 */
+       U8                      Primitive;                  /* 0x03 */
+} MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
+MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE,
+Mpi2EventDataSasNotifyPrimitive_t,
+MPI2_POINTER pMpi2EventDataSasNotifyPrimitive_t;
+
+/* defines for the Primitive field */
+#define MPI2_EVENT_NOTIFY_ENABLE_SPINUP                     (0x01)
+#define MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED               (0x02)
+#define MPI2_EVENT_NOTIFY_RESERVED1                         (0x03)
+#define MPI2_EVENT_NOTIFY_RESERVED2                         (0x04)
+
 
 /* SAS Initiator Device Status Change Event data */
 
@@ -1000,6 +1060,53 @@ typedef struct _MPI2_EVENT_ACK_REPLY
   Mpi2EventAckReply_t, MPI2_POINTER pMpi2EventAckReply_t;
 
 
+/****************************************************************************
+*  SendHostMessage message
+****************************************************************************/
+
+/* SendHostMessage Request message */
+typedef struct _MPI2_SEND_HOST_MESSAGE_REQUEST {
+       U16                     HostDataLength;                 /* 0x00 */
+       U8                      ChainOffset;                    /* 0x02 */
+       U8                      Function;                       /* 0x03 */
+       U16                     Reserved1;                      /* 0x04 */
+       U8                      Reserved2;                      /* 0x06 */
+       U8                      MsgFlags;                       /* 0x07 */
+       U8                      VP_ID;                          /* 0x08 */
+       U8                      VF_ID;                          /* 0x09 */
+       U16                     Reserved3;                      /* 0x0A */
+       U8                      Reserved4;                      /* 0x0C */
+       U8                      DestVF_ID;                      /* 0x0D */
+       U16                     Reserved5;                      /* 0x0E */
+       U32                     Reserved6;                      /* 0x10 */
+       U32                     Reserved7;                      /* 0x14 */
+       U32                     Reserved8;                      /* 0x18 */
+       U32                     Reserved9;                      /* 0x1C */
+       U32                     Reserved10;                     /* 0x20 */
+       U32                     HostData[1];                    /* 0x24 */
+} MPI2_SEND_HOST_MESSAGE_REQUEST,
+MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REQUEST,
+Mpi2SendHostMessageRequest_t, MPI2_POINTER pMpi2SendHostMessageRequest_t;
+
+
+/* SendHostMessage Reply message */
+typedef struct _MPI2_SEND_HOST_MESSAGE_REPLY {
+       U16                     HostDataLength;                 /* 0x00 */
+       U8                      MsgLength;                      /* 0x02 */
+       U8                      Function;                       /* 0x03 */
+       U16                     Reserved1;                      /* 0x04 */
+       U8                      Reserved2;                      /* 0x06 */
+       U8                      MsgFlags;                       /* 0x07 */
+       U8                      VP_ID;                          /* 0x08 */
+       U8                      VF_ID;                          /* 0x09 */
+       U16                     Reserved3;                      /* 0x0A */
+       U16                     Reserved4;                      /* 0x0C */
+       U16                     IOCStatus;                      /* 0x0E */
+       U32                     IOCLogInfo;                     /* 0x10 */
+} MPI2_SEND_HOST_MESSAGE_REPLY, MPI2_POINTER PTR_MPI2_SEND_HOST_MESSAGE_REPLY,
+Mpi2SendHostMessageReply_t, MPI2_POINTER pMpi2SendHostMessageReply_t;
+
+
 /****************************************************************************
 *  FWDownload message
 ****************************************************************************/
index 81209ca87274d9ff090f5d08ae0174c0e13c6d7c..beda04a8404b5b72579f90e7f870bb8b6aeb1a98 100644 (file)
@@ -81,6 +81,15 @@ static int missing_delay[2] = {-1, -1};
 module_param_array(missing_delay, int, NULL, 0);
 MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
 
+static int mpt2sas_fwfault_debug;
+MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
+       "and halt firmware - (default=0)");
+
+static int disable_discovery = -1;
+module_param(disable_discovery, int, 0);
+MODULE_PARM_DESC(disable_discovery, " disable discovery ");
+
+
 /* diag_buffer_enable is bitwise
  * bit 0 set = TRACE
  * bit 1 set = SNAPSHOT
@@ -93,14 +102,6 @@ module_param(diag_buffer_enable, int, 0);
 MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
     "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
 
-static int mpt2sas_fwfault_debug;
-MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
-    "and halt firmware - (default=0)");
-
-static int disable_discovery = -1;
-module_param(disable_discovery, int, 0);
-MODULE_PARM_DESC(disable_discovery, " disable discovery ");
-
 /**
  * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
  *
@@ -691,6 +692,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
                memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
        }
        ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
+
        complete(&ioc->base_cmds.done);
        return 1;
 }
@@ -3469,6 +3471,58 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
        return 0;
 }
 
+/**
+ * mpt2sas_port_enable_done - command completion routine for port enable
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @msix_index: MSIX table index supplied by the OS
+ * @reply: reply message frame(lower 32bit addr)
+ *
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
+ */
+u8
+mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
+       u32 reply)
+{
+       MPI2DefaultReply_t *mpi_reply;
+       u16 ioc_status;
+
+       mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
+       if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
+               return 1;
+
+       if (ioc->port_enable_cmds.status == MPT2_CMD_NOT_USED)
+               return 1;
+
+       ioc->port_enable_cmds.status |= MPT2_CMD_COMPLETE;
+       if (mpi_reply) {
+               ioc->port_enable_cmds.status |= MPT2_CMD_REPLY_VALID;
+               memcpy(ioc->port_enable_cmds.reply, mpi_reply,
+                   mpi_reply->MsgLength*4);
+       }
+       ioc->port_enable_cmds.status &= ~MPT2_CMD_PENDING;
+
+       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
+
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
+               ioc->port_enable_failed = 1;
+
+       if (ioc->is_driver_loading) {
+               if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+                       mpt2sas_port_enable_complete(ioc);
+                       return 1;
+               } else {
+                       ioc->start_scan_failed = ioc_status;
+                       ioc->start_scan = 0;
+                       return 1;
+               }
+       }
+       complete(&ioc->port_enable_cmds.done);
+       return 1;
+}
+
+
 /**
  * _base_send_port_enable - send port_enable(discovery stuff) to firmware
  * @ioc: per adapter object
@@ -3480,66 +3534,150 @@ static int
 _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
 {
        Mpi2PortEnableRequest_t *mpi_request;
-       u32 ioc_state;
+       Mpi2PortEnableReply_t *mpi_reply;
        unsigned long timeleft;
        int r = 0;
        u16 smid;
+       u16 ioc_status;
 
        printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
 
-       if (ioc->base_cmds.status & MPT2_CMD_PENDING) {
+       if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
                printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
                    ioc->name, __func__);
                return -EAGAIN;
        }
 
-       smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx);
+       smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
        if (!smid) {
                printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
                    ioc->name, __func__);
                return -EAGAIN;
        }
 
-       ioc->base_cmds.status = MPT2_CMD_PENDING;
+       ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
        mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
-       ioc->base_cmds.smid = smid;
+       ioc->port_enable_cmds.smid = smid;
        memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
        mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
-       mpi_request->VF_ID = 0; /* TODO */
-       mpi_request->VP_ID = 0;
 
+       init_completion(&ioc->port_enable_cmds.done);
        mpt2sas_base_put_smid_default(ioc, smid);
-       init_completion(&ioc->base_cmds.done);
-       timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
+       timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done,
            300*HZ);
-       if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
+       if (!(ioc->port_enable_cmds.status & MPT2_CMD_COMPLETE)) {
                printk(MPT2SAS_ERR_FMT "%s: timeout\n",
                    ioc->name, __func__);
                _debug_dump_mf(mpi_request,
                    sizeof(Mpi2PortEnableRequest_t)/4);
-               if (ioc->base_cmds.status & MPT2_CMD_RESET)
+               if (ioc->port_enable_cmds.status & MPT2_CMD_RESET)
                        r = -EFAULT;
                else
                        r = -ETIME;
                goto out;
-       } else
-               dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n",
-                   ioc->name, __func__));
+       }
+       mpi_reply = ioc->port_enable_cmds.reply;
 
-       ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL,
-           60, sleep_flag);
-       if (ioc_state) {
-               printk(MPT2SAS_ERR_FMT "%s: failed going to operational state "
-                   " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state);
+       ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK;
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+               printk(MPT2SAS_ERR_FMT "%s: failed with (ioc_status=0x%08x)\n",
+                   ioc->name, __func__, ioc_status);
                r = -EFAULT;
+               goto out;
        }
  out:
-       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
-       printk(MPT2SAS_INFO_FMT "port enable: %s\n",
-           ioc->name, ((r == 0) ? "SUCCESS" : "FAILED"));
+       ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
+       printk(MPT2SAS_INFO_FMT "port enable: %s\n", ioc->name, ((r == 0) ?
+           "SUCCESS" : "FAILED"));
        return r;
 }
 
+/**
+ * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply)
+ * @ioc: per adapter object
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+int
+mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc)
+{
+       Mpi2PortEnableRequest_t *mpi_request;
+       u16 smid;
+
+       printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name);
+
+       if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
+               printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n",
+                   ioc->name, __func__);
+               return -EAGAIN;
+       }
+
+       smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx);
+       if (!smid) {
+               printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
+                   ioc->name, __func__);
+               return -EAGAIN;
+       }
+
+       ioc->port_enable_cmds.status = MPT2_CMD_PENDING;
+       mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
+       ioc->port_enable_cmds.smid = smid;
+       memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
+       mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
+
+       mpt2sas_base_put_smid_default(ioc, smid);
+       return 0;
+}
+
+/**
+ * _base_determine_wait_on_discovery - desposition
+ * @ioc: per adapter object
+ *
+ * Decide whether to wait on discovery to complete. Used to either
+ * locate boot device, or report volumes ahead of physical devices.
+ *
+ * Returns 1 for wait, 0 for don't wait
+ */
+static int
+_base_determine_wait_on_discovery(struct MPT2SAS_ADAPTER *ioc)
+{
+       /* We wait for discovery to complete if IR firmware is loaded.
+        * The sas topology events arrive before PD events, so we need time to
+        * turn on the bit in ioc->pd_handles to indicate PD
+        * Also, it maybe required to report Volumes ahead of physical
+        * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set.
+        */
+       if (ioc->ir_firmware)
+               return 1;
+
+       /* if no Bios, then we don't need to wait */
+       if (!ioc->bios_pg3.BiosVersion)
+               return 0;
+
+       /* Bios is present, then we drop down here.
+        *
+        * If there any entries in the Bios Page 2, then we wait
+        * for discovery to complete.
+        */
+
+       /* Current Boot Device */
+       if ((ioc->bios_pg2.CurrentBootDeviceForm &
+           MPI2_BIOSPAGE2_FORM_MASK) ==
+           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
+       /* Request Boot Device */
+          (ioc->bios_pg2.ReqBootDeviceForm &
+           MPI2_BIOSPAGE2_FORM_MASK) ==
+           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED &&
+       /* Alternate Request Boot Device */
+          (ioc->bios_pg2.ReqAltBootDeviceForm &
+           MPI2_BIOSPAGE2_FORM_MASK) ==
+           MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED)
+               return 0;
+
+       return 1;
+}
+
+
 /**
  * _base_unmask_events - turn on notification for this event
  * @ioc: per adapter object
@@ -3962,6 +4100,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
  skip_init_reply_post_host_index:
 
        _base_unmask_interrupts(ioc);
+
        r = _base_event_notification(ioc, sleep_flag);
        if (r)
                return r;
@@ -3969,7 +4108,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
        if (sleep_flag == CAN_SLEEP)
                _base_static_config_pages(ioc);
 
-       if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) {
+
+       if (ioc->is_driver_loading) {
+
+
+
+               ioc->wait_for_discovery_to_complete =
+                   _base_determine_wait_on_discovery(ioc);
+               return r; /* scan_start and scan_finished support */
+       }
+
+
+       if (ioc->wait_for_discovery_to_complete && ioc->is_warpdrive) {
                if (ioc->manu_pg10.OEMIdentifier  == 0x80) {
                        hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
                            MFG_PAGE10_HIDE_SSDS_MASK);
@@ -3978,13 +4128,6 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
                }
        }
 
-       if (ioc->wait_for_port_enable_to_complete) {
-               if (diag_buffer_enable != 0)
-                       mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
-               if (disable_discovery > 0)
-                       return r;
-       }
-
        r = _base_send_port_enable(ioc, sleep_flag);
        if (r)
                return r;
@@ -4121,6 +4264,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
        ioc->base_cmds.status = MPT2_CMD_NOT_USED;
 
+       /* port_enable command bits */
+       ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
+       ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED;
+
        /* transport internal command bits */
        ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
        ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
@@ -4162,8 +4309,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
                goto out_free_resources;
        }
 
-       init_completion(&ioc->shost_recovery_done);
-
        for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
                ioc->event_masks[i] = -1;
 
@@ -4186,7 +4331,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
                _base_update_missing_delay(ioc, missing_delay[0],
                    missing_delay[1]);
 
-       mpt2sas_base_start_watchdog(ioc);
        return 0;
 
  out_free_resources:
@@ -4204,6 +4348,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        kfree(ioc->scsih_cmds.reply);
        kfree(ioc->config_cmds.reply);
        kfree(ioc->base_cmds.reply);
+       kfree(ioc->port_enable_cmds.reply);
        kfree(ioc->ctl_cmds.reply);
        kfree(ioc->ctl_cmds.sense);
        kfree(ioc->pfacts);
@@ -4243,6 +4388,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
        kfree(ioc->ctl_cmds.reply);
        kfree(ioc->ctl_cmds.sense);
        kfree(ioc->base_cmds.reply);
+       kfree(ioc->port_enable_cmds.reply);
        kfree(ioc->tm_cmds.reply);
        kfree(ioc->transport_cmds.reply);
        kfree(ioc->scsih_cmds.reply);
@@ -4284,6 +4430,20 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
                        mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid);
                        complete(&ioc->base_cmds.done);
                }
+               if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) {
+                       ioc->port_enable_failed = 1;
+                       ioc->port_enable_cmds.status |= MPT2_CMD_RESET;
+                       mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid);
+                       if (ioc->is_driver_loading) {
+                               ioc->start_scan_failed =
+                                   MPI2_IOCSTATUS_INTERNAL_ERROR;
+                               ioc->start_scan = 0;
+                               ioc->port_enable_cmds.status =
+                                               MPT2_CMD_NOT_USED;
+                       } else
+                               complete(&ioc->port_enable_cmds.done);
+
+               }
                if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
                        ioc->config_cmds.status |= MPT2_CMD_RESET;
                        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,
 {
        int r;
        unsigned long flags;
-       u8 pe_complete = ioc->wait_for_port_enable_to_complete;
 
        dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
@@ -4396,7 +4555,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
        /* If this hard reset is called while port enable is active, then
         * there is no reason to call make_ioc_operational
         */
-       if (pe_complete) {
+       if (ioc->is_driver_loading && ioc->port_enable_failed) {
+               ioc->remove_host = 1;
                r = -EFAULT;
                goto out;
        }
@@ -4410,7 +4570,6 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
        spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
        ioc->ioc_reset_in_progress_status = r;
        ioc->shost_recovery = 0;
-       complete(&ioc->shost_recovery_done);
        spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
        mutex_unlock(&ioc->reset_in_progress_mutex);
 
index 59354dba68c0c7619b532f619bfbb019d1e554bb..3c3babc7d260ef0eaeed4fd1ba18278d50ee47fe 100644 (file)
 #define MPT2SAS_DRIVER_NAME            "mpt2sas"
 #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION    "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION         "09.100.00.01"
-#define MPT2SAS_MAJOR_VERSION          09
+#define MPT2SAS_DRIVER_VERSION         "10.100.00.00"
+#define MPT2SAS_MAJOR_VERSION          10
 #define MPT2SAS_MINOR_VERSION          100
 #define MPT2SAS_BUILD_VERSION          00
-#define MPT2SAS_RELEASE_VERSION                01
+#define MPT2SAS_RELEASE_VERSION                00
 
 /*
  * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -655,7 +655,12 @@ enum mutex_type {
  * @ignore_loginfos: ignore loginfos during task management
  * @remove_host: flag for when driver unloads, to avoid sending dev resets
  * @pci_error_recovery: flag to prevent ioc access until slot reset completes
- * @wait_for_port_enable_to_complete:
+ * @wait_for_discovery_to_complete: flag set at driver load time when
+ *                                               waiting on reporting devices
+ * @is_driver_loading: flag set at driver load time
+ * @port_enable_failed: flag set when port enable has failed
+ * @start_scan: flag set from scan_start callback, cleared from _mpt2sas_fw_work
+ * @start_scan_failed: means port enable failed, return's the ioc_status
  * @msix_enable: flag indicating msix is enabled
  * @msix_vector_count: number msix vectors
  * @cpu_msix_table: table for mapping cpus to msix index
@@ -790,15 +795,20 @@ struct MPT2SAS_ADAPTER {
        u8              shost_recovery;
 
        struct mutex    reset_in_progress_mutex;
-       struct completion       shost_recovery_done;
        spinlock_t      ioc_reset_in_progress_lock;
        u8              ioc_link_reset_in_progress;
-       int             ioc_reset_in_progress_status;
+       u8              ioc_reset_in_progress_status;
 
        u8              ignore_loginfos;
        u8              remove_host;
        u8              pci_error_recovery;
-       u8              wait_for_port_enable_to_complete;
+       u8              wait_for_discovery_to_complete;
+       struct completion       port_enable_done;
+       u8              is_driver_loading;
+       u8              port_enable_failed;
+
+       u8              start_scan;
+       u16             start_scan_failed;
 
        u8              msix_enable;
        u16             msix_vector_count;
@@ -814,11 +824,13 @@ struct MPT2SAS_ADAPTER {
        u8              scsih_cb_idx;
        u8              ctl_cb_idx;
        u8              base_cb_idx;
+       u8              port_enable_cb_idx;
        u8              config_cb_idx;
        u8              tm_tr_cb_idx;
        u8              tm_tr_volume_cb_idx;
        u8              tm_sas_control_cb_idx;
        struct _internal_cmd base_cmds;
+       struct _internal_cmd port_enable_cmds;
        struct _internal_cmd transport_cmds;
        struct _internal_cmd scsih_cmds;
        struct _internal_cmd tm_cmds;
@@ -1001,6 +1013,8 @@ void mpt2sas_base_release_callback_handler(u8 cb_idx);
 
 u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
     u32 reply);
+u8 mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid,
+       u8 msix_index,  u32 reply);
 void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);
 
 u32 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
 
 void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
 
+int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);
+
 /* scsih shared API */
 u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
     u32 reply);
@@ -1032,6 +1048,8 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAP
 struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address(
     struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
 
+void mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc);
+
 void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
 
 /* config shared API */
index 2b1101076cfe73c437473e0edea26dab7f86eff5..36ea0b2d80209e017e1ddffe50baf71eeaec4d2b 100644 (file)
@@ -1356,6 +1356,9 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
        Mpi2ConfigReply_t mpi_reply;
        int r, i, config_page_sz;
        u16 ioc_status;
+       int config_num;
+       u16 element_type;
+       u16 phys_disk_dev_handle;
 
        *volume_handle = 0;
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
@@ -1371,35 +1374,53 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
        if (r)
                goto out;
 
-       mpi_request.PageAddress =
-           cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
        mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
        config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
        config_page = kmalloc(config_page_sz, GFP_KERNEL);
-       if (!config_page)
-               goto out;
-       r = _config_request(ioc, &mpi_request, &mpi_reply,
-           MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-           config_page_sz);
-       if (r)
+       if (!config_page) {
+               r = -1;
                goto out;
-
-       r = -1;
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-               goto out;
-       for (i = 0; i < config_page->NumElements; i++) {
-               if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) &
-                   MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
-                   MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT)
-                       continue;
-               if (le16_to_cpu(config_page->ConfigElement[i].
-                   PhysDiskDevHandle) == pd_handle) {
-                       *volume_handle = le16_to_cpu(config_page->
-                           ConfigElement[i].VolDevHandle);
-                       r = 0;
+       }
+       config_num = 0xff;
+       while (1) {
+               mpi_request.PageAddress = cpu_to_le32(config_num +
+                   MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
+               r = _config_request(ioc, &mpi_request, &mpi_reply,
+                   MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+                   config_page_sz);
+               if (r)
+                       goto out;
+               r = -1;
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
                        goto out;
+               for (i = 0; i < config_page->NumElements; i++) {
+                       element_type = le16_to_cpu(config_page->
+                           ConfigElement[i].ElementFlags) &
+                           MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
+                       if (element_type ==
+                           MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
+                           element_type ==
+                           MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
+                               phys_disk_dev_handle =
+                                   le16_to_cpu(config_page->ConfigElement[i].
+                                   PhysDiskDevHandle);
+                               if (phys_disk_dev_handle == pd_handle) {
+                                       *volume_handle =
+                                           le16_to_cpu(config_page->
+                                           ConfigElement[i].VolDevHandle);
+                                       r = 0;
+                                       goto out;
+                               }
+                       } else if (element_type ==
+                           MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
+                               *volume_handle = 0;
+                               r = 0;
+                               goto out;
+                       }
                }
+               config_num = config_page->ConfigNum;
        }
  out:
        kfree(config_page);
index 9adb0133d6fb92cfa9e7eab6b3e71be4adddc645..aabcb911706e11155bb886ec420051b9edb04e36 100644 (file)
@@ -1207,6 +1207,9 @@ _ctl_do_reset(void __user *arg)
        if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
                return -ENODEV;
 
+       if (ioc->shost_recovery || ioc->pci_error_recovery ||
+               ioc->is_driver_loading)
+               return -EAGAIN;
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
 
@@ -2178,7 +2181,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
                    !ioc)
                        return -ENODEV;
 
-               if (ioc->shost_recovery || ioc->pci_error_recovery)
+               if (ioc->shost_recovery || ioc->pci_error_recovery ||
+                               ioc->is_driver_loading)
                        return -EAGAIN;
 
                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)
        if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
                return -ENODEV;
 
-       if (ioc->shost_recovery || ioc->pci_error_recovery)
+       if (ioc->shost_recovery || ioc->pci_error_recovery ||
+                       ioc->is_driver_loading)
                return -EAGAIN;
 
        memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
index 1da1aa1a11e2360d6275f86a90c3db9126ee9233..4e041f6d808cd6e49666b35c8d8aec0f1b0a76c5 100644 (file)
@@ -71,6 +71,9 @@ static void _firmware_event_work(struct work_struct *work);
 
 static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
 
+static void _scsih_scan_start(struct Scsi_Host *shost);
+static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time);
+
 /* global parameters */
 LIST_HEAD(mpt2sas_ioc_list);
 
@@ -79,6 +82,7 @@ static u8 scsi_io_cb_idx = -1;
 static u8 tm_cb_idx = -1;
 static u8 ctl_cb_idx = -1;
 static u8 base_cb_idx = -1;
+static u8 port_enable_cb_idx = -1;
 static u8 transport_cb_idx = -1;
 static u8 scsih_cb_idx = -1;
 static u8 config_cb_idx = -1;
@@ -103,6 +107,18 @@ static int max_lun = MPT2SAS_MAX_LUN;
 module_param(max_lun, int, 0);
 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
 
+/* diag_buffer_enable is bitwise
+ * bit 0 set = TRACE
+ * bit 1 set = SNAPSHOT
+ * bit 2 set = EXTENDED
+ *
+ * Either bit can be set, or both
+ */
+static int diag_buffer_enable = -1;
+module_param(diag_buffer_enable, int, 0);
+MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
+       "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
+
 /**
  * struct sense_info - common structure for obtaining sense keys
  * @skey: sense key
@@ -117,8 +133,8 @@ struct sense_info {
 
 
 #define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
-#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
-
+#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
+#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
 /**
  * struct fw_event_work - firmware event struct
  * @list: link list framework
@@ -372,31 +388,34 @@ _scsih_get_sas_address(struct MPT2SAS_ADAPTER *ioc, u16 handle,
        Mpi2SasDevicePage0_t sas_device_pg0;
        Mpi2ConfigReply_t mpi_reply;
        u32 ioc_status;
+       *sas_address = 0;
 
        if (handle <= ioc->sas_hba.num_phys) {
                *sas_address = ioc->sas_hba.sas_address;
                return 0;
-       } else
-               *sas_address = 0;
+       }
 
        if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
            MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
+               __FILE__, __LINE__, __func__);
                return -ENXIO;
        }
 
-       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-           MPI2_IOCSTATUS_MASK;
-       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
-               printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
-                   "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
-                    __FILE__, __LINE__, __func__);
-               return -EIO;
+       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
+       if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
+               *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
+               return 0;
        }
 
-       *sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
-       return 0;
+       /* we hit this becuase the given parent handle doesn't exist */
+       if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+               return -ENXIO;
+       /* else error case */
+       printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x), "
+           "failure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
+            __FILE__, __LINE__, __func__);
+       return -EIO;
 }
 
 /**
@@ -424,7 +443,11 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc,
        u16 slot;
 
         /* only process this function when driver loads */
-       if (!ioc->wait_for_port_enable_to_complete)
+       if (!ioc->is_driver_loading)
+               return;
+
+        /* no Bios, return immediately */
+       if (!ioc->bios_pg3.BiosVersion)
                return;
 
        if (!is_raid) {
@@ -587,8 +610,15 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
        if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-            sas_device->sas_address_parent))
+            sas_device->sas_address_parent)) {
                _scsih_sas_device_remove(ioc, sas_device);
+               } else if (!sas_device->starget) {
+                       if (!ioc->is_driver_loading)
+                               mpt2sas_transport_port_remove(ioc,
+                               sas_device->sas_address,
+                           sas_device->sas_address_parent);
+                       _scsih_sas_device_remove(ioc, sas_device);
+               }
 }
 
 /**
@@ -1400,6 +1430,10 @@ _scsih_slave_destroy(struct scsi_device *sdev)
 {
        struct MPT2SAS_TARGET *sas_target_priv_data;
        struct scsi_target *starget;
+       struct Scsi_Host *shost;
+       struct MPT2SAS_ADAPTER *ioc;
+       struct _sas_device *sas_device;
+       unsigned long flags;
 
        if (!sdev->hostdata)
                return;
@@ -1407,6 +1441,19 @@ _scsih_slave_destroy(struct scsi_device *sdev)
        starget = scsi_target(sdev);
        sas_target_priv_data = starget->hostdata;
        sas_target_priv_data->num_luns--;
+
+       shost = dev_to_shost(&starget->dev);
+       ioc = shost_priv(shost);
+
+       if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
+               spin_lock_irqsave(&ioc->sas_device_lock, flags);
+               sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+                  sas_target_priv_data->sas_address);
+               if (sas_device)
+                       sas_device->starget = NULL;
+               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+       }
+
        kfree(sdev->hostdata);
        sdev->hostdata = NULL;
 }
@@ -1598,8 +1645,10 @@ _scsih_set_level(struct scsi_device *sdev, struct _raid_device *raid_device)
  * _scsih_get_volume_capabilities - volume capabilities
  * @ioc: per adapter object
  * @sas_device: the raid_device object
+ *
+ * Returns 0 for success, else 1
  */
-static void
+static int
 _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
     struct _raid_device *raid_device)
 {
@@ -1612,9 +1661,10 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
 
        if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
            &num_pds)) || !num_pds) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
+               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
+                   __func__));
+               return 1;
        }
 
        raid_device->num_pds = num_pds;
@@ -1622,17 +1672,19 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
            sizeof(Mpi2RaidVol0PhysDisk_t));
        vol_pg0 = kzalloc(sz, GFP_KERNEL);
        if (!vol_pg0) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
-               return;
+               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
+                   __func__));
+               return 1;
        }
 
        if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
             MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
-               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                   ioc->name, __FILE__, __LINE__, __func__);
+               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
+                   __func__));
                kfree(vol_pg0);
-               return;
+               return 1;
        }
 
        raid_device->volume_type = vol_pg0->VolumeType;
@@ -1652,6 +1704,7 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc,
        }
 
        kfree(vol_pg0);
+       return 0;
 }
 /**
  * _scsih_disable_ddio - Disable direct I/O for all the volumes
@@ -1922,13 +1975,20 @@ _scsih_slave_configure(struct scsi_device *sdev)
                     sas_target_priv_data->handle);
                spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
                if (!raid_device) {
-                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-                           ioc->name, __FILE__, __LINE__, __func__);
-                       return 0;
+                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                           "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+                           __LINE__, __func__));
+                       return 1;
                }
 
                _scsih_get_volume_capabilities(ioc, raid_device);
 
+               if (_scsih_get_volume_capabilities(ioc, raid_device)) {
+                       dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                           "failure at %s:%d/%s()!\n", ioc->name, __FILE__,
+                           __LINE__, __func__));
+                       return 1;
+               }
                /*
                 * WARPDRIVE: Initialize the required data for Direct IO
                 */
@@ -2002,11 +2062,22 @@ _scsih_slave_configure(struct scsi_device *sdev)
        if (sas_device) {
                if (sas_target_priv_data->flags &
                    MPT_TARGET_FLAGS_RAID_COMPONENT) {
-                       mpt2sas_config_get_volume_handle(ioc,
-                           sas_device->handle, &sas_device->volume_handle);
-                       mpt2sas_config_get_volume_wwid(ioc,
+                       if (mpt2sas_config_get_volume_handle(ioc,
+                           sas_device->handle, &sas_device->volume_handle)) {
+                               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                                   "failure at %s:%d/%s()!\n", ioc->name,
+                                   __FILE__, __LINE__, __func__));
+                               return 1;
+                       }
+                       if (sas_device->volume_handle &&
+                           mpt2sas_config_get_volume_wwid(ioc,
                            sas_device->volume_handle,
-                           &sas_device->volume_wwid);
+                           &sas_device->volume_wwid)) {
+                               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                                   "failure at %s:%d/%s()!\n", ioc->name,
+                                   __FILE__, __LINE__, __func__));
+                               return 1;
+                       }
                }
                if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) {
                        qdepth = MPT2SAS_SAS_QUEUE_DEPTH;
@@ -2035,6 +2106,11 @@ _scsih_slave_configure(struct scsi_device *sdev)
 
                if (!ssp_target)
                        _scsih_display_sata_capabilities(ioc, sas_device, sdev);
+       } else {
+               dfailprintk(ioc, printk(MPT2SAS_WARN_FMT
+                   "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__,
+                   __func__));
+               return 1;
        }
 
        _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT);
@@ -2714,22 +2790,43 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
 
 
 /**
- * _scsih_queue_rescan - queue a topology rescan from user context
+ * _scsih_error_recovery_delete_devices - remove devices not responding
  * @ioc: per adapter object
  *
  * Return nothing.
  */
 static void
-_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
+_scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc)
 {
        struct fw_event_work *fw_event;
 
-       if (ioc->wait_for_port_enable_to_complete)
+       if (ioc->is_driver_loading)
+               return;
+
+       fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+       if (!fw_event)
                return;
+
+       fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES;
+       fw_event->ioc = ioc;
+       _scsih_fw_event_add(ioc, fw_event);
+}
+
+/**
+ * mpt2sas_port_enable_complete - port enable completed (fake event)
+ * @ioc: per adapter object
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc)
+{
+       struct fw_event_work *fw_event;
+
        fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
        if (!fw_event)
                return;
-       fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
+       fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE;
        fw_event->ioc = ioc;
        _scsih_fw_event_add(ioc, fw_event);
 }
@@ -2977,14 +3074,27 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
        Mpi2SCSITaskManagementRequest_t *mpi_request;
        u16 smid;
        struct _sas_device *sas_device;
-       struct MPT2SAS_TARGET *sas_target_priv_data;
+       struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
+       u64 sas_address = 0;
        unsigned long flags;
        struct _tr_list *delayed_tr;
+       u32 ioc_state;
 
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
+       if (ioc->remove_host) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
+                   "removed: handle(0x%04x)\n", __func__, ioc->name, handle));
+               return;
+       } else if (ioc->pci_error_recovery) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
+                   "error recovery: handle(0x%04x)\n", __func__, ioc->name,
+                   handle));
+               return;
+       }
+       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
+       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
+                  "operational: handle(0x%04x)\n", __func__, ioc->name,
+                  handle));
                return;
        }
 
@@ -2998,13 +3108,18 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
             sas_device->starget->hostdata) {
                sas_target_priv_data = sas_device->starget->hostdata;
                sas_target_priv_data->deleted = 1;
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-                   "setting delete flag: handle(0x%04x), "
-                   "sas_addr(0x%016llx)\n", ioc->name, handle,
-                   (unsigned long long) sas_device->sas_address));
+               sas_address = sas_device->sas_address;
        }
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
+       if (sas_target_priv_data) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "setting delete flag: "
+               "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, handle,
+                       (unsigned long long)sas_address));
+               _scsih_ublock_io_device(ioc, handle);
+               sas_target_priv_data->handle = MPT2SAS_INVALID_DEVICE_HANDLE;
+       }
+
        smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
        if (!smid) {
                delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
@@ -3185,11 +3300,21 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
            mpt2sas_base_get_reply_virt_addr(ioc, reply);
        Mpi2SasIoUnitControlRequest_t *mpi_request;
        u16 smid_sas_ctrl;
+       u32 ioc_state;
 
-       if (ioc->shost_recovery || ioc->remove_host ||
-           ioc->pci_error_recovery) {
-               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
-                  "progress!\n", __func__, ioc->name));
+       if (ioc->remove_host) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host has been "
+                  "removed\n", __func__, ioc->name));
+               return 1;
+       } else if (ioc->pci_error_recovery) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host in pci "
+                   "error recovery\n", __func__, ioc->name));
+               return 1;
+       }
+       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
+       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host is not "
+                   "operational\n", __func__, ioc->name));
                return 1;
        }
 
@@ -5099,7 +5224,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
        /* get device name */
        sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
 
-       if (ioc->wait_for_port_enable_to_complete)
+       if (ioc->wait_for_discovery_to_complete)
                _scsih_sas_device_init_add(ioc, sas_device);
        else
                _scsih_sas_device_add(ioc, sas_device);
@@ -5135,6 +5260,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
        if (sas_device_backup.starget && sas_device_backup.starget->hostdata) {
                sas_target_priv_data = sas_device_backup.starget->hostdata;
                sas_target_priv_data->deleted = 1;
+               _scsih_ublock_io_device(ioc, sas_device_backup.handle);
+               sas_target_priv_data->handle =
+                    MPT2SAS_INVALID_DEVICE_HANDLE;
        }
 
        _scsih_ublock_io_device(ioc, sas_device_backup.handle);
@@ -5288,7 +5416,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
                _scsih_sas_topology_change_event_debug(ioc, event_data);
 #endif
 
-       if (ioc->shost_recovery || ioc->remove_host || ioc->pci_error_recovery)
+       if (ioc->remove_host || ioc->pci_error_recovery)
                return;
 
        if (!ioc->sas_hba.num_phys)
@@ -5349,6 +5477,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
                switch (reason_code) {
                case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
 
+                       if (ioc->shost_recovery)
+                               break;
+
                        if (link_rate == prev_link_rate)
                                break;
 
@@ -5362,6 +5493,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
                        break;
                case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
 
+                       if (ioc->shost_recovery)
+                               break;
+
                        mpt2sas_transport_update_links(ioc, sas_address,
                            handle, phy_number, link_rate);
 
@@ -5622,7 +5756,7 @@ broadcast_aen_retry:
        termination_count = 0;
        query_count = 0;
        for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
-               if (ioc->ioc_reset_in_progress_status)
+               if (ioc->shost_recovery)
                        goto out;
                scmd = _scsih_scsi_lookup_get(ioc, smid);
                if (!scmd)
@@ -5644,7 +5778,7 @@ broadcast_aen_retry:
                lun = sas_device_priv_data->lun;
                query_count++;
 
-               if (ioc->ioc_reset_in_progress_status)
+               if (ioc->shost_recovery)
                        goto out;
 
                spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -5686,7 +5820,7 @@ broadcast_aen_retry:
                        goto broadcast_aen_retry;
                }
 
-               if (ioc->ioc_reset_in_progress_status)
+               if (ioc->shost_recovery)
                        goto out_no_lock;
 
                r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
@@ -5725,7 +5859,7 @@ broadcast_aen_retry:
            ioc->name, __func__, query_count, termination_count));
 
        ioc->broadcast_aen_busy = 0;
-       if (!ioc->ioc_reset_in_progress_status)
+       if (!ioc->shost_recovery)
                _scsih_ublock_io_all_device(ioc);
        mutex_unlock(&ioc->tm_cmds.mutex);
 }
@@ -5789,8 +5923,11 @@ _scsih_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach)
 static void
 _scsih_reprobe_target(struct scsi_target *starget, int no_uld_attach)
 {
-       struct MPT2SAS_TARGET *sas_target_priv_data = starget->hostdata;
+       struct MPT2SAS_TARGET *sas_target_priv_data;
 
+       if (starget == NULL)
+               return;
+       sas_target_priv_data = starget->hostdata;
        if (no_uld_attach)
                sas_target_priv_data->flags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
        else
@@ -5845,7 +5982,7 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
        raid_device->handle = handle;
        raid_device->wwid = wwid;
        _scsih_raid_device_add(ioc, raid_device);
-       if (!ioc->wait_for_port_enable_to_complete) {
+       if (!ioc->wait_for_discovery_to_complete) {
                rc = scsi_add_device(ioc->shost, RAID_CHANNEL,
                    raid_device->id, 0);
                if (rc)
@@ -6127,6 +6264,10 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
                _scsih_sas_ir_config_change_event_debug(ioc, event_data);
 
 #endif
+
+       if (ioc->shost_recovery)
+               return;
+
        foreign_config = (le32_to_cpu(event_data->Flags) &
            MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
 
@@ -6185,6 +6326,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
        int rc;
        Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
 
+       if (ioc->shost_recovery)
+               return;
+
        if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
                return;
 
@@ -6267,6 +6411,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
        Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
        u64 sas_address;
 
+       if (ioc->shost_recovery)
+               return;
+
        if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
                return;
 
@@ -6510,10 +6657,10 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
        u32 device_info;
        u16 slot;
 
-       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
+       printk(MPT2SAS_INFO_FMT "search for end-devices: start\n", ioc->name);
 
        if (list_empty(&ioc->sas_device_list))
-               return;
+               goto out;
 
        handle = 0xFFFF;
        while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -6532,6 +6679,9 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
                _scsih_mark_responding_sas_device(ioc, sas_address, slot,
                    handle);
        }
+out:
+       printk(MPT2SAS_INFO_FMT "search for end-devices: complete\n",
+           ioc->name);
 }
 
 /**
@@ -6607,10 +6757,14 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
        u16 handle;
        u8 phys_disk_num;
 
-       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
+       if (!ioc->ir_firmware)
+               return;
+
+       printk(MPT2SAS_INFO_FMT "search for raid volumes: start\n",
+           ioc->name);
 
        if (list_empty(&ioc->raid_device_list))
-               return;
+               goto out;
 
        handle = 0xFFFF;
        while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -6649,6 +6803,9 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
                        set_bit(handle, ioc->pd_handles);
                }
        }
+out:
+       printk(MPT2SAS_INFO_FMT "search for responding raid volumes: "
+           "complete\n", ioc->name);
 }
 
 /**
@@ -6708,10 +6865,10 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
        u64 sas_address;
        u16 handle;
 
-       printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
+       printk(MPT2SAS_INFO_FMT "search for expanders: start\n", ioc->name);
 
        if (list_empty(&ioc->sas_expander_list))
-               return;
+               goto out;
 
        handle = 0xFFFF;
        while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -6730,6 +6887,8 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
                _scsih_mark_responding_expander(ioc, sas_address, handle);
        }
 
+ out:
+       printk(MPT2SAS_INFO_FMT "search for expanders: complete\n", ioc->name);
 }
 
 /**
@@ -6745,6 +6904,8 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
        struct _sas_node *sas_expander;
        struct _raid_device *raid_device, *raid_device_next;
 
+       printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n",
+           ioc->name);
 
        list_for_each_entry_safe(sas_device, sas_device_next,
            &ioc->sas_device_list, list) {
@@ -6764,6 +6925,9 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
                _scsih_remove_device(ioc, sas_device);
        }
 
+       if (!ioc->ir_firmware)
+               goto retry_expander_search;
+
        list_for_each_entry_safe(raid_device, raid_device_next,
            &ioc->raid_device_list, list) {
                if (raid_device->responding) {
@@ -6790,52 +6954,170 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
                mpt2sas_expander_remove(ioc, sas_expander->sas_address);
                goto retry_expander_search;
        }
+       printk(MPT2SAS_INFO_FMT "removing unresponding devices: complete\n",
+           ioc->name);
+       /* unblock devices */
+       _scsih_ublock_io_all_device(ioc);
+}
+
+static void
+_scsih_refresh_expander_links(struct MPT2SAS_ADAPTER *ioc,
+       struct _sas_node *sas_expander, u16 handle)
+{
+       Mpi2ExpanderPage1_t expander_pg1;
+       Mpi2ConfigReply_t mpi_reply;
+       int i;
+
+       for (i = 0 ; i < sas_expander->num_phys ; i++) {
+               if ((mpt2sas_config_get_expander_pg1(ioc, &mpi_reply,
+                   &expander_pg1, i, handle))) {
+                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                           ioc->name, __FILE__, __LINE__, __func__);
+                       return;
+               }
+
+               mpt2sas_transport_update_links(ioc, sas_expander->sas_address,
+                   le16_to_cpu(expander_pg1.AttachedDevHandle), i,
+                   expander_pg1.NegotiatedLinkRate >> 4);
+       }
 }
 
 /**
- * _scsih_hide_unhide_sas_devices - add/remove device to/from OS
+ * _scsih_scan_for_devices_after_reset - scan for devices after host reset
  * @ioc: per adapter object
  *
  * Return nothing.
  */
 static void
-_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc)
+_scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
 {
-       struct _sas_device *sas_device, *sas_device_next;
+       Mpi2ExpanderPage0_t expander_pg0;
+       Mpi2SasDevicePage0_t sas_device_pg0;
+       Mpi2RaidVolPage1_t volume_pg1;
+       Mpi2RaidVolPage0_t volume_pg0;
+       Mpi2RaidPhysDiskPage0_t pd_pg0;
+       Mpi2EventIrConfigElement_t element;
+       Mpi2ConfigReply_t mpi_reply;
+       u8 phys_disk_num;
+       u16 ioc_status;
+       u16 handle, parent_handle;
+       u64 sas_address;
+       struct _sas_device *sas_device;
+       struct _sas_node *expander_device;
+       static struct _raid_device *raid_device;
 
-       if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag !=
-           MFG_PAGE10_HIDE_IF_VOL_PRESENT)
-               return;
+       printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
 
-       if (ioc->hide_drives) {
-               if (_scsih_get_num_volumes(ioc))
-                       return;
-               ioc->hide_drives = 0;
-               list_for_each_entry_safe(sas_device, sas_device_next,
-                   &ioc->sas_device_list, list) {
-                       if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
-                               sas_device->sas_address_parent)) {
-                               _scsih_sas_device_remove(ioc, sas_device);
-                       } else if (!sas_device->starget) {
-                               mpt2sas_transport_port_remove(ioc,
-                                   sas_device->sas_address,
-                                   sas_device->sas_address_parent);
-                               _scsih_sas_device_remove(ioc, sas_device);
-                       }
+       _scsih_sas_host_refresh(ioc);
+
+       /* expanders */
+       handle = 0xFFFF;
+       while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
+           MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               handle = le16_to_cpu(expander_pg0.DevHandle);
+               expander_device = mpt2sas_scsih_expander_find_by_sas_address(
+                   ioc, le64_to_cpu(expander_pg0.SASAddress));
+               if (expander_device)
+                       _scsih_refresh_expander_links(ioc, expander_device,
+                           handle);
+               else
+                       _scsih_expander_add(ioc, handle);
+       }
+
+       if (!ioc->ir_firmware)
+               goto skip_to_sas;
+
+       /* phys disk */
+       phys_disk_num = 0xFF;
+       while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
+           &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
+           phys_disk_num))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               phys_disk_num = pd_pg0.PhysDiskNum;
+               handle = le16_to_cpu(pd_pg0.DevHandle);
+               sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
+               if (sas_device)
+                       continue;
+               if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
+                   &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
+                   handle) != 0)
+                       continue;
+               parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+               if (!_scsih_get_sas_address(ioc, parent_handle,
+                   &sas_address)) {
+                       mpt2sas_transport_update_links(ioc, sas_address,
+                           handle, sas_device_pg0.PhyNum,
+                           MPI2_SAS_NEG_LINK_RATE_1_5);
+                       set_bit(handle, ioc->pd_handles);
+                       _scsih_add_device(ioc, handle, 0, 1);
                }
-       } else {
-               if (!_scsih_get_num_volumes(ioc))
-                       return;
-               ioc->hide_drives = 1;
-               list_for_each_entry_safe(sas_device, sas_device_next,
-                   &ioc->sas_device_list, list) {
-                       mpt2sas_transport_port_remove(ioc,
-                           sas_device->sas_address,
-                           sas_device->sas_address_parent);
+       }
+
+       /* volumes */
+       handle = 0xFFFF;
+       while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
+           &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               handle = le16_to_cpu(volume_pg1.DevHandle);
+               raid_device = _scsih_raid_device_find_by_wwid(ioc,
+                   le64_to_cpu(volume_pg1.WWID));
+               if (raid_device)
+                       continue;
+               if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply,
+                   &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
+                    sizeof(Mpi2RaidVolPage0_t)))
+                       continue;
+               if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
+                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
+                   volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
+                       memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
+                       element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
+                       element.VolDevHandle = volume_pg1.DevHandle;
+                       _scsih_sas_volume_add(ioc, &element);
                }
        }
+
+ skip_to_sas:
+
+       /* sas devices */
+       handle = 0xFFFF;
+       while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
+           &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE,
+           handle))) {
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+                       break;
+               handle = le16_to_cpu(sas_device_pg0.DevHandle);
+               if (!(_scsih_is_end_device(
+                   le32_to_cpu(sas_device_pg0.DeviceInfo))))
+                       continue;
+               sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
+                   le64_to_cpu(sas_device_pg0.SASAddress));
+               if (sas_device)
+                       continue;
+               parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
+               if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
+                       mpt2sas_transport_update_links(ioc, sas_address, handle,
+                           sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+                       _scsih_add_device(ioc, handle, 0, 0);
+               }
+       }
+
+       printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
 }
 
+
 /**
  * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
  * @ioc: per adapter object
@@ -6871,7 +7153,6 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
                }
                _scsih_fw_event_cleanup_queue(ioc);
                _scsih_flush_running_cmds(ioc);
-               _scsih_queue_rescan(ioc);
                break;
        case MPT2_IOC_DONE_RESET:
                dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: "
@@ -6881,6 +7162,13 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
                _scsih_search_responding_sas_devices(ioc);
                _scsih_search_responding_raid_devices(ioc);
                _scsih_search_responding_expanders(ioc);
+               if (!ioc->is_driver_loading) {
+                       _scsih_prep_device_scan(ioc);
+                       _scsih_search_responding_sas_devices(ioc);
+                       _scsih_search_responding_raid_devices(ioc);
+                       _scsih_search_responding_expanders(ioc);
+                       _scsih_error_recovery_delete_devices(ioc);
+               }
                break;
        }
 }
@@ -6898,7 +7186,6 @@ _firmware_event_work(struct work_struct *work)
 {
        struct fw_event_work *fw_event = container_of(work,
            struct fw_event_work, delayed_work.work);
-       unsigned long flags;
        struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
 
        /* the queue is being flushed so ignore this event */
@@ -6908,23 +7195,21 @@ _firmware_event_work(struct work_struct *work)
                return;
        }
 
-       if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
-               _scsih_fw_event_free(ioc, fw_event);
-               spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-               if (ioc->shost_recovery) {
-                       init_completion(&ioc->shost_recovery_done);
-                       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-                           flags);
-                       wait_for_completion(&ioc->shost_recovery_done);
-               } else
-                       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-                           flags);
+       switch (fw_event->event) {
+       case MPT2SAS_REMOVE_UNRESPONDING_DEVICES:
+               while (scsi_host_in_recovery(ioc->shost))
+                       ssleep(1);
                _scsih_remove_unresponding_sas_devices(ioc);
-               _scsih_hide_unhide_sas_devices(ioc);
-               return;
-       }
+               _scsih_scan_for_devices_after_reset(ioc);
+               break;
+       case MPT2SAS_PORT_ENABLE_COMPLETE:
+               ioc->start_scan = 0;
 
-       switch (fw_event->event) {
+
+
+               dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
+                   "from worker thread\n", ioc->name));
+               break;
        case MPT2SAS_TURN_ON_FAULT_LED:
                _scsih_turn_on_fault_led(ioc, fw_event->device_handle);
                break;
@@ -7121,6 +7406,8 @@ static struct scsi_host_template scsih_driver_template = {
        .slave_configure                = _scsih_slave_configure,
        .target_destroy                 = _scsih_target_destroy,
        .slave_destroy                  = _scsih_slave_destroy,
+       .scan_finished                  = _scsih_scan_finished,
+       .scan_start                     = _scsih_scan_start,
        .change_queue_depth             = _scsih_change_queue_depth,
        .change_queue_type              = _scsih_change_queue_type,
        .eh_abort_handler               = _scsih_abort,
@@ -7381,7 +7668,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
        unsigned long flags;
        int rc;
 
+        /* no Bios, return immediately */
+       if (!ioc->bios_pg3.BiosVersion)
+               return;
+
        device = NULL;
+       is_raid = 0;
        if (ioc->req_boot_device.device) {
                device =  ioc->req_boot_device.device;
                is_raid = ioc->req_boot_device.is_raid;
@@ -7417,8 +7709,9 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
                    sas_device->sas_address_parent)) {
                        _scsih_sas_device_remove(ioc, sas_device);
                } else if (!sas_device->starget) {
-                       mpt2sas_transport_port_remove(ioc, sas_address,
-                           sas_address_parent);
+                       if (!ioc->is_driver_loading)
+                               mpt2sas_transport_port_remove(ioc, sas_address,
+                                       sas_address_parent);
                        _scsih_sas_device_remove(ioc, sas_device);
                }
        }
@@ -7462,22 +7755,28 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
        /* SAS Device List */
        list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list,
            list) {
-               spin_lock_irqsave(&ioc->sas_device_lock, flags);
-               list_move_tail(&sas_device->list, &ioc->sas_device_list);
-               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
                if (ioc->hide_drives)
                        continue;
 
                if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
                    sas_device->sas_address_parent)) {
-                       _scsih_sas_device_remove(ioc, sas_device);
+                       list_del(&sas_device->list);
+                       kfree(sas_device);
+                       continue;
                } else if (!sas_device->starget) {
-                       mpt2sas_transport_port_remove(ioc,
-                           sas_device->sas_address,
-                           sas_device->sas_address_parent);
-                       _scsih_sas_device_remove(ioc, sas_device);
+                       if (!ioc->is_driver_loading)
+                               mpt2sas_transport_port_remove(ioc,
+                                       sas_device->sas_address,
+                                       sas_device->sas_address_parent);
+                       list_del(&sas_device->list);
+                       kfree(sas_device);
+                       continue;
+
                }
+               spin_lock_irqsave(&ioc->sas_device_lock, flags);
+               list_move_tail(&sas_device->list, &ioc->sas_device_list);
+               spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
        }
 }
 
@@ -7490,9 +7789,7 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
 static void
 _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
 {
-       u16 volume_mapping_flags =
-           le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
-           MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
+       u16 volume_mapping_flags;
 
        if (!(ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR))
                return;  /* return when IOC doesn't support initiator mode */
@@ -7500,18 +7797,93 @@ _scsih_probe_devices(struct MPT2SAS_ADAPTER *ioc)
        _scsih_probe_boot_devices(ioc);
 
        if (ioc->ir_firmware) {
-               if ((volume_mapping_flags &
-                    MPI2_IOCPAGE8_IRFLAGS_HIGH_VOLUME_MAPPING)) {
-                       _scsih_probe_sas(ioc);
+               volume_mapping_flags =
+                   le16_to_cpu(ioc->ioc_pg8.IRVolumeMappingFlags) &
+                   MPI2_IOCPAGE8_IRFLAGS_MASK_VOLUME_MAPPING_MODE;
+               if (volume_mapping_flags ==
+                   MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING) {
                        _scsih_probe_raid(ioc);
+                       _scsih_probe_sas(ioc);
                } else {
-                       _scsih_probe_raid(ioc);
                        _scsih_probe_sas(ioc);
+                       _scsih_probe_raid(ioc);
                }
        } else
                _scsih_probe_sas(ioc);
 }
 
+
+/**
+ * _scsih_scan_start - scsi lld callback for .scan_start
+ * @shost: SCSI host pointer
+ *
+ * The shost has the ability to discover targets on its own instead
+ * of scanning the entire bus.  In our implemention, we will kick off
+ * firmware discovery.
+ */
+static void
+_scsih_scan_start(struct Scsi_Host *shost)
+{
+       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+       int rc;
+
+       if (diag_buffer_enable != -1 && diag_buffer_enable != 0)
+               mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
+
+       ioc->start_scan = 1;
+       rc = mpt2sas_port_enable(ioc);
+
+       if (rc != 0)
+               printk(MPT2SAS_INFO_FMT "port enable: FAILED\n", ioc->name);
+}
+
+/**
+ * _scsih_scan_finished - scsi lld callback for .scan_finished
+ * @shost: SCSI host pointer
+ * @time: elapsed time of the scan in jiffies
+ *
+ * This function will be called periodically until it returns 1 with the
+ * scsi_host and the elapsed time of the scan in jiffies. In our implemention,
+ * we wait for firmware discovery to complete, then return 1.
+ */
+static int
+_scsih_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+       struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
+
+       if (time >= (300 * HZ)) {
+               ioc->base_cmds.status = MPT2_CMD_NOT_USED;
+               printk(MPT2SAS_INFO_FMT "port enable: FAILED with timeout "
+                   "(timeout=300s)\n", ioc->name);
+               ioc->is_driver_loading = 0;
+               return 1;
+       }
+
+       if (ioc->start_scan)
+               return 0;
+
+       if (ioc->start_scan_failed) {
+               printk(MPT2SAS_INFO_FMT "port enable: FAILED with "
+                   "(ioc_status=0x%08x)\n", ioc->name, ioc->start_scan_failed);
+               ioc->is_driver_loading = 0;
+               ioc->wait_for_discovery_to_complete = 0;
+               ioc->remove_host = 1;
+               return 1;
+       }
+
+       printk(MPT2SAS_INFO_FMT "port enable: SUCCESS\n", ioc->name);
+       ioc->base_cmds.status = MPT2_CMD_NOT_USED;
+
+       if (ioc->wait_for_discovery_to_complete) {
+               ioc->wait_for_discovery_to_complete = 0;
+               _scsih_probe_devices(ioc);
+       }
+       mpt2sas_base_start_watchdog(ioc);
+       ioc->is_driver_loading = 0;
+       return 1;
+}
+
+
 /**
  * _scsih_probe - attach and add scsi host
  * @pdev: PCI device struct
@@ -7548,6 +7920,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        ioc->tm_cb_idx = tm_cb_idx;
        ioc->ctl_cb_idx = ctl_cb_idx;
        ioc->base_cb_idx = base_cb_idx;
+       ioc->port_enable_cb_idx = port_enable_cb_idx;
        ioc->transport_cb_idx = transport_cb_idx;
        ioc->scsih_cb_idx = scsih_cb_idx;
        ioc->config_cb_idx = config_cb_idx;
@@ -7620,14 +7993,14 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto out_thread_fail;
        }
 
-       ioc->wait_for_port_enable_to_complete = 1;
+       ioc->is_driver_loading = 1;
        if ((mpt2sas_base_attach(ioc))) {
                printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
                    ioc->name, __FILE__, __LINE__, __func__);
                goto out_attach_fail;
        }
 
-       ioc->wait_for_port_enable_to_complete = 0;
+       scsi_scan_host(shost);
        if (ioc->is_warpdrive) {
                if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS)
                        ioc->hide_drives = 0;
@@ -7650,6 +8023,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  out_thread_fail:
        list_del(&ioc->list);
        scsi_remove_host(shost);
+       scsi_host_put(shost);
  out_add_shost_fail:
        return -ENODEV;
 }
@@ -7896,6 +8270,8 @@ _scsih_init(void)
 
        /* base internal commands callback handler */
        base_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_base_done);
+       port_enable_cb_idx = mpt2sas_base_register_callback_handler(
+               mpt2sas_port_enable_done);
 
        /* transport internal commands callback handler */
        transport_cb_idx = mpt2sas_base_register_callback_handler(
@@ -7950,6 +8326,7 @@ _scsih_exit(void)
        mpt2sas_base_release_callback_handler(scsi_io_cb_idx);
        mpt2sas_base_release_callback_handler(tm_cb_idx);
        mpt2sas_base_release_callback_handler(base_cb_idx);
+       mpt2sas_base_release_callback_handler(port_enable_cb_idx);
        mpt2sas_base_release_callback_handler(transport_cb_idx);
        mpt2sas_base_release_callback_handler(scsih_cb_idx);
        mpt2sas_base_release_callback_handler(config_cb_idx);
index 621b5e07275871808482316c7c3c0949ff7a30b7..6f589195746c3e7ba1774c6084e9753c9f3bd783 100644 (file)
@@ -732,6 +732,16 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = {
                .class_mask     = 0,
                .driver_data    = chip_9485,
        },
+       { PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */
+       { PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1041), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1042), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1043), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1044), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1080), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1083), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
+       { PCI_VDEVICE(OCZ, 0x1084), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
 
        { }     /* terminate list */
 };
index 86afb13f1e79daf521c4f835a63b4926ad422087..c06b8e5aa2cf3c2a488fa6f5af0455b54cf03e78 100644 (file)
@@ -40,6 +40,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <scsi/osd_initiator.h>
 #include <scsi/osd_sec.h>
index b86db84d6f325c98623233d1a884ffca787b0680..5163edb925cb33684702cc4c4b061a254c2b98df 100644 (file)
@@ -4102,7 +4102,7 @@ static long pmcraid_chr_ioctl(
        struct pmcraid_ioctl_header *hdr = NULL;
        int retval = -ENOTTY;
 
-       hdr = kmalloc(GFP_KERNEL, sizeof(struct pmcraid_ioctl_header));
+       hdr = kmalloc(sizeof(struct pmcraid_ioctl_header), GFP_KERNEL);
 
        if (!hdr) {
                pmcraid_err("faile to allocate memory for ioctl header\n");
index cd178b9e40cdde6d0266d103974357028a3e3807..959f10055be77cf2e9cf04e98d0229633cfa8489 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/cdrom.h>
 #include <linux/highmem.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <scsi/scsi.h>
index 3474e86e98ab65177ee02358585e4310f81dd61f..2516adf1aeeaa946372ac137da595d37466418c7 100644 (file)
@@ -2279,7 +2279,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
        ha = rsp->hw;
 
        /* Clear the interrupt, if enabled, for this response queue */
-       if (rsp->options & ~BIT_6) {
+       if (!ha->flags.disable_msix_handshake) {
                reg = &ha->iobase->isp24;
                spin_lock_irqsave(&ha->hardware_lock, flags);
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
index fc3f168decb4606cf479e5b6878236f9cfb5ca24..f85cfa6c47b5212982bcbfcd9065936c27360f3d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/mempool.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -1408,6 +1409,8 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
 
        blk_start_request(req);
 
+       scmd_printk(KERN_INFO, cmd, "killing request\n");
+
        sdev = cmd->device;
        starget = scsi_target(sdev);
        shost = sdev->host;
@@ -1489,7 +1492,6 @@ static void scsi_request_fn(struct request_queue *q)
        struct request *req;
 
        if (!sdev) {
-               printk("scsi: killing requests for dead queue\n");
                while ((req = blk_peek_request(q)) != NULL)
                        scsi_kill_request(req, q);
                return;
@@ -1698,6 +1700,15 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
 
 void scsi_free_queue(struct request_queue *q)
 {
+       unsigned long flags;
+
+       WARN_ON(q->queuedata);
+
+       /* cause scsi_request_fn() to kill all non-finished requests */
+       spin_lock_irqsave(q->queue_lock, flags);
+       q->request_fn(q);
+       spin_unlock_irqrestore(q->queue_lock, flags);
+
        blk_cleanup_queue(q);
 }
 
index dcd128583b89795c6294d79c2b61df6fdc0f3dd5..2ac3f3975f785f86843bcade103446ddc28d722a 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 
 #include <scsi/scsi.h>
index 26a8a45584ef844f02c9b31528918cc129e7c775..44f76e8b58af62a13467e9dc4e080c9e21584e68 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/security.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/netlink.h>
 
index d82a023a90154db7fe9e5a19b70eb738a009988f..d329f8b12e2b11503bd52b391bc198798aa1f297 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/pm_runtime.h>
+#include <linux/export.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
index 44e8ca398efa790083006131f5adb3bf37cd57aa..89da43f73c00ca209b816ecc68b70a95fbfc0888 100644 (file)
@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
                kfree(sdev);
                goto out;
        }
-       blk_get_queue(sdev->request_queue);
+       WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));
        sdev->request_queue->queuedata = sdev;
        scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 
@@ -319,10 +319,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
        return sdev;
 
 out_device_destroy:
-       scsi_device_set_state(sdev, SDEV_DEL);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       put_device(&sdev->sdev_gendev);
+       __scsi_remove_device(sdev);
 out:
        if (display_failure_msg)
                printk(ALLOC_FAILURE_MSG, __func__);
index 0172de19700874280447d563520feea7d901125d..6209110f295d22598b87053c875a01a709cc1bcd 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/gfp.h>
 #include <linux/file.h>
+#include <linux/export.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
index 1bcd65a509e693153493356e8690a2a1ef28ca15..96029e6d027fd654ad4a1f17272b74e0a215565c 100644 (file)
@@ -520,7 +520,7 @@ fail_host_msg:
 /**
  * iscsi_bsg_host_add - Create and add the bsg hooks to receive requests
  * @shost: shost for iscsi_host
- * @cls_host: iscsi_cls_host adding the structures to
+ * @ihost: iscsi_cls_host adding the structures to
  */
 static int
 iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost)
index a7942e5c8be8c91dfc3f5dd45ee96fa4195be987..fa3a5918009cfd9e9223a650a6c487585af36fa4 100644 (file)
@@ -2590,18 +2590,16 @@ static int sd_probe(struct device *dev)
                spin_unlock(&sd_index_lock);
        } while (error == -EAGAIN);
 
-       if (error)
+       if (error) {
+               sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n");
                goto out_put;
-
-       if (index >= SD_MAX_DISKS) {
-               error = -ENODEV;
-               sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n");
-               goto out_free_index;
        }
 
        error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
-       if (error)
+       if (error) {
+               sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name length exceeded.\n");
                goto out_free_index;
+       }
 
        sdkp->device = sdp;
        sdkp->driver = &sd_template;
index 6ad798bfd52a05b0c45de905756e0898c324e3f0..4163f2910e3de300ca7d2c37a2ef38fc65d59206 100644 (file)
@@ -8,12 +8,6 @@
  */
 #define SD_MAJORS      16
 
-/*
- * This is limited by the naming scheme enforced in sd_probe,
- * add another character to it if you really need more disks.
- */
-#define SD_MAX_DISKS   (((26 * 26) + 26 + 1) * 26)
-
 /*
  * Time out in seconds for disks and Magneto-opticals (which are slower).
  */
index 8be30554119bf0c9e88bc1ffef7cbbab33448676..a3911c39ea50ae1f0ff98c2108f1b40377b314da 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/blkpg.h>
 #include <linux/cdrom.h>
 #include <linux/delay.h>
index 1871b8ae83ae7031f73084470278c7a89ce8da96..9b28f39bac26b06dd8ce2f91e00e045436855abe 100644 (file)
@@ -462,14 +462,16 @@ static void st_scsi_execute_end(struct request *req, int uptodate)
 {
        struct st_request *SRpnt = req->end_io_data;
        struct scsi_tape *STp = SRpnt->stp;
+       struct bio *tmp;
 
        STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
        STp->buffer->cmdstat.residual = req->resid_len;
 
+       tmp = SRpnt->bio;
        if (SRpnt->waiting)
                complete(SRpnt->waiting);
 
-       blk_rq_unmap_user(SRpnt->bio);
+       blk_rq_unmap_user(tmp);
        __blk_put_request(req->q, req);
 }
 
index b7cf220d44ec575f31160926433eefc50653dd87..1d5cfe854cf7d536640c8a1b7e52aff5801ab121 100644 (file)
@@ -55,6 +55,9 @@
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 */
+
+#include <linux/sysfs.h>
+
 struct sfi_table_key{
        char    *sig;
        char    *oem_id;
index 24e6cec0ae8dfb51efbb704f6e37d0228ddcc3fe..67e272ab162310645f0c3339c7cd29987f3b4dd8 100644 (file)
@@ -7,3 +7,11 @@ obj-$(CONFIG_HAVE_CLK)         += clk/
 obj-$(CONFIG_MAPLE)            += maple/
 obj-$(CONFIG_SUPERHYWAY)       += superhyway/
 obj-$(CONFIG_GENERIC_GPIO)     += pfc.o
+
+#
+# For the moment we only use this framework for ARM-based SH/R-Mobile
+# platforms and generic SH. SH-based SH-Mobile platforms are still using
+# an older framework that is pending up-porting, at which point this
+# special casing can go away.
+#
+obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE)    += pm_runtime.o
index dc8d022c07a1505b2cc0bd86ccfb2e097c6f1f16..db257a35e71a545aa724b97d40dbdd6dbf1fe7f2 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/debugfs.h>
 #include <linux/cpufreq.h>
 #include <linux/clk.h>
 #include <linux/sh_clk.h>
@@ -173,6 +172,26 @@ long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
        return clk_rate_round_helper(&div_range_round);
 }
 
+static long clk_rate_mult_range_iter(unsigned int pos,
+                                     struct clk_rate_round_data *rounder)
+{
+       return clk_get_rate(rounder->arg) * pos;
+}
+
+long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
+                              unsigned int mult_max, unsigned long rate)
+{
+       struct clk_rate_round_data mult_range_round = {
+               .min    = mult_min,
+               .max    = mult_max,
+               .func   = clk_rate_mult_range_iter,
+               .arg    = clk_get_parent(clk),
+               .rate   = rate,
+       };
+
+       return clk_rate_round_helper(&mult_range_round);
+}
+
 int clk_rate_table_find(struct clk *clk,
                        struct cpufreq_frequency_table *freq_table,
                        unsigned long rate)
@@ -205,9 +224,6 @@ int clk_reparent(struct clk *child, struct clk *parent)
                list_add(&child->sibling, &parent->children);
        child->parent = parent;
 
-       /* now do the debugfs renaming to reattach the child
-          to the proper parent */
-
        return 0;
 }
 
@@ -665,89 +681,6 @@ static int __init clk_syscore_init(void)
 subsys_initcall(clk_syscore_init);
 #endif
 
-/*
- *     debugfs support to trace clock tree hierarchy and attributes
- */
-static struct dentry *clk_debugfs_root;
-
-static int clk_debugfs_register_one(struct clk *c)
-{
-       int err;
-       struct dentry *d;
-       struct clk *pa = c->parent;
-       char s[255];
-       char *p = s;
-
-       p += sprintf(p, "%p", c);
-       d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
-       if (!d)
-               return -ENOMEM;
-       c->dentry = d;
-
-       d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       return 0;
-
-err_out:
-       debugfs_remove_recursive(c->dentry);
-       return err;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
-       int err;
-       struct clk *pa = c->parent;
-
-       if (pa && !pa->dentry) {
-               err = clk_debugfs_register(pa);
-               if (err)
-                       return err;
-       }
-
-       if (!c->dentry) {
-               err = clk_debugfs_register_one(c);
-               if (err)
-                       return err;
-       }
-       return 0;
-}
-
-static int __init clk_debugfs_init(void)
-{
-       struct clk *c;
-       struct dentry *d;
-       int err;
-
-       d = debugfs_create_dir("clock", NULL);
-       if (!d)
-               return -ENOMEM;
-       clk_debugfs_root = d;
-
-       list_for_each_entry(c, &clock_list, node) {
-               err = clk_debugfs_register(c);
-               if (err)
-                       goto err_out;
-       }
-       return 0;
-err_out:
-       debugfs_remove_recursive(clk_debugfs_root);
-       return err;
-}
-late_initcall(clk_debugfs_init);
-
 static int __init clk_late_init(void)
 {
        unsigned long flags;
index e0ada37737862b703f312c3a9eef5327cfe37fb3..7b246efa94ea657de185facca3f622a47adfb9be 100644 (file)
@@ -186,7 +186,7 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
     !defined(CONFIG_CPU_SUBTYPE_SH7709)
        [IRQ_TYPE_LEVEL_HIGH] = VALID(3),
 #endif
-#if defined(CONFIG_ARCH_SH7372)
+#if defined(CONFIG_ARM) /* all recent SH-Mobile / R-Mobile ARM support this */
        [IRQ_TYPE_EDGE_BOTH] = VALID(4),
 #endif
 };
index c6ca115c71dfc57babfe3804494729d14f078b79..8b7a141ff35e848b5a505c0bb89e85daaa14ee05 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/interrupt.h>
 #include <linux/sh_intc.h>
 #include <linux/sysdev.h>
@@ -29,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/radix-tree.h>
+#include <linux/export.h>
 #include "internals.h"
 
 LIST_HEAD(intc_list);
index a3677c9dfe36e3fa6ebcac37bee81af58d9ece5c..5fea1ee8799afed9a7a028450df90e6c897060e1 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/bitmap.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include "internals.h" /* only for activate_irq() damage.. */
 
 /*
index 1e6e2d0353ea52987e6ef25a5baf42173c0cea03..c7ec49ffd9f63806a73b14e39ec6bbedbf6de8cf 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/radix-tree.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include "internals.h"
 
 static struct intc_map_entry intc_irq_xlate[NR_IRQS];
index 1e20604257af96e0ade525afadb014916a038744..bec81c2404f784e2cefd24a1cab92ab2aa845d88 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/maple.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 #include <asm/io.h>
diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
new file mode 100644 (file)
index 0000000..afe9282
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Runtime PM support code
+ *
+ *  Copyright (C) 2009-2010 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int default_platform_runtime_idle(struct device *dev)
+{
+       /* suspend synchronously to disable clocks immediately */
+       return pm_runtime_suspend(dev);
+}
+
+static struct dev_pm_domain default_pm_domain = {
+       .ops = {
+               .runtime_suspend = pm_clk_suspend,
+               .runtime_resume = pm_clk_resume,
+               .runtime_idle = default_platform_runtime_idle,
+               USE_PLATFORM_PM_SLEEP_OPS
+       },
+};
+
+#define DEFAULT_PM_DOMAIN_PTR  (&default_pm_domain)
+
+#else
+
+#define DEFAULT_PM_DOMAIN_PTR  NULL
+
+#endif /* CONFIG_PM_RUNTIME */
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+       .pm_domain = DEFAULT_PM_DOMAIN_PTR,
+       .con_ids = { NULL, },
+};
+
+static int __init sh_pm_runtime_init(void)
+{
+       pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+       return 0;
+}
+core_initcall(sh_pm_runtime_init);
+
+static int __init sh_pm_runtime_late_init(void)
+{
+       pm_genpd_poweroff_unused();
+       return 0;
+}
+late_initcall(sh_pm_runtime_late_init);
index a1fd73df5416129c62d8889f87c1d003b0b6b47c..8ba4510a95195392da12a65ce641ea5f164f3c20 100644 (file)
@@ -199,7 +199,7 @@ config SPI_FSL_LIB
        depends on FSL_SOC
 
 config SPI_FSL_SPI
-       tristate "Freescale SPI controller"
+       bool "Freescale SPI controller"
        depends on FSL_SOC
        select SPI_FSL_LIB
        help
@@ -208,7 +208,7 @@ config SPI_FSL_SPI
          MPC8569 uses the controller in QE mode, MPC8610 in cpu mode.
 
 config SPI_FSL_ESPI
-       tristate "Freescale eSPI controller"
+       bool "Freescale eSPI controller"
        depends on FSL_SOC
        select SPI_FSL_LIB
        help
index 881c1967741d396502caa94194a6aae4ac6a91c3..c00d00e96ee43784d8cd37715258f760a54bcbf8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index 024b48aed5ca6bba6f32857965e8904fe012ca1b..acc88b4d28693da4d59d315b350f0e717837e607 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
index 79665e2e6ec524b89f02c6aa680ca5b133009fa9..16d6a839c7faca2ea0f2bd7a948036d546fc46b6 100644 (file)
@@ -907,7 +907,7 @@ static void atmel_spi_cleanup(struct spi_device *spi)
 
 /*-------------------------------------------------------------------------*/
 
-static int __init atmel_spi_probe(struct platform_device *pdev)
+static int __devinit atmel_spi_probe(struct platform_device *pdev)
 {
        struct resource         *regs;
        int                     irq;
@@ -1003,7 +1003,7 @@ out_free:
        return ret;
 }
 
-static int __exit atmel_spi_remove(struct platform_device *pdev)
+static int __devexit atmel_spi_remove(struct platform_device *pdev)
 {
        struct spi_master       *master = platform_get_drvdata(pdev);
        struct atmel_spi        *as = spi_master_get_devdata(master);
@@ -1072,6 +1072,7 @@ static struct platform_driver atmel_spi_driver = {
        },
        .suspend        = atmel_spi_suspend,
        .resume         = atmel_spi_resume,
+       .probe          = atmel_spi_probe,
        .remove         = __exit_p(atmel_spi_remove),
 };
 module_platform_driver(atmel_spi_driver);
index bddee5f516b2cb1af1e8e5ac4e3292a065f14c91..5784c8799616dac41c81a872b8cf758204cd8085 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
index 02d57fbba2952cd8a84c1803e1c57d0fa976d06d..aef59b1a15f7f13881cd82f21864eb5ec59712b3 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
index 9f907ec52defa1cf74a46a9936939269cd83421d..5ed08e5374335e2fcefe76a73bf5d2718d621ce4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/parport.h>
 
index fac399c3022cd4a1045ac09f962309d9e9c63d23..db2f1ba06eaba180a5f7a2a833907ec351aadc35 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/scatterlist.h>
+#include <linux/module.h>
 
 #include "spi-dw.h"
 
index c5f37f03ac8bf3dbf99c4721703ce4d35c3d8e40..f64250ea161100be2d9ddc2708ee95e7a684d194 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
+#include <linux/module.h>
 
 #include "spi-dw.h"
 
index 296d94f4cf723cea761c225b3497e5d01bcbb6f5..082458d73ce9798d38bb494840d3bec058650643 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/highmem.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
index 635ff08b377f999c5f46ca21603272c97f60e277..0094c645ff0d4cc4562412ef020e6ba838966779 100644 (file)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
@@ -255,7 +256,7 @@ static void spi_gpio_cleanup(struct spi_device *spi)
        spi_bitbang_cleanup(spi);
 }
 
-static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
+static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
 {
        int value;
 
@@ -269,7 +270,7 @@ static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
        return value;
 }
 
-static int __init
+static int __devinit
 spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label,
        u16 *res_flags)
 {
index e763254741c296169b6d662d5f398c1a90170cc2..182e9c873822a64b6e9e25976470044eae8bc338 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
@@ -426,7 +427,7 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev)
                goto err_clk;
        }
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
        nuc900_init_spi(hw);
 
        err = spi_bitbang_start(&hw->bitbang);
index 897274e8715c1913413d96b483f4fdc4f70553bf..698018fd992b57f6875df66d29207fe0384b1c9b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
index 00a8e9d7dbe4ae3a21b57e728ff1027fe43aea96..610f7391456eadaaa33cd3f610a2e0503cbeb527 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
index 9421a390a5e3a3fcfe32046108a26938d4cf7eaf..13448c832c4420094afc5f57d8abd5a8b729ae7a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/orion_spi.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 
 #define DRIVER_NAME                    "orion_spi"
index f103e470cb6362e248a264576e457e03f0ab5409..5559b229919870fad59680b722e1390585ba61ca 100644 (file)
@@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
                goto  err_clk_prep;
        }
 
+       status = clk_enable(pl022->clk);
+       if (status) {
+               dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
+               goto err_no_clk_en;
+       }
+
        /* Disable SSP */
        writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
               SSP_CR1(pl022->virtbase));
@@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
        free_irq(adev->irq[0], pl022);
  err_no_irq:
+       clk_disable(pl022->clk);
+ err_no_clk_en:
        clk_unprepare(pl022->clk);
  err_clk_prep:
        clk_put(pl022->clk);
index 378e504f89ebdf8dd7b2b503e6c3a79d8820f269..8caa07d58e69cc4f9097ae33fe10a6b3ff2a26e8 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
+#include <linux/module.h>
 #include <linux/spi/pxa2xx_spi.h>
 
 struct ce4100_info {
index b857a3e7af949138d136872339d17231bc7830dc..fc064535f4fceebbade550885518402b5584bf98 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
 
 #include <plat/regs-spi.h>
 #include <mach/spi.h>
index 0f4834ae28cdea08f0ff995708001a2a2c67cf56..1f466bc66d9df21e92dc5b638272214b243b333b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
index 8844bc3427824209808519db50eb94fdaccb4b8d..097e506042bee82762e729d48cd515bc62b9146b 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
+#include <linux/module.h>
 
 #include <asm/spi.h>
 #include <asm/io.h>
index 7963c60063d6843bae1aea0d63dea4d7d80f13d0..3f6f6e81c65553a61bb146b66725b7473b5e5115 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/err.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/ti_ssp.h>
index 940e73d1cf09920e0967c76ef0e22cd70c6e2103..0ce5c12aab5520d3761f33c7e3cf34530aabd8e2 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include <linux/spi/spi.h>
index f0a2ab0428a36306f017bc6abfd8b1c6a44443bc..d5a3cbb646cb45a3e3dbd97adb8f6b163f7220c2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <asm/gpio.h>
 
 
index 4d1b9f517ce842011ecf377257dae53eb429563f..77eae99af11ce7ee1541816f3e8c99b352b7a241 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/spi/spi.h>
 #include <linux/of_spi.h>
 #include <linux/pm_runtime.h>
+#include <linux/export.h>
 
 static void spidev_release(struct device *dev)
 {
index bf53e44c82a1f48c2d8dca06d55b29db21935cba..bad7ba517a1c8f0d1b0e925e033d91a35fb2e849 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <linux/ssb/ssb.h>
 
 #include "ssb_private.h"
index 5d9c97c24797200c3b69634ff29f75271977d1b4..e9d2ca11283b3e60fd8d63a31bf59b739135739e 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 
 #include "ssb_private.h"
index 52901c14c68b47a36da5d74452f31eaede9ea7ed..e5a2e0e9bc19bbf586c49cc06b49f35cb16c5a88 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ssb/ssb_regs.h>
 #include <linux/ssb/ssb_driver_chipcommon.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include "ssb_private.h"
 
index 3adb98dad70cd34d82f7031cc1b399916f9e197c..f30ea689933a8be5608c1a0cc331b075a10051fd 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_driver_gige.h>
+#include <linux/export.h>
 #include <linux/pci.h>
 #include <linux/pci_regs.h>
 #include <linux/slab.h>
index e6ac3177fbbe57437fe0844457ffcbed784c8f21..84c934c0a5455950f1244de76ebcfe3b8b5a4aaf 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/ssb/ssb.h>
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/ssb/ssb_embedded.h>
 
index eec3e267be4d5038be0d569926944a3c841f5d5e..9ef124f9ee2d4e73f20db392e45b29b7c558ec00 100644 (file)
@@ -8,6 +8,7 @@
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
+#include <linux/export.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
 #include <linux/ssb/ssb_driver_pci.h>
index d0cbdb0cf9d53a12099fdafd2cc5f14d291a36d2..bb6317fb925ce922908e0053e9acc740cc7fe541 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_regs.h>
 #include <linux/ssb/ssb_driver_gige.h>
index 116a8116984b2479038adb1f2da6574eef7ec7b4..af5448f5e2d2242b86fff652fe58c0f8d3219b67 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/ssb/ssb.h>
 
index 21d8c1c16cd891e42bf1621d7ff1ba8f0dc5e580..5e78c77d5a08277611c183c92dae273362caed58 100644 (file)
@@ -671,7 +671,7 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
        }
 
        insns =
-           kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+           kcalloc(insnlist.n_insns, sizeof(struct comedi_insn), GFP_KERNEL);
        if (!insns) {
                DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
@@ -1432,7 +1432,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        return ret;
 }
 
-static void comedi_unmap(struct vm_area_struct *area)
+
+static void comedi_vm_open(struct vm_area_struct *area)
+{
+       struct comedi_async *async;
+       struct comedi_device *dev;
+
+       async = area->vm_private_data;
+       dev = async->subdevice->device;
+
+       mutex_lock(&dev->mutex);
+       async->mmap_count++;
+       mutex_unlock(&dev->mutex);
+}
+
+static void comedi_vm_close(struct vm_area_struct *area)
 {
        struct comedi_async *async;
        struct comedi_device *dev;
@@ -1446,15 +1460,13 @@ static void comedi_unmap(struct vm_area_struct *area)
 }
 
 static struct vm_operations_struct comedi_vm_ops = {
-       .close = comedi_unmap,
+       .open = comedi_vm_open,
+       .close = comedi_vm_close,
 };
 
 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
 {
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_async *async = NULL;
        unsigned long start = vma->vm_start;
        unsigned long size;
@@ -1462,6 +1474,15 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        int i;
        int retval;
        struct comedi_subdevice *s;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+
+       dev_file_info = comedi_get_device_file_info(minor);
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1528,11 +1549,17 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
 {
        unsigned int mask = 0;
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_subdevice *read_subdev;
        struct comedi_subdevice *write_subdev;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1578,9 +1605,15 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1640,11 +1673,11 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                                retval = -EAGAIN;
                                break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       schedule();
                        if (!s->busy)
                                break;
                        if (s->busy != file) {
@@ -1683,9 +1716,15 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1741,11 +1780,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
                                retval = -EAGAIN;
                                break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       schedule();
                        if (!s->busy) {
                                retval = 0;
                                break;
@@ -1885,11 +1924,17 @@ ok:
 static int comedi_close(struct inode *inode, struct file *file)
 {
        const unsigned minor = iminor(inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_subdevice *s = NULL;
        int i;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
 
@@ -1923,10 +1968,15 @@ static int comedi_close(struct inode *inode, struct file *file)
 static int comedi_fasync(int fd, struct file *file, int on)
 {
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
 
-       struct comedi_device *dev = dev_file_info->device;
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        return fasync_helper(fd, file, on, &dev->async_queue);
 }
index a8fea9a9173349799c0f2f629d23ce30412cf356..6144afb8cbaaf92a1ca09dfa5404787d72ee35ed 100644 (file)
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v0.5"
+#define DRIVER_VERSION "v0.6"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"
 /*
@@ -25,7 +25,7 @@ Driver: usbduxsigma
 Description: University of Stirling USB DAQ & INCITE Technology Limited
 Devices: [ITL] USB-DUX (usbduxsigma.o)
 Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 21 Jul 2011
+Updated: 8 Nov 2011
 Status: testing
 */
 /*
@@ -44,6 +44,7 @@ Status: testing
  *   0.3: proper vendor ID and driver name
  *   0.4: fixed D/A voltage range
  *   0.5: various bug fixes, health check at startup
+ *   0.6: corrected wrong input range
  */
 
 /* generates loads of debug info */
@@ -175,7 +176,7 @@ Status: testing
 /* comedi constants */
 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
                                                                BIP_RANGE
-                                                               (2.65)
+                                                               (2.65/2.0)
                                                                }
 };
 
index 24e009c0149bc3c07c5733d862596771bf7a6b88..911c0e4375fd404ee4e3cb4e1c28e0f81f0079b3 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/types.h>
 #include <linux/netdevice.h>
+#include <linux/module.h>
 #include <linux/hdlc.h>
 #include <linux/if_arp.h>
 #include <linux/init.h>
index 9e1864c6dfd08caf355f1e0c3aa347d6b0386beb..8190f2aaf53bb88aaea8df5c025d6f83c2ee68d1 100644 (file)
@@ -1,6 +1,7 @@
 config ET131X
        tristate "Agere ET-1310 Gigabit Ethernet support"
-       depends on PCI
+       depends on PCI && NET && NETDEVICES
+       select PHYLIB
        default n
        ---help---
          This driver supports Agere ET-1310 ethernet adapters.
index f5f44a02456fd5aa20ae06b9b524dee1b1c01757..0c1c6ca8c3794de60d440f3dc33bb60f8ebb2e83 100644 (file)
@@ -4469,6 +4469,12 @@ static int et131x_resume(struct device *dev)
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume);
+#define ET131X_PM_OPS (&et131x_pm_ops)
+#else
+#define ET131X_PM_OPS NULL
+#endif
+
 /* ISR functions */
 
 /**
@@ -5470,12 +5476,6 @@ err_out:
        return result;
 }
 
-static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume);
-#define ET131X_PM_OPS (&et131x_pm_ops)
-#else
-#define ET131X_PM_OPS NULL
-#endif
-
 static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = {
        { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL},
        { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL},
index e33432df510ca0934b7be02e6610f1160f131f85..51cbf65268e6f747bcd00ee932b44958087226e2 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/export.h>
 
 #include "psb_drv.h"
 #include "psb_intel_reg.h"
index 9050c0f78b15b1c964ed7f35a576bda9f9bdf96d..3f979db2c3a5460e3f2d17f1b0d56f6ff2fae9f2 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/intel_scu_ipc.h>
 #include "mdfld_dsi_pkg_sender.h"
 #include <linux/pm_runtime.h>
+#include <linux/moduleparam.h>
 
 #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
 
index ee55f87ba1fda419f5416018789dea3b89a2a388..eabf53d58f923baa07a574f6787a92993c55658c 100644 (file)
@@ -26,6 +26,7 @@
 */
 
 #include <linux/init.h>
+#include <linux/moduleparam.h>
 #include "mdfld_dsi_dbi.h"
 #include "mdfld_dsi_dpi.h"
 #include "mdfld_dsi_output.h"
@@ -167,4 +168,4 @@ void mdfld_output_setup(struct drm_device *dev)
                else
                        mdfld_dbi_dsr_init(dev);
        }
-}
\ No newline at end of file
+}
index 8cfe301f8fb20900477cde5dae5213bc4e4064ed..ee3c0368e3200ab30cebb12bc36a2bcf77e86fa5 100644 (file)
@@ -23,6 +23,7 @@
  * - Check ioremap failures
  */
 
+#include <linux/moduleparam.h>
 #include <drm/drmP.h>
 #include <drm/drm.h>
 #include "psb_drm.h"
index 351b9d897b9fd45bd31793c3fb2bd1a1e0e34486..36e7edc4d14c7b0c38679db46079b624dce70a1d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include "psb_drv.h"
 
 #define HDMI_READ(reg)         readl(hdmi_dev->regs + (reg))
index dc676c2ce810c1d5303a36f6b034424afe8ad652..986a04d16ba8641f2aaf4c265e3bb54087206186 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/notifier.h>
 #include <linux/spinlock.h>
 #include <linux/pm_runtime.h>
+#include <linux/module.h>
 #include <acpi/video.h>
 
 static int drm_psb_trap_pagefaults;
index dbd883294d6c024feba885bb8789201c28eb4abe..0016ed378e3a68e2236e725277d1bc25a8af4bc4 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index f448258884c5abbdee74214b327f59b7f48eae72..bce505e716d05f04f26a12a52f9fc9e5a4017593 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index 838d3012c87b43c369f3d78eae9d92a16a796ae5..1fdfe6f6ac6ec54fe2b09120c4759d5ece381941 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index 50165f9ddc52afe92d17590072a60b15ece48062..24bcb8e15c55d708e1735b3e2aff7af06ecfc95e 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index 08551bb48f18d4c2443f2adc2b7d855c5b6c3fd4..6fd3d8f51f2c48a5bc2f7b6615bb0b5da7da7176 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index 55b661c98d2db6ccde9e2f65d27e0d56898c95d4..6e542af02c095eebb4281d374dae7f8d10f0a11f 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index bb66364bef042e195f64b7cc8f18677ab627205c..d17e39d9545901480ee126c4f5a4a7385871a93a 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index 8df8a9791d5ea10bb92f077c3b4a9dc69904212b..c5d82c1a55d96f408ebb0797bb788a750ad47aa5 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index 34f1e7e6a56f35c89a96ef23a393d0ebc169afb4..b907ca3f4fdf5145a994f835c4f6a6869a5efcbf 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index 13f1d142eea3ed8bef37519fa87449e96d0c24f8..8e0ce568e64c29cf9048ae5044c85ef1c6b96072 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index 5c542dd046162eaf5fc5d1b32f5f34bf7f20d79b..89527af8f4c5aa30fd3c99dee46b52207027c93e 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../ring_sw.h"
index a831b92cd08250707cdaf1ff0783f19f00cf87ff..999f8f746cff5c7122d60675a4b9955466d8c052 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
index 48389e1c19f11fe058a8ecc170b4125c273aae59..974c6f5b60c4bd9758381035f4c3ebe42ffd87cd 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
index 38cf3f4bf726c582900af9f4940fadf524c51ffc..ff1b5a82b3d62d022ccb2cb13b0a941dcaabee0c 100644 (file)
@@ -6,6 +6,7 @@
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
index 679c1515571640e4d562bec3ed82140ce899f8c1..52a9e784e7c8f73b4bf575d688b5da5c4d6749cd 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/kernel.h>
index 2f2b2160f44d73b1812e929461f87bd761fd4a85..8299cd18d705f2b32445858942080377852c445e 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index f0b36d25414da2105270f40a14a655501f535f99..edad0e7b4f4d0e7a8f9eab4f19a6f6518daaaa11 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
index c3682458d78dbc3e042b9d87b973d03b410914ed..fd886bf51a6d8a2fd7a31472fe8e98c3924dcea5 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../ring_sw.h"
index bf991531e0d6dd0b243602236265e719cd9068f0..5bf0007575222377b2005ed6427b9d77b0e81689 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index 6dd5d7d629a162d7c74830728e2991209bceefc2..9df0ce81dadebce8d13f2e159669550637deab88 100644 (file)
@@ -14,6 +14,7 @@
  * - Alternative access techniques?
  */
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
index 326e967d54ef035258e7d4c325c4d6c26d731edc..aec9311b108c7c73b2b599c42976cbe99e1ca8b2 100644 (file)
@@ -242,19 +242,26 @@ static const struct file_operations iio_event_chrdev_fileops = {
 
 static int iio_event_getfd(struct iio_dev *indio_dev)
 {
-       if (indio_dev->event_interface == NULL)
+       struct iio_event_interface *ev_int = indio_dev->event_interface;
+       int fd;
+
+       if (ev_int == NULL)
                return -ENODEV;
 
-       mutex_lock(&indio_dev->event_interface->event_list_lock);
-       if (test_and_set_bit(IIO_BUSY_BIT_POS,
-                            &indio_dev->event_interface->flags)) {
-               mutex_unlock(&indio_dev->event_interface->event_list_lock);
+       mutex_lock(&ev_int->event_list_lock);
+       if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
+               mutex_unlock(&ev_int->event_list_lock);
                return -EBUSY;
        }
-       mutex_unlock(&indio_dev->event_interface->event_list_lock);
-       return anon_inode_getfd("iio:event",
-                               &iio_event_chrdev_fileops,
-                               indio_dev->event_interface, O_RDONLY);
+       mutex_unlock(&ev_int->event_list_lock);
+       fd = anon_inode_getfd("iio:event",
+                               &iio_event_chrdev_fileops, ev_int, O_RDONLY);
+       if (fd < 0) {
+               mutex_lock(&ev_int->event_list_lock);
+               clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
+               mutex_unlock(&ev_int->event_list_lock);
+       }
+       return fd;
 }
 
 static int __init iio_init(void)
index 99ade658a2dcc048edbec37c76907de7a167d4cb..00fa2ac5c4597636ef4ffa7050bc1b64464e5c9e 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Licensed under the GPL-2.
  */
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
index 392dfe30244335ca5ddab0764f0ee4fa58ed8dc8..b6569c706651dffb8a0776ebf92aa0b9a0ea449c 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
+#include <linux/export.h>
 
 #include "../iio.h"
 #include "../trigger.h"
index c303d85011b03f9b1cbb22a27aff96ead4dbe84e..ff9aaec0557f232e12108de124638a5cf58d1080 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/firmware.h>
 #include <linux/miscdevice.h>
 #include <linux/pm_runtime.h>
+#include <linux/module.h>
 #include <asm/mrst.h>
 #include "intel_sst.h"
 #include "intel_sst_ioctl.h"
index 69daa1404b68f740752921d1ca13c840fba92b6d..22bd29c0c439055a73c97f0ec1652c193ba56293 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/fs.h>
 #include <linux/firmware.h>
 #include <linux/pm_runtime.h>
+#include <linux/export.h>
 #include "intel_sst.h"
 #include "intel_sst_ioctl.h"
 #include "intel_sst_fw_ipc.h"
index 61db1f99b0c8ffe5c62eae7b8ad505da141de5df..8e7398393a592d1491aa64867f727ecedce748d5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <sound/core.h>
 #include <sound/initval.h>
+#include <linux/export.h>
 
 #include "driver.h"
 #include "audio.h"
index d335c7d6fa0f849ac22dbdbe526948dafb5e872b..828526d4c28985221e6b6ebba019053e1a137d21 100644 (file)
@@ -32,8 +32,8 @@
 #include "as102_fw.h"
 #include "dvbdev.h"
 
-int debug;
-module_param_named(debug, debug, int, 0644);
+int as102_debug;
+module_param_named(debug, as102_debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
 
 int dual_tuner;
index bcda635b5a9967454f95c843ccf4ae4c42a22d15..fd33f5a12dcc2167cf9dada508b13521f7159b8f 100644 (file)
@@ -37,7 +37,8 @@ extern struct spi_driver as102_spi_driver;
 #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
 #define DRIVER_NAME "as10x_usb"
 
-extern int debug;
+extern int as102_debug;
+#define debug  as102_debug
 
 #define dprintk(debug, args...) \
        do { if (debug) {       \
index 59274bfca95bf53182f2800aae636ad0d91a7725..2cd0de28a633eb7ca74386baff9199e870748b30 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/slab.h>
 #include <linux/freezer.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index b445cd63f901dc4299d55eef54c6675151d8387a..2542c37439049e8e878f29600b8d08c7f6635cd3 100644 (file)
@@ -275,7 +275,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
-                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page) + fs->page_offset));
+                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));
                        hw_buffer.s.size = fs->size;
                        CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
                }
index 3b32f9e6e4f09a38f62afb07038286790e2d8f60..87c9cdc8bd29866446783f85e09d4c923ed9c7f5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_eh.h>
index 480b0ed2e4de8975ea315504190c5eff02e5ac59..115635f9502456d7e8e3f16470b7f4a269b23b5b 100644 (file)
@@ -1021,6 +1021,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci,
        th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan");
        if (IS_ERR(th)) {
                printk(KERN_ERR "Unable to start the device-scanning thread\n");
+               complete(&dev->scanning_done);
                quiesce_and_remove_host(dev);
                err = PTR_ERR(th);
                goto errout;
index 5cde96b2e6e17d10c71f03a1e8e13fcb78179e6a..5c2a15b42dfede39997352cc7289871bd4dfd161 100644 (file)
@@ -1,6 +1,6 @@
 config SLICOSS
        tristate "Alacritech Gigabit IS-NIC support"
-       depends on PCI && X86
+       depends on PCI && X86 && NET
        default n
        help
          This driver supports Alacritech's IS-NIC gigabit ethernet cards.
index 2bd34662beb5bea4e8606bbc3dcaf20f64d4b6f6..a9c309a167c2d43f71c79b670a4e00d6e76b567f 100644 (file)
@@ -340,7 +340,7 @@ u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
                struct mtd_oob_ops ops;
                int ret;
 
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.datbuf = read_data;
                ops.len = DeviceInfo.wPageDataSize;
                ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
@@ -400,7 +400,7 @@ u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
                struct mtd_oob_ops ops;
                int ret;
 
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.datbuf = write_data;
                ops.len = DeviceInfo.wPageDataSize;
                ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
@@ -473,7 +473,7 @@ u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
                struct mtd_oob_ops ops;
                int ret;
 
-               ops.mode = MTD_OOB_AUTO;
+               ops.mode = MTD_OPS_AUTO_OOB;
                ops.datbuf = NULL;
                ops.len = 0;
                ops.oobbuf = read_data;
index f4b53d103c54e8533f487c5467e05ed7cd79d8cb..3b7a847f4657c38f6db0a42a3db80a1afac9843e 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/sock.h>
 
 #include "usbip_common.h"
index ecd1862539cd7a91786711da0575cb8c005c9cd7..d332a34ddb6d125f7e737d8abe146f12750f8faa 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/export.h>
 
 #include "usbip_common.h"
 
index 09c44abb89e8239c322bacb1671418dcd4b32e0a..3872b8cccdcf715067f273e091f3fd2cf419d6ac 100644 (file)
@@ -68,6 +68,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 {
        struct usbip_device *ud = &vdev->ud;
        struct urb *urb;
+       unsigned long flags;
 
        spin_lock(&vdev->priv_lock);
        urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
@@ -101,9 +102,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 
        usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
-       spin_lock(&the_controller->lock);
+       spin_lock_irqsave(&the_controller->lock, flags);
        usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
-       spin_unlock(&the_controller->lock);
+       spin_unlock_irqrestore(&the_controller->lock, flags);
 
        usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
 
@@ -141,6 +142,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 {
        struct vhci_unlink *unlink;
        struct urb *urb;
+       unsigned long flags;
 
        usbip_dump_header(pdu);
 
@@ -170,9 +172,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
                urb->status = pdu->u.ret_unlink.status;
                pr_info("urb->status %d\n", urb->status);
 
-               spin_lock(&the_controller->lock);
+               spin_lock_irqsave(&the_controller->lock, flags);
                usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
-               spin_unlock(&the_controller->lock);
+               spin_unlock_irqrestore(&the_controller->lock, flags);
 
                usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
                                     urb->status);
index a2e8bd452ed9dfed2ae3f324b19cab9e0672075f..f958eb4f0d8146ffb18a667a295802b36b6fdb75 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <net/mac80211.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 
 #include "core.h"
 #include "mds_f.h"
index 321580267feda4a7840dc3523361b2f73f970263..2faee2dd4bb1a801773f65b29cfb6efaf574f963 100644 (file)
@@ -82,6 +82,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
index 4d01768fcd90f1483ac0e8d9819ad992b8a46232..8599545cdf9e6d6c90a07510844f6290ab0a1be6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kthread.h>
 #include <linux/crypto.h>
 #include <linux/completion.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 #include <scsi/scsi_device.h>
 #include <scsi/iscsi_proto.h>
@@ -613,13 +614,12 @@ int iscsit_add_reject(
        hdr     = (struct iscsi_reject *) cmd->pdu;
        hdr->reason = reason;
 
-       cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
+       cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
        if (!cmd->buf_ptr) {
                pr_err("Unable to allocate memory for cmd->buf_ptr\n");
                iscsit_release_cmd(cmd);
                return -1;
        }
-       memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN);
 
        spin_lock_bh(&conn->cmd_lock);
        list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
@@ -660,13 +660,12 @@ int iscsit_add_reject_from_cmd(
        hdr     = (struct iscsi_reject *) cmd->pdu;
        hdr->reason = reason;
 
-       cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
+       cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
        if (!cmd->buf_ptr) {
                pr_err("Unable to allocate memory for cmd->buf_ptr\n");
                iscsit_release_cmd(cmd);
                return -1;
        }
-       memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN);
 
        if (add_to_conn) {
                spin_lock_bh(&conn->cmd_lock);
@@ -1016,11 +1015,6 @@ done:
                                " non-existent or non-exported iSCSI LUN:"
                                " 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
                }
-               if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES)
-                       return iscsit_add_reject_from_cmd(
-                                       ISCSI_REASON_BOOKMARK_NO_RESOURCES,
-                                       1, 1, buf, cmd);
-
                send_check_condition = 1;
                goto attach_cmd;
        }
@@ -1043,6 +1037,8 @@ done:
                 */
                send_check_condition = 1;
        } else {
+               cmd->data_length = cmd->se_cmd.data_length;
+
                if (iscsit_decide_list_to_build(cmd, payload_length) < 0)
                        return iscsit_add_reject_from_cmd(
                                ISCSI_REASON_BOOKMARK_NO_RESOURCES,
@@ -1079,7 +1075,9 @@ attach_cmd:
         */
        if (!cmd->immediate_data) {
                cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
-               if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+               if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+                       return 0;
+               else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
                        return iscsit_add_reject_from_cmd(
                                ISCSI_REASON_PROTOCOL_ERROR,
                                1, 0, buf, cmd);
@@ -1120,7 +1118,7 @@ attach_cmd:
         * the backend memory allocation.
         */
        ret = transport_generic_new_cmd(&cmd->se_cmd);
-       if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) {
+       if (ret < 0) {
                immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
                dump_immediate_data = 1;
                goto after_immediate_data;
@@ -1338,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
 
                spin_lock_irqsave(&se_cmd->t_state_lock, flags);
                if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) ||
-                    (se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED))
+                    (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
                        dump_unsolicited_data = 1;
                spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
 
@@ -1819,17 +1817,16 @@ attach:
                int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
                if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
                        out_of_order_cmdsn = 1;
-               else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+               else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
                        return 0;
-               } else { /* (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) */
+               else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
                        return iscsit_add_reject_from_cmd(
                                        ISCSI_REASON_PROTOCOL_ERROR,
                                        1, 0, buf, cmd);
-               }
        }
        iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
 
-       if (out_of_order_cmdsn)
+       if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
                return 0;
        /*
         * Found the referenced task, send to transport for processing.
@@ -2511,10 +2508,10 @@ static int iscsit_send_data_in(
        if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
                if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
                        hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
-                       hdr->residual_count = cpu_to_be32(cmd->residual_count);
+                       hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
                } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
                        hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
-                       hdr->residual_count = cpu_to_be32(cmd->residual_count);
+                       hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
                }
        }
        hton24(hdr->dlength, datain.length);
@@ -3016,10 +3013,10 @@ static int iscsit_send_status(
        hdr->flags              |= ISCSI_FLAG_CMD_FINAL;
        if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
                hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW;
-               hdr->residual_count = cpu_to_be32(cmd->residual_count);
+               hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
        } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
                hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
-               hdr->residual_count = cpu_to_be32(cmd->residual_count);
+               hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
        }
        hdr->response           = cmd->iscsi_response;
        hdr->cmd_status         = cmd->se_cmd.scsi_status;
@@ -3131,6 +3128,7 @@ static int iscsit_send_task_mgt_rsp(
        hdr                     = (struct iscsi_tm_rsp *) cmd->pdu;
        memset(hdr, 0, ISCSI_HDR_LEN);
        hdr->opcode             = ISCSI_OP_SCSI_TMFUNC_RSP;
+       hdr->flags              = ISCSI_FLAG_CMD_FINAL;
        hdr->response           = iscsit_convert_tcm_tmr_rsp(se_tmr);
        hdr->itt                = cpu_to_be32(cmd->init_task_tag);
        cmd->stat_sn            = conn->stat_sn++;
index beb39469e7f1e4f91c971f6da468c742a338699d..1cd6ce373b83508fd396f82b80290b91372c9e96 100644 (file)
 
 static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len)
 {
-       int j = DIV_ROUND_UP(len, 2);
+       int j = DIV_ROUND_UP(len, 2), rc;
 
-       hex2bin(dst, src, j);
+       rc = hex2bin(dst, src, j);
+       if (rc < 0)
+               pr_debug("CHAP string contains non hex digit symbols\n");
 
        dst[j] = '\0';
        return j;
index f1643dbf6a92923d9a55fcc9732ded891a7afaa6..db327845e46b46fc04d6f2be7a21d68d9aa53d53 100644 (file)
@@ -20,6 +20,7 @@
  ****************************************************************************/
 
 #include <linux/configfs.h>
+#include <linux/export.h>
 #include <target/target_core_base.h>
 #include <target/target_core_transport.h>
 #include <target/target_core_fabric_ops.h>
index 3723d90d5ae573db84b658fbd70bf2cd7a82bafa..f1a02dad05a02855b4ef59a6341e4bb61660ef30 100644 (file)
@@ -398,7 +398,6 @@ struct iscsi_cmd {
        u32                     pdu_send_order;
        /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */
        u32                     pdu_start;
-       u32                     residual_count;
        /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */
        u32                     seq_send_order;
        /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */
@@ -535,7 +534,6 @@ struct iscsi_conn {
        atomic_t                connection_exit;
        atomic_t                connection_recovery;
        atomic_t                connection_reinstatement;
-       atomic_t                connection_wait;
        atomic_t                connection_wait_rcfr;
        atomic_t                sleep_on_conn_wait_comp;
        atomic_t                transport_failed;
@@ -643,7 +641,6 @@ struct iscsi_session {
        atomic_t                session_reinstatement;
        atomic_t                session_stop_active;
        atomic_t                sleep_on_sess_wait_comp;
-       atomic_t                transport_wait_cmds;
        /* connection list */
        struct list_head        sess_conn_list;
        struct list_head        cr_active_list;
index c4c68da3e5004b3fa39eeb71829bbefab4e38632..101b1beb3bca205aed7611ec4424f54cc5b20671 100644 (file)
@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
                 * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
                 */
                if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
-                       if (se_cmd->se_cmd_flags &
-                                       SCF_SCSI_RESERVATION_CONFLICT) {
+                       if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) {
                                cmd->i_state = ISTATE_SEND_STATUS;
                                spin_unlock_bh(&cmd->istate_lock);
                                iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
index daad362a93cecebeca5c9bcce26233da3b202df1..d734bdec24f9cf2b451a7f905b07fab421a19b3b 100644 (file)
@@ -224,7 +224,7 @@ static int iscsi_login_zero_tsih_s1(
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
                pr_err("Could not allocate memory for session\n");
-               return -1;
+               return -ENOMEM;
        }
 
        iscsi_login_set_conn_values(sess, conn, pdu->cid);
@@ -250,7 +250,8 @@ static int iscsi_login_zero_tsih_s1(
                pr_err("idr_pre_get() for sess_idr failed\n");
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
-               return -1;
+               kfree(sess);
+               return -ENOMEM;
        }
        spin_lock(&sess_idr_lock);
        idr_get_new(&sess_idr, NULL, &sess->session_index);
@@ -270,14 +271,16 @@ static int iscsi_login_zero_tsih_s1(
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
                pr_err("Unable to allocate memory for"
                                " struct iscsi_sess_ops.\n");
-               return -1;
+               kfree(sess);
+               return -ENOMEM;
        }
 
        sess->se_sess = transport_init_session();
-       if (!sess->se_sess) {
+       if (IS_ERR(sess->se_sess)) {
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
-               return -1;
+               kfree(sess);
+               return -ENOMEM;
        }
 
        return 0;
index 426cd4bf6a9aab344425723cd51766aa932cc536..98936cb7c2947ceb0edbaa41dda91d6641a9b892 100644 (file)
@@ -981,14 +981,13 @@ struct iscsi_login *iscsi_target_init_negotiation(
                return NULL;
        }
 
-       login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
+       login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL);
        if (!login->req) {
                pr_err("Unable to allocate memory for Login Request.\n");
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
                goto out;
        }
-       memcpy(login->req, login_pdu, ISCSI_HDR_LEN);
 
        login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
        if (!login->req_buf) {
index bbdbe9301b27e3e1561d9b45fa7f9a6181145bf9..f1db83077e0a8418d448a7d9b210cc63014b1d3c 100644 (file)
@@ -20,6 +20,7 @@
  ******************************************************************************/
 
 #include <linux/configfs.h>
+#include <linux/export.h>
 #include <scsi/iscsi_proto.h>
 #include <target/target_core_base.h>
 #include <target/target_core_transport.h>
index b15d8cbf630b663065fdad8d77a7dd9b225cb982..81d5832fbbd537e7bbffe2c21b1792c1e7a2acde 100644 (file)
@@ -113,11 +113,9 @@ static struct se_cmd *tcm_loop_allocate_core_cmd(
                        scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr,
                        &tl_cmd->tl_sense_buf[0]);
 
-       /*
-        * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi
-        */
        if (scsi_bidi_cmnd(sc))
-               se_cmd->t_tasks_bidi = 1;
+               se_cmd->se_cmd_flags |= SCF_BIDI;
+
        /*
         * Locate the struct se_lun pointer and attach it to struct se_cmd
         */
@@ -148,46 +146,46 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
         * Allocate the necessary tasks to complete the received CDB+data
         */
        ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
-       if (ret == -ENOMEM) {
-               /* Out of Resources */
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
-       } else if (ret == -EINVAL) {
-               /*
-                * Handle case for SAM_STAT_RESERVATION_CONFLICT
-                */
-               if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
-                       return PYX_TRANSPORT_RESERVATION_CONFLICT;
-               /*
-                * Otherwise, return SAM_STAT_CHECK_CONDITION and return
-                * sense data.
-                */
-               return PYX_TRANSPORT_USE_SENSE_REASON;
-       }
-
+       if (ret != 0)
+               return ret;
        /*
         * For BIDI commands, pass in the extra READ buffer
         * to transport_generic_map_mem_to_cmd() below..
         */
-       if (se_cmd->t_tasks_bidi) {
+       if (se_cmd->se_cmd_flags & SCF_BIDI) {
                struct scsi_data_buffer *sdb = scsi_in(sc);
 
                sgl_bidi = sdb->table.sgl;
                sgl_bidi_count = sdb->table.nents;
        }
+       /*
+        * Because some userspace code via scsi-generic do not memset their
+        * associated read buffers, go ahead and do that here for type
+        * SCF_SCSI_CONTROL_SG_IO_CDB.  Also note that this is currently
+        * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB
+        * by target core in transport_generic_allocate_tasks() ->
+        * transport_generic_cmd_sequencer().
+        */
+       if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB &&
+           se_cmd->data_direction == DMA_FROM_DEVICE) {
+               struct scatterlist *sg = scsi_sglist(sc);
+               unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
+
+               if (buf != NULL) {
+                       memset(buf, 0, sg->length);
+                       kunmap(sg_page(sg));
+               }
+       }
 
        /* Tell the core about our preallocated memory */
-       ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
+       return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
                        scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
-       if (ret < 0)
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
-
-       return 0;
 }
 
 /*
  * Called from struct target_core_fabric_ops->check_stop_free()
  */
-static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
+static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
 {
        /*
         * Do not release struct se_cmd's containing a valid TMR
@@ -195,12 +193,13 @@ static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
         * with transport_generic_free_cmd().
         */
        if (se_cmd->se_tmr_req)
-               return;
+               return 0;
        /*
         * Release the struct se_cmd, which will make a callback to release
         * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
         */
        transport_generic_free_cmd(se_cmd, 0);
+       return 1;
 }
 
 static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
@@ -1341,17 +1340,16 @@ void tcm_loop_drop_scsi_hba(
 {
        struct tcm_loop_hba *tl_hba = container_of(wwn,
                                struct tcm_loop_hba, tl_hba_wwn);
-       int host_no = tl_hba->sh->host_no;
+
+       pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target"
+               " SAS Address: %s at Linux/SCSI Host ID: %d\n",
+               tl_hba->tl_wwn_address, tl_hba->sh->host_no);
        /*
         * Call device_unregister() on the original tl_hba->dev.
         * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
         * release *tl_hba;
         */
        device_unregister(&tl_hba->dev);
-
-       pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target"
-               " SAS Address: %s at Linux/SCSI Host ID: %d\n",
-               config_item_name(&wwn->wwn_group.cg_item), host_no);
 }
 
 /* Start items for tcm_loop_cit */
index 8f4447749c7141f245137cddca5bc44ca4d9da48..1dcbef499d6a09f2add951dee10c955f3541ccb8 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/configfs.h>
+#include <linux/export.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
@@ -58,8 +59,9 @@ struct t10_alua_lu_gp *default_lu_gp;
  *
  * See spc4r17 section 6.27
  */
-int core_emulate_report_target_port_groups(struct se_cmd *cmd)
+int target_emulate_report_target_port_groups(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
        struct se_port *port;
        struct t10_alua_tg_pt_gp *tg_pt_gp;
@@ -164,6 +166,8 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd)
 
        transport_kunmap_first_data_page(cmd);
 
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
@@ -172,8 +176,9 @@ int core_emulate_report_target_port_groups(struct se_cmd *cmd)
  *
  * See spc4r17 section 6.35
  */
-int core_emulate_set_target_port_groups(struct se_cmd *cmd)
+int target_emulate_set_target_port_groups(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        struct se_subsystem_dev *su_dev = dev->se_sub_dev;
        struct se_port *port, *l_port = cmd->se_lun->lun_sep;
@@ -186,9 +191,10 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
        int alua_access_state, primary = 0, rc;
        u16 tg_pt_id, rtpi;
 
-       if (!l_port)
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
-
+       if (!l_port) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
+       }
        buf = transport_kmap_first_data_page(cmd);
 
        /*
@@ -198,7 +204,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
        l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem;
        if (!l_tg_pt_gp_mem) {
                pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n");
-               rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               rc = -EINVAL;
                goto out;
        }
        spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -206,7 +213,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
        if (!l_tg_pt_gp) {
                spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock);
                pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n");
-               rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               rc = -EINVAL;
                goto out;
        }
        rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA);
@@ -215,7 +223,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
        if (!rc) {
                pr_debug("Unable to process SET_TARGET_PORT_GROUPS"
                                " while TPGS_EXPLICT_ALUA is disabled\n");
-               rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               rc = -EINVAL;
                goto out;
        }
 
@@ -240,7 +249,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
                         * REQUEST, and the additional sense code set to INVALID
                         * FIELD IN PARAMETER LIST.
                         */
-                       rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       rc = -EINVAL;
                        goto out;
                }
                rc = -1;
@@ -293,7 +303,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
                         * throw an exception with ASCQ: INVALID_PARAMETER_LIST
                         */
                        if (rc != 0) {
-                               rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                               rc = -EINVAL;
                                goto out;
                        }
                } else {
@@ -330,7 +341,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
                         * INVALID_PARAMETER_LIST
                         */
                        if (rc != 0) {
-                               rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                               rc = -EINVAL;
                                goto out;
                        }
                }
@@ -341,7 +353,8 @@ int core_emulate_set_target_port_groups(struct se_cmd *cmd)
 
 out:
        transport_kunmap_first_data_page(cmd);
-
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
@@ -1178,7 +1191,6 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
         * struct t10_alua_lu_gp.
         */
        spin_lock(&lu_gps_lock);
-       atomic_set(&lu_gp->lu_gp_shutdown, 1);
        list_del(&lu_gp->lu_gp_node);
        alua_lu_gps_count--;
        spin_unlock(&lu_gps_lock);
@@ -1432,7 +1444,6 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
 
        tg_pt_gp_mem->tg_pt = port;
        port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem;
-       atomic_set(&port->sep_tg_pt_gp_active, 1);
 
        return tg_pt_gp_mem;
 }
index c86f97a081edf8e348956e2f39785931be36bcf6..c5b4ecd3e745ceb61c27fb9b18020d34258b9c41 100644 (file)
@@ -66,8 +66,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
 extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
 extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
 
-extern int core_emulate_report_target_port_groups(struct se_cmd *);
-extern int core_emulate_set_target_port_groups(struct se_cmd *);
+extern int target_emulate_report_target_port_groups(struct se_task *);
+extern int target_emulate_set_target_port_groups(struct se_task *);
 extern int core_alua_check_nonop_delay(struct se_cmd *);
 extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
                                struct se_device *, struct se_port *,
index 38535eb13929ba5242e128629abfeadae409fc7a..831468b3163d777f3eb5c982fc05819d37dea3e6 100644 (file)
@@ -32,6 +32,7 @@
 #include <target/target_core_transport.h>
 #include <target/target_core_fabric_ops.h>
 #include "target_core_ua.h"
+#include "target_core_cdb.h"
 
 static void
 target_fill_alua_data(struct se_port *port, unsigned char *buf)
@@ -477,7 +478,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
        if (cmd->data_length < 60)
                return 0;
 
-       buf[2] = 0x3c;
+       buf[3] = 0x3c;
        /* Set HEADSUP, ORDSUP, SIMPSUP */
        buf[5] = 0x07;
 
@@ -679,16 +680,18 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
        return 0;
 }
 
-static int
-target_emulate_inquiry(struct se_cmd *cmd)
+int target_emulate_inquiry(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        unsigned char *buf;
        unsigned char *cdb = cmd->t_task_cdb;
        int p, ret;
 
-       if (!(cdb[1] & 0x1))
-               return target_emulate_inquiry_std(cmd);
+       if (!(cdb[1] & 0x1)) {
+               ret = target_emulate_inquiry_std(cmd);
+               goto out;
+       }
 
        /*
         * Make sure we at least have 4 bytes of INQUIRY response
@@ -700,6 +703,7 @@ target_emulate_inquiry(struct se_cmd *cmd)
        if (cmd->data_length < 4) {
                pr_err("SCSI Inquiry payload length: %u"
                        " too small for EVPD=1\n", cmd->data_length);
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
                return -EINVAL;
        }
 
@@ -707,22 +711,31 @@ target_emulate_inquiry(struct se_cmd *cmd)
 
        buf[0] = dev->transport->get_device_type(dev);
 
-       for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p)
+       for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) {
                if (cdb[2] == evpd_handlers[p].page) {
                        buf[1] = cdb[2];
                        ret = evpd_handlers[p].emulate(cmd, buf);
-                       transport_kunmap_first_data_page(cmd);
-                       return ret;
+                       goto out_unmap;
                }
+       }
 
-       transport_kunmap_first_data_page(cmd);
        pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]);
-       return -EINVAL;
+       cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+       ret = -EINVAL;
+
+out_unmap:
+       transport_kunmap_first_data_page(cmd);
+out:
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
+       return ret;
 }
 
-static int
-target_emulate_readcapacity(struct se_cmd *cmd)
+int target_emulate_readcapacity(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        unsigned char *buf;
        unsigned long long blocks_long = dev->transport->get_blocks(dev);
@@ -751,12 +764,14 @@ target_emulate_readcapacity(struct se_cmd *cmd)
 
        transport_kunmap_first_data_page(cmd);
 
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
-static int
-target_emulate_readcapacity_16(struct se_cmd *cmd)
+int target_emulate_readcapacity_16(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        unsigned char *buf;
        unsigned long long blocks = dev->transport->get_blocks(dev);
@@ -784,6 +799,8 @@ target_emulate_readcapacity_16(struct se_cmd *cmd)
 
        transport_kunmap_first_data_page(cmd);
 
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
@@ -922,14 +939,15 @@ target_modesense_dpofua(unsigned char *buf, int type)
        }
 }
 
-static int
-target_emulate_modesense(struct se_cmd *cmd, int ten)
+int target_emulate_modesense(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        char *cdb = cmd->t_task_cdb;
        unsigned char *rbuf;
        int type = dev->transport->get_device_type(dev);
-       int offset = (ten) ? 8 : 4;
+       int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
+       int offset = ten ? 8 : 4;
        int length = 0;
        unsigned char buf[SE_MODE_PAGE_BUF];
 
@@ -953,7 +971,8 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
        default:
                pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n",
                       cdb[2] & 0x3f, cdb[3]);
-               return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
+               cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
+               return -EINVAL;
        }
        offset += length;
 
@@ -995,12 +1014,14 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
        memcpy(rbuf, buf, offset);
        transport_kunmap_first_data_page(cmd);
 
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
-static int
-target_emulate_request_sense(struct se_cmd *cmd)
+int target_emulate_request_sense(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        unsigned char *cdb = cmd->t_task_cdb;
        unsigned char *buf;
        u8 ua_asc = 0, ua_ascq = 0;
@@ -1009,7 +1030,8 @@ target_emulate_request_sense(struct se_cmd *cmd)
        if (cdb[1] & 0x01) {
                pr_err("REQUEST_SENSE description emulation not"
                        " supported\n");
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -ENOSYS;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -1059,7 +1081,8 @@ target_emulate_request_sense(struct se_cmd *cmd)
 
 end:
        transport_kunmap_first_data_page(cmd);
-
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
@@ -1067,8 +1090,7 @@ end:
  * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
  * Note this is not used for TCM/pSCSI passthrough
  */
-static int
-target_emulate_unmap(struct se_task *task)
+int target_emulate_unmap(struct se_task *task)
 {
        struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
@@ -1079,6 +1101,13 @@ target_emulate_unmap(struct se_task *task)
        int ret = 0, offset;
        unsigned short dl, bd_dl;
 
+       if (!dev->transport->do_discard) {
+               pr_err("UNMAP emulation not supported for: %s\n",
+                               dev->transport->name);
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               return -ENOSYS;
+       }
+
        /* First UNMAP block descriptor starts at 8 byte offset */
        offset = 8;
        size -= 8;
@@ -1110,7 +1139,10 @@ target_emulate_unmap(struct se_task *task)
 
 err:
        transport_kunmap_first_data_page(cmd);
-
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
        return ret;
 }
 
@@ -1118,14 +1150,29 @@ err:
  * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
  * Note this is not used for TCM/pSCSI passthrough
  */
-static int
-target_emulate_write_same(struct se_task *task, u32 num_blocks)
+int target_emulate_write_same(struct se_task *task)
 {
        struct se_cmd *cmd = task->task_se_cmd;
        struct se_device *dev = cmd->se_dev;
        sector_t range;
        sector_t lba = cmd->t_task_lba;
+       u32 num_blocks;
        int ret;
+
+       if (!dev->transport->do_discard) {
+               pr_err("WRITE_SAME emulation not supported"
+                               " for: %s\n", dev->transport->name);
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               return -ENOSYS;
+       }
+
+       if (cmd->t_task_cdb[0] == WRITE_SAME)
+               num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]);
+       else if (cmd->t_task_cdb[0] == WRITE_SAME_16)
+               num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]);
+       else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */
+               num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]);
+
        /*
         * Use the explicit range when non zero is supplied, otherwise calculate
         * the remaining range based on ->get_blocks() - starting LBA.
@@ -1144,127 +1191,32 @@ target_emulate_write_same(struct se_task *task, u32 num_blocks)
                return ret;
        }
 
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
        return 0;
 }
 
-int
-transport_emulate_control_cdb(struct se_task *task)
+int target_emulate_synchronize_cache(struct se_task *task)
 {
+       struct se_device *dev = task->task_se_cmd->se_dev;
        struct se_cmd *cmd = task->task_se_cmd;
-       struct se_device *dev = cmd->se_dev;
-       unsigned short service_action;
-       int ret = 0;
 
-       switch (cmd->t_task_cdb[0]) {
-       case INQUIRY:
-               ret = target_emulate_inquiry(cmd);
-               break;
-       case READ_CAPACITY:
-               ret = target_emulate_readcapacity(cmd);
-               break;
-       case MODE_SENSE:
-               ret = target_emulate_modesense(cmd, 0);
-               break;
-       case MODE_SENSE_10:
-               ret = target_emulate_modesense(cmd, 1);
-               break;
-       case SERVICE_ACTION_IN:
-               switch (cmd->t_task_cdb[1] & 0x1f) {
-               case SAI_READ_CAPACITY_16:
-                       ret = target_emulate_readcapacity_16(cmd);
-                       break;
-               default:
-                       pr_err("Unsupported SA: 0x%02x\n",
-                               cmd->t_task_cdb[1] & 0x1f);
-                       return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               }
-               break;
-       case REQUEST_SENSE:
-               ret = target_emulate_request_sense(cmd);
-               break;
-       case UNMAP:
-               if (!dev->transport->do_discard) {
-                       pr_err("UNMAP emulation not supported for: %s\n",
-                                       dev->transport->name);
-                       return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               }
-               ret = target_emulate_unmap(task);
-               break;
-       case WRITE_SAME:
-               if (!dev->transport->do_discard) {
-                       pr_err("WRITE_SAME emulation not supported"
-                                       " for: %s\n", dev->transport->name);
-                       return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               }
-               ret = target_emulate_write_same(task,
-                               get_unaligned_be16(&cmd->t_task_cdb[7]));
-               break;
-       case WRITE_SAME_16:
-               if (!dev->transport->do_discard) {
-                       pr_err("WRITE_SAME_16 emulation not supported"
-                                       " for: %s\n", dev->transport->name);
-                       return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               }
-               ret = target_emulate_write_same(task,
-                               get_unaligned_be32(&cmd->t_task_cdb[10]));
-               break;
-       case VARIABLE_LENGTH_CMD:
-               service_action =
-                       get_unaligned_be16(&cmd->t_task_cdb[8]);
-               switch (service_action) {
-               case WRITE_SAME_32:
-                       if (!dev->transport->do_discard) {
-                               pr_err("WRITE_SAME_32 SA emulation not"
-                                       " supported for: %s\n",
-                                       dev->transport->name);
-                               return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-                       }
-                       ret = target_emulate_write_same(task,
-                               get_unaligned_be32(&cmd->t_task_cdb[28]));
-                       break;
-               default:
-                       pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"
-                                       " 0x%02x\n", service_action);
-                       break;
-               }
-               break;
-       case SYNCHRONIZE_CACHE:
-       case 0x91: /* SYNCHRONIZE_CACHE_16: */
-               if (!dev->transport->do_sync_cache) {
-                       pr_err("SYNCHRONIZE_CACHE emulation not supported"
-                               " for: %s\n", dev->transport->name);
-                       return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               }
-               dev->transport->do_sync_cache(task);
-               break;
-       case ALLOW_MEDIUM_REMOVAL:
-       case ERASE:
-       case REZERO_UNIT:
-       case SEEK_10:
-       case SPACE:
-       case START_STOP:
-       case TEST_UNIT_READY:
-       case VERIFY:
-       case WRITE_FILEMARKS:
-               break;
-       default:
-               pr_err("Unsupported SCSI Opcode: 0x%02x for %s\n",
-                       cmd->t_task_cdb[0], dev->transport->name);
-               return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+       if (!dev->transport->do_sync_cache) {
+               pr_err("SYNCHRONIZE_CACHE emulation not supported"
+                       " for: %s\n", dev->transport->name);
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               return -ENOSYS;
        }
 
-       if (ret < 0)
-               return ret;
-       /*
-        * Handle the successful completion here unless a caller
-        * has explictly requested an asychronous completion.
-        */
-       if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) {
-               task->task_scsi_status = GOOD;
-               transport_complete_task(task, 1);
-       }
+       dev->transport->do_sync_cache(task);
+       return 0;
+}
 
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+int target_emulate_noop(struct se_task *task)
+{
+       task->task_scsi_status = GOOD;
+       transport_complete_task(task, 1);
+       return 0;
 }
 
 /*
diff --git a/drivers/target/target_core_cdb.h b/drivers/target/target_core_cdb.h
new file mode 100644 (file)
index 0000000..ad6b1e3
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef TARGET_CORE_CDB_H
+#define TARGET_CORE_CDB_H
+
+int target_emulate_inquiry(struct se_task *task);
+int target_emulate_readcapacity(struct se_task *task);
+int target_emulate_readcapacity_16(struct se_task *task);
+int target_emulate_modesense(struct se_task *task);
+int target_emulate_request_sense(struct se_task *task);
+int target_emulate_unmap(struct se_task *task);
+int target_emulate_write_same(struct se_task *task);
+int target_emulate_synchronize_cache(struct se_task *task);
+int target_emulate_noop(struct se_task *task);
+
+#endif /* TARGET_CORE_CDB_H */
index e0c1e8a8dd4e2140e13d7adedb4c84d414b45725..93d4f6a1b7980c597c119ae7f7f0506d57846993 100644 (file)
@@ -67,9 +67,6 @@ static struct config_group target_core_hbagroup;
 static struct config_group alua_group;
 static struct config_group alua_lu_gps_group;
 
-static DEFINE_SPINLOCK(se_device_lock);
-static LIST_HEAD(se_dev_list);
-
 static inline struct se_hba *
 item_to_hba(struct config_item *item)
 {
@@ -2741,7 +2738,6 @@ static struct config_group *target_core_make_subdev(
                                " struct se_subsystem_dev\n");
                goto unlock;
        }
-       INIT_LIST_HEAD(&se_dev->se_dev_node);
        INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list);
        spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock);
        INIT_LIST_HEAD(&se_dev->t10_pr.registration_list);
@@ -2777,9 +2773,6 @@ static struct config_group *target_core_make_subdev(
                        " from allocate_virtdevice()\n");
                goto out;
        }
-       spin_lock(&se_device_lock);
-       list_add_tail(&se_dev->se_dev_node, &se_dev_list);
-       spin_unlock(&se_device_lock);
 
        config_group_init_type_name(&se_dev->se_dev_group, name,
                        &target_core_dev_cit);
@@ -2874,10 +2867,6 @@ static void target_core_drop_subdev(
        mutex_lock(&hba->hba_access_mutex);
        t = hba->transport;
 
-       spin_lock(&se_device_lock);
-       list_del(&se_dev->se_dev_node);
-       spin_unlock(&se_device_lock);
-
        dev_stat_grp = &se_dev->dev_stat_grps.stat_group;
        for (i = 0; dev_stat_grp->default_groups[i]; i++) {
                df_item = &dev_stat_grp->default_groups[i]->cg_item;
index f870c3bcfd829f1dd68795cd017553441234911f..9b8639425472d8322aab749c6ae03fb56ea2a377 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
 #include <linux/in.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
@@ -103,7 +104,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
                se_cmd->se_lun = deve->se_lun;
                se_cmd->pr_res_key = deve->pr_res_key;
                se_cmd->orig_fe_lun = unpacked_lun;
-               se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev;
                se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
        }
        spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags);
@@ -136,7 +136,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
                se_lun = &se_sess->se_tpg->tpg_virt_lun0;
                se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0;
                se_cmd->orig_fe_lun = 0;
-               se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev;
                se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
        }
        /*
@@ -199,7 +198,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
                se_lun = deve->se_lun;
                se_cmd->pr_res_key = deve->pr_res_key;
                se_cmd->orig_fe_lun = unpacked_lun;
-               se_cmd->se_orig_obj_ptr = se_cmd->se_dev;
        }
        spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags);
 
@@ -651,23 +649,15 @@ void core_dev_unexport(
        lun->lun_se_dev = NULL;
 }
 
-int transport_core_report_lun_response(struct se_cmd *se_cmd)
+int target_report_luns(struct se_task *se_task)
 {
+       struct se_cmd *se_cmd = se_task->task_se_cmd;
        struct se_dev_entry *deve;
        struct se_lun *se_lun;
        struct se_session *se_sess = se_cmd->se_sess;
-       struct se_task *se_task;
        unsigned char *buf;
        u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
 
-       list_for_each_entry(se_task, &se_cmd->t_task_list, t_list)
-               break;
-
-       if (!se_task) {
-               pr_err("Unable to locate struct se_task for struct se_cmd\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
-       }
-
        buf = transport_kmap_first_data_page(se_cmd);
 
        /*
@@ -713,7 +703,9 @@ done:
        buf[2] = ((lun_count >> 8) & 0xff);
        buf[3] = (lun_count & 0xff);
 
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       se_task->task_scsi_status = GOOD;
+       transport_complete_task(se_task, 1);
+       return 0;
 }
 
 /*     se_release_device_for_hba():
@@ -962,8 +954,12 @@ int se_dev_set_emulate_dpo(struct se_device *dev, int flag)
                return -EINVAL;
        }
 
-       pr_err("dpo_emulated not supported\n");
-       return -EINVAL;
+       if (flag) {
+               pr_err("dpo_emulated not supported\n");
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
 int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
@@ -973,7 +969,7 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
                return -EINVAL;
        }
 
-       if (dev->transport->fua_write_emulated == 0) {
+       if (flag && dev->transport->fua_write_emulated == 0) {
                pr_err("fua_write_emulated not supported\n");
                return -EINVAL;
        }
@@ -990,8 +986,12 @@ int se_dev_set_emulate_fua_read(struct se_device *dev, int flag)
                return -EINVAL;
        }
 
-       pr_err("ua read emulated not supported\n");
-       return -EINVAL;
+       if (flag) {
+               pr_err("ua read emulated not supported\n");
+               return -EINVAL;
+       }
+
+       return 0;
 }
 
 int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
@@ -1000,7 +1000,7 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
                pr_err("Illegal value %d\n", flag);
                return -EINVAL;
        }
-       if (dev->transport->write_cache_emulated == 0) {
+       if (flag && dev->transport->write_cache_emulated == 0) {
                pr_err("write_cache_emulated not supported\n");
                return -EINVAL;
        }
@@ -1061,7 +1061,7 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag)
         * We expect this value to be non-zero when generic Block Layer
         * Discard supported is detected iblock_create_virtdevice().
         */
-       if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
+       if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
                pr_err("Generic Block Discard not supported\n");
                return -ENOSYS;
        }
@@ -1082,7 +1082,7 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag)
         * We expect this value to be non-zero when generic Block Layer
         * Discard supported is detected iblock_create_virtdevice().
         */
-       if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
+       if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
                pr_err("Generic Block Discard not supported\n");
                return -ENOSYS;
        }
@@ -1592,7 +1592,6 @@ int core_dev_setup_virtual_lun0(void)
                ret = -ENOMEM;
                goto out;
        }
-       INIT_LIST_HEAD(&se_dev->se_dev_node);
        INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list);
        spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock);
        INIT_LIST_HEAD(&se_dev->t10_pr.registration_list);
index 39f021b855ef3ff42897d9c9909541eca27fb2b6..ec4249be617e348aaed580cfa027df1fc5174bbf 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
+#include <linux/export.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
index 19a0be9c6570ecb6772ed745549d9b5245c6b787..b4864fba4ef0d511758916a8debac60ee9f43674 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 
@@ -288,9 +289,9 @@ static int fd_do_readv(struct se_task *task)
                return -ENOMEM;
        }
 
-       for (i = 0; i < task->task_sg_nents; i++) {
-               iov[i].iov_len = sg[i].length;
-               iov[i].iov_base = sg_virt(&sg[i]);
+       for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
+               iov[i].iov_len = sg->length;
+               iov[i].iov_base = sg_virt(sg);
        }
 
        old_fs = get_fs();
@@ -341,9 +342,9 @@ static int fd_do_writev(struct se_task *task)
                return -ENOMEM;
        }
 
-       for (i = 0; i < task->task_sg_nents; i++) {
-               iov[i].iov_len = sg[i].length;
-               iov[i].iov_base = sg_virt(&sg[i]);
+       for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
+               iov[i].iov_len = sg->length;
+               iov[i].iov_base = sg_virt(sg);
        }
 
        old_fs = get_fs();
@@ -437,7 +438,7 @@ static int fd_do_task(struct se_task *task)
                if (ret > 0 &&
                    dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 &&
                    dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
-                   cmd->t_tasks_fua) {
+                   (cmd->se_cmd_flags & SCF_FUA)) {
                        /*
                         * We might need to be a bit smarter here
                         * and return some sense data to let the initiator
@@ -448,13 +449,15 @@ static int fd_do_task(struct se_task *task)
 
        }
 
-       if (ret < 0)
+       if (ret < 0) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                return ret;
+       }
        if (ret) {
                task->task_scsi_status = GOOD;
                transport_complete_task(task, 1);
        }
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       return 0;
 }
 
 /*     fd_free_task(): (Part of se_subsystem_api_t template)
index 0639b975d6f55c79944583c4260e3c1722bf7909..c68019d6c406292335522d536760fb8bb5904629 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
+#include <linux/module.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 
index 41ad02b5fb87d00d558872d85efd5f43344ca0c8..4aa9922044382628fc21e12d8df3ab67840c23ae 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/bio.h>
 #include <linux/genhd.h>
 #include <linux/file.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 
@@ -530,7 +531,7 @@ static int iblock_do_task(struct se_task *task)
                 */
                if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 ||
                    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
-                    task->task_se_cmd->t_tasks_fua))
+                    (cmd->se_cmd_flags & SCF_FUA)))
                        rw = WRITE_FUA;
                else
                        rw = WRITE;
@@ -553,12 +554,15 @@ static int iblock_do_task(struct se_task *task)
        else {
                pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
                                " %u\n", dev->se_sub_dev->se_dev_attrib.block_size);
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -ENOSYS;
        }
 
        bio = iblock_get_bio(task, block_lba, sg_num);
-       if (!bio)
-               return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+       if (!bio) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -ENOMEM;
+       }
 
        bio_list_init(&list);
        bio_list_add(&list, bio);
@@ -587,12 +591,13 @@ static int iblock_do_task(struct se_task *task)
                submit_bio(rw, bio);
        blk_finish_plug(&plug);
 
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       return 0;
 
 fail:
        while ((bio = bio_list_pop(&list)))
                bio_put(bio);
-       return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       return -ENOMEM;
 }
 
 static u32 iblock_get_device_rev(struct se_device *dev)
index 0c4f783f924c450efcd82bf91a71027cbf60e508..95dee7074aeb5eb05f630fdded543e948ac206b3 100644 (file)
@@ -116,114 +116,21 @@ static int core_scsi2_reservation_check(struct se_cmd *cmd, u32 *pr_reg_type)
        return ret;
 }
 
-static int core_scsi2_reservation_release(struct se_cmd *cmd)
-{
-       struct se_device *dev = cmd->se_dev;
-       struct se_session *sess = cmd->se_sess;
-       struct se_portal_group *tpg = sess->se_tpg;
-
-       if (!sess || !tpg)
-               return 0;
-
-       spin_lock(&dev->dev_reservation_lock);
-       if (!dev->dev_reserved_node_acl || !sess) {
-               spin_unlock(&dev->dev_reservation_lock);
-               return 0;
-       }
-
-       if (dev->dev_reserved_node_acl != sess->se_node_acl) {
-               spin_unlock(&dev->dev_reservation_lock);
-               return 0;
-       }
-       dev->dev_reserved_node_acl = NULL;
-       dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
-       if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
-               dev->dev_res_bin_isid = 0;
-               dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
-       }
-       pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
-               " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
-               cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
-               sess->se_node_acl->initiatorname);
-       spin_unlock(&dev->dev_reservation_lock);
-
-       return 0;
-}
-
-static int core_scsi2_reservation_reserve(struct se_cmd *cmd)
-{
-       struct se_device *dev = cmd->se_dev;
-       struct se_session *sess = cmd->se_sess;
-       struct se_portal_group *tpg = sess->se_tpg;
-
-       if ((cmd->t_task_cdb[1] & 0x01) &&
-           (cmd->t_task_cdb[1] & 0x02)) {
-               pr_err("LongIO and Obselete Bits set, returning"
-                               " ILLEGAL_REQUEST\n");
-               return PYX_TRANSPORT_ILLEGAL_REQUEST;
-       }
-       /*
-        * This is currently the case for target_core_mod passthrough struct se_cmd
-        * ops
-        */
-       if (!sess || !tpg)
-               return 0;
-
-       spin_lock(&dev->dev_reservation_lock);
-       if (dev->dev_reserved_node_acl &&
-          (dev->dev_reserved_node_acl != sess->se_node_acl)) {
-               pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n",
-                       tpg->se_tpg_tfo->get_fabric_name());
-               pr_err("Original reserver LUN: %u %s\n",
-                       cmd->se_lun->unpacked_lun,
-                       dev->dev_reserved_node_acl->initiatorname);
-               pr_err("Current attempt - LUN: %u -> MAPPED LUN: %u"
-                       " from %s \n", cmd->se_lun->unpacked_lun,
-                       cmd->se_deve->mapped_lun,
-                       sess->se_node_acl->initiatorname);
-               spin_unlock(&dev->dev_reservation_lock);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
-       }
-
-       dev->dev_reserved_node_acl = sess->se_node_acl;
-       dev->dev_flags |= DF_SPC2_RESERVATIONS;
-       if (sess->sess_bin_isid != 0) {
-               dev->dev_res_bin_isid = sess->sess_bin_isid;
-               dev->dev_flags |= DF_SPC2_RESERVATIONS_WITH_ISID;
-       }
-       pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u"
-               " for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
-               cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
-               sess->se_node_acl->initiatorname);
-       spin_unlock(&dev->dev_reservation_lock);
-
-       return 0;
-}
-
 static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
                                        struct se_node_acl *, struct se_session *);
 static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
 
-/*
- * Setup in target_core_transport.c:transport_generic_cmd_sequencer()
- * and called via struct se_cmd->transport_emulate_cdb() in TCM processing
- * thread context.
- */
-int core_scsi2_emulate_crh(struct se_cmd *cmd)
+static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
 {
        struct se_session *se_sess = cmd->se_sess;
        struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
        struct t10_pr_registration *pr_reg;
        struct t10_reservation *pr_tmpl = &su_dev->t10_pr;
-       unsigned char *cdb = &cmd->t_task_cdb[0];
        int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
        int conflict = 0;
 
-       if (!se_sess)
-               return 0;
-
        if (!crh)
-               goto after_crh;
+               return false;
 
        pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
                        se_sess);
@@ -251,14 +158,16 @@ int core_scsi2_emulate_crh(struct se_cmd *cmd)
                 */
                if (pr_reg->pr_res_holder) {
                        core_scsi3_put_pr_reg(pr_reg);
-                       return 0;
+                       *ret = 0;
+                       return false;
                }
                if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
                    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
                    (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
                    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
                        core_scsi3_put_pr_reg(pr_reg);
-                       return 0;
+                       *ret = 0;
+                       return true;
                }
                core_scsi3_put_pr_reg(pr_reg);
                conflict = 1;
@@ -282,18 +191,120 @@ int core_scsi2_emulate_crh(struct se_cmd *cmd)
                pr_err("Received legacy SPC-2 RESERVE/RELEASE"
                        " while active SPC-3 registrations exist,"
                        " returning RESERVATION_CONFLICT\n");
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return true;
        }
 
-after_crh:
-       if ((cdb[0] == RESERVE) || (cdb[0] == RESERVE_10))
-               return core_scsi2_reservation_reserve(cmd);
-       else if ((cdb[0] == RELEASE) || (cdb[0] == RELEASE_10))
-               return core_scsi2_reservation_release(cmd);
-       else
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+       return false;
+}
+
+int target_scsi2_reservation_release(struct se_task *task)
+{
+       struct se_cmd *cmd = task->task_se_cmd;
+       struct se_device *dev = cmd->se_dev;
+       struct se_session *sess = cmd->se_sess;
+       struct se_portal_group *tpg = sess->se_tpg;
+       int ret = 0;
+
+       if (!sess || !tpg)
+               goto out;
+       if (target_check_scsi2_reservation_conflict(cmd, &ret))
+               goto out;
+
+       ret = 0;
+       spin_lock(&dev->dev_reservation_lock);
+       if (!dev->dev_reserved_node_acl || !sess)
+               goto out_unlock;
+
+       if (dev->dev_reserved_node_acl != sess->se_node_acl)
+               goto out_unlock;
+
+       dev->dev_reserved_node_acl = NULL;
+       dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
+       if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
+               dev->dev_res_bin_isid = 0;
+               dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
+       }
+       pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
+               " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
+               cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
+               sess->se_node_acl->initiatorname);
+
+out_unlock:
+       spin_unlock(&dev->dev_reservation_lock);
+out:
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
+       return ret;
 }
 
+int target_scsi2_reservation_reserve(struct se_task *task)
+{
+       struct se_cmd *cmd = task->task_se_cmd;
+       struct se_device *dev = cmd->se_dev;
+       struct se_session *sess = cmd->se_sess;
+       struct se_portal_group *tpg = sess->se_tpg;
+       int ret = 0;
+
+       if ((cmd->t_task_cdb[1] & 0x01) &&
+           (cmd->t_task_cdb[1] & 0x02)) {
+               pr_err("LongIO and Obselete Bits set, returning"
+                               " ILLEGAL_REQUEST\n");
+               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
+               ret = -EINVAL;
+               goto out;
+       }
+       /*
+        * This is currently the case for target_core_mod passthrough struct se_cmd
+        * ops
+        */
+       if (!sess || !tpg)
+               goto out;
+       if (target_check_scsi2_reservation_conflict(cmd, &ret))
+               goto out;
+
+       ret = 0;
+       spin_lock(&dev->dev_reservation_lock);
+       if (dev->dev_reserved_node_acl &&
+          (dev->dev_reserved_node_acl != sess->se_node_acl)) {
+               pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n",
+                       tpg->se_tpg_tfo->get_fabric_name());
+               pr_err("Original reserver LUN: %u %s\n",
+                       cmd->se_lun->unpacked_lun,
+                       dev->dev_reserved_node_acl->initiatorname);
+               pr_err("Current attempt - LUN: %u -> MAPPED LUN: %u"
+                       " from %s \n", cmd->se_lun->unpacked_lun,
+                       cmd->se_deve->mapped_lun,
+                       sess->se_node_acl->initiatorname);
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
+       dev->dev_reserved_node_acl = sess->se_node_acl;
+       dev->dev_flags |= DF_SPC2_RESERVATIONS;
+       if (sess->sess_bin_isid != 0) {
+               dev->dev_res_bin_isid = sess->sess_bin_isid;
+               dev->dev_flags |= DF_SPC2_RESERVATIONS_WITH_ISID;
+       }
+       pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u"
+               " for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
+               cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
+               sess->se_node_acl->initiatorname);
+
+out_unlock:
+       spin_unlock(&dev->dev_reservation_lock);
+out:
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
+       return ret;
+}
+
+
 /*
  * Begin SPC-3/SPC-4 Persistent Reservations emulation support
  *
@@ -418,12 +429,12 @@ static int core_scsi3_pr_seq_non_holder(
                break;
        case RELEASE:
        case RELEASE_10:
-               /* Handled by CRH=1 in core_scsi2_emulate_crh() */
+               /* Handled by CRH=1 in target_scsi2_reservation_release() */
                ret = 0;
                break;
        case RESERVE:
        case RESERVE_10:
-               /* Handled by CRH=1 in core_scsi2_emulate_crh() */
+               /* Handled by CRH=1 in target_scsi2_reservation_reserve() */
                ret = 0;
                break;
        case TEST_UNIT_READY:
@@ -1501,7 +1512,8 @@ static int core_scsi3_decode_spec_i_port(
        tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL);
        if (!tidh_new) {
                pr_err("Unable to allocate tidh_new\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        INIT_LIST_HEAD(&tidh_new->dest_list);
        tidh_new->dest_tpg = tpg;
@@ -1513,7 +1525,8 @@ static int core_scsi3_decode_spec_i_port(
                                sa_res_key, all_tg_pt, aptpl);
        if (!local_pr_reg) {
                kfree(tidh_new);
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -ENOMEM;
        }
        tidh_new->dest_pr_reg = local_pr_reg;
        /*
@@ -1539,7 +1552,8 @@ static int core_scsi3_decode_spec_i_port(
                pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header"
                        " does not equal CDB data_length: %u\n", tpdl,
                        cmd->data_length);
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
        /*
@@ -1589,7 +1603,9 @@ static int core_scsi3_decode_spec_i_port(
                                        " for tmp_tpg\n");
                                atomic_dec(&tmp_tpg->tpg_pr_ref_count);
                                smp_mb__after_atomic_dec();
-                               ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+                               cmd->scsi_sense_reason =
+                                       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                               ret = -EINVAL;
                                goto out;
                        }
                        /*
@@ -1619,7 +1635,9 @@ static int core_scsi3_decode_spec_i_port(
                                atomic_dec(&dest_node_acl->acl_pr_ref_count);
                                smp_mb__after_atomic_dec();
                                core_scsi3_tpg_undepend_item(tmp_tpg);
-                               ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+                               cmd->scsi_sense_reason =
+                                       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                               ret = -EINVAL;
                                goto out;
                        }
 
@@ -1637,7 +1655,8 @@ static int core_scsi3_decode_spec_i_port(
                if (!dest_tpg) {
                        pr_err("SPC-3 PR SPEC_I_PT: Unable to locate"
                                        " dest_tpg\n");
-                       ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       ret = -EINVAL;
                        goto out;
                }
 #if 0
@@ -1651,7 +1670,8 @@ static int core_scsi3_decode_spec_i_port(
                                " %u for Transport ID: %s\n", tid_len, ptr);
                        core_scsi3_nodeacl_undepend_item(dest_node_acl);
                        core_scsi3_tpg_undepend_item(dest_tpg);
-                       ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       ret = -EINVAL;
                        goto out;
                }
                /*
@@ -1669,7 +1689,8 @@ static int core_scsi3_decode_spec_i_port(
 
                        core_scsi3_nodeacl_undepend_item(dest_node_acl);
                        core_scsi3_tpg_undepend_item(dest_tpg);
-                       ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       ret = -EINVAL;
                        goto out;
                }
 
@@ -1681,7 +1702,9 @@ static int core_scsi3_decode_spec_i_port(
                        smp_mb__after_atomic_dec();
                        core_scsi3_nodeacl_undepend_item(dest_node_acl);
                        core_scsi3_tpg_undepend_item(dest_tpg);
-                       ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+                       cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       ret = -EINVAL;
                        goto out;
                }
 #if 0
@@ -1718,7 +1741,9 @@ static int core_scsi3_decode_spec_i_port(
                        core_scsi3_lunacl_undepend_item(dest_se_deve);
                        core_scsi3_nodeacl_undepend_item(dest_node_acl);
                        core_scsi3_tpg_undepend_item(dest_tpg);
-                       ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+                       cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       ret = -ENOMEM;
                        goto out;
                }
                INIT_LIST_HEAD(&tidh_new->dest_list);
@@ -1750,7 +1775,8 @@ static int core_scsi3_decode_spec_i_port(
                        core_scsi3_nodeacl_undepend_item(dest_node_acl);
                        core_scsi3_tpg_undepend_item(dest_tpg);
                        kfree(tidh_new);
-                       ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       ret = -EINVAL;
                        goto out;
                }
                tidh_new->dest_pr_reg = dest_pr_reg;
@@ -2089,7 +2115,8 @@ static int core_scsi3_emulate_pro_register(
 
        if (!se_sess || !se_lun) {
                pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        se_tpg = se_sess->se_tpg;
        se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
@@ -2108,13 +2135,14 @@ static int core_scsi3_emulate_pro_register(
                if (res_key) {
                        pr_warn("SPC-3 PR: Reservation Key non-zero"
                                " for SA REGISTER, returning CONFLICT\n");
-                       return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                       cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                       return -EINVAL;
                }
                /*
                 * Do nothing but return GOOD status.
                 */
                if (!sa_res_key)
-                       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+                       return 0;
 
                if (!spec_i_pt) {
                        /*
@@ -2129,7 +2157,8 @@ static int core_scsi3_emulate_pro_register(
                        if (ret != 0) {
                                pr_err("Unable to allocate"
                                        " struct t10_pr_registration\n");
-                               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                               return -EINVAL;
                        }
                } else {
                        /*
@@ -2188,14 +2217,16 @@ static int core_scsi3_emulate_pro_register(
                                        " 0x%016Lx\n", res_key,
                                        pr_reg->pr_res_key);
                                core_scsi3_put_pr_reg(pr_reg);
-                               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                               return -EINVAL;
                        }
                }
                if (spec_i_pt) {
                        pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT"
                                " set while sa_res_key=0\n");
                        core_scsi3_put_pr_reg(pr_reg);
-                       return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       return -EINVAL;
                }
                /*
                 * An existing ALL_TG_PT=1 registration being released
@@ -2206,7 +2237,8 @@ static int core_scsi3_emulate_pro_register(
                                " registration exists, but ALL_TG_PT=1 bit not"
                                " present in received PROUT\n");
                        core_scsi3_put_pr_reg(pr_reg);
-                       return PYX_TRANSPORT_INVALID_CDB_FIELD;
+                       cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+                       return -EINVAL;
                }
                /*
                 * Allocate APTPL metadata buffer used for UNREGISTER ops
@@ -2218,7 +2250,9 @@ static int core_scsi3_emulate_pro_register(
                                pr_err("Unable to allocate"
                                        " pr_aptpl_buf\n");
                                core_scsi3_put_pr_reg(pr_reg);
-                               return PYX_TRANSPORT_LU_COMM_FAILURE;
+                               cmd->scsi_sense_reason =
+                                       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                               return -EINVAL;
                        }
                }
                /*
@@ -2232,7 +2266,8 @@ static int core_scsi3_emulate_pro_register(
                        if (pr_holder < 0) {
                                kfree(pr_aptpl_buf);
                                core_scsi3_put_pr_reg(pr_reg);
-                               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                               return -EINVAL;
                        }
 
                        spin_lock(&pr_tmpl->registration_lock);
@@ -2396,7 +2431,8 @@ static int core_scsi3_pro_reserve(
 
        if (!se_sess || !se_lun) {
                pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        se_tpg = se_sess->se_tpg;
        se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
@@ -2408,7 +2444,8 @@ static int core_scsi3_pro_reserve(
        if (!pr_reg) {
                pr_err("SPC-3 PR: Unable to locate"
                        " PR_REGISTERED *pr_reg for RESERVE\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        /*
         * From spc4r17 Section 5.7.9: Reserving:
@@ -2424,7 +2461,8 @@ static int core_scsi3_pro_reserve(
                        " does not match existing SA REGISTER res_key:"
                        " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        /*
         * From spc4r17 Section 5.7.9: Reserving:
@@ -2439,7 +2477,8 @@ static int core_scsi3_pro_reserve(
        if (scope != PR_SCOPE_LU_SCOPE) {
                pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
        /*
         * See if we have an existing PR reservation holder pointer at
@@ -2471,7 +2510,8 @@ static int core_scsi3_pro_reserve(
 
                        spin_unlock(&dev->dev_reservation_lock);
                        core_scsi3_put_pr_reg(pr_reg);
-                       return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                       cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                       return -EINVAL;
                }
                /*
                 * From spc4r17 Section 5.7.9: Reserving:
@@ -2494,7 +2534,8 @@ static int core_scsi3_pro_reserve(
 
                        spin_unlock(&dev->dev_reservation_lock);
                        core_scsi3_put_pr_reg(pr_reg);
-                       return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                       cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                       return -EINVAL;
                }
                /*
                 * From spc4r17 Section 5.7.9: Reserving:
@@ -2508,7 +2549,7 @@ static int core_scsi3_pro_reserve(
                 */
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+               return 0;
        }
        /*
         * Otherwise, our *pr_reg becomes the PR reservation holder for said
@@ -2565,7 +2606,8 @@ static int core_scsi3_emulate_pro_reserve(
        default:
                pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:"
                        " 0x%02x\n", type);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        return ret;
@@ -2621,7 +2663,8 @@ static int core_scsi3_emulate_pro_release(
 
        if (!se_sess || !se_lun) {
                pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        /*
         * Locate the existing *pr_reg via struct se_node_acl pointers
@@ -2630,7 +2673,8 @@ static int core_scsi3_emulate_pro_release(
        if (!pr_reg) {
                pr_err("SPC-3 PR: Unable to locate"
                        " PR_REGISTERED *pr_reg for RELEASE\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        /*
         * From spc4r17 Section 5.7.11.2 Releasing:
@@ -2652,7 +2696,7 @@ static int core_scsi3_emulate_pro_release(
                 */
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+               return 0;
        }
        if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
            (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))
@@ -2666,7 +2710,7 @@ static int core_scsi3_emulate_pro_release(
                 */
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+               return 0;
        }
        /*
         * From spc4r17 Section 5.7.11.2 Releasing:
@@ -2688,7 +2732,8 @@ static int core_scsi3_emulate_pro_release(
                        " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        /*
         * From spc4r17 Section 5.7.11.2 Releasing and above:
@@ -2710,7 +2755,8 @@ static int core_scsi3_emulate_pro_release(
 
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        /*
         * In response to a persistent reservation release request from the
@@ -2793,7 +2839,8 @@ static int core_scsi3_emulate_pro_clear(
        if (!pr_reg_n) {
                pr_err("SPC-3 PR: Unable to locate"
                        " PR_REGISTERED *pr_reg for CLEAR\n");
-                       return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        /*
         * From spc4r17 section 5.7.11.6, Clearing:
@@ -2812,7 +2859,8 @@ static int core_scsi3_emulate_pro_clear(
                        " existing SA REGISTER res_key:"
                        " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
                core_scsi3_put_pr_reg(pr_reg_n);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        /*
         * a) Release the persistent reservation, if any;
@@ -2970,8 +3018,10 @@ static int core_scsi3_pro_preempt(
        int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
        int prh_type = 0, prh_scope = 0, ret;
 
-       if (!se_sess)
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+       if (!se_sess) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
+       }
 
        se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
        pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
@@ -2980,16 +3030,19 @@ static int core_scsi3_pro_preempt(
                pr_err("SPC-3 PR: Unable to locate"
                        " PR_REGISTERED *pr_reg for PREEMPT%s\n",
                        (abort) ? "_AND_ABORT" : "");
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        if (pr_reg_n->pr_res_key != res_key) {
                core_scsi3_put_pr_reg(pr_reg_n);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        if (scope != PR_SCOPE_LU_SCOPE) {
                pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
                core_scsi3_put_pr_reg(pr_reg_n);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
        INIT_LIST_HEAD(&preempt_and_abort_list);
 
@@ -3003,7 +3056,8 @@ static int core_scsi3_pro_preempt(
        if (!all_reg && !sa_res_key) {
                spin_unlock(&dev->dev_reservation_lock);
                core_scsi3_put_pr_reg(pr_reg_n);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
        /*
         * From spc4r17, section 5.7.11.4.4 Removing Registrations:
@@ -3097,7 +3151,8 @@ static int core_scsi3_pro_preempt(
                if (!released_regs) {
                        spin_unlock(&dev->dev_reservation_lock);
                        core_scsi3_put_pr_reg(pr_reg_n);
-                       return PYX_TRANSPORT_RESERVATION_CONFLICT;
+                       cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                       return -EINVAL;
                }
                /*
                 * For an existing all registrants type reservation
@@ -3288,7 +3343,8 @@ static int core_scsi3_emulate_pro_preempt(
        default:
                pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
                        " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        return ret;
@@ -3322,7 +3378,8 @@ static int core_scsi3_emulate_pro_register_and_move(
 
        if (!se_sess || !se_lun) {
                pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        memset(dest_iport, 0, 64);
        memset(i_buf, 0, PR_REG_ISID_ID_LEN);
@@ -3340,7 +3397,8 @@ static int core_scsi3_emulate_pro_register_and_move(
        if (!pr_reg) {
                pr_err("SPC-3 PR: Unable to locate PR_REGISTERED"
                        " *pr_reg for REGISTER_AND_MOVE\n");
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
        }
        /*
         * The provided reservation key much match the existing reservation key
@@ -3351,7 +3409,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                        " res_key: 0x%016Lx does not match existing SA REGISTER"
                        " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
        /*
         * The service active reservation key needs to be non zero
@@ -3360,7 +3419,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero"
                        " sa_res_key\n");
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
 
        /*
@@ -3383,7 +3443,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                        " does not equal CDB data_length: %u\n", tid_len,
                        cmd->data_length);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
 
        spin_lock(&dev->se_port_lock);
@@ -3408,7 +3469,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                        atomic_dec(&dest_se_tpg->tpg_pr_ref_count);
                        smp_mb__after_atomic_dec();
                        core_scsi3_put_pr_reg(pr_reg);
-                       return PYX_TRANSPORT_LU_COMM_FAILURE;
+                       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       return -EINVAL;
                }
 
                spin_lock(&dev->se_port_lock);
@@ -3421,7 +3483,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                        " fabric ops from Relative Target Port Identifier:"
                        " %hu\n", rtpi);
                core_scsi3_put_pr_reg(pr_reg);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               return -EINVAL;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -3436,14 +3499,16 @@ static int core_scsi3_emulate_pro_register_and_move(
                        " from fabric: %s\n", proto_ident,
                        dest_tf_ops->get_fabric_proto_ident(dest_se_tpg),
                        dest_tf_ops->get_fabric_name());
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
        if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) {
                pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not"
                        " containg a valid tpg_parse_pr_out_transport_id"
                        " function pointer\n");
-               ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               ret = -EINVAL;
                goto out;
        }
        initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg,
@@ -3451,7 +3516,8 @@ static int core_scsi3_emulate_pro_register_and_move(
        if (!initiator_str) {
                pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
                        " initiator_str from Transport ID\n");
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
 
@@ -3480,7 +3546,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s"
                        " matches: %s on received I_T Nexus\n", initiator_str,
                        pr_reg_nacl->initiatorname);
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
        if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) {
@@ -3488,7 +3555,8 @@ static int core_scsi3_emulate_pro_register_and_move(
                        " matches: %s %s on received I_T Nexus\n",
                        initiator_str, iport_ptr, pr_reg_nacl->initiatorname,
                        pr_reg->pr_reg_isid);
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
 after_iport_check:
@@ -3508,7 +3576,8 @@ after_iport_check:
                pr_err("Unable to locate %s dest_node_acl for"
                        " TransportID%s\n", dest_tf_ops->get_fabric_name(),
                        initiator_str);
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
        ret = core_scsi3_nodeacl_depend_item(dest_node_acl);
@@ -3518,7 +3587,8 @@ after_iport_check:
                atomic_dec(&dest_node_acl->acl_pr_ref_count);
                smp_mb__after_atomic_dec();
                dest_node_acl = NULL;
-               ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
 #if 0
@@ -3534,7 +3604,8 @@ after_iport_check:
        if (!dest_se_deve) {
                pr_err("Unable to locate %s dest_se_deve from RTPI:"
                        " %hu\n",  dest_tf_ops->get_fabric_name(), rtpi);
-               ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
                goto out;
        }
 
@@ -3544,7 +3615,8 @@ after_iport_check:
                atomic_dec(&dest_se_deve->pr_ref_count);
                smp_mb__after_atomic_dec();
                dest_se_deve = NULL;
-               ret = PYX_TRANSPORT_LU_COMM_FAILURE;
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               ret = -EINVAL;
                goto out;
        }
 #if 0
@@ -3563,7 +3635,8 @@ after_iport_check:
                pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation"
                        " currently held\n");
                spin_unlock(&dev->dev_reservation_lock);
-               ret = PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               ret = -EINVAL;
                goto out;
        }
        /*
@@ -3576,7 +3649,8 @@ after_iport_check:
                pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T"
                        " Nexus is not reservation holder\n");
                spin_unlock(&dev->dev_reservation_lock);
-               ret = PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               ret = -EINVAL;
                goto out;
        }
        /*
@@ -3594,7 +3668,8 @@ after_iport_check:
                        " reservation for type: %s\n",
                        core_scsi3_pr_dump_type(pr_res_holder->pr_res_type));
                spin_unlock(&dev->dev_reservation_lock);
-               ret = PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               ret = -EINVAL;
                goto out;
        }
        pr_res_nacl = pr_res_holder->pr_reg_nacl;
@@ -3631,7 +3706,8 @@ after_iport_check:
                                sa_res_key, 0, aptpl, 2, 1);
                if (ret != 0) {
                        spin_unlock(&dev->dev_reservation_lock);
-                       ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+                       cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+                       ret = -EINVAL;
                        goto out;
                }
                dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
@@ -3739,23 +3815,49 @@ static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
 /*
  * See spc4r17 section 6.14 Table 170
  */
-static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
+int target_scsi3_emulate_pr_out(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
+       unsigned char *cdb = &cmd->t_task_cdb[0];
        unsigned char *buf;
        u64 res_key, sa_res_key;
        int sa, scope, type, aptpl;
        int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
+       int ret;
+
+       /*
+        * Following spc2r20 5.5.1 Reservations overview:
+        *
+        * If a logical unit has been reserved by any RESERVE command and is
+        * still reserved by any initiator, all PERSISTENT RESERVE IN and all
+        * PERSISTENT RESERVE OUT commands shall conflict regardless of
+        * initiator or service action and shall terminate with a RESERVATION
+        * CONFLICT status.
+        */
+       if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
+               pr_err("Received PERSISTENT_RESERVE CDB while legacy"
+                       " SPC-2 reservation is held, returning"
+                       " RESERVATION_CONFLICT\n");
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               ret = EINVAL;
+               goto out;
+       }
+
        /*
         * FIXME: A NULL struct se_session pointer means an this is not coming from
         * a $FABRIC_MOD's nexus, but from internal passthrough ops.
         */
-       if (!cmd->se_sess)
-               return PYX_TRANSPORT_LU_COMM_FAILURE;
+       if (!cmd->se_sess) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               return -EINVAL;
+       }
 
        if (cmd->data_length < 24) {
                pr_warn("SPC-PR: Received PR OUT parameter list"
                        " length too small: %u\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
+               goto out;
        }
        /*
         * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB)
@@ -3788,8 +3890,12 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
        /*
         * SPEC_I_PT=1 is only valid for Service action: REGISTER
         */
-       if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER))
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+       if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) {
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
+               goto out;
+       }
+
        /*
         * From spc4r17 section 6.14:
         *
@@ -3803,7 +3909,9 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
            (cmd->data_length != 24)) {
                pr_warn("SPC-PR: Received PR OUT illegal parameter"
                        " list length: %u\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
+               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
+               ret = -EINVAL;
+               goto out;
        }
        /*
         * (core_scsi3_emulate_pro_* function parameters
@@ -3812,35 +3920,48 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
         */
        switch (sa) {
        case PRO_REGISTER:
-               return core_scsi3_emulate_pro_register(cmd,
+               ret = core_scsi3_emulate_pro_register(cmd,
                        res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0);
+               break;
        case PRO_RESERVE:
-               return core_scsi3_emulate_pro_reserve(cmd,
-                       type, scope, res_key);
+               ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key);
+               break;
        case PRO_RELEASE:
-               return core_scsi3_emulate_pro_release(cmd,
-                       type, scope, res_key);
+               ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key);
+               break;
        case PRO_CLEAR:
-               return core_scsi3_emulate_pro_clear(cmd, res_key);
+               ret = core_scsi3_emulate_pro_clear(cmd, res_key);
+               break;
        case PRO_PREEMPT:
-               return core_scsi3_emulate_pro_preempt(cmd, type, scope,
+               ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
                                        res_key, sa_res_key, 0);
+               break;
        case PRO_PREEMPT_AND_ABORT:
-               return core_scsi3_emulate_pro_preempt(cmd, type, scope,
+               ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
                                        res_key, sa_res_key, 1);
+               break;
        case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
-               return core_scsi3_emulate_pro_register(cmd,
+               ret = core_scsi3_emulate_pro_register(cmd,
                        0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1);
+               break;
        case PRO_REGISTER_AND_MOVE:
-               return core_scsi3_emulate_pro_register_and_move(cmd, res_key,
+               ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key,
                                sa_res_key, aptpl, unreg);
+               break;
        default:
                pr_err("Unknown PERSISTENT_RESERVE_OUT service"
                        " action: 0x%02x\n", cdb[1] & 0x1f);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               ret = -EINVAL;
+               break;
        }
 
-       return PYX_TRANSPORT_INVALID_CDB_FIELD;
+out:
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
+       return ret;
 }
 
 /*
@@ -3859,7 +3980,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
        if (cmd->data_length < 8) {
                pr_err("PRIN SA READ_KEYS SCSI Data Length: %u"
                        " too small\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -3918,7 +4040,8 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
        if (cmd->data_length < 8) {
                pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
                        " too small\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -4000,7 +4123,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
        if (cmd->data_length < 6) {
                pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
                        " %u too small\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -4061,7 +4185,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
        if (cmd->data_length < 8) {
                pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
                        " too small\n", cmd->data_length);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               return -EINVAL;
        }
 
        buf = transport_kmap_first_data_page(cmd);
@@ -4190,29 +4315,11 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
        return 0;
 }
 
-static int core_scsi3_emulate_pr_in(struct se_cmd *cmd, unsigned char *cdb)
+int target_scsi3_emulate_pr_in(struct se_task *task)
 {
-       switch (cdb[1] & 0x1f) {
-       case PRI_READ_KEYS:
-               return core_scsi3_pri_read_keys(cmd);
-       case PRI_READ_RESERVATION:
-               return core_scsi3_pri_read_reservation(cmd);
-       case PRI_REPORT_CAPABILITIES:
-               return core_scsi3_pri_report_capabilities(cmd);
-       case PRI_READ_FULL_STATUS:
-               return core_scsi3_pri_read_full_status(cmd);
-       default:
-               pr_err("Unknown PERSISTENT_RESERVE_IN service"
-                       " action: 0x%02x\n", cdb[1] & 0x1f);
-               return PYX_TRANSPORT_INVALID_CDB_FIELD;
-       }
-
-}
+       struct se_cmd *cmd = task->task_se_cmd;
+       int ret;
 
-int core_scsi3_emulate_pr(struct se_cmd *cmd)
-{
-       unsigned char *cdb = &cmd->t_task_cdb[0];
-       struct se_device *dev = cmd->se_dev;
        /*
         * Following spc2r20 5.5.1 Reservations overview:
         *
@@ -4222,16 +4329,40 @@ int core_scsi3_emulate_pr(struct se_cmd *cmd)
         * initiator or service action and shall terminate with a RESERVATION
         * CONFLICT status.
         */
-       if (dev->dev_flags & DF_SPC2_RESERVATIONS) {
+       if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
                pr_err("Received PERSISTENT_RESERVE CDB while legacy"
                        " SPC-2 reservation is held, returning"
                        " RESERVATION_CONFLICT\n");
-               return PYX_TRANSPORT_RESERVATION_CONFLICT;
+               cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+               return -EINVAL;
        }
 
-       return (cdb[0] == PERSISTENT_RESERVE_OUT) ?
-              core_scsi3_emulate_pr_out(cmd, cdb) :
-              core_scsi3_emulate_pr_in(cmd, cdb);
+       switch (cmd->t_task_cdb[1] & 0x1f) {
+       case PRI_READ_KEYS:
+               ret = core_scsi3_pri_read_keys(cmd);
+               break;
+       case PRI_READ_RESERVATION:
+               ret = core_scsi3_pri_read_reservation(cmd);
+               break;
+       case PRI_REPORT_CAPABILITIES:
+               ret = core_scsi3_pri_report_capabilities(cmd);
+               break;
+       case PRI_READ_FULL_STATUS:
+               ret = core_scsi3_pri_read_full_status(cmd);
+               break;
+       default:
+               pr_err("Unknown PERSISTENT_RESERVE_IN service"
+                       " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               ret = -EINVAL;
+               break;
+       }
+
+       if (!ret) {
+               task->task_scsi_status = GOOD;
+               transport_complete_task(task, 1);
+       }
+       return ret;
 }
 
 static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)
index c8f47d06458494a3ecb9239a9259d2939ab279fa..b97f6940dd051a9e6c18e1842d0626af3a60ebbc 100644 (file)
@@ -47,7 +47,8 @@ extern struct kmem_cache *t10_pr_reg_cache;
 
 extern int core_pr_dump_initiator_port(struct t10_pr_registration *,
                        char *, u32);
-extern int core_scsi2_emulate_crh(struct se_cmd *);
+extern int target_scsi2_reservation_release(struct se_task *task);
+extern int target_scsi2_reservation_reserve(struct se_task *task);
 extern int core_scsi3_alloc_aptpl_registration(
                        struct t10_reservation *, u64,
                        unsigned char *, unsigned char *, u32,
@@ -61,7 +62,9 @@ extern void core_scsi3_free_all_registrations(struct se_device *);
 extern unsigned char *core_scsi3_pr_dump_type(int);
 extern int core_scsi3_check_cdb_abort_and_preempt(struct list_head *,
                                                  struct se_cmd *);
-extern int core_scsi3_emulate_pr(struct se_cmd *);
+
+extern int target_scsi3_emulate_pr_in(struct se_task *task);
+extern int target_scsi3_emulate_pr_out(struct se_task *task);
 extern int core_setup_reservations(struct se_device *, int);
 
 #endif /* TARGET_CORE_PR_H */
index dad671dee9e92172c04142a7dfd4ae6dcc8d206c..8b15e56b038461169872d964055316c0318e7e31 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/genhd.h>
 #include <linux/cdrom.h>
 #include <linux/file.h>
+#include <linux/module.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
@@ -962,6 +963,7 @@ static inline struct bio *pscsi_get_bio(int sg_num)
 static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
                struct bio **hbio)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
        u32 task_sg_num = task->task_sg_nents;
        struct bio *bio = NULL, *tbio = NULL;
@@ -970,7 +972,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
        u32 data_len = task->task_size, i, len, bytes, off;
        int nr_pages = (task->task_size + task_sg[0].offset +
                        PAGE_SIZE - 1) >> PAGE_SHIFT;
-       int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+       int nr_vecs = 0, rc;
        int rw = (task->task_data_direction == DMA_TO_DEVICE);
 
        *hbio = NULL;
@@ -1057,11 +1059,13 @@ fail:
                bio->bi_next = NULL;
                bio_endio(bio, 0);      /* XXX: should be error */
        }
-       return ret;
+       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       return -ENOMEM;
 }
 
 static int pscsi_do_task(struct se_task *task)
 {
+       struct se_cmd *cmd = task->task_se_cmd;
        struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr;
        struct pscsi_plugin_task *pt = PSCSI_TASK(task);
        struct request *req;
@@ -1077,7 +1081,9 @@ static int pscsi_do_task(struct se_task *task)
                if (!req || IS_ERR(req)) {
                        pr_err("PSCSI: blk_get_request() failed: %ld\n",
                                        req ? IS_ERR(req) : -ENOMEM);
-                       return PYX_TRANSPORT_LU_COMM_FAILURE;
+                       cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       return -ENODEV;
                }
        } else {
                BUG_ON(!task->task_size);
@@ -1086,12 +1092,15 @@ static int pscsi_do_task(struct se_task *task)
                 * Setup the main struct request for the task->task_sg[] payload
                 */
                ret = pscsi_map_sg(task, task->task_sg, &hbio);
-               if (ret < 0)
-                       return PYX_TRANSPORT_LU_COMM_FAILURE;
+               if (ret < 0) {
+                       cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       return ret;
+               }
 
                req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
                                       GFP_KERNEL);
-               if (!req) {
+               if (IS_ERR(req)) {
                        pr_err("pSCSI: blk_make_request() failed\n");
                        goto fail;
                }
@@ -1114,7 +1123,7 @@ static int pscsi_do_task(struct se_task *task)
                        (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
                        pscsi_req_done);
 
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       return 0;
 
 fail:
        while (hbio) {
@@ -1123,7 +1132,8 @@ fail:
                bio->bi_next = NULL;
                bio_endio(bio, 0);      /* XXX: should be error */
        }
-       return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+       cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+       return -ENOMEM;
 }
 
 /*     pscsi_get_sense_buffer():
@@ -1197,9 +1207,8 @@ static inline void pscsi_process_SAM_status(
                        " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0],
                        pt->pscsi_result);
                task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
-               task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-               task->task_se_cmd->transport_error_status =
-                                       PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+               task->task_se_cmd->scsi_sense_reason =
+                                       TCM_UNSUPPORTED_SCSI_OPCODE;
                transport_complete_task(task, 0);
                break;
        }
index 5158d3846f19cf8f79f69e7efe97f72558b0d413..02e51faa2f4ea168f0a6139c8e303fc9fca81c28 100644 (file)
@@ -343,235 +343,74 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
        return NULL;
 }
 
-/*     rd_MEMCPY_read():
- *
- *
- */
-static int rd_MEMCPY_read(struct rd_request *req)
+static int rd_MEMCPY(struct rd_request *req, u32 read_rd)
 {
        struct se_task *task = &req->rd_task;
        struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr;
        struct rd_dev_sg_table *table;
-       struct scatterlist *sg_d, *sg_s;
-       void *dst, *src;
-       u32 i = 0, j = 0, dst_offset = 0, src_offset = 0;
-       u32 length, page_end = 0, table_sg_end;
+       struct scatterlist *rd_sg;
+       struct sg_mapping_iter m;
        u32 rd_offset = req->rd_offset;
+       u32 src_len;
 
        table = rd_get_sg_table(dev, req->rd_page);
        if (!table)
                return -EINVAL;
 
-       table_sg_end = (table->page_end_offset - req->rd_page);
-       sg_d = task->task_sg;
-       sg_s = &table->sg_table[req->rd_page - table->page_start_offset];
+       rd_sg = &table->sg_table[req->rd_page - table->page_start_offset];
 
-       pr_debug("RD[%u]: Read LBA: %llu, Size: %u Page: %u, Offset:"
-               " %u\n", dev->rd_dev_id, task->task_lba, req->rd_size,
-               req->rd_page, req->rd_offset);
-
-       src_offset = rd_offset;
+       pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n",
+                       dev->rd_dev_id, read_rd ? "Read" : "Write",
+                       task->task_lba, req->rd_size, req->rd_page,
+                       rd_offset);
 
+       src_len = PAGE_SIZE - rd_offset;
+       sg_miter_start(&m, task->task_sg, task->task_sg_nents,
+                       read_rd ? SG_MITER_TO_SG : SG_MITER_FROM_SG);
        while (req->rd_size) {
-               if ((sg_d[i].length - dst_offset) <
-                   (sg_s[j].length - src_offset)) {
-                       length = (sg_d[i].length - dst_offset);
-
-                       pr_debug("Step 1 - sg_d[%d]: %p length: %d"
-                               " offset: %u sg_s[%d].length: %u\n", i,
-                               &sg_d[i], sg_d[i].length, sg_d[i].offset, j,
-                               sg_s[j].length);
-                       pr_debug("Step 1 - length: %u dst_offset: %u"
-                               " src_offset: %u\n", length, dst_offset,
-                               src_offset);
-
-                       if (length > req->rd_size)
-                               length = req->rd_size;
-
-                       dst = sg_virt(&sg_d[i++]) + dst_offset;
-                       BUG_ON(!dst);
-
-                       src = sg_virt(&sg_s[j]) + src_offset;
-                       BUG_ON(!src);
-
-                       dst_offset = 0;
-                       src_offset = length;
-                       page_end = 0;
-               } else {
-                       length = (sg_s[j].length - src_offset);
-
-                       pr_debug("Step 2 - sg_d[%d]: %p length: %d"
-                               " offset: %u sg_s[%d].length: %u\n", i,
-                               &sg_d[i], sg_d[i].length, sg_d[i].offset,
-                               j, sg_s[j].length);
-                       pr_debug("Step 2 - length: %u dst_offset: %u"
-                               " src_offset: %u\n", length, dst_offset,
-                               src_offset);
-
-                       if (length > req->rd_size)
-                               length = req->rd_size;
-
-                       dst = sg_virt(&sg_d[i]) + dst_offset;
-                       BUG_ON(!dst);
-
-                       if (sg_d[i].length == length) {
-                               i++;
-                               dst_offset = 0;
-                       } else
-                               dst_offset = length;
-
-                       src = sg_virt(&sg_s[j++]) + src_offset;
-                       BUG_ON(!src);
-
-                       src_offset = 0;
-                       page_end = 1;
-               }
+               u32 len;
+               void *rd_addr;
 
-               memcpy(dst, src, length);
+               sg_miter_next(&m);
+               len = min((u32)m.length, src_len);
+               m.consumed = len;
 
-               pr_debug("page: %u, remaining size: %u, length: %u,"
-                       " i: %u, j: %u\n", req->rd_page,
-                       (req->rd_size - length), length, i, j);
+               rd_addr = sg_virt(rd_sg) + rd_offset;
 
-               req->rd_size -= length;
-               if (!req->rd_size)
-                       return 0;
+               if (read_rd)
+                       memcpy(m.addr, rd_addr, len);
+               else
+                       memcpy(rd_addr, m.addr, len);
 
-               if (!page_end)
+               req->rd_size -= len;
+               if (!req->rd_size)
                        continue;
 
-               if (++req->rd_page <= table->page_end_offset) {
-                       pr_debug("page: %u in same page table\n",
-                               req->rd_page);
+               src_len -= len;
+               if (src_len) {
+                       rd_offset += len;
                        continue;
                }
 
-               pr_debug("getting new page table for page: %u\n",
-                               req->rd_page);
-
-               table = rd_get_sg_table(dev, req->rd_page);
-               if (!table)
-                       return -EINVAL;
-
-               sg_s = &table->sg_table[j = 0];
-       }
-
-       return 0;
-}
-
-/*     rd_MEMCPY_write():
- *
- *
- */
-static int rd_MEMCPY_write(struct rd_request *req)
-{
-       struct se_task *task = &req->rd_task;
-       struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr;
-       struct rd_dev_sg_table *table;
-       struct scatterlist *sg_d, *sg_s;
-       void *dst, *src;
-       u32 i = 0, j = 0, dst_offset = 0, src_offset = 0;
-       u32 length, page_end = 0, table_sg_end;
-       u32 rd_offset = req->rd_offset;
-
-       table = rd_get_sg_table(dev, req->rd_page);
-       if (!table)
-               return -EINVAL;
-
-       table_sg_end = (table->page_end_offset - req->rd_page);
-       sg_d = &table->sg_table[req->rd_page - table->page_start_offset];
-       sg_s = task->task_sg;
-
-       pr_debug("RD[%d] Write LBA: %llu, Size: %u, Page: %u,"
-               " Offset: %u\n", dev->rd_dev_id, task->task_lba, req->rd_size,
-               req->rd_page, req->rd_offset);
-
-       dst_offset = rd_offset;
-
-       while (req->rd_size) {
-               if ((sg_s[i].length - src_offset) <
-                   (sg_d[j].length - dst_offset)) {
-                       length = (sg_s[i].length - src_offset);
-
-                       pr_debug("Step 1 - sg_s[%d]: %p length: %d"
-                               " offset: %d sg_d[%d].length: %u\n", i,
-                               &sg_s[i], sg_s[i].length, sg_s[i].offset,
-                               j, sg_d[j].length);
-                       pr_debug("Step 1 - length: %u src_offset: %u"
-                               " dst_offset: %u\n", length, src_offset,
-                               dst_offset);
-
-                       if (length > req->rd_size)
-                               length = req->rd_size;
-
-                       src = sg_virt(&sg_s[i++]) + src_offset;
-                       BUG_ON(!src);
-
-                       dst = sg_virt(&sg_d[j]) + dst_offset;
-                       BUG_ON(!dst);
-
-                       src_offset = 0;
-                       dst_offset = length;
-                       page_end = 0;
-               } else {
-                       length = (sg_d[j].length - dst_offset);
-
-                       pr_debug("Step 2 - sg_s[%d]: %p length: %d"
-                               " offset: %d sg_d[%d].length: %u\n", i,
-                               &sg_s[i], sg_s[i].length, sg_s[i].offset,
-                               j, sg_d[j].length);
-                       pr_debug("Step 2 - length: %u src_offset: %u"
-                               " dst_offset: %u\n", length, src_offset,
-                               dst_offset);
-
-                       if (length > req->rd_size)
-                               length = req->rd_size;
-
-                       src = sg_virt(&sg_s[i]) + src_offset;
-                       BUG_ON(!src);
-
-                       if (sg_s[i].length == length) {
-                               i++;
-                               src_offset = 0;
-                       } else
-                               src_offset = length;
-
-                       dst = sg_virt(&sg_d[j++]) + dst_offset;
-                       BUG_ON(!dst);
-
-                       dst_offset = 0;
-                       page_end = 1;
-               }
-
-               memcpy(dst, src, length);
-
-               pr_debug("page: %u, remaining size: %u, length: %u,"
-                       " i: %u, j: %u\n", req->rd_page,
-                       (req->rd_size - length), length, i, j);
-
-               req->rd_size -= length;
-               if (!req->rd_size)
-                       return 0;
-
-               if (!page_end)
-                       continue;
-
-               if (++req->rd_page <= table->page_end_offset) {
-                       pr_debug("page: %u in same page table\n",
-                               req->rd_page);
+               /* rd page completed, next one please */
+               req->rd_page++;
+               rd_offset = 0;
+               src_len = PAGE_SIZE;
+               if (req->rd_page <= table->page_end_offset) {
+                       rd_sg++;
                        continue;
                }
 
-               pr_debug("getting new page table for page: %u\n",
-                               req->rd_page);
-
                table = rd_get_sg_table(dev, req->rd_page);
-               if (!table)
+               if (!table) {
+                       sg_miter_stop(&m);
                        return -EINVAL;
+               }
 
-               sg_d = &table->sg_table[j = 0];
+               /* since we increment, the first sg entry is correct */
+               rd_sg = table->sg_table;
        }
-
+       sg_miter_stop(&m);
        return 0;
 }
 
@@ -583,28 +422,21 @@ static int rd_MEMCPY_do_task(struct se_task *task)
 {
        struct se_device *dev = task->task_se_cmd->se_dev;
        struct rd_request *req = RD_REQ(task);
-       unsigned long long lba;
+       u64 tmp;
        int ret;
 
-       req->rd_page = (task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size) / PAGE_SIZE;
-       lba = task->task_lba;
-       req->rd_offset = (do_div(lba,
-                         (PAGE_SIZE / dev->se_sub_dev->se_dev_attrib.block_size))) *
-                          dev->se_sub_dev->se_dev_attrib.block_size;
+       tmp = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size;
+       req->rd_offset = do_div(tmp, PAGE_SIZE);
+       req->rd_page = tmp;
        req->rd_size = task->task_size;
 
-       if (task->task_data_direction == DMA_FROM_DEVICE)
-               ret = rd_MEMCPY_read(req);
-       else
-               ret = rd_MEMCPY_write(req);
-
+       ret = rd_MEMCPY(req, task->task_data_direction == DMA_FROM_DEVICE);
        if (ret != 0)
                return ret;
 
        task->task_scsi_status = GOOD;
        transport_complete_task(task, 1);
-
-       return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+       return 0;
 }
 
 /*     rd_free_task(): (Part of se_subsystem_api_t template)
index 570b144a1edb8f0ce696f1f8515b1f74a9317fbc..684522805a1f370a99a5745c2fa3815a9c722912 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/export.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
@@ -118,7 +119,7 @@ static void core_tmr_drain_tmr_list(
                /*
                 * Allow the received TMR to return with FUNCTION_COMPLETE.
                 */
-               if (tmr && (tmr_p == tmr))
+               if (tmr_p == tmr)
                        continue;
 
                cmd = tmr_p->task_cmd;
@@ -147,19 +148,18 @@ static void core_tmr_drain_tmr_list(
                }
                spin_unlock(&cmd->t_state_lock);
 
-               list_move_tail(&tmr->tmr_list, &drain_tmr_list);
+               list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
        }
        spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
 
-       while (!list_empty(&drain_tmr_list)) {
-               tmr = list_entry(drain_tmr_list.next, struct se_tmr_req, tmr_list);
-               list_del(&tmr->tmr_list);
+       list_for_each_entry_safe(tmr_p, tmr_pp, &drain_tmr_list, tmr_list) {
+               list_del_init(&tmr_p->tmr_list);
                cmd = tmr_p->task_cmd;
 
                pr_debug("LUN_RESET: %s releasing TMR %p Function: 0x%02x,"
                        " Response: 0x%02x, t_state: %d\n",
-                       (preempt_and_abort_list) ? "Preempt" : "", tmr,
-                       tmr->function, tmr->response, cmd->t_state);
+                       (preempt_and_abort_list) ? "Preempt" : "", tmr_p,
+                       tmr_p->function, tmr_p->response, cmd->t_state);
 
                transport_cmd_finish_abort(cmd, 1);
        }
@@ -330,16 +330,6 @@ static void core_tmr_drain_cmd_list(
                 */
                if (prout_cmd == cmd)
                        continue;
-               /*
-                * Skip direct processing of TRANSPORT_FREE_CMD_INTR for
-                * HW target mode fabrics.
-                */
-               spin_lock(&cmd->t_state_lock);
-               if (cmd->t_state == TRANSPORT_FREE_CMD_INTR) {
-                       spin_unlock(&cmd->t_state_lock);
-                       continue;
-               }
-               spin_unlock(&cmd->t_state_lock);
 
                atomic_set(&cmd->t_transport_queue_active, 0);
                atomic_dec(&qobj->queue_cnt);
@@ -355,10 +345,6 @@ static void core_tmr_drain_cmd_list(
                        " %d t_fe_count: %d\n", (preempt_and_abort_list) ?
                        "Preempt" : "", cmd, cmd->t_state,
                        atomic_read(&cmd->t_fe_count));
-               /*
-                * Signal that the command has failed via cmd->se_cmd_flags,
-                */
-               transport_new_cmd_failure(cmd);
 
                core_tmr_handle_tas_abort(tmr_nacl, cmd, tas,
                                atomic_read(&cmd->t_fe_count));
index 49fd0a9b0a569d64971565c9652759827d3e09ae..8ddd133025b932a98a5968bfeb4f30b0d396a3d2 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/in.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
index d75255804481b8340774e88cf60494eed3c0bd7c..0257658e2e3ea8a75642ae0dcabc77547ac2379b 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/kthread.h>
 #include <linux/in.h>
 #include <linux/cdrom.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 #include <net/sock.h>
 #include <net/tcp.h>
@@ -52,6 +53,7 @@
 #include <target/target_core_configfs.h>
 
 #include "target_core_alua.h"
+#include "target_core_cdb.h"
 #include "target_core_hba.h"
 #include "target_core_pr.h"
 #include "target_core_ua.h"
@@ -59,7 +61,6 @@
 static int sub_api_initialized;
 
 static struct workqueue_struct *target_completion_wq;
-static struct kmem_cache *se_cmd_cache;
 static struct kmem_cache *se_sess_cache;
 struct kmem_cache *se_tmr_req_cache;
 struct kmem_cache *se_ua_cache;
@@ -80,24 +81,18 @@ static int transport_generic_get_mem(struct se_cmd *cmd);
 static void transport_put_cmd(struct se_cmd *cmd);
 static void transport_remove_cmd_from_queue(struct se_cmd *cmd);
 static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
-static void transport_generic_request_failure(struct se_cmd *, int, int);
+static void transport_generic_request_failure(struct se_cmd *);
 static void target_complete_ok_work(struct work_struct *work);
 
 int init_se_kmem_caches(void)
 {
-       se_cmd_cache = kmem_cache_create("se_cmd_cache",
-                       sizeof(struct se_cmd), __alignof__(struct se_cmd), 0, NULL);
-       if (!se_cmd_cache) {
-               pr_err("kmem_cache_create for struct se_cmd failed\n");
-               goto out;
-       }
        se_tmr_req_cache = kmem_cache_create("se_tmr_cache",
                        sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req),
                        0, NULL);
        if (!se_tmr_req_cache) {
                pr_err("kmem_cache_create() for struct se_tmr_req"
                                " failed\n");
-               goto out_free_cmd_cache;
+               goto out;
        }
        se_sess_cache = kmem_cache_create("se_sess_cache",
                        sizeof(struct se_session), __alignof__(struct se_session),
@@ -180,8 +175,6 @@ out_free_sess_cache:
        kmem_cache_destroy(se_sess_cache);
 out_free_tmr_req_cache:
        kmem_cache_destroy(se_tmr_req_cache);
-out_free_cmd_cache:
-       kmem_cache_destroy(se_cmd_cache);
 out:
        return -ENOMEM;
 }
@@ -189,7 +182,6 @@ out:
 void release_se_kmem_caches(void)
 {
        destroy_workqueue(target_completion_wq);
-       kmem_cache_destroy(se_cmd_cache);
        kmem_cache_destroy(se_tmr_req_cache);
        kmem_cache_destroy(se_sess_cache);
        kmem_cache_destroy(se_ua_cache);
@@ -268,6 +260,9 @@ struct se_session *transport_init_session(void)
        }
        INIT_LIST_HEAD(&se_sess->sess_list);
        INIT_LIST_HEAD(&se_sess->sess_acl_list);
+       INIT_LIST_HEAD(&se_sess->sess_cmd_list);
+       INIT_LIST_HEAD(&se_sess->sess_wait_list);
+       spin_lock_init(&se_sess->sess_cmd_lock);
 
        return se_sess;
 }
@@ -514,13 +509,16 @@ static int transport_cmd_check_stop(
                         * Some fabric modules like tcm_loop can release
                         * their internally allocated I/O reference now and
                         * struct se_cmd now.
+                        *
+                        * Fabric modules are expected to return '1' here if the
+                        * se_cmd being passed is released at this point,
+                        * or zero if not being released.
                         */
                        if (cmd->se_tfo->check_stop_free != NULL) {
                                spin_unlock_irqrestore(
                                        &cmd->t_state_lock, flags);
 
-                               cmd->se_tfo->check_stop_free(cmd);
-                               return 1;
+                               return cmd->se_tfo->check_stop_free(cmd);
                        }
                }
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
@@ -672,9 +670,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good)
                task->task_scsi_status = GOOD;
        } else {
                task->task_scsi_status = SAM_STAT_CHECK_CONDITION;
-               task->task_error_status = PYX_TRANSPORT_ILLEGAL_REQUEST;
-               task->task_se_cmd->transport_error_status =
-                                       PYX_TRANSPORT_ILLEGAL_REQUEST;
+               task->task_se_cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
        }
 
        transport_complete_task(task, good);
@@ -685,7 +683,7 @@ static void target_complete_failure_work(struct work_struct *work)
 {
        struct se_cmd *cmd = container_of(work, struct se_cmd, work);
 
-       transport_generic_request_failure(cmd, 1, 1);
+       transport_generic_request_failure(cmd);
 }
 
 /*     transport_complete_task():
@@ -730,6 +728,10 @@ void transport_complete_task(struct se_task *task, int success)
                complete(&task->task_stop_comp);
                return;
        }
+
+       if (!success)
+               cmd->t_tasks_failed = 1;
+
        /*
         * Decrement the outstanding t_task_cdbs_left count.  The last
         * struct se_task from struct se_cmd will complete itself into the
@@ -740,13 +742,14 @@ void transport_complete_task(struct se_task *task, int success)
                return;
        }
 
-       if (!success || cmd->t_tasks_failed) {
+       if (cmd->t_tasks_failed) {
                if (!task->task_error_status) {
                        task->task_error_status =
-                               PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
-                       cmd->transport_error_status =
-                               PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+                       cmd->scsi_sense_reason =
+                               TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                }
+
                INIT_WORK(&cmd->work, target_complete_failure_work);
        } else {
                atomic_set(&cmd->t_transport_complete, 1);
@@ -908,7 +911,7 @@ void transport_remove_task_from_execute_queue(
 }
 
 /*
- * Handle QUEUE_FULL / -EAGAIN status
+ * Handle QUEUE_FULL / -EAGAIN and -ENOMEM status
  */
 
 static void target_qf_do_work(struct work_struct *work)
@@ -1323,23 +1326,17 @@ struct se_device *transport_add_device_to_core_hba(
        dev->se_hba             = hba;
        dev->se_sub_dev         = se_dev;
        dev->transport          = transport;
-       atomic_set(&dev->active_cmds, 0);
        INIT_LIST_HEAD(&dev->dev_list);
        INIT_LIST_HEAD(&dev->dev_sep_list);
        INIT_LIST_HEAD(&dev->dev_tmr_list);
        INIT_LIST_HEAD(&dev->execute_task_list);
        INIT_LIST_HEAD(&dev->delayed_cmd_list);
-       INIT_LIST_HEAD(&dev->ordered_cmd_list);
        INIT_LIST_HEAD(&dev->state_task_list);
        INIT_LIST_HEAD(&dev->qf_cmd_list);
        spin_lock_init(&dev->execute_task_lock);
        spin_lock_init(&dev->delayed_cmd_lock);
-       spin_lock_init(&dev->ordered_cmd_lock);
-       spin_lock_init(&dev->state_task_lock);
-       spin_lock_init(&dev->dev_alua_lock);
        spin_lock_init(&dev->dev_reservation_lock);
        spin_lock_init(&dev->dev_status_lock);
-       spin_lock_init(&dev->dev_status_thr_lock);
        spin_lock_init(&dev->se_port_lock);
        spin_lock_init(&dev->se_tmr_lock);
        spin_lock_init(&dev->qf_cmd_lock);
@@ -1495,14 +1492,14 @@ void transport_init_se_cmd(
 {
        INIT_LIST_HEAD(&cmd->se_lun_node);
        INIT_LIST_HEAD(&cmd->se_delayed_node);
-       INIT_LIST_HEAD(&cmd->se_ordered_node);
        INIT_LIST_HEAD(&cmd->se_qf_node);
        INIT_LIST_HEAD(&cmd->se_queue_node);
-
+       INIT_LIST_HEAD(&cmd->se_cmd_list);
        INIT_LIST_HEAD(&cmd->t_task_list);
        init_completion(&cmd->transport_lun_fe_stop_comp);
        init_completion(&cmd->transport_lun_stop_comp);
        init_completion(&cmd->t_transport_stop_comp);
+       init_completion(&cmd->cmd_wait_comp);
        spin_lock_init(&cmd->t_state_lock);
        atomic_set(&cmd->transport_dev_active, 1);
 
@@ -1560,6 +1557,8 @@ int transport_generic_allocate_tasks(
                pr_err("Received SCSI CDB with command_size: %d that"
                        " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
                        scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE);
+               cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
+               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
                return -EINVAL;
        }
        /*
@@ -1575,6 +1574,9 @@ int transport_generic_allocate_tasks(
                                " %u > sizeof(cmd->__t_task_cdb): %lu ops\n",
                                scsi_command_size(cdb),
                                (unsigned long)sizeof(cmd->__t_task_cdb));
+                       cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
+                       cmd->scsi_sense_reason =
+                                       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
                        return -ENOMEM;
                }
        } else
@@ -1645,13 +1647,9 @@ int transport_handle_cdb_direct(
         * and call transport_generic_request_failure() if necessary..
         */
        ret = transport_generic_new_cmd(cmd);
-       if (ret == -EAGAIN)
-               return 0;
-       else if (ret < 0) {
-               cmd->transport_error_status = ret;
-               transport_generic_request_failure(cmd, 0,
-                               (cmd->data_direction != DMA_TO_DEVICE));
-       }
+       if (ret < 0)
+               transport_generic_request_failure(cmd);
+
        return 0;
 }
 EXPORT_SYMBOL(transport_handle_cdb_direct);
@@ -1717,13 +1715,6 @@ int transport_generic_handle_tmr(
 }
 EXPORT_SYMBOL(transport_generic_handle_tmr);
 
-void transport_generic_free_cmd_intr(
-       struct se_cmd *cmd)
-{
-       transport_add_cmd_to_queue(cmd, TRANSPORT_FREE_CMD_INTR, false);
-}
-EXPORT_SYMBOL(transport_generic_free_cmd_intr);
-
 /*
  * If the task is active, request it to be stopped and sleep until it
  * has completed.
@@ -1794,20 +1785,16 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
 /*
  * Handle SAM-esque emulation for generic transport request failures.
  */
-static void transport_generic_request_failure(
-       struct se_cmd *cmd,
-       int complete,
-       int sc)
+static void transport_generic_request_failure(struct se_cmd *cmd)
 {
        int ret = 0;
 
        pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x"
                " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd),
                cmd->t_task_cdb[0]);
-       pr_debug("-----[ i_state: %d t_state: %d transport_error_status: %d\n",
+       pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n",
                cmd->se_tfo->get_cmd_state(cmd),
-               cmd->t_state,
-               cmd->transport_error_status);
+               cmd->t_state, cmd->scsi_sense_reason);
        pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d"
                " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --"
                " t_transport_active: %d t_transport_stop: %d"
@@ -1825,46 +1812,19 @@ static void transport_generic_request_failure(
        if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
                transport_complete_task_attr(cmd);
 
-       if (complete) {
-               cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE;
-       }
-
-       switch (cmd->transport_error_status) {
-       case PYX_TRANSPORT_UNKNOWN_SAM_OPCODE:
-               cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
-               break;
-       case PYX_TRANSPORT_REQ_TOO_MANY_SECTORS:
-               cmd->scsi_sense_reason = TCM_SECTOR_COUNT_TOO_MANY;
-               break;
-       case PYX_TRANSPORT_INVALID_CDB_FIELD:
-               cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
-               break;
-       case PYX_TRANSPORT_INVALID_PARAMETER_LIST:
-               cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
-               break;
-       case PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES:
-               if (!sc)
-                       transport_new_cmd_failure(cmd);
-               /*
-                * Currently for PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES,
-                * we force this session to fall back to session
-                * recovery.
-                */
-               cmd->se_tfo->fall_back_to_erl0(cmd->se_sess);
-               cmd->se_tfo->stop_session(cmd->se_sess, 0, 0);
-
-               goto check_stop;
-       case PYX_TRANSPORT_LU_COMM_FAILURE:
-       case PYX_TRANSPORT_ILLEGAL_REQUEST:
-               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-               break;
-       case PYX_TRANSPORT_UNKNOWN_MODE_PAGE:
-               cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE;
-               break;
-       case PYX_TRANSPORT_WRITE_PROTECTED:
-               cmd->scsi_sense_reason = TCM_WRITE_PROTECTED;
+       switch (cmd->scsi_sense_reason) {
+       case TCM_NON_EXISTENT_LUN:
+       case TCM_UNSUPPORTED_SCSI_OPCODE:
+       case TCM_INVALID_CDB_FIELD:
+       case TCM_INVALID_PARAMETER_LIST:
+       case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
+       case TCM_UNKNOWN_MODE_PAGE:
+       case TCM_WRITE_PROTECTED:
+       case TCM_CHECK_CONDITION_ABORT_CMD:
+       case TCM_CHECK_CONDITION_UNIT_ATTENTION:
+       case TCM_CHECK_CONDITION_NOT_READY:
                break;
-       case PYX_TRANSPORT_RESERVATION_CONFLICT:
+       case TCM_RESERVATION_CONFLICT:
                /*
                 * No SENSE Data payload for this case, set SCSI Status
                 * and queue the response to $FABRIC_MOD.
@@ -1886,18 +1846,12 @@ static void transport_generic_request_failure(
                                ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
 
                ret = cmd->se_tfo->queue_status(cmd);
-               if (ret == -EAGAIN)
+               if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
                goto check_stop;
-       case PYX_TRANSPORT_USE_SENSE_REASON:
-               /*
-                * struct se_cmd->scsi_sense_reason already set
-                */
-               break;
        default:
                pr_err("Unknown transport error for CDB 0x%02x: %d\n",
-                       cmd->t_task_cdb[0],
-                       cmd->transport_error_status);
+                       cmd->t_task_cdb[0], cmd->scsi_sense_reason);
                cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
                break;
        }
@@ -1908,14 +1862,10 @@ static void transport_generic_request_failure(
         * transport_send_check_condition_and_sense() after handling
         * possible unsoliticied write data payloads.
         */
-       if (!sc && !cmd->se_tfo->new_cmd_map)
-               transport_new_cmd_failure(cmd);
-       else {
-               ret = transport_send_check_condition_and_sense(cmd,
-                               cmd->scsi_sense_reason, 0);
-               if (ret == -EAGAIN)
-                       goto queue_full;
-       }
+       ret = transport_send_check_condition_and_sense(cmd,
+                       cmd->scsi_sense_reason, 0);
+       if (ret == -EAGAIN || ret == -ENOMEM)
+               goto queue_full;
 
 check_stop:
        transport_lun_remove_cmd(cmd);
@@ -1998,19 +1948,12 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd)
         * to allow the passed struct se_cmd list of tasks to the front of the list.
         */
         if (cmd->sam_task_attr == MSG_HEAD_TAG) {
-               atomic_inc(&cmd->se_dev->dev_hoq_count);
-               smp_mb__after_atomic_inc();
                pr_debug("Added HEAD_OF_QUEUE for CDB:"
                        " 0x%02x, se_ordered_id: %u\n",
                        cmd->t_task_cdb[0],
                        cmd->se_ordered_id);
                return 1;
        } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) {
-               spin_lock(&cmd->se_dev->ordered_cmd_lock);
-               list_add_tail(&cmd->se_ordered_node,
-                               &cmd->se_dev->ordered_cmd_list);
-               spin_unlock(&cmd->se_dev->ordered_cmd_lock);
-
                atomic_inc(&cmd->se_dev->dev_ordered_sync);
                smp_mb__after_atomic_inc();
 
@@ -2072,9 +2015,9 @@ static int transport_execute_tasks(struct se_cmd *cmd)
 {
        int add_tasks;
 
-       if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) {
-               cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE;
-               transport_generic_request_failure(cmd, 0, 1);
+       if (se_dev_check_online(cmd->se_dev) != 0) {
+               cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+               transport_generic_request_failure(cmd);
                return 0;
        }
 
@@ -2153,62 +2096,19 @@ check_depth:
                atomic_set(&cmd->t_transport_sent, 1);
 
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-       /*
-        * The struct se_cmd->transport_emulate_cdb() function pointer is used
-        * to grab REPORT_LUNS and other CDBs we want to handle before they hit the
-        * struct se_subsystem_api->do_task() caller below.
-        */
-       if (cmd->transport_emulate_cdb) {
-               error = cmd->transport_emulate_cdb(cmd);
-               if (error != 0) {
-                       cmd->transport_error_status = error;
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       task->task_flags &= ~TF_ACTIVE;
-                       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-                       atomic_set(&cmd->t_transport_sent, 0);
-                       transport_stop_tasks_for_cmd(cmd);
-                       atomic_inc(&dev->depth_left);
-                       transport_generic_request_failure(cmd, 0, 1);
-                       goto check_depth;
-               }
-               /*
-                * Handle the successful completion for transport_emulate_cdb()
-                * for synchronous operation, following SCF_EMULATE_CDB_ASYNC
-                * Otherwise the caller is expected to complete the task with
-                * proper status.
-                */
-               if (!(cmd->se_cmd_flags & SCF_EMULATE_CDB_ASYNC)) {
-                       cmd->scsi_status = SAM_STAT_GOOD;
-                       task->task_scsi_status = GOOD;
-                       transport_complete_task(task, 1);
-               }
-       } else {
-               /*
-                * Currently for all virtual TCM plugins including IBLOCK, FILEIO and
-                * RAMDISK we use the internal transport_emulate_control_cdb() logic
-                * with struct se_subsystem_api callers for the primary SPC-3 TYPE_DISK
-                * LUN emulation code.
-                *
-                * For TCM/pSCSI and all other SCF_SCSI_DATA_SG_IO_CDB I/O tasks we
-                * call ->do_task() directly and let the underlying TCM subsystem plugin
-                * code handle the CDB emulation.
-                */
-               if ((dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) &&
-                   (!(task->task_se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
-                       error = transport_emulate_control_cdb(task);
-               else
-                       error = dev->transport->do_task(task);
 
-               if (error != 0) {
-                       cmd->transport_error_status = error;
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       task->task_flags &= ~TF_ACTIVE;
-                       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-                       atomic_set(&cmd->t_transport_sent, 0);
-                       transport_stop_tasks_for_cmd(cmd);
-                       atomic_inc(&dev->depth_left);
-                       transport_generic_request_failure(cmd, 0, 1);
-               }
+       if (cmd->execute_task)
+               error = cmd->execute_task(task);
+       else
+               error = dev->transport->do_task(task);
+       if (error != 0) {
+               spin_lock_irqsave(&cmd->t_state_lock, flags);
+               task->task_flags &= ~TF_ACTIVE;
+               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+               atomic_set(&cmd->t_transport_sent, 0);
+               transport_stop_tasks_for_cmd(cmd);
+               atomic_inc(&dev->depth_left);
+               transport_generic_request_failure(cmd);
        }
 
        goto check_depth;
@@ -2216,19 +2116,6 @@ check_depth:
        return 0;
 }
 
-void transport_new_cmd_failure(struct se_cmd *se_cmd)
-{
-       unsigned long flags;
-       /*
-        * Any unsolicited data will get dumped for failed command inside of
-        * the fabric plugin
-        */
-       spin_lock_irqsave(&se_cmd->t_state_lock, flags);
-       se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED;
-       se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-       spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
-}
-
 static inline u32 transport_get_sectors_6(
        unsigned char *cdb,
        struct se_cmd *cmd,
@@ -2251,10 +2138,15 @@ static inline u32 transport_get_sectors_6(
 
        /*
         * Everything else assume TYPE_DISK Sector CDB location.
-        * Use 8-bit sector value.
+        * Use 8-bit sector value.  SBC-3 says:
+        *
+        *   A TRANSFER LENGTH field set to zero specifies that 256
+        *   logical blocks shall be written.  Any other value
+        *   specifies the number of logical blocks that shall be
+        *   written.
         */
 type_disk:
-       return (u32)cdb[4];
+       return cdb[4] ? : 256;
 }
 
 static inline u32 transport_get_sectors_10(
@@ -2498,27 +2390,6 @@ static int transport_get_sense_data(struct se_cmd *cmd)
        return -1;
 }
 
-static int
-transport_handle_reservation_conflict(struct se_cmd *cmd)
-{
-       cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-       cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
-       cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
-       /*
-        * For UA Interlock Code 11b, a RESERVATION CONFLICT will
-        * establish a UNIT ATTENTION with PREVIOUS RESERVATION
-        * CONFLICT STATUS.
-        *
-        * See spc4r17, section 7.4.6 Control Mode Page, Table 349
-        */
-       if (cmd->se_sess &&
-           cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2)
-               core_scsi3_ua_allocate(cmd->se_sess->se_node_acl,
-                       cmd->orig_fe_lun, 0x2C,
-                       ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
-       return -EINVAL;
-}
-
 static inline long long transport_dev_end_lba(struct se_device *dev)
 {
        return dev->transport->get_blocks(dev) + 1;
@@ -2633,8 +2504,12 @@ static int transport_generic_cmd_sequencer(
         */
        if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) {
                if (su_dev->t10_pr.pr_ops.t10_seq_non_holder(
-                                       cmd, cdb, pr_reg_type) != 0)
-                       return transport_handle_reservation_conflict(cmd);
+                                       cmd, cdb, pr_reg_type) != 0) {
+                       cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
+                       cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
+                       cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
+                       return -EBUSY;
+               }
                /*
                 * This means the CDB is allowed for the SCSI Initiator port
                 * when said port is *NOT* holding the legacy SPC-2 or
@@ -2642,6 +2517,13 @@ static int transport_generic_cmd_sequencer(
                 */
        }
 
+       /*
+        * If we operate in passthrough mode we skip most CDB emulation and
+        * instead hand the commands down to the physical SCSI device.
+        */
+       passthrough =
+               (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV);
+
        switch (cdb[0]) {
        case READ_6:
                sectors = transport_get_sectors_6(cdb, cmd, &sector_ret);
@@ -2689,7 +2571,8 @@ static int transport_generic_cmd_sequencer(
                        goto out_unsupported_cdb;
                size = transport_get_size(sectors, cdb, cmd);
                cmd->t_task_lba = transport_lba_32(cdb);
-               cmd->t_tasks_fua = (cdb[1] & 0x8);
+               if (cdb[1] & 0x8)
+                       cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
                break;
        case WRITE_12:
@@ -2698,7 +2581,8 @@ static int transport_generic_cmd_sequencer(
                        goto out_unsupported_cdb;
                size = transport_get_size(sectors, cdb, cmd);
                cmd->t_task_lba = transport_lba_32(cdb);
-               cmd->t_tasks_fua = (cdb[1] & 0x8);
+               if (cdb[1] & 0x8)
+                       cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
                break;
        case WRITE_16:
@@ -2707,12 +2591,13 @@ static int transport_generic_cmd_sequencer(
                        goto out_unsupported_cdb;
                size = transport_get_size(sectors, cdb, cmd);
                cmd->t_task_lba = transport_lba_64(cdb);
-               cmd->t_tasks_fua = (cdb[1] & 0x8);
+               if (cdb[1] & 0x8)
+                       cmd->se_cmd_flags |= SCF_FUA;
                cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
                break;
        case XDWRITEREAD_10:
                if ((cmd->data_direction != DMA_TO_DEVICE) ||
-                   !(cmd->t_tasks_bidi))
+                   !(cmd->se_cmd_flags & SCF_BIDI))
                        goto out_invalid_cdb_field;
                sectors = transport_get_sectors_10(cdb, cmd, &sector_ret);
                if (sector_ret)
@@ -2721,24 +2606,21 @@ static int transport_generic_cmd_sequencer(
                cmd->t_task_lba = transport_lba_32(cdb);
                cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
 
-               if (dev->transport->transport_type ==
-                               TRANSPORT_PLUGIN_PHBA_PDEV)
+               /*
+                * Do now allow BIDI commands for passthrough mode.
+                */
+               if (passthrough)
                        goto out_unsupported_cdb;
+
                /*
                 * Setup BIDI XOR callback to be run after I/O completion.
                 */
                cmd->transport_complete_callback = &transport_xor_callback;
-               cmd->t_tasks_fua = (cdb[1] & 0x8);
+               if (cdb[1] & 0x8)
+                       cmd->se_cmd_flags |= SCF_FUA;
                break;
        case VARIABLE_LENGTH_CMD:
                service_action = get_unaligned_be16(&cdb[8]);
-               /*
-                * Determine if this is TCM/PSCSI device and we should disable
-                * internal emulation for this CDB.
-                */
-               passthrough = (dev->transport->transport_type ==
-                                       TRANSPORT_PLUGIN_PHBA_PDEV);
-
                switch (service_action) {
                case XDWRITEREAD_32:
                        sectors = transport_get_sectors_32(cdb, cmd, &sector_ret);
@@ -2752,14 +2634,19 @@ static int transport_generic_cmd_sequencer(
                        cmd->t_task_lba = transport_lba_64_ext(cdb);
                        cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB;
 
+                       /*
+                        * Do now allow BIDI commands for passthrough mode.
+                        */
                        if (passthrough)
                                goto out_unsupported_cdb;
+
                        /*
                         * Setup BIDI XOR callback to be run during after I/O
                         * completion.
                         */
                        cmd->transport_complete_callback = &transport_xor_callback;
-                       cmd->t_tasks_fua = (cdb[10] & 0x8);
+                       if (cdb[1] & 0x8)
+                               cmd->se_cmd_flags |= SCF_FUA;
                        break;
                case WRITE_SAME_32:
                        sectors = transport_get_sectors_32(cdb, cmd, &sector_ret);
@@ -2779,7 +2666,8 @@ static int transport_generic_cmd_sequencer(
 
                        if (target_check_write_same_discard(&cdb[10], dev) < 0)
                                goto out_invalid_cdb_field;
-
+                       if (!passthrough)
+                               cmd->execute_task = target_emulate_write_same;
                        break;
                default:
                        pr_err("VARIABLE_LENGTH_CMD service action"
@@ -2793,12 +2681,10 @@ static int transport_generic_cmd_sequencer(
                        /*
                         * Check for emulated MI_REPORT_TARGET_PGS.
                         */
-                       if (cdb[1] == MI_REPORT_TARGET_PGS) {
-                               cmd->transport_emulate_cdb =
-                               (su_dev->t10_alua.alua_type ==
-                                SPC3_ALUA_EMULATED) ?
-                               core_emulate_report_target_port_groups :
-                               NULL;
+                       if (cdb[1] == MI_REPORT_TARGET_PGS &&
+                           su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+                               cmd->execute_task =
+                                       target_emulate_report_target_port_groups;
                        }
                        size = (cdb[6] << 24) | (cdb[7] << 16) |
                               (cdb[8] << 8) | cdb[9];
@@ -2819,8 +2705,15 @@ static int transport_generic_cmd_sequencer(
        case MODE_SENSE:
                size = cdb[4];
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_modesense;
                break;
        case MODE_SENSE_10:
+               size = (cdb[7] << 8) + cdb[8];
+               cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_modesense;
+               break;
        case GPCMD_READ_BUFFER_CAPACITY:
        case GPCMD_SEND_OPC:
        case LOG_SELECT:
@@ -2840,11 +2733,14 @@ static int transport_generic_cmd_sequencer(
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
                break;
        case PERSISTENT_RESERVE_IN:
+               if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
+                       cmd->execute_task = target_scsi3_emulate_pr_in;
+               size = (cdb[7] << 8) + cdb[8];
+               cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               break;
        case PERSISTENT_RESERVE_OUT:
-               cmd->transport_emulate_cdb =
-                       (su_dev->t10_pr.res_type ==
-                        SPC3_PERSISTENT_RESERVATIONS) ?
-                       core_scsi3_emulate_pr : NULL;
+               if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
+                       cmd->execute_task = target_scsi3_emulate_pr_out;
                size = (cdb[7] << 8) + cdb[8];
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
                break;
@@ -2863,12 +2759,10 @@ static int transport_generic_cmd_sequencer(
                         *
                         * Check for emulated MO_SET_TARGET_PGS.
                         */
-                       if (cdb[1] == MO_SET_TARGET_PGS) {
-                               cmd->transport_emulate_cdb =
-                               (su_dev->t10_alua.alua_type ==
-                                       SPC3_ALUA_EMULATED) ?
-                               core_emulate_set_target_port_groups :
-                               NULL;
+                       if (cdb[1] == MO_SET_TARGET_PGS &&
+                           su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+                               cmd->execute_task =
+                                       target_emulate_set_target_port_groups;
                        }
 
                        size = (cdb[6] << 24) | (cdb[7] << 16) |
@@ -2888,6 +2782,8 @@ static int transport_generic_cmd_sequencer(
                if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
                        cmd->sam_task_attr = MSG_HEAD_TAG;
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_inquiry;
                break;
        case READ_BUFFER:
                size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
@@ -2896,6 +2792,8 @@ static int transport_generic_cmd_sequencer(
        case READ_CAPACITY:
                size = READ_CAP_LEN;
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_readcapacity;
                break;
        case READ_MEDIA_SERIAL_NUMBER:
        case SECURITY_PROTOCOL_IN:
@@ -2904,6 +2802,21 @@ static int transport_generic_cmd_sequencer(
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
                break;
        case SERVICE_ACTION_IN:
+               switch (cmd->t_task_cdb[1] & 0x1f) {
+               case SAI_READ_CAPACITY_16:
+                       if (!passthrough)
+                               cmd->execute_task =
+                                       target_emulate_readcapacity_16;
+                       break;
+               default:
+                       if (passthrough)
+                               break;
+
+                       pr_err("Unsupported SA: 0x%02x\n",
+                               cmd->t_task_cdb[1] & 0x1f);
+                       goto out_unsupported_cdb;
+               }
+               /*FALLTHROUGH*/
        case ACCESS_CONTROL_IN:
        case ACCESS_CONTROL_OUT:
        case EXTENDED_COPY:
@@ -2934,6 +2847,8 @@ static int transport_generic_cmd_sequencer(
        case REQUEST_SENSE:
                size = cdb[4];
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_request_sense;
                break;
        case READ_ELEMENT_STATUS:
                size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9];
@@ -2961,10 +2876,8 @@ static int transport_generic_cmd_sequencer(
                 * is running in SPC_PASSTHROUGH, and wants reservations
                 * emulation disabled.
                 */
-               cmd->transport_emulate_cdb =
-                               (su_dev->t10_pr.res_type !=
-                                SPC_PASSTHROUGH) ?
-                               core_scsi2_emulate_crh : NULL;
+               if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
+                       cmd->execute_task = target_scsi2_reservation_reserve;
                cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
                break;
        case RELEASE:
@@ -2978,10 +2891,8 @@ static int transport_generic_cmd_sequencer(
                else
                        size = cmd->data_length;
 
-               cmd->transport_emulate_cdb =
-                               (su_dev->t10_pr.res_type !=
-                                SPC_PASSTHROUGH) ?
-                               core_scsi2_emulate_crh : NULL;
+               if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
+                       cmd->execute_task = target_scsi2_reservation_release;
                cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
                break;
        case SYNCHRONIZE_CACHE:
@@ -3002,16 +2913,9 @@ static int transport_generic_cmd_sequencer(
                size = transport_get_size(sectors, cdb, cmd);
                cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
 
-               /*
-                * For TCM/pSCSI passthrough, skip cmd->transport_emulate_cdb()
-                */
-               if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+               if (passthrough)
                        break;
-               /*
-                * Set SCF_EMULATE_CDB_ASYNC to ensure asynchronous operation
-                * for SYNCHRONIZE_CACHE* Immed=1 case in __transport_execute_tasks()
-                */
-               cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC;
+
                /*
                 * Check to ensure that LBA + Range does not exceed past end of
                 * device for IBLOCK and FILEIO ->do_sync_cache() backend calls
@@ -3020,10 +2924,13 @@ static int transport_generic_cmd_sequencer(
                        if (transport_cmd_get_valid_sectors(cmd) < 0)
                                goto out_invalid_cdb_field;
                }
+               cmd->execute_task = target_emulate_synchronize_cache;
                break;
        case UNMAP:
                size = get_unaligned_be16(&cdb[7]);
                cmd->se_cmd_flags |= SCF_SCSI_CONTROL_SG_IO_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_unmap;
                break;
        case WRITE_SAME_16:
                sectors = transport_get_sectors_16(cdb, cmd, &sector_ret);
@@ -3042,6 +2949,8 @@ static int transport_generic_cmd_sequencer(
 
                if (target_check_write_same_discard(&cdb[1], dev) < 0)
                        goto out_invalid_cdb_field;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_write_same;
                break;
        case WRITE_SAME:
                sectors = transport_get_sectors_10(cdb, cmd, &sector_ret);
@@ -3063,26 +2972,31 @@ static int transport_generic_cmd_sequencer(
                 */
                if (target_check_write_same_discard(&cdb[1], dev) < 0)
                        goto out_invalid_cdb_field;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_write_same;
                break;
        case ALLOW_MEDIUM_REMOVAL:
-       case GPCMD_CLOSE_TRACK:
        case ERASE:
-       case INITIALIZE_ELEMENT_STATUS:
-       case GPCMD_LOAD_UNLOAD:
        case REZERO_UNIT:
        case SEEK_10:
-       case GPCMD_SET_SPEED:
        case SPACE:
        case START_STOP:
        case TEST_UNIT_READY:
        case VERIFY:
        case WRITE_FILEMARKS:
+               cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
+               if (!passthrough)
+                       cmd->execute_task = target_emulate_noop;
+               break;
+       case GPCMD_CLOSE_TRACK:
+       case INITIALIZE_ELEMENT_STATUS:
+       case GPCMD_LOAD_UNLOAD:
+       case GPCMD_SET_SPEED:
        case MOVE_MEDIUM:
                cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
                break;
        case REPORT_LUNS:
-               cmd->transport_emulate_cdb =
-                               transport_core_report_lun_response;
+               cmd->execute_task = target_report_luns;
                size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
                /*
                 * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS
@@ -3134,6 +3048,11 @@ static int transport_generic_cmd_sequencer(
                cmd->data_length = size;
        }
 
+       /* reject any command that we don't have a handler for */
+       if (!(passthrough || cmd->execute_task ||
+            (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)))
+               goto out_unsupported_cdb;
+
        /* Let's limit control cdbs to a page, for simplicity's sake. */
        if ((cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) &&
            size > PAGE_SIZE)
@@ -3170,18 +3089,13 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
                        " SIMPLE: %u\n", dev->dev_cur_ordered_id,
                        cmd->se_ordered_id);
        } else if (cmd->sam_task_attr == MSG_HEAD_TAG) {
-               atomic_dec(&dev->dev_hoq_count);
-               smp_mb__after_atomic_dec();
                dev->dev_cur_ordered_id++;
                pr_debug("Incremented dev_cur_ordered_id: %u for"
                        " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id,
                        cmd->se_ordered_id);
        } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) {
-               spin_lock(&dev->ordered_cmd_lock);
-               list_del(&cmd->se_ordered_node);
                atomic_dec(&dev->dev_ordered_sync);
                smp_mb__after_atomic_dec();
-               spin_unlock(&dev->ordered_cmd_lock);
 
                dev->dev_cur_ordered_id++;
                pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:"
@@ -3308,7 +3222,7 @@ static void target_complete_ok_work(struct work_struct *work)
                if (cmd->scsi_status) {
                        ret = transport_send_check_condition_and_sense(
                                        cmd, reason, 1);
-                       if (ret == -EAGAIN)
+                       if (ret == -EAGAIN || ret == -ENOMEM)
                                goto queue_full;
 
                        transport_lun_remove_cmd(cmd);
@@ -3333,7 +3247,7 @@ static void target_complete_ok_work(struct work_struct *work)
                spin_unlock(&cmd->se_lun->lun_sep_lock);
 
                ret = cmd->se_tfo->queue_data_in(cmd);
-               if (ret == -EAGAIN)
+               if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
                break;
        case DMA_TO_DEVICE:
@@ -3354,14 +3268,14 @@ static void target_complete_ok_work(struct work_struct *work)
                        }
                        spin_unlock(&cmd->se_lun->lun_sep_lock);
                        ret = cmd->se_tfo->queue_data_in(cmd);
-                       if (ret == -EAGAIN)
+                       if (ret == -EAGAIN || ret == -ENOMEM)
                                goto queue_full;
                        break;
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
                ret = cmd->se_tfo->queue_status(cmd);
-               if (ret == -EAGAIN)
+               if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
                break;
        default:
@@ -3494,6 +3408,18 @@ int transport_generic_map_mem_to_cmd(
 
        if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) ||
            (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) {
+               /*
+                * Reject SCSI data overflow with map_mem_to_cmd() as incoming
+                * scatterlists already have been set to follow what the fabric
+                * passes for the original expected data transfer length.
+                */
+               if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
+                       pr_warn("Rejecting SCSI DATA overflow for fabric using"
+                               " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n");
+                       cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
+                       cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+                       return -EINVAL;
+               }
 
                cmd->t_data_sg = sgl;
                cmd->t_data_nents = sgl_count;
@@ -3812,7 +3738,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
            cmd->data_length) {
                ret = transport_generic_get_mem(cmd);
                if (ret < 0)
-                       return ret;
+                       goto out_fail;
        }
 
        /*
@@ -3841,8 +3767,15 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
                task_cdbs = transport_allocate_control_task(cmd);
        }
 
-       if (task_cdbs <= 0)
+       if (task_cdbs < 0)
                goto out_fail;
+       else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) {
+               cmd->t_state = TRANSPORT_COMPLETE;
+               atomic_set(&cmd->t_transport_active, 1);
+               INIT_WORK(&cmd->work, target_complete_ok_work);
+               queue_work(target_completion_wq, &cmd->work);
+               return 0;
+       }
 
        if (set_counts) {
                atomic_inc(&cmd->t_fe_count);
@@ -3890,7 +3823,10 @@ EXPORT_SYMBOL(transport_generic_process_write);
 
 static void transport_write_pending_qf(struct se_cmd *cmd)
 {
-       if (cmd->se_tfo->write_pending(cmd) == -EAGAIN) {
+       int ret;
+
+       ret = cmd->se_tfo->write_pending(cmd);
+       if (ret == -EAGAIN || ret == -ENOMEM) {
                pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n",
                         cmd);
                transport_handle_queue_full(cmd, cmd->se_dev);
@@ -3920,18 +3856,18 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
         * frontend know that WRITE buffers are ready.
         */
        ret = cmd->se_tfo->write_pending(cmd);
-       if (ret == -EAGAIN)
+       if (ret == -EAGAIN || ret == -ENOMEM)
                goto queue_full;
        else if (ret < 0)
                return ret;
 
-       return PYX_TRANSPORT_WRITE_PENDING;
+       return 1;
 
 queue_full:
        pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
        cmd->t_state = TRANSPORT_COMPLETE_QF_WP;
        transport_handle_queue_full(cmd, cmd->se_dev);
-       return ret;
+       return 0;
 }
 
 /**
@@ -3949,6 +3885,14 @@ void transport_release_cmd(struct se_cmd *cmd)
                core_tmr_release_req(cmd->se_tmr_req);
        if (cmd->t_task_cdb != cmd->__t_task_cdb)
                kfree(cmd->t_task_cdb);
+       /*
+        * Check if target_wait_for_sess_cmds() is expecting to
+        * release se_cmd directly here..
+        */
+       if (cmd->check_release != 0 && cmd->se_tfo->check_release_cmd)
+               if (cmd->se_tfo->check_release_cmd(cmd) != 0)
+                       return;
+
        cmd->se_tfo->release_cmd(cmd);
 }
 EXPORT_SYMBOL(transport_release_cmd);
@@ -3976,6 +3920,114 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 }
 EXPORT_SYMBOL(transport_generic_free_cmd);
 
+/* target_get_sess_cmd - Add command to active ->sess_cmd_list
+ * @se_sess:   session to reference
+ * @se_cmd:    command descriptor to add
+ */
+void target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+       list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
+       se_cmd->check_release = 1;
+       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+}
+EXPORT_SYMBOL(target_get_sess_cmd);
+
+/* target_put_sess_cmd - Check for active I/O shutdown or list delete
+ * @se_sess:   session to reference
+ * @se_cmd:    command descriptor to drop
+ */
+int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+       if (list_empty(&se_cmd->se_cmd_list)) {
+               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+               WARN_ON(1);
+               return 0;
+       }
+
+       if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
+               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+               complete(&se_cmd->cmd_wait_comp);
+               return 1;
+       }
+       list_del(&se_cmd->se_cmd_list);
+       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(target_put_sess_cmd);
+
+/* target_splice_sess_cmd_list - Split active cmds into sess_wait_list
+ * @se_sess:   session to split
+ */
+void target_splice_sess_cmd_list(struct se_session *se_sess)
+{
+       struct se_cmd *se_cmd;
+       unsigned long flags;
+
+       WARN_ON(!list_empty(&se_sess->sess_wait_list));
+       INIT_LIST_HEAD(&se_sess->sess_wait_list);
+
+       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+       se_sess->sess_tearing_down = 1;
+
+       list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
+
+       list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list)
+               se_cmd->cmd_wait_set = 1;
+
+       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+}
+EXPORT_SYMBOL(target_splice_sess_cmd_list);
+
+/* target_wait_for_sess_cmds - Wait for outstanding descriptors
+ * @se_sess:    session to wait for active I/O
+ * @wait_for_tasks:    Make extra transport_wait_for_tasks call
+ */
+void target_wait_for_sess_cmds(
+       struct se_session *se_sess,
+       int wait_for_tasks)
+{
+       struct se_cmd *se_cmd, *tmp_cmd;
+       bool rc = false;
+
+       list_for_each_entry_safe(se_cmd, tmp_cmd,
+                               &se_sess->sess_wait_list, se_cmd_list) {
+               list_del(&se_cmd->se_cmd_list);
+
+               pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
+                       " %d\n", se_cmd, se_cmd->t_state,
+                       se_cmd->se_tfo->get_cmd_state(se_cmd));
+
+               if (wait_for_tasks) {
+                       pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d,"
+                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
+                               se_cmd->se_tfo->get_cmd_state(se_cmd));
+
+                       rc = transport_wait_for_tasks(se_cmd);
+
+                       pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d,"
+                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
+                               se_cmd->se_tfo->get_cmd_state(se_cmd));
+               }
+
+               if (!rc) {
+                       wait_for_completion(&se_cmd->cmd_wait_comp);
+                       pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
+                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
+                               se_cmd->se_tfo->get_cmd_state(se_cmd));
+               }
+
+               se_cmd->se_tfo->release_cmd(se_cmd);
+       }
+}
+EXPORT_SYMBOL(target_wait_for_sess_cmds);
+
 /*     transport_lun_wait_for_tasks():
  *
  *     Called from ConfigFS context to stop the passed struct se_cmd to allow
@@ -4152,14 +4204,14 @@ int transport_clear_lun_from_sessions(struct se_lun *lun)
  * Called from frontend fabric context to wait for storage engine
  * to pause and/or release frontend generated struct se_cmd.
  */
-void transport_wait_for_tasks(struct se_cmd *cmd)
+bool transport_wait_for_tasks(struct se_cmd *cmd)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
        if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req)) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return;
+               return false;
        }
        /*
         * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE
@@ -4167,7 +4219,7 @@ void transport_wait_for_tasks(struct se_cmd *cmd)
         */
        if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && !cmd->se_tmr_req) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return;
+               return false;
        }
        /*
         * If we are already stopped due to an external event (ie: LUN shutdown)
@@ -4210,7 +4262,7 @@ void transport_wait_for_tasks(struct se_cmd *cmd)
        if (!atomic_read(&cmd->t_transport_active) ||
             atomic_read(&cmd->t_transport_aborted)) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return;
+               return false;
        }
 
        atomic_set(&cmd->t_transport_stop, 1);
@@ -4235,6 +4287,8 @@ void transport_wait_for_tasks(struct se_cmd *cmd)
                cmd->se_tfo->get_task_tag(cmd));
 
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+       return true;
 }
 EXPORT_SYMBOL(transport_wait_for_tasks);
 
@@ -4480,9 +4534,6 @@ void transport_send_task_abort(struct se_cmd *cmd)
                if (cmd->se_tfo->write_pending_status(cmd) != 0) {
                        atomic_inc(&cmd->t_transport_aborted);
                        smp_mb__after_atomic_inc();
-                       cmd->scsi_status = SAM_STAT_TASK_ABORTED;
-                       transport_new_cmd_failure(cmd);
-                       return;
                }
        }
        cmd->scsi_status = SAM_STAT_TASK_ABORTED;
@@ -4548,8 +4599,6 @@ static int transport_processing_thread(void *param)
        struct se_cmd *cmd;
        struct se_device *dev = (struct se_device *) param;
 
-       set_user_nice(current, -20);
-
        while (!kthread_should_stop()) {
                ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq,
                                atomic_read(&dev->dev_queue_obj.queue_cnt) ||
@@ -4576,28 +4625,18 @@ get_cmd:
                        }
                        ret = cmd->se_tfo->new_cmd_map(cmd);
                        if (ret < 0) {
-                               cmd->transport_error_status = ret;
-                               transport_generic_request_failure(cmd,
-                                               0, (cmd->data_direction !=
-                                                   DMA_TO_DEVICE));
+                               transport_generic_request_failure(cmd);
                                break;
                        }
                        ret = transport_generic_new_cmd(cmd);
-                       if (ret == -EAGAIN)
+                       if (ret < 0) {
+                               transport_generic_request_failure(cmd);
                                break;
-                       else if (ret < 0) {
-                               cmd->transport_error_status = ret;
-                               transport_generic_request_failure(cmd,
-                                       0, (cmd->data_direction !=
-                                        DMA_TO_DEVICE));
                        }
                        break;
                case TRANSPORT_PROCESS_WRITE:
                        transport_generic_process_write(cmd);
                        break;
-               case TRANSPORT_FREE_CMD_INTR:
-                       transport_generic_free_cmd(cmd, 0);
-                       break;
                case TRANSPORT_PROCESS_TMR:
                        transport_generic_do_tmr(cmd);
                        break;
index 3749d8b4b4233115a3e1fb1bede71e15104f8a01..e05c55100ec679e1633b2ecf7fc5b988288481c5 100644 (file)
@@ -156,7 +156,7 @@ int ft_lport_notify(struct notifier_block *, unsigned long, void *);
 /*
  * IO methods.
  */
-void ft_check_stop_free(struct se_cmd *);
+int ft_check_stop_free(struct se_cmd *);
 void ft_release_cmd(struct se_cmd *);
 int ft_queue_status(struct se_cmd *);
 int ft_queue_data_in(struct se_cmd *);
index 6195026cc7b02bb908cecd6ed32f9527a3b34399..71fc9cea5dc9ba120b725a4e0f6bf94c879d1340 100644 (file)
@@ -112,9 +112,10 @@ void ft_release_cmd(struct se_cmd *se_cmd)
        ft_free_cmd(cmd);
 }
 
-void ft_check_stop_free(struct se_cmd *se_cmd)
+int ft_check_stop_free(struct se_cmd *se_cmd)
 {
        transport_generic_free_cmd(se_cmd, 0);
+       return 1;
 }
 
 /*
@@ -199,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd)
        lport = ep->lp;
        fp = fc_frame_alloc(lport, sizeof(*txrdy));
        if (!fp)
-               return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+               return -ENOMEM; /* Signal QUEUE_FULL */
 
        txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
        memset(txrdy, 0, sizeof(*txrdy));
index 5f770412ca403265ddfc19856ef4934470a25c63..9402b7387cac570d91ff6001a885daed3bbd8b6d 100644 (file)
@@ -436,8 +436,7 @@ static void ft_del_lport(struct se_wwn *wwn)
        struct ft_lport_acl *lacl = container_of(wwn,
                                struct ft_lport_acl, fc_lport_wwn);
 
-       pr_debug("del lport %s\n",
-                       config_item_name(&wwn->wwn_group.cg_item));
+       pr_debug("del lport %s\n", lacl->name);
        mutex_lock(&ft_lport_lock);
        list_del(&lacl->list);
        mutex_unlock(&ft_lport_lock);
index 708f8e92771a6d03c6ef3615571898da0cd1321e..dd9a5743fa991f3fb789d2e17d12563deaead0cd 100644 (file)
@@ -678,10 +678,10 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                return;
 
        if (delay > 1000)
-               schedule_delayed_work(&(tz->poll_queue),
+               queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
                                      round_jiffies(msecs_to_jiffies(delay)));
        else
-               schedule_delayed_work(&(tz->poll_queue),
+               queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
                                      msecs_to_jiffies(delay));
 }
 
index e371753ba921d24f33622172a497b1d115b315c6..4222035acfb71987a7f3f7c50db32cd5aae87262 100644 (file)
@@ -34,6 +34,15 @@ config HVC_ISERIES
        help
          iSeries machines support a hypervisor virtual console.
 
+config HVC_OPAL
+       bool "OPAL Console support"
+       depends on PPC_POWERNV
+       select HVC_DRIVER
+       select HVC_IRQ
+       default y
+       help
+         PowerNV machines running under OPAL need that driver to get a console
+
 config HVC_RTAS
        bool "IBM RTAS Console support"
        depends on PPC_RTAS
index e29205316376394db8dfc7f2f340c65433daddee..89abf40bc73d3bd30c8d363e5224e3b2ef7a9927 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_HVC_CONSOLE)      += hvc_vio.o hvsi_lib.o
+obj-$(CONFIG_HVC_OPAL)         += hvc_opal.o hvsi_lib.o
 obj-$(CONFIG_HVC_OLD_HVSI)     += hvsi.o
 obj-$(CONFIG_HVC_ISERIES)      += hvc_iseries.o
 obj-$(CONFIG_HVC_RTAS)         += hvc_rtas.o
index 7430bc3c8d53643e0616b27c5cf08db0380892bb..b6b2d18fa38dc9827f47a297cfeb6d013f6b21f7 100644 (file)
@@ -852,7 +852,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
         * find index to use:
         * see if this vterm id matches one registered for console.
         */
-       for (i = 0; i < MAX_NR_HVC_CONSOLES; i++)
+       for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
                if (vtermnos[i] == hp->vtermno &&
                    cons_ops[i] == hp->ops)
                        break;
@@ -862,13 +862,9 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
                i = ++last_hvc;
 
        hp->index = i;
-       hvc_console.index = i;
-       vtermnos[i] = vtermno;
-       cons_ops[i] = ops;
 
        list_add_tail(&(hp->next), &hvc_structs);
        spin_unlock(&hvc_structs_lock);
-       register_console(&hvc_console);
 
        return hp;
 }
@@ -879,7 +875,6 @@ int hvc_remove(struct hvc_struct *hp)
        unsigned long flags;
        struct tty_struct *tty;
 
-       unregister_console(&hvc_console);
        spin_lock_irqsave(&hp->lock, flags);
        tty = tty_kref_get(hp->tty);
 
index 435f6facbc238606feeea4ce26b508ed34ddb6af..44fbebab5075f98f337d880288993b01ad9e7271 100644 (file)
@@ -46,6 +46,7 @@ static inline char __dcc_getchar(void)
 
        asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
                : "=r" (__c));
+       isb();
 
        return __c;
 }
@@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c)
        asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
                : /* no output register */
                : "r" (c));
+       isb();
 }
 
 static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
index 21c54955084e743c17bfcbb817ac5464fe717e36..3f4a897bf4d7b39d4977bbe3b0698bf5fffa1f09 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/console.h>
 
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
new file mode 100644 (file)
index 0000000..ced26c8
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * opal driver interface to hvc_console.c
+ *
+ * Copyright 2011 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/console.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/export.h>
+
+#include <asm/hvconsole.h>
+#include <asm/prom.h>
+#include <asm/firmware.h>
+#include <asm/hvsi.h>
+#include <asm/udbg.h>
+#include <asm/opal.h>
+
+#include "hvc_console.h"
+
+static const char hvc_opal_name[] = "hvc_opal";
+
+static struct of_device_id hvc_opal_match[] __devinitdata = {
+       { .name = "serial", .compatible = "ibm,opal-console-raw" },
+       { .name = "serial", .compatible = "ibm,opal-console-hvsi" },
+       { },
+};
+
+typedef enum hv_protocol {
+       HV_PROTOCOL_RAW,
+       HV_PROTOCOL_HVSI
+} hv_protocol_t;
+
+struct hvc_opal_priv {
+       hv_protocol_t           proto;  /* Raw data or HVSI packets */
+       struct hvsi_priv        hvsi;   /* HVSI specific data */
+};
+static struct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES];
+
+/* For early boot console */
+static struct hvc_opal_priv hvc_opal_boot_priv;
+static u32 hvc_opal_boot_termno;
+
+static const struct hv_ops hvc_opal_raw_ops = {
+       .get_chars = opal_get_chars,
+       .put_chars = opal_put_chars,
+       .notifier_add = notifier_add_irq,
+       .notifier_del = notifier_del_irq,
+       .notifier_hangup = notifier_hangup_irq,
+};
+
+static int hvc_opal_hvsi_get_chars(uint32_t vtermno, char *buf, int count)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
+
+       if (WARN_ON(!pv))
+               return -ENODEV;
+
+       return hvsilib_get_chars(&pv->hvsi, buf, count);
+}
+
+static int hvc_opal_hvsi_put_chars(uint32_t vtermno, const char *buf, int count)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
+
+       if (WARN_ON(!pv))
+               return -ENODEV;
+
+       return hvsilib_put_chars(&pv->hvsi, buf, count);
+}
+
+static int hvc_opal_hvsi_open(struct hvc_struct *hp, int data)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
+       int rc;
+
+       pr_devel("HVSI@%x: do open !\n", hp->vtermno);
+
+       rc = notifier_add_irq(hp, data);
+       if (rc)
+               return rc;
+
+       return hvsilib_open(&pv->hvsi, hp);
+}
+
+static void hvc_opal_hvsi_close(struct hvc_struct *hp, int data)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
+
+       pr_devel("HVSI@%x: do close !\n", hp->vtermno);
+
+       hvsilib_close(&pv->hvsi, hp);
+
+       notifier_del_irq(hp, data);
+}
+
+void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
+
+       pr_devel("HVSI@%x: do hangup !\n", hp->vtermno);
+
+       hvsilib_close(&pv->hvsi, hp);
+
+       notifier_hangup_irq(hp, data);
+}
+
+static int hvc_opal_hvsi_tiocmget(struct hvc_struct *hp)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
+
+       if (!pv)
+               return -EINVAL;
+       return pv->hvsi.mctrl;
+}
+
+static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
+                               unsigned int clear)
+{
+       struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
+
+       pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n",
+                hp->vtermno, set, clear);
+
+       if (set & TIOCM_DTR)
+               hvsilib_write_mctrl(&pv->hvsi, 1);
+       else if (clear & TIOCM_DTR)
+               hvsilib_write_mctrl(&pv->hvsi, 0);
+
+       return 0;
+}
+
+static const struct hv_ops hvc_opal_hvsi_ops = {
+       .get_chars = hvc_opal_hvsi_get_chars,
+       .put_chars = hvc_opal_hvsi_put_chars,
+       .notifier_add = hvc_opal_hvsi_open,
+       .notifier_del = hvc_opal_hvsi_close,
+       .notifier_hangup = hvc_opal_hvsi_hangup,
+       .tiocmget = hvc_opal_hvsi_tiocmget,
+       .tiocmset = hvc_opal_hvsi_tiocmset,
+};
+
+static int __devinit hvc_opal_probe(struct platform_device *dev)
+{
+       const struct hv_ops *ops;
+       struct hvc_struct *hp;
+       struct hvc_opal_priv *pv;
+       hv_protocol_t proto;
+       unsigned int termno, boot = 0;
+       const __be32 *reg;
+
+       if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
+               proto = HV_PROTOCOL_RAW;
+               ops = &hvc_opal_raw_ops;
+       } else if (of_device_is_compatible(dev->dev.of_node,
+                                          "ibm,opal-console-hvsi")) {
+               proto = HV_PROTOCOL_HVSI;
+               ops = &hvc_opal_hvsi_ops;
+       } else {
+               pr_err("hvc_opal: Unkown protocol for %s\n",
+                      dev->dev.of_node->full_name);
+               return -ENXIO;
+       }
+
+       reg = of_get_property(dev->dev.of_node, "reg", NULL);
+       termno = reg ? be32_to_cpup(reg) : 0;
+
+       /* Is it our boot one ? */
+       if (hvc_opal_privs[termno] == &hvc_opal_boot_priv) {
+               pv = hvc_opal_privs[termno];
+               boot = 1;
+       } else if (hvc_opal_privs[termno] == NULL) {
+               pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL);
+               if (!pv)
+                       return -ENOMEM;
+               pv->proto = proto;
+               hvc_opal_privs[termno] = pv;
+               if (proto == HV_PROTOCOL_HVSI)
+                       hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars,
+                                    termno, 0);
+
+               /* Instanciate now to establish a mapping index==vtermno */
+               hvc_instantiate(termno, termno, ops);
+       } else {
+               pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n",
+                      dev->dev.of_node->full_name, termno);
+               return -ENXIO;
+       }
+
+       pr_info("hvc%d: %s protocol on %s%s\n", termno,
+               proto == HV_PROTOCOL_RAW ? "raw" : "hvsi",
+               dev->dev.of_node->full_name,
+               boot ? " (boot console)" : "");
+
+       /* We don't do IRQ yet */
+       hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS);
+       if (IS_ERR(hp))
+               return PTR_ERR(hp);
+       dev_set_drvdata(&dev->dev, hp);
+
+       return 0;
+}
+
+static int __devexit hvc_opal_remove(struct platform_device *dev)
+{
+       struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
+       int rc, termno;
+
+       termno = hp->vtermno;
+       rc = hvc_remove(hp);
+       if (rc == 0) {
+               if (hvc_opal_privs[termno] != &hvc_opal_boot_priv)
+                       kfree(hvc_opal_privs[termno]);
+               hvc_opal_privs[termno] = NULL;
+       }
+       return rc;
+}
+
+static struct platform_driver hvc_opal_driver = {
+       .probe          = hvc_opal_probe,
+       .remove         = __devexit_p(hvc_opal_remove),
+       .driver         = {
+               .name   = hvc_opal_name,
+               .owner  = THIS_MODULE,
+               .of_match_table = hvc_opal_match,
+       }
+};
+
+static int __init hvc_opal_init(void)
+{
+       if (!firmware_has_feature(FW_FEATURE_OPAL))
+               return -ENODEV;
+
+       /* Register as a vio device to receive callbacks */
+       return platform_driver_register(&hvc_opal_driver);
+}
+module_init(hvc_opal_init);
+
+static void __exit hvc_opal_exit(void)
+{
+       platform_driver_unregister(&hvc_opal_driver);
+}
+module_exit(hvc_opal_exit);
+
+static void udbg_opal_putc(char c)
+{
+       unsigned int termno = hvc_opal_boot_termno;
+       int count = -1;
+
+       if (c == '\n')
+               udbg_opal_putc('\r');
+
+       do {
+               switch(hvc_opal_boot_priv.proto) {
+               case HV_PROTOCOL_RAW:
+                       count = opal_put_chars(termno, &c, 1);
+                       break;
+               case HV_PROTOCOL_HVSI:
+                       count = hvc_opal_hvsi_put_chars(termno, &c, 1);
+                       break;
+               }
+       } while(count == 0 || count == -EAGAIN);
+}
+
+static int udbg_opal_getc_poll(void)
+{
+       unsigned int termno = hvc_opal_boot_termno;
+       int rc = 0;
+       char c;
+
+       switch(hvc_opal_boot_priv.proto) {
+       case HV_PROTOCOL_RAW:
+               rc = opal_get_chars(termno, &c, 1);
+               break;
+       case HV_PROTOCOL_HVSI:
+               rc = hvc_opal_hvsi_get_chars(termno, &c, 1);
+               break;
+       }
+       if (!rc)
+               return -1;
+       return c;
+}
+
+static int udbg_opal_getc(void)
+{
+       int ch;
+       for (;;) {
+               ch = udbg_opal_getc_poll();
+               if (ch == -1) {
+                       /* This shouldn't be needed...but... */
+                       volatile unsigned long delay;
+                       for (delay=0; delay < 2000000; delay++)
+                               ;
+               } else {
+                       return ch;
+               }
+       }
+}
+
+static void udbg_init_opal_common(void)
+{
+       udbg_putc = udbg_opal_putc;
+       udbg_getc = udbg_opal_getc;
+       udbg_getc_poll = udbg_opal_getc_poll;
+       tb_ticks_per_usec = 0x200; /* Make udelay not suck */
+}
+
+void __init hvc_opal_init_early(void)
+{
+       struct device_node *stdout_node = NULL;
+       const u32 *termno;
+       const char *name = NULL;
+       const struct hv_ops *ops;
+       u32 index;
+
+       /* find the boot console from /chosen/stdout */
+       if (of_chosen)
+               name = of_get_property(of_chosen, "linux,stdout-path", NULL);
+       if (name) {
+               stdout_node = of_find_node_by_path(name);
+               if (!stdout_node) {
+                       pr_err("hvc_opal: Failed to locate default console!\n");
+                       return;
+               }
+       } else {
+               struct device_node *opal, *np;
+
+               /* Current OPAL takeover doesn't provide the stdout
+                * path, so we hard wire it
+                */
+               opal = of_find_node_by_path("/ibm,opal/consoles");
+               if (opal)
+                       pr_devel("hvc_opal: Found consoles in new location\n");
+               if (!opal) {
+                       opal = of_find_node_by_path("/ibm,opal");
+                       if (opal)
+                               pr_devel("hvc_opal: "
+                                        "Found consoles in old location\n");
+               }
+               if (!opal)
+                       return;
+               for_each_child_of_node(opal, np) {
+                       if (!strcmp(np->name, "serial")) {
+                               stdout_node = np;
+                               break;
+                       }
+               }
+               of_node_put(opal);
+       }
+       if (!stdout_node)
+               return;
+       termno = of_get_property(stdout_node, "reg", NULL);
+       index = termno ? *termno : 0;
+       if (index >= MAX_NR_HVC_CONSOLES)
+               return;
+       hvc_opal_privs[index] = &hvc_opal_boot_priv;
+
+       /* Check the protocol */
+       if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) {
+               hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
+               ops = &hvc_opal_raw_ops;
+               pr_devel("hvc_opal: Found RAW console\n");
+       }
+       else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
+               hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
+               ops = &hvc_opal_hvsi_ops;
+               hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars,
+                            opal_put_chars, index, 1);
+               /* HVSI, perform the handshake now */
+               hvsilib_establish(&hvc_opal_boot_priv.hvsi);
+               pr_devel("hvc_opal: Found HVSI console\n");
+       } else
+               goto out;
+       hvc_opal_boot_termno = index;
+       udbg_init_opal_common();
+       add_preferred_console("hvc", index, NULL);
+       hvc_instantiate(index, index, ops);
+out:
+       of_node_put(stdout_node);
+}
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW
+void __init udbg_init_debug_opal(void)
+{
+       u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
+       hvc_opal_privs[index] = &hvc_opal_boot_priv;
+       hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
+       hvc_opal_boot_termno = index;
+       udbg_init_opal_common();
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_RAW */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI
+void __init udbg_init_debug_opal_hvsi(void)
+{
+       u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
+       hvc_opal_privs[index] = &hvc_opal_boot_priv;
+       hvc_opal_boot_termno = index;
+       udbg_init_opal_common();
+       hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars,
+                    index, 1);
+       hvsilib_establish(&hvc_opal_boot_priv.hvsi);
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI */
index 130aace67f3103c2e8bb6209de58d6ee65c031a0..fc3c3ad6c0727918412f5f778ffb704d7f8d1ad0 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/console.h>
+#include <linux/module.h>
 
 #include <asm/hvconsole.h>
 #include <asm/vio.h>
index 55882b5930a650dd9ece5286688597cf890a78f2..b9040bec36bdad64a50a9f4dbbcb7d8ad0094fb4 100644 (file)
@@ -1532,7 +1532,7 @@ static int __devinit hvcs_initialize(void)
                goto register_fail;
        }
 
-       hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       hvcs_pi_buff = (unsigned long *) __get_free_page(GFP_KERNEL);
        if (!hvcs_pi_buff) {
                rc = -ENOMEM;
                goto buff_alloc_fail;
@@ -1548,7 +1548,7 @@ static int __devinit hvcs_initialize(void)
        return 0;
 
 kthread_fail:
-       kfree(hvcs_pi_buff);
+       free_page((unsigned long)hvcs_pi_buff);
 buff_alloc_fail:
        tty_unregister_driver(hvcs_tty_driver);
 register_fail:
@@ -1597,7 +1597,7 @@ static void __exit hvcs_module_exit(void)
        kthread_stop(hvcs_task);
 
        spin_lock(&hvcs_pi_lock);
-       kfree(hvcs_pi_buff);
+       free_page((unsigned long)hvcs_pi_buff);
        hvcs_pi_buff = NULL;
        spin_unlock(&hvcs_pi_lock);
 
index bd9b09827b24991db437deb492e1b6f82a43ae26..6f4dd83d869533a3ff61b3e1b0d0c3d80a0f6c99 100644 (file)
@@ -183,7 +183,7 @@ int hvsilib_get_chars(struct hvsi_priv *pv, char *buf, int count)
        unsigned int tries, read = 0;
 
        if (WARN_ON(!pv))
-               return 0;
+               return -ENXIO;
 
        /* If we aren't open, don't do anything in order to avoid races
         * 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)
        int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA);
 
        if (WARN_ON(!pv))
-               return 0;
+               return -ENODEV;
 
        dp.hdr.type = VS_DATA_PACKET_HEADER;
        dp.hdr.len = adjcount + sizeof(struct hvsi_header);
index 4cb0d0a3e57b774c22d6a8909cc20a7615c6ed60..fc7bbba585cee2c2b0d5282c42fb986bfb032a0a 100644 (file)
 static int debug;
 module_param(debug, int, 0600);
 
-#define T1     (HZ/10)
-#define T2     (HZ/3)
-#define N2     3
+/* Defaults: these are from the specification */
+
+#define T1     10              /* 100mS */
+#define T2     34              /* 333mS */
+#define N2     3               /* Retry 3 times */
 
 /* Use long timers for testing at low speed with debug on */
 #ifdef DEBUG_TIMING
-#define T1     HZ
-#define T2     (2 * HZ)
+#define T1     100
+#define T2     200
 #endif
 
 /*
index a87a56cb5417b0f0804e532c5a260ab81b2329ea..eeadf1b8e093202234b30c688490da2de10a3c04 100644 (file)
@@ -450,24 +450,6 @@ static void au_serial_out(struct uart_port *p, int offset, int value)
        __raw_writel(value, p->membase + offset);
 }
 
-static unsigned int tsi_serial_in(struct uart_port *p, int offset)
-{
-       unsigned int tmp;
-       offset = map_8250_in_reg(p, offset) << p->regshift;
-       if (offset == UART_IIR) {
-               tmp = readl(p->membase + (UART_IIR & ~3));
-               return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
-       } else
-               return readb(p->membase + offset);
-}
-
-static void tsi_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = map_8250_out_reg(p, offset) << p->regshift;
-       if (!((offset == UART_IER) && (value & UART_IER_UUE)))
-               writeb(value, p->membase + offset);
-}
-
 static unsigned int io_serial_in(struct uart_port *p, int offset)
 {
        offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -508,11 +490,6 @@ static void set_io_from_upio(struct uart_port *p)
                p->serial_out = au_serial_out;
                break;
 
-       case UPIO_TSI:
-               p->serial_in = tsi_serial_in;
-               p->serial_out = tsi_serial_out;
-               break;
-
        default:
                p->serial_in = io_serial_in;
                p->serial_out = io_serial_out;
index 5f479dada6f2b25a309b48c50d5b2dee0a35777d..925a1e547a834f10942ab878357a0568254b6ae8 100644 (file)
@@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60
          Support for the IFX6x60 modem devices on Intel MID platforms.
 
 config SERIAL_PCH_UART
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
+       tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART"
        depends on PCI
        select SERIAL_CORE
        help
@@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART
          which is an IOH(Input/Output Hub) for x86 embedded processor.
          Enabling PCH_DMA, this PCH UART works as DMA mode.
 
-         This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7213 and ML7223.
-         ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
-         for MP(Media Phone) use.
-         ML7213/ML7223 is companion chip for Intel Atom E6xx series.
-         ML7213/ML7223 is completely compatible for Intel EG20T PCH.
+         This driver also can be used for LAPIS Semiconductor IOH(Input/
+         Output Hub), ML7213, ML7223 and ML7831.
+         ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is
+         for MP(Media Phone) use and ML7831 IOH is for general purpose use.
+         ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
 
 config SERIAL_MSM_SMD
        bool "Enable tty device interface for some SMD ports"
index 4a0f86fa1e90566c03c693c413a581a80e40e7b6..4c823f341d9895cd88a5f0d710f56449714fef86 100644 (file)
@@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
        if (rs485conf->flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
                atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
-               if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
+               if ((rs485conf->delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port, rs485conf->delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
        } else {
@@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
 
        if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
-               if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+               if ((atmel_port->rs485.delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port,
                                        atmel_port->rs485.delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
@@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
                dev_dbg(port->dev, "Setting UART to RS485\n");
-               if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+               if ((atmel_port->rs485.delay_rts_after_send) > 0)
                        UART_PUT_TTGR(port,
                                        atmel_port->rs485.delay_rts_after_send);
                mode |= ATMEL_US_USMODE_RS485;
@@ -1447,16 +1447,6 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
                rs485conf->delay_rts_after_send = rs485_delay[1];
                rs485conf->flags = 0;
 
-               if (rs485conf->delay_rts_before_send == 0 &&
-                   rs485conf->delay_rts_after_send == 0) {
-                       rs485conf->flags |= SER_RS485_RTS_ON_SEND;
-               } else {
-                       if (rs485conf->delay_rts_before_send)
-                               rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
-                       if (rs485conf->delay_rts_after_send)
-                               rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
-               }
-
                if (of_get_property(np, "rs485-rx-during-tx", NULL))
                        rs485conf->flags |= SER_RS485_RX_DURING_TX;
 
index b7435043f2fe90d87d646141060318851ad12a86..1dfba7b779c84ed1f151b490295b0a99751b7b72 100644 (file)
@@ -3234,9 +3234,8 @@ rs_write(struct tty_struct *tty,
                e100_disable_rx(info);
                e100_enable_rx_irq(info);
 #endif
-               if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) &&
-                       (info->rs485.delay_rts_before_send > 0))
-                               msleep(info->rs485.delay_rts_before_send);
+               if (info->rs485.delay_rts_before_send > 0)
+                       msleep(info->rs485.delay_rts_before_send);
        }
 #endif /* CONFIG_ETRAX_RS485 */
 
@@ -3693,10 +3692,6 @@ rs_ioctl(struct tty_struct *tty,
 
                rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
                rs485data.flags = 0;
-               if (rs485data.delay_rts_before_send != 0)
-                       rs485data.flags |= SER_RS485_RTS_BEFORE_SEND;
-               else
-                       rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
 
                if (rs485ctrl.enabled)
                        rs485data.flags |= SER_RS485_ENABLED;
@@ -4531,7 +4526,6 @@ static int __init rs_init(void)
                /* Set sane defaults */
                info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
                info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
-               info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
                info->rs485.delay_rts_before_send = 0;
                info->rs485.flags &= ~(SER_RS485_ENABLED);
 #endif
index 648b6a3efa32d2c27da8f694b24591eb20885ee9..7c867a046c9752214773ba5f2a1237893ed2ebfd 100644 (file)
@@ -24,7 +24,7 @@
  *
  *
  ***********************************************************************/
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 
index 87e7e6c876d4b857aacea79feab04bf3c5d04953..2b42a01a81c6984ace5d8b343d6920c4a0ed748a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/console.h>
 #include <linux/vt_kern.h>
 #include <linux/input.h>
+#include <linux/module.h>
 
 #define MAX_CONFIG_LEN         40
 
index 2af5aa5f3a80e3a8a08c464fb5855d09a199a7fa..8a6cc8c30b5a74eafdb774e1986712d9e80da61c 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/spi/spi.h>
index d73aadd7a9ad6614385b62f92582c5c7b87c7b61..90c40f22ec709422e51a52648db2ea2fde4bfd9a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/sfi.h>
+#include <linux/module.h>
 #include <asm/mrst.h>
 #include "max3107.h"
 
index db00b595cab08eba2edc1d6295b6b66946becaf7..7827000db4f558901a92551fd067943b78c079ed 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/freezer.h>
+#include <linux/module.h>
 #include "max3107.h"
 
 static const struct baud_table brg26_ext[] = {
index 286c386d9c4677d16cf0effcf9769f34c9249e52..e272d3919c67fdb6b465902fe7a5cb17978cc3a5 100644 (file)
@@ -884,7 +884,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
 {
        struct uart_hsu_port *up =
                        container_of(port, struct uart_hsu_port, port);
-       struct tty_struct *tty = port->state->port.tty;
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
@@ -907,8 +906,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        /* CMSPAR isn't supported by this driver */
-       if (tty)
-               tty->termios->c_cflag &= ~CMSPAR;
+       termios->c_cflag &= ~CMSPAR;
 
        if (termios->c_cflag & CSTOPB)
                cval |= UART_LCR_STOP;
index 9beaff1cec24dc024ac47bacf8d5bd944780ad79..dd4c31d1aee5d527198b36529524b319a90a4920 100644 (file)
@@ -10,6 +10,7 @@
  *
  */
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/console.h>
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
index 21febef926aa7c31f09ef26dbbbfa34d78f76df1..d6aba8c087e4784370648976c0d018a569c374f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
  *
  *This program is free software; you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
@@ -46,8 +46,8 @@ enum {
 
 /* Set the max number of UART port
  * Intel EG20T PCH: 4 port
- * OKI SEMICONDUCTOR ML7213 IOH: 3 port
- * OKI SEMICONDUCTOR ML7223 IOH: 2 port
+ * LAPIS Semiconductor ML7213 IOH: 3 port
+ * LAPIS Semiconductor ML7223 IOH: 2 port
 */
 #define PCH_UART_NR    4
 
@@ -258,6 +258,8 @@ enum pch_uart_num_t {
        pch_ml7213_uart2,
        pch_ml7223_uart0,
        pch_ml7223_uart1,
+       pch_ml7831_uart0,
+       pch_ml7831_uart1,
 };
 
 static struct pch_uart_driver_data drv_dat[] = {
@@ -270,6 +272,8 @@ static struct pch_uart_driver_data drv_dat[] = {
        [pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
        [pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
        [pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
+       [pch_ml7831_uart0] = {PCH_UART_8LINE, 0},
+       [pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
 };
 
 static unsigned int default_baud = 9600;
@@ -628,6 +632,7 @@ static void pch_request_dma(struct uart_port *port)
                dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
                        __func__);
                dma_release_channel(priv->chan_tx);
+               priv->chan_tx = NULL;
                return;
        }
 
@@ -1215,8 +1220,7 @@ static void pch_uart_shutdown(struct uart_port *port)
                dev_err(priv->port.dev,
                        "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);
 
-       if (priv->use_dma_flag)
-               pch_free_dma(port);
+       pch_free_dma(port);
 
        free_irq(priv->port.irq, priv);
 }
@@ -1280,6 +1284,7 @@ static void pch_uart_set_termios(struct uart_port *port,
        if (rtn)
                goto out;
 
+       pch_uart_set_mctrl(&priv->port, priv->port.mctrl);
        /* Don't rewrite B0 */
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
@@ -1552,6 +1557,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
         .driver_data = pch_ml7223_uart0},
        {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
         .driver_data = pch_ml7223_uart1},
+       {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811),
+        .driver_data = pch_ml7831_uart0},
+       {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812),
+        .driver_data = pch_ml7831_uart1},
        {0,},
 };
 
index 1945c70539c2bb8326bdda5ec1e31d7c69980d43..aff9d612dff02a46b38d6b4133d0283dbc3f8468 100644 (file)
@@ -206,6 +206,25 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
                [SCLSR]         = sci_reg_invalid,
        },
 
+       /*
+        * Common SH-2(A) SCIF definitions for ports with FIFO data
+        * count registers.
+        */
+       [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = {
+               [SCSMR]         = { 0x00, 16 },
+               [SCBRR]         = { 0x04,  8 },
+               [SCSCR]         = { 0x08, 16 },
+               [SCxTDR]        = { 0x0c,  8 },
+               [SCxSR]         = { 0x10, 16 },
+               [SCxRDR]        = { 0x14,  8 },
+               [SCFCR]         = { 0x18, 16 },
+               [SCFDR]         = { 0x1c, 16 },
+               [SCTFDR]        = sci_reg_invalid,
+               [SCRFDR]        = sci_reg_invalid,
+               [SCSPTR]        = { 0x20, 16 },
+               [SCLSR]         = { 0x24, 16 },
+       },
+
        /*
         * Common SH-3 SCIF definitions.
         */
index a4b63bfeaa2f4e1a03d80ac0db64b6a883726325..e76c8b747fb83876dbf3c685c41fdb4dcedd4415 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "timbuart.h"
 
index 8c03b127fd03145f6d99b5796c57319d392264ab..b627363352e5c3fe8e32fff003830f7834bff7ee 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/module.h>
 
 #define XUARTPS_TTY_NAME       "ttyPS"
 #define XUARTPS_NAME           "xuartps"
index 512c49f98e85a2c59e70b2c454877589756376a2..8e0924f55446f963b8b9d79a0d66347d30c982bc 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/kmod.h>
 #include <linux/nsproxy.h>
+#include <linux/ratelimit.h>
 
 /*
  *     This guards the refcounted line discipline lists. The lock
@@ -547,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
 /**
  *     tty_ldisc_wait_idle     -       wait for the ldisc to become idle
  *     @tty: tty to wait for
+ *     @timeout: for how long to wait at most
  *
  *     Wait for the line discipline to become idle. The discipline must
  *     have been halted for this to guarantee it remains idle.
  */
-static int tty_ldisc_wait_idle(struct tty_struct *tty)
+static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
 {
-       int ret;
+       long ret;
        ret = wait_event_timeout(tty_ldisc_idle,
-                       atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
+                       atomic_read(&tty->ldisc->users) == 1, timeout);
        if (ret < 0)
                return ret;
        return ret > 0 ? 0 : -EBUSY;
@@ -665,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 
        tty_ldisc_flush_works(tty);
 
-       retval = tty_ldisc_wait_idle(tty);
+       retval = tty_ldisc_wait_idle(tty, 5 * HZ);
 
        tty_lock();
        mutex_lock(&tty->ldisc_mutex);
@@ -762,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
        if (IS_ERR(ld))
                return -1;
 
-       WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
-
        tty_ldisc_close(tty, tty->ldisc);
        tty_ldisc_put(tty->ldisc);
        tty->ldisc = NULL;
@@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
        tty_unlock();
        cancel_work_sync(&tty->buf.work);
        mutex_unlock(&tty->ldisc_mutex);
-
+retry:
        tty_lock();
        mutex_lock(&tty->ldisc_mutex);
 
@@ -847,6 +847,22 @@ void tty_ldisc_hangup(struct tty_struct *tty)
           it means auditing a lot of other paths so this is
           a FIXME */
        if (tty->ldisc) {       /* Not yet closed */
+               if (atomic_read(&tty->ldisc->users) != 1) {
+                       char cur_n[TASK_COMM_LEN], tty_n[64];
+                       long timeout = 3 * HZ;
+                       tty_unlock();
+
+                       while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
+                               timeout = MAX_SCHEDULE_TIMEOUT;
+                               printk_ratelimited(KERN_WARNING
+                                       "%s: waiting (%s) for %s took too long, but we keep waiting...\n",
+                                       __func__, get_task_comm(cur_n, current),
+                                       tty_name(tty, tty_n));
+                       }
+                       mutex_unlock(&tty->ldisc_mutex);
+                       goto retry;
+               }
+
                if (reset == 0) {
 
                        if (!tty_ldisc_reinit(tty, tty->termios->c_line))
index 66825c9f516a2a871c5908d4d9da40aa48431270..7a367ff5122bad25b33277e464ecf575d0b13054 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/tty.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
index bdc3db946122f425a13b2cf619e61d3acbcae622..ff505951735122088ac3c39da63c11a18f67ed87 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/uio_driver.h>
 #include <linux/stringify.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #define DRIVER_NAME "uio_pdrv"
index 0b2ed71e3bfa22c31de8eb9a03743d53808b989f..25de302009a1a300bcda77c62d98d0f476f2d3a9 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/uio_driver.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
 #include <linux/pm_runtime.h>
index 62050f7a4f97fb7d8eebc8ea610056c6ad5adb3a..57ae44cd0b88daaef5d6e4f6832f8cab5ea4a3ff 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/c67x00.h>
 
index 6960715c5063ce15d18ad1437af834bdb6be1c20..e8c564a533469f00f7e40435933ae496187aa20a 100644 (file)
@@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm)
 {
        int i;
 
-       mutex_lock(&open_mutex);
        if (acm->dev) {
                usb_autopm_get_interface(acm->control);
                acm_set_control(acm, acm->ctrlout = 0);
@@ -551,14 +550,15 @@ static void acm_port_down(struct acm *acm)
                acm->control->needs_remote_wakeup = 0;
                usb_autopm_put_interface(acm->control);
        }
-       mutex_unlock(&open_mutex);
 }
 
 static void acm_tty_hangup(struct tty_struct *tty)
 {
        struct acm *acm = tty->driver_data;
        tty_port_hangup(&acm->port);
+       mutex_lock(&open_mutex);
        acm_port_down(acm);
+       mutex_unlock(&open_mutex);
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
@@ -569,8 +569,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
           shutdown */
        if (!acm)
                return;
+
+       mutex_lock(&open_mutex);
        if (tty_port_close_start(&acm->port, tty, filp) == 0) {
-               mutex_lock(&open_mutex);
                if (!acm->dev) {
                        tty_port_tty_set(&acm->port, NULL);
                        acm_tty_unregister(acm);
@@ -582,6 +583,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
        acm_port_down(acm);
        tty_port_close_end(&acm->port, tty);
        tty_port_tty_set(&acm->port, NULL);
+       mutex_unlock(&open_mutex);
 }
 
 static int acm_tty_write(struct tty_struct *tty,
index 3b029a0a478787fbf05e298ef148637968fce33e..45887a0ff873cee3440869fe83d19ab130b0cd7d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/usb.h>
 #include <linux/usb/quirks.h>
 #include <linux/usb/hcd.h>
@@ -1667,6 +1668,11 @@ int usb_runtime_suspend(struct device *dev)
                return -EAGAIN;
 
        status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
+
+       /* Allow a retry if autosuspend failed temporarily */
+       if (status == -EAGAIN || status == -EBUSY)
+               usb_mark_last_busy(udev);
+
        /* The PM core reacts badly unless the return code is 0,
         * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
         */
index 96f05b29c9ad23ba6c0874a29dc2066c16806476..79781461eec97ad27c4986178266a63034f4693f 100644 (file)
@@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                                        USB_PORT_FEAT_C_PORT_LINK_STATE);
                }
 
+               if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
+                               hub_is_superspeed(hub->hdev)) {
+                       need_debounce_delay = true;
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_BH_PORT_RESET);
+               }
                /* We can forget about a "removed" device when there's a
                 * physical disconnect or the connect status changes.
                 */
index 7542dce3f5a1e2b01bcbd2ef78c08bd870c31b1a..7728c91dfa2e61eb50b21d75f558a96342db60a2 100644 (file)
@@ -10,6 +10,7 @@
 
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/notifier.h>
 #include <linux/usb.h>
 #include <linux/mutex.h>
index d6a8d8269bfbe6b68648d52068d846208aa9dd05..ecf12e15a7ef48a201c192dbc056b108c2416340 100644 (file)
@@ -50,15 +50,42 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Logitech Webcam B/C500 */
        { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C600 */
+       { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam Pro 9000 */
        { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C905 */
+       { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C210 */
+       { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C260 */
+       { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam C310 */
        { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Webcam C910 */
+       { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Webcam C160 */
+       { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Webcam C270 */
        { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Logitech Quickcam Pro 9000 */
+       { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Quickcam E3500 */
+       { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
+
+       /* Logitech Quickcam Vision Pro */
+       { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
+
        /* Logitech Harmony 700-series */
        { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
 
index fa824cfdd2eb42bf0869257303835a4305a16690..25dbd8614e7226ccf915bfa30817226a10272f3c 100644 (file)
@@ -1284,6 +1284,7 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
                        int             ret;
 
                        dep->endpoint.maxpacket = 1024;
+                       dep->endpoint.max_streams = 15;
                        dep->endpoint.ops = &dwc3_gadget_ep_ops;
                        list_add_tail(&dep->endpoint.ep_list,
                                        &dwc->gadget.ep_list);
index b21cd376c11af5978095c97f49bdee67aa1ec6d0..23a447373c51f0c7d3f9a08cadad7a90f217c24a 100644 (file)
@@ -469,7 +469,7 @@ config USB_LANGWELL
           gadget drivers to also be dynamically linked.
 
 config USB_EG20T
-       tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC"
+       tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
        depends on PCI
        select USB_GADGET_DUALSPEED
        help
@@ -485,10 +485,11 @@ config USB_EG20T
          This driver dose not support interrupt transfer or isochronous
          transfer modes.
 
-         This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
+         This driver also can be used for LAPIS Semiconductor's ML7213 which is
          for IVI(In-Vehicle Infotainment) use.
-         ML7213 is companion chip for Intel Atom E6xx series.
-         ML7213 is completely compatible for Intel EG20T PCH.
+         ML7831 is for general purpose use.
+         ML7213/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7213/ML7831 is completely compatible for Intel EG20T PCH.
 
 config USB_CI13XXX_MSM
        tristate "MIPS USB CI13xxx for MSM"
index 4730016d7cd42d8644e8fb5fa8791fc9df080591..45f422ac103fb61678633ee08241b33b7dfe235a 100644 (file)
@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,
        u32 tmp;
 
        if (!driver || !bind || !driver->setup
-                       || driver->speed != USB_SPEED_HIGH)
+                       || driver->speed < USB_SPEED_HIGH)
                return -EINVAL;
        if (!dev)
                return -ENODEV;
index 672674c2fb3dda35e871a1d488e07cad00a0853a..725550f06fab60c832b51da725ea3feb805b32d7 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/utsname.h>
+#include <linux/module.h>
 
 #include "u_ether.h"
 #include "u_serial.h"
index 4eedfe557154c285b9625d2117523ea3feef78ea..1fc612914c52e464ec89a82ec9e39048068c0b27 100644 (file)
@@ -122,3 +122,5 @@ static int __init ci13xxx_msm_init(void)
        return platform_driver_register(&ci13xxx_msm_driver);
 }
 module_init(ci13xxx_msm_init);
+
+MODULE_LICENSE("GPL v2");
index 83428f56253bd5283a8962448fa8cd7b899aee96..9a0c3979ff43faa2c54f05efa5fe8c76d8f23dff 100644 (file)
@@ -71,6 +71,9 @@
 /******************************************************************************
  * DEFINE
  *****************************************************************************/
+
+#define DMA_ADDR_INVALID       (~(dma_addr_t)0)
+
 /* ctrl register bank access */
 static DEFINE_SPINLOCK(udc_lock);
 
@@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
                return -EALREADY;
 
        mReq->req.status = -EALREADY;
-       if (length && !mReq->req.dma) {
+       if (length && mReq->req.dma == DMA_ADDR_INVALID) {
                mReq->req.dma = \
                        dma_map_single(mEp->device, mReq->req.buf,
                                       length, mEp->dir ? DMA_TO_DEVICE :
@@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
                                dma_unmap_single(mEp->device, mReq->req.dma,
                                        length, mEp->dir ? DMA_TO_DEVICE :
                                        DMA_FROM_DEVICE);
-                               mReq->req.dma = 0;
+                               mReq->req.dma = DMA_ADDR_INVALID;
                                mReq->map     = 0;
                        }
                        return -ENOMEM;
@@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
        if (mReq->map) {
                dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
                                 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               mReq->req.dma = 0;
+               mReq->req.dma = DMA_ADDR_INVALID;
                mReq->map     = 0;
        }
 
@@ -1610,7 +1613,6 @@ __acquires(mEp->lock)
  * @gadget: gadget
  *
  * This function returns an error code
- * Caller must hold lock
  */
 static int _gadget_stop_activity(struct usb_gadget *gadget)
 {
@@ -2189,6 +2191,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
        mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
        if (mReq != NULL) {
                INIT_LIST_HEAD(&mReq->queue);
+               mReq->req.dma = DMA_ADDR_INVALID;
 
                mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
                                           &mReq->dma);
@@ -2328,7 +2331,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        if (mReq->map) {
                dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
                                 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-               mReq->req.dma = 0;
+               mReq->req.dma = DMA_ADDR_INVALID;
                mReq->map     = 0;
        }
        req->status = -ECONNRESET;
@@ -2500,12 +2503,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget)
        spin_lock_irqsave(udc->lock, flags);
        if (!udc->remote_wakeup) {
                ret = -EOPNOTSUPP;
-               dbg_trace("remote wakeup feature is not enabled\n");
+               trace("remote wakeup feature is not enabled\n");
                goto out;
        }
        if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
                ret = -EINVAL;
-               dbg_trace("port is not suspended\n");
+               trace("port is not suspended\n");
                goto out;
        }
        hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
@@ -2703,7 +2706,9 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver)
                if (udc->udc_driver->notify_event)
                        udc->udc_driver->notify_event(udc,
                        CI13XXX_CONTROLLER_STOPPED_EVENT);
+               spin_unlock_irqrestore(udc->lock, flags);
                _gadget_stop_activity(&udc->gadget);
+               spin_lock_irqsave(udc->lock, flags);
                pm_runtime_put(&udc->gadget.dev);
        }
 
@@ -2850,7 +2855,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
        struct ci13xxx *udc;
        int retval = 0;
 
-       trace("%p, %p, %p", dev, regs, name);
+       trace("%p, %p, %p", dev, regs, driver->name);
 
        if (dev == NULL || regs == NULL || driver == NULL ||
                        driver->name == NULL)
index 8a5529d214fbcd4cc71689885f1f7e0e77d15c38..f71b0787983f29469222e3e83631d17636c400ce 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kallsyms.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/utsname.h>
 
index f855ecf7a637f7153711e770f8088e0d90eb4acf..6256420089f3a4bca25bd649fab2e3dab0b0515f 100644 (file)
@@ -9,6 +9,7 @@
 /* verbose messages */
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
index 6b1c20b6c9b2e71817f9d62d89d0714d7b3e0655..acb38004eec08ba72819477df0af6eacd00bcd34 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/pagemap.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include <linux/usb/composite.h>
index 52583a2353304acb25119365a5432c916e0aeb73..c39d58860fa0414a2c862941dbc4382ddb2e1b0f 100644 (file)
@@ -624,7 +624,8 @@ static int fsg_setup(struct usb_function *f,
                if (ctrl->bRequestType !=
                    (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                        break;
-               if (w_index != fsg->interface_number || w_value != 0)
+               if (w_index != fsg->interface_number || w_value != 0 ||
+                               w_length != 0)
                        return -EDOM;
 
                /*
@@ -639,7 +640,8 @@ static int fsg_setup(struct usb_function *f,
                if (ctrl->bRequestType !=
                    (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                        break;
-               if (w_index != fsg->interface_number || w_value != 0)
+               if (w_index != fsg->interface_number || w_value != 0 ||
+                               w_length != 1)
                        return -EDOM;
                VDBG(fsg, "get max LUN\n");
                *(u8 *)req->buf = fsg->common->nluns - 1;
index 67b222908cf9fe264a3213b945f0beae5fa83569..3797b3d6c622bd49ff709b33303a86e323294c44 100644 (file)
@@ -95,7 +95,6 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req);
 
 DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
 DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
-DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16);
 DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
 
 /* B.3.1  Standard AC Interface Descriptor */
@@ -140,26 +139,6 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = {
        /* .wTotalLength =      DYNAMIC */
 };
 
-/* B.4.3  Embedded MIDI IN Jack Descriptor */
-static struct usb_midi_in_jack_descriptor jack_in_emb_desc = {
-       .bLength =            USB_DT_MIDI_IN_SIZE,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubtype =   USB_MS_MIDI_IN_JACK,
-       .bJackType =        USB_MS_EMBEDDED,
-       /* .bJackID =           DYNAMIC */
-};
-
-/* B.4.4  Embedded MIDI OUT Jack Descriptor */
-static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = {
-       /* .bLength =           DYNAMIC */
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubtype =   USB_MS_MIDI_OUT_JACK,
-       .bJackType =            USB_MS_EMBEDDED,
-       /* .bJackID =           DYNAMIC */
-       /* .bNrInputPins =      DYNAMIC */
-       /* .pins =              DYNAMIC */
-};
-
 /* B.5.1  Standard Bulk OUT Endpoint Descriptor */
 static struct usb_endpoint_descriptor bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_AUDIO_SIZE,
@@ -758,9 +737,11 @@ fail:
 static int __init
 f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 {
-       struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12];
+       struct usb_descriptor_header **midi_function;
        struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
+       struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
        struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
+       struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS];
        struct usb_composite_dev *cdev = c->cdev;
        struct f_midi *midi = func_to_midi(f);
        int status, n, jack = 1, i = 0;
@@ -798,6 +779,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
                goto fail;
        midi->out_ep->driver_data = cdev;       /* claim */
 
+       /* allocate temporary function list */
+       midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function),
+                               GFP_KERNEL);
+       if (!midi_function) {
+               status = -ENOMEM;
+               goto fail;
+       }
+
        /*
         * construct the function's descriptor set. As the number of
         * input and output MIDI ports is configurable, we have to do
@@ -811,73 +800,74 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 
        /* calculate the header's wTotalLength */
        n = USB_DT_MS_HEADER_SIZE
-               + (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE
-               + (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1);
+               + (midi->in_ports + midi->out_ports) *
+                       (USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));
        ms_header_desc.wTotalLength = cpu_to_le16(n);
 
        midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
 
-       /* we have one embedded IN jack */
-       jack_in_emb_desc.bJackID = jack++;
-       midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc;
-
-       /* and a dynamic amount of external IN jacks */
-       for (n = 0; n < midi->in_ports; n++) {
-               struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n];
-
-               ext->bLength =                  USB_DT_MIDI_IN_SIZE;
-               ext->bDescriptorType =          USB_DT_CS_INTERFACE;
-               ext->bDescriptorSubtype =       USB_MS_MIDI_IN_JACK;
-               ext->bJackType =                USB_MS_EXTERNAL;
-               ext->bJackID =                  jack++;
-               ext->iJack =                    0;
-
-               midi_function[i++] = (struct usb_descriptor_header *) ext;
-       }
-
-       /* one embedded OUT jack ... */
-       jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports);
-       jack_out_emb_desc.bJackID = jack++;
-       jack_out_emb_desc.bNrInputPins = midi->in_ports;
-       /* ... which referencess all external IN jacks */
+       /* configure the external IN jacks, each linked to an embedded OUT jack */
        for (n = 0; n < midi->in_ports; n++) {
-               jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID;
-               jack_out_emb_desc.pins[n].baSourcePin = 1;
+               struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n];
+               struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n];
+
+               in_ext->bLength                 = USB_DT_MIDI_IN_SIZE;
+               in_ext->bDescriptorType         = USB_DT_CS_INTERFACE;
+               in_ext->bDescriptorSubtype      = USB_MS_MIDI_IN_JACK;
+               in_ext->bJackType               = USB_MS_EXTERNAL;
+               in_ext->bJackID                 = jack++;
+               in_ext->iJack                   = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) in_ext;
+
+               out_emb->bLength                = USB_DT_MIDI_OUT_SIZE(1);
+               out_emb->bDescriptorType        = USB_DT_CS_INTERFACE;
+               out_emb->bDescriptorSubtype     = USB_MS_MIDI_OUT_JACK;
+               out_emb->bJackType              = USB_MS_EMBEDDED;
+               out_emb->bJackID                = jack++;
+               out_emb->bNrInputPins           = 1;
+               out_emb->pins[0].baSourcePin    = 1;
+               out_emb->pins[0].baSourceID     = in_ext->bJackID;
+               out_emb->iJack                  = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) out_emb;
+
+               /* link it to the endpoint */
+               ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
        }
 
-       midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc;
-
-       /* and multiple external OUT jacks ... */
+       /* configure the external OUT jacks, each linked to an embedded IN jack */
        for (n = 0; n < midi->out_ports; n++) {
-               struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n];
-               int m;
-
-               ext->bLength =                  USB_DT_MIDI_OUT_SIZE(1);
-               ext->bDescriptorType =          USB_DT_CS_INTERFACE;
-               ext->bDescriptorSubtype =       USB_MS_MIDI_OUT_JACK;
-               ext->bJackType =                USB_MS_EXTERNAL;
-               ext->bJackID =                  jack++;
-               ext->bNrInputPins =             1;
-               ext->iJack =                    0;
-               /* ... which all reference the same embedded IN jack */
-               for (m = 0; m < midi->out_ports; m++) {
-                       ext->pins[m].baSourceID =       jack_in_emb_desc.bJackID;
-                       ext->pins[m].baSourcePin =      1;
-               }
-
-               midi_function[i++] = (struct usb_descriptor_header *) ext;
+               struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n];
+               struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n];
+
+               in_emb->bLength                 = USB_DT_MIDI_IN_SIZE;
+               in_emb->bDescriptorType         = USB_DT_CS_INTERFACE;
+               in_emb->bDescriptorSubtype      = USB_MS_MIDI_IN_JACK;
+               in_emb->bJackType               = USB_MS_EMBEDDED;
+               in_emb->bJackID                 = jack++;
+               in_emb->iJack                   = 0;
+               midi_function[i++] = (struct usb_descriptor_header *) in_emb;
+
+               out_ext->bLength =              USB_DT_MIDI_OUT_SIZE(1);
+               out_ext->bDescriptorType =      USB_DT_CS_INTERFACE;
+               out_ext->bDescriptorSubtype =   USB_MS_MIDI_OUT_JACK;
+               out_ext->bJackType =            USB_MS_EXTERNAL;
+               out_ext->bJackID =              jack++;
+               out_ext->bNrInputPins =         1;
+               out_ext->iJack =                0;
+               out_ext->pins[0].baSourceID =   in_emb->bJackID;
+               out_ext->pins[0].baSourcePin =  1;
+               midi_function[i++] = (struct usb_descriptor_header *) out_ext;
+
+               /* link it to the endpoint */
+               ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
        }
 
        /* configure the endpoint descriptors ... */
        ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
        ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
-       for (n = 0; n < midi->in_ports; n++)
-               ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID;
 
        ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
        ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
-       for (n = 0; n < midi->out_ports; n++)
-               ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID;
 
        /* ... and add them to the list */
        midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc;
@@ -901,6 +891,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
                f->descriptors = usb_copy_descriptors(midi_function);
        }
 
+       kfree(midi_function);
+
        return 0;
 
 fail:
index e3f74bf5da2d835b18b284a4c6d51e03fdb7fbab..5f400f66aa9b5dfa3c4844639d62ad23ad11608b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/module.h>
 
 #include "u_serial.h"
 #include "gadget_chips.h"
index 3490770333383d3d63c08977901b9311ff7cef15..16a509ae517b6b5a317422aa2553ce1316da46c5 100644 (file)
@@ -346,7 +346,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
                }
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
-                               skb->len == 0, req->actual);
+                               skb->len <= 1, req->actual);
                page = NULL;
 
                if (req->actual < req->length) { /* Last fragment */
index 91fdf790ed20b122bf0a13df0d3c8aed5285ac3c..cf33a8d0fd5df46ec339f5b481b68dc61121243a 100644 (file)
@@ -131,8 +131,8 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        }
        if (!gser->port.in->desc || !gser->port.out->desc) {
                DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
-               if (!config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
-                   !config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
+               if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
+                   config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
                        gser->port.in->desc = NULL;
                        gser->port.out->desc = NULL;
                        return -EINVAL;
index 168906d2b5d42128459073d7160e7c6fb47d815d..7aa7ac82c02c187cfd6af99eea6c4a937ad2e993 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/module.h>
 
 #include "g_zero.h"
 #include "gadget_chips.h"
index 3ac4f51cd0bbb50e98d3cc2b70785def49593022..11b5196284aed6253180b699094cd7b6dbc762ea 100644 (file)
 #include <linux/kref.h>
 #include <linux/kthread.h>
 #include <linux/limits.h>
+#include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -858,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0 || w_value != 0) {
+                       if (w_index != 0 || w_value != 0 || w_length != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -874,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_IN |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0 || w_value != 0) {
+                       if (w_index != 0 || w_value != 0 || w_length != 1) {
                                value = -EDOM;
                                break;
                        }
index 43a49ecc1f36ed1009eb836350bd07800a4d8c09..dcbc0a2e48dde8be9b27a5c429a4c004bfb8aa9c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/fsl_devices.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 
@@ -88,7 +89,6 @@ eenahb:
 void fsl_udc_clk_finalize(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-#if defined(CONFIG_SOC_IMX35)
        if (cpu_is_mx35()) {
                unsigned int v;
 
@@ -101,7 +101,6 @@ void fsl_udc_clk_finalize(struct platform_device *pdev)
                                        USBPHYCTRL_OTGBASE_OFFSET));
                }
        }
-#endif
 
        /* ULPI transceivers don't need usbpll */
        if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
index 2a03e4de11c1a277cfe27b670ac48f11cabc006a..e00cf92409ce5114f061801c3d3e29b6b6bae23e 100644 (file)
@@ -2336,8 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver,
        if (!udc_controller)
                return -ENODEV;
 
-       if (!driver || (driver->speed != USB_SPEED_FULL
-                       && driver->speed != USB_SPEED_HIGH)
+       if (!driver || driver->speed < USB_SPEED_FULL
                        || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
index b2c44e1d58134c185966e672508ec0a9f8d24d84..dd28ef3def71f394f281b70f8ee2335b629f42e6 100644 (file)
@@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
                kfree(req);
 }
 
-/*-------------------------------------------------------------------------*/
+/* Actually add a dTD chain to an empty dQH and let go */
+static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td)
+{
+       struct ep_queue_head *qh = get_qh_by_ep(ep);
+
+       /* Write dQH next pointer and terminate bit to 0 */
+       qh->next_dtd_ptr = cpu_to_hc32(td->td_dma
+                       & EP_QUEUE_HEAD_NEXT_POINTER_MASK);
+
+       /* Clear active and halt bit */
+       qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
+                                       | EP_QUEUE_HEAD_STATUS_HALT));
+
+       /* Ensure that updates to the QH will occur before priming. */
+       wmb();
+
+       /* Prime endpoint by writing correct bit to ENDPTPRIME */
+       fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16))
+                       : (1 << (ep_index(ep))), &dr_regs->endpointprime);
+}
+
+/* Add dTD chain to the dQH of an EP */
 static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 {
-       int i = ep_index(ep) * 2 + ep_is_in(ep);
        u32 temp, bitmask, tmp_stat;
-       struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
 
        /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
        VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
@@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                        cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
                /* Read prime bit, if 1 goto done */
                if (fsl_readl(&dr_regs->endpointprime) & bitmask)
-                       goto out;
+                       return;
 
                do {
                        /* Set ATDTW bit in USBCMD */
@@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
 
                if (tmp_stat)
-                       goto out;
+                       return;
        }
 
-       /* Write dQH next pointer and terminate bit to 0 */
-       temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
-       dQH->next_dtd_ptr = cpu_to_hc32(temp);
-
-       /* Clear active and halt bit */
-       temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
-                       | EP_QUEUE_HEAD_STATUS_HALT));
-       dQH->size_ioc_int_sts &= temp;
-
-       /* Ensure that updates to the QH will occur before priming. */
-       wmb();
-
-       /* Prime endpoint by writing 1 to ENDPTPRIME */
-       temp = ep_is_in(ep)
-               ? (1 << (ep_index(ep) + 16))
-               : (1 << (ep_index(ep)));
-       fsl_writel(temp, &dr_regs->endpointprime);
-out:
-       return;
+       fsl_prime_ep(ep, req->head);
 }
 
 /* Fill in the dTD structure
@@ -877,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                VDBG("%s, bad ep", __func__);
                return -EINVAL;
        }
-       if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+       if (usb_endpoint_xfer_isoc(ep->desc)) {
                if (req->req.length > ep->ep.maxpacket)
                        return -EMSGSIZE;
        }
@@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
                /* The request isn't the last request in this ep queue */
                if (req->queue.next != &ep->queue) {
-                       struct ep_queue_head *qh;
                        struct fsl_req *next_req;
 
-                       qh = ep->qh;
                        next_req = list_entry(req->queue.next, struct fsl_req,
                                        queue);
 
-                       /* Point the QH to the first TD of next request */
-                       fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr);
+                       /* prime with dTD of next request */
+                       fsl_prime_ep(ep, next_req->head);
                }
-
-               /* The request hasn't been processed, patch up the TD chain */
+       /* The request hasn't been processed, patch up the TD chain */
        } else {
                struct fsl_req *prev_req;
 
                prev_req = list_entry(req->queue.prev, struct fsl_req, queue);
-               fsl_writel(fsl_readl(&req->tail->next_td_ptr),
-                               &prev_req->tail->next_td_ptr);
-
+               prev_req->tail->next_td_ptr = req->tail->next_td_ptr;
        }
 
        done(ep, req, -ECONNRESET);
@@ -1032,7 +1028,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
                goto out;
        }
 
-       if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+       if (usb_endpoint_xfer_isoc(ep->desc)) {
                status = -EOPNOTSUPP;
                goto out;
        }
@@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
        struct fsl_udc *udc;
        int size = 0;
        u32 bitmask;
-       struct ep_queue_head *d_qh;
+       struct ep_queue_head *qh;
 
        ep = container_of(_ep, struct fsl_ep, ep);
        if (!_ep || (!ep->desc && ep_index(ep) != 0))
@@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
        if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
                return -ESHUTDOWN;
 
-       d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)];
+       qh = get_qh_by_ep(ep);
 
        bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
            (1 << (ep_index(ep)));
 
        if (fsl_readl(&dr_regs->endptstatus) & bitmask)
-               size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE)
+               size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE)
                    >> DTD_LENGTH_BIT_POS;
 
        pr_debug("%s %u\n", __func__, size);
@@ -1717,7 +1713,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)
 
 static inline enum usb_device_speed portscx_device_speed(u32 reg)
 {
-       switch (speed & PORTSCX_PORT_SPEED_MASK) {
+       switch (reg & PORTSCX_PORT_SPEED_MASK) {
        case PORTSCX_PORT_SPEED_HIGH:
                return USB_SPEED_HIGH;
        case PORTSCX_PORT_SPEED_FULL:
@@ -1938,8 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver,
        if (!udc_controller)
                return -ENODEV;
 
-       if (!driver || (driver->speed != USB_SPEED_FULL
-                               && driver->speed != USB_SPEED_HIGH)
+       if (!driver || driver->speed < USB_SPEED_FULL
                        || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
@@ -2480,8 +2475,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 
 #ifndef CONFIG_ARCH_MXC
        if (pdata->have_sysif_regs)
-               usb_sys_regs = (struct usb_sys_interface *)
-                               ((u32)dr_regs + USB_DR_SYS_OFFSET);
+               usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
 #endif
 
        /* Initialize USB clocks */
index 1d51be83fda87402d4a77a28ff4fa636d17bff62..f781f5dec41776629584a33a1be5817d8e6778d6 100644 (file)
@@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
                                        * 2 + ((windex & USB_DIR_IN) ? 1 : 0))
 #define get_pipe_by_ep(EP)     (ep_index(EP) * 2 + ep_is_in(EP))
 
+static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
+{
+       /* we only have one ep0 structure but two queue heads */
+       if (ep_index(ep) != 0)
+               return ep->qh;
+       else
+               return &ep->udc->ep_qh[(ep->udc->ep0_dir ==
+                               USB_DIR_IN) ? 1 : 0];
+}
+
 struct platform_device;
 #ifdef CONFIG_ARCH_MXC
 int fsl_udc_clk_init(struct platform_device *pdev);
index e593f2849fa9499bb0efcdb748b4f610e1d3b22a..74da206c84060c7226a717a5a4ec76309fddc8d5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
index 8fcde37aa6d4416398d7e7c1c7c79629a3b4cf86..681bd038b1d8354f6317b7f23652f5667c584a68 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/utsname.h>
+#include <linux/module.h>
 #include <linux/device.h>
 
 #include <sound/core.h>
index a392ec0d2d5179beebf3923dc6b275001b4961c5..6ccae2707e596c3f24d5705495264f0dcfa4f31b 100644 (file)
@@ -1730,8 +1730,9 @@ static void
 gadgetfs_disconnect (struct usb_gadget *gadget)
 {
        struct dev_data         *dev = get_gadget_data (gadget);
+       unsigned long           flags;
 
-       spin_lock (&dev->lock);
+       spin_lock_irqsave (&dev->lock, flags);
        if (dev->state == STATE_DEV_UNCONNECTED)
                goto exit;
        dev->state = STATE_DEV_UNCONNECTED;
@@ -1740,7 +1741,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget)
        next_event (dev, GADGETFS_DISCONNECT);
        ep0_readable (dev);
 exit:
-       spin_unlock (&dev->lock);
+       spin_unlock_irqrestore (&dev->lock, flags);
 }
 
 static void
index 91d0af2a24a8537728fb5c5cb176ff0108095ab5..9aa1cbbee45b64597ef9bcc44d5ba5ed219b2d6a 100644 (file)
@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver,
        int retval;
 
        if (!driver
-                       || driver->speed != USB_SPEED_HIGH
+                       || driver->speed < USB_SPEED_HIGH
                        || !bind
                        || !driver->setup)
                return -EINVAL;
index 7f1bc9a73cda5a1fe45f8c053f426407758e0f50..da2b9d0be3ca0d444d9df8ca5f0b7a9800c3d078 100644 (file)
@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget,
         * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
         * "must not be used in normal operation"
         */
-       if (!driver || driver->speed != USB_SPEED_HIGH
+       if (!driver || driver->speed < USB_SPEED_HIGH
                        || !driver->setup)
                return -EINVAL;
 
index 550d6dcdf10454253cdb3d93f6a7d86219ce4a50..5048a0c07640a4ed649c848a43ae4b83c5298be4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -354,6 +354,7 @@ struct pch_udc_dev {
 #define PCI_DEVICE_ID_INTEL_EG20T_UDC  0x8808
 #define PCI_VENDOR_ID_ROHM             0x10DB
 #define PCI_DEVICE_ID_ML7213_IOH_UDC   0x801D
+#define PCI_DEVICE_ID_ML7831_IOH_UDC   0x8808
 
 static const char      ep0_string[] = "ep0in";
 static DEFINE_SPINLOCK(udc_stall_spinlock);    /* stall spin lock */
@@ -2970,6 +2971,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {
                .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
                .class_mask = 0xffffffff,
        },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC),
+               .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
+               .class_mask = 0xffffffff,
+       },
        { 0 },
 };
 
@@ -2999,5 +3005,5 @@ static void __exit pch_udc_pci_exit(void)
 module_exit(pch_udc_pci_exit);
 
 MODULE_DESCRIPTION("Intel EG20T USB Device Controller");
-MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
+MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");
 MODULE_LICENSE("GPL");
index 68a826a1b866e8a9191711da9c5e0da40eaf2e22..fc719a3f855717b88417aaff8c2e89d9a2723109 100644 (file)
@@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)
        if (list_empty(&ep->queue) && !ep->busy) {
                pipe_stop(ep->r8a66597, ep->pipenum);
                r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
+               r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr);
+               r8a66597_write(ep->r8a66597, 0, ep->pipectr);
        }
        spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
 }
@@ -1742,26 +1744,16 @@ static int r8a66597_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
-       int retval;
 
        if (!driver
-                       || driver->speed != USB_SPEED_HIGH
+                       || driver->speed < USB_SPEED_HIGH
                        || !driver->setup)
                return -EINVAL;
        if (!r8a66597)
                return -ENODEV;
 
        /* hook up the driver */
-       driver->driver.bus = NULL;
        r8a66597->driver = driver;
-       r8a66597->gadget.dev.driver = &driver->driver;
-
-       retval = device_add(&r8a66597->gadget.dev);
-       if (retval) {
-               dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n",
-                       retval);
-               goto error;
-       }
 
        init_controller(r8a66597);
        r8a66597_bset(r8a66597, VBSE, INTENB0);
@@ -1775,12 +1767,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
        }
 
        return 0;
-
-error:
-       r8a66597->driver = NULL;
-       r8a66597->gadget.dev.driver = NULL;
-
-       return retval;
 }
 
 static int r8a66597_stop(struct usb_gadget *gadget,
@@ -1794,7 +1780,6 @@ static int r8a66597_stop(struct usb_gadget *gadget,
        disable_controller(r8a66597);
        spin_unlock_irqrestore(&r8a66597->lock, flags);
 
-       device_del(&r8a66597->gadget.dev);
        r8a66597->driver = NULL;
        return 0;
 }
@@ -1845,6 +1830,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
                clk_put(r8a66597->clk);
        }
 #endif
+       device_unregister(&r8a66597->gadget.dev);
        kfree(r8a66597);
        return 0;
 }
@@ -1924,13 +1910,17 @@ static int __init r8a66597_probe(struct platform_device *pdev)
        r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
 
        r8a66597->gadget.ops = &r8a66597_gadget_ops;
-       device_initialize(&r8a66597->gadget.dev);
        dev_set_name(&r8a66597->gadget.dev, "gadget");
        r8a66597->gadget.is_dualspeed = 1;
        r8a66597->gadget.dev.parent = &pdev->dev;
        r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
        r8a66597->gadget.dev.release = pdev->dev.release;
        r8a66597->gadget.name = udc_name;
+       ret = device_register(&r8a66597->gadget.dev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "device_register failed\n");
+               goto clean_up;
+       }
 
        init_timer(&r8a66597->timer);
        r8a66597->timer.function = r8a66597_timer;
@@ -1945,7 +1935,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
                                clk_name);
                        ret = PTR_ERR(r8a66597->clk);
-                       goto clean_up;
+                       goto clean_up_dev;
                }
                clk_enable(r8a66597->clk);
        }
@@ -2014,7 +2004,9 @@ clean_up2:
                clk_disable(r8a66597->clk);
                clk_put(r8a66597->clk);
        }
+clean_up_dev:
 #endif
+       device_unregister(&r8a66597->gadget.dev);
 clean_up:
        if (r8a66597) {
                if (r8a66597->sudmac_reg)
index a552453dc94632cacee3ea5212f60aa4563fa519..b31448229f0b26c3a38014cf59e3339060253cb3 100644 (file)
@@ -2586,10 +2586,8 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver,
                return -EINVAL;
        }
 
-       if (driver->speed != USB_SPEED_HIGH &&
-           driver->speed != USB_SPEED_FULL) {
+       if (driver->speed < USB_SPEED_FULL)
                dev_err(hsotg->dev, "%s: bad speed\n", __func__);
-       }
 
        if (!bind || !driver->setup) {
                dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
index 8d54f893cefe9df7c97363c1812b4f30bb822ff7..20a553b46aedc1d17ecaeaf033ff62eb8f5f472c 100644 (file)
@@ -1142,8 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver,
        int ret;
 
        if (!driver
-               || (driver->speed != USB_SPEED_FULL &&
-                       driver->speed != USB_SPEED_HIGH)
+               || driver->speed < USB_SPEED_FULL
                || !bind
                || !driver->unbind || !driver->disconnect || !driver->setup)
                return -EINVAL;
index 3a4a664bab44c44583ce696e8918146d504e5ae2..6597a6813e438adbd192cb86f3675ddd368c2d7d 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "u_serial.h"
 
index 022baeca7c94f4f55819d6cf2be5550752e3318a..6939e17f4580099af82d236c413547fe3660a18d 100644 (file)
@@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 
        if (udc_is_newstyle(udc)) {
-               usb_gadget_disconnect(udc->gadget);
+               udc->driver->disconnect(udc->gadget);
                udc->driver->unbind(udc->gadget);
                usb_gadget_udc_stop(udc->gadget, udc->driver);
-
+               usb_gadget_disconnect(udc->gadget);
        } else {
                usb_gadget_stop(udc->gadget, udc->driver);
        }
@@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
 static ssize_t usb_udc_srp_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t n)
 {
-       struct usb_udc          *udc = dev_get_drvdata(dev);
+       struct usb_udc          *udc = container_of(dev, struct usb_udc, dev);
 
        if (sysfs_streq(buf, "1"))
                usb_gadget_wakeup(udc->gadget);
@@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%s\n",
                        usb_speed_string(udc->gadget->speed));
 }
-static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
+static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL);
 
 #define USB_UDC_ATTR(name)                                     \
 ssize_t usb_udc_##name##_show(struct device *dev,              \
@@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev,           \
                                                                \
        return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);  \
 }                                                              \
-static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL)
+static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
 
 static USB_UDC_ATTR(is_dualspeed);
 static USB_UDC_ATTR(is_otg);
index 2e829fae648291d1fc885653e274b7e891d4e09e..a60679cbbf858e3c97a978218e16d931635ae1a3 100644 (file)
@@ -1475,30 +1475,36 @@ iso_stream_schedule (
         * jump until after the queue is primed.
         */
        else {
+               int done = 0;
                start = SCHEDULE_SLOP + (now & ~0x07);
 
                /* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
 
-               /* find a uframe slot with enough bandwidth */
-               next = start + period;
-               for (; start < next; start++) {
-
+               /* find a uframe slot with enough bandwidth.
+                * Early uframes are more precious because full-speed
+                * iso IN transfers can't use late uframes,
+                * and therefore they should be allocated last.
+                */
+               next = start;
+               start += period;
+               do {
+                       start--;
                        /* check schedule: enough space? */
                        if (stream->highspeed) {
                                if (itd_slot_ok(ehci, mod, start,
                                                stream->usecs, period))
-                                       break;
+                                       done = 1;
                        } else {
                                if ((start % 8) >= 6)
                                        continue;
                                if (sitd_slot_ok(ehci, mod, stream,
                                                start, sched, period))
-                                       break;
+                                       done = 1;
                        }
-               }
+               } while (start > next && !done);
 
                /* no room in the schedule */
-               if (start == next) {
+               if (!done) {
                        ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
                                urb, now, now + mod);
                        status = -ENOSPC;
index fe74bd6760187c221e79dae448005c07a25863be..b4fb511d24bcda76a4101aa605e01384c5962d21 100644 (file)
@@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd)
 
        ehci->caps = hcd->regs;
        ehci->regs = hcd->regs +
-               HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+               HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
        dbg_hcs_params(ehci, "reset");
        dbg_hcc_params(ehci, "reset");
 
index 79a66d622f9c265bdc2c8f6780f0df7c299a1235..9037035ad1e46034137a875572b99f6a4e41a985 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/of_platform.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 
 struct fsl_usb2_dev_data {
        char *dr_mode;          /* controller mode */
index 2c7fc830c9e48b39080188a295d443cffa11fa38..a7dc1e1d45f2a77e1cfce4de339b449b8863f778 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/usb.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/usb/isp1760.h>
 #include <linux/usb/hcd.h>
index ba3a46b78b75a7bd16e54e7e9d3690dd5f9df4ef..95a9fec38e89b4e8a6daff8a3c0c75fd73315d4c 100644 (file)
@@ -223,6 +223,9 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
        if (port < 0 || port >= 2)
                return;
 
+       if (pdata->vbus_pin[port] <= 0)
+               return;
+
        gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);
 }
 
@@ -231,6 +234,9 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
        if (port < 0 || port >= 2)
                return -EINVAL;
 
+       if (pdata->vbus_pin[port] <= 0)
+               return -EINVAL;
+
        return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;
 }
 
index 34efd479e068cbd8133fbd98f8c2a2cd47efa862..b2639191549e88172e803281a6c53300bd103b67 100644 (file)
@@ -389,17 +389,14 @@ ohci_shutdown (struct usb_hcd *hcd)
        struct ohci_hcd *ohci;
 
        ohci = hcd_to_ohci (hcd);
-       ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
-       ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+       ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
 
-       /* If the SHUTDOWN quirk is set, don't put the controller in RESET */
-       ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ?
-                       OHCI_CTRL_RWC | OHCI_CTRL_HCFS :
-                       OHCI_CTRL_RWC);
-       ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+       /* Software reset, after which the controller goes into SUSPEND */
+       ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
+       ohci_readl(ohci, &ohci->regs->cmdstatus);       /* flush the writes */
+       udelay(10);
 
-       /* flush the writes */
-       (void) ohci_readl (ohci, &ohci->regs->control);
+       ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
 }
 
 static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
index ad8166c681e2894424b81850aa3a366108d8d11c..bc01b064585ac9da1d232106586d71937b78db66 100644 (file)
@@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
        return 0;
 }
 
-/* nVidia controllers continue to drive Reset signalling on the bus
- * even after system shutdown, wasting power.  This flag tells the
- * shutdown routine to leave the controller OPERATIONAL instead of RESET.
- */
-static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd)
-{
-       struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
-       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
-       /* Evidently nVidia fixed their later hardware; this is a guess at
-        * the changeover point.
-        */
-#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB          0x026d
-
-       if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) {
-               ohci->flags |= OHCI_QUIRK_SHUTDOWN;
-               ohci_dbg(ohci, "enabled nVidia shutdown quirk\n");
-       }
-
-       return 0;
-}
-
 static void sb800_prefetch(struct ohci_hcd *ohci, int on)
 {
        struct pci_dev *pdev;
@@ -260,10 +238,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {
                PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
                .driver_data = (unsigned long)ohci_quirk_amd700,
        },
-       {
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
-               .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown,
-       },
 
        /* FIXME for some of the early AMD 760 southbridges, OHCI
         * won't work at all.  blacklist them.
index 35e5fd640ce75388c7f373544c62e965f34c0111..0795b934d00c9709800948c137a1aa84fd96e47d 100644 (file)
@@ -403,7 +403,6 @@ struct ohci_hcd {
 #define        OHCI_QUIRK_HUB_POWER    0x100                   /* distrust firmware power/oc setup */
 #define        OHCI_QUIRK_AMD_PLL      0x200                   /* AMD PLL quirk*/
 #define        OHCI_QUIRK_AMD_PREFETCH 0x400                   /* pre-fetch for ISO transfer */
-#define        OHCI_QUIRK_SHUTDOWN     0x800                   /* nVidia power bug */
        // there are also chip quirks/bugs in init logic
 
        struct work_struct      nec_work;       /* Worker for NEC quirk */
index 629a96813fd66a9ebde456a2232a572c13f13dba..caf87428ca43c3f38985d9469b566645ea3d3bf9 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include "pci-quirks.h"
@@ -36,6 +37,7 @@
 #define OHCI_INTRENABLE                0x10
 #define OHCI_INTRDISABLE       0x14
 #define OHCI_FMINTERVAL                0x34
+#define OHCI_HCFS              (3 << 6)        /* hc functional state */
 #define OHCI_HCR               (1 << 0)        /* host controller reset */
 #define OHCI_OCR               (1 << 3)        /* ownership change request */
 #define OHCI_CTRL_RWC          (1 << 9)        /* remote wakeup connected */
@@ -465,6 +467,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 {
        void __iomem *base;
        u32 control;
+       u32 fminterval;
+       int cnt;
 
        if (!mmio_resource_enabled(pdev, 0))
                return;
@@ -497,41 +501,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
        }
 #endif
 
-       /* reset controller, preserving RWC (and possibly IR) */
-       writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
-       readl(base + OHCI_CONTROL);
+       /* disable interrupts */
+       writel((u32) ~0, base + OHCI_INTRDISABLE);
 
-       /* Some NVIDIA controllers stop working if kept in RESET for too long */
-       if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
-               u32 fminterval;
-               int cnt;
+       /* Reset the USB bus, if the controller isn't already in RESET */
+       if (control & OHCI_HCFS) {
+               /* Go into RESET, preserving RWC (and possibly IR) */
+               writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
+               readl(base + OHCI_CONTROL);
 
-               /* drive reset for at least 50 ms (7.1.7.5) */
+               /* drive bus reset for at least 50 ms (7.1.7.5) */
                msleep(50);
+       }
 
-               /* software reset of the controller, preserving HcFmInterval */
-               fminterval = readl(base + OHCI_FMINTERVAL);
-               writel(OHCI_HCR, base + OHCI_CMDSTATUS);
+       /* software reset of the controller, preserving HcFmInterval */
+       fminterval = readl(base + OHCI_FMINTERVAL);
+       writel(OHCI_HCR, base + OHCI_CMDSTATUS);
 
-               /* reset requires max 10 us delay */
-               for (cnt = 30; cnt > 0; --cnt) {        /* ... allow extra time */
-                       if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
-                               break;
-                       udelay(1);
-               }
-               writel(fminterval, base + OHCI_FMINTERVAL);
-
-               /* Now we're in the SUSPEND state with all devices reset
-                * and wakeups and interrupts disabled
-                */
+       /* reset requires max 10 us delay */
+       for (cnt = 30; cnt > 0; --cnt) {        /* ... allow extra time */
+               if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
+                       break;
+               udelay(1);
        }
+       writel(fminterval, base + OHCI_FMINTERVAL);
 
-       /*
-        * disable interrupts
-        */
-       writel(~(u32)0, base + OHCI_INTRDISABLE);
-       writel(~(u32)0, base + OHCI_INTRSTATUS);
-
+       /* Now the controller is safely in SUSPEND and nothing can wake it up */
        iounmap(base);
 }
 
@@ -626,7 +621,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
        void __iomem *base, *op_reg_base;
        u32     hcc_params, cap, val;
        u8      offset, cap_length;
-       int     wait_time, delta, count = 256/4;
+       int     wait_time, count = 256/4;
 
        if (!mmio_resource_enabled(pdev, 0))
                return;
@@ -672,11 +667,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
                writel(val, op_reg_base + EHCI_USBCMD);
 
                wait_time = 2000;
-               delta = 100;
                do {
                        writel(0x3f, op_reg_base + EHCI_USBSTS);
-                       udelay(delta);
-                       wait_time -= delta;
+                       udelay(100);
+                       wait_time -= 100;
                        val = readl(op_reg_base + EHCI_USBSTS);
                        if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
                                break;
index 767af265e0021f36336664ed32be46d66caac159..ba61dae9e4d2ce84bf5d75f12754ab4bf8d5d2c5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 #include "../../wusbcore/wusbhc.h"
 
index 9546f6cd01f09c103ffd82b9e52e1109b800ee92..1e141f755b26dd22836461a28ac0d2f1c9a7bcbd 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/uwb/umc.h>
 
 #include "../../wusbcore/wusbhc.h"
index d6e175428618d4b31f69bd3d323e7c5aef93deae..a403b53e86b9fd3dcc742b9da5759330fbc4d212 100644 (file)
@@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
 {
        qset->td_start = qset->td_end = qset->ntds = 0;
 
-       qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
+       qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
        qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
        qset->qh.err_count = 0;
        qset->qh.scratch[0] = 0;
index 431efe72b1f7807cf25840dba6cca3fd81905fa4..430e88fd3f6cd170261592175d51b6971406c1f2 100644 (file)
@@ -20,6 +20,7 @@
  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/gfp.h>
 #include <asm/unaligned.h>
 
 #include "xhci.h"
index 42a22b8e692262fde4eab6b2133fc6cf485555a7..0e4b25fa3bcd262a898d6337aeeb9b6cec7b5600 100644 (file)
@@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
        struct xhci_virt_device *dev;
        struct xhci_ep_ctx      *ep0_ctx;
        struct xhci_slot_ctx    *slot_ctx;
-       struct xhci_input_control_ctx *ctrl_ctx;
        u32                     port_num;
        struct usb_device *top_dev;
 
@@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
                return -EINVAL;
        }
        ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
-       ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
        slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
 
-       /* 2) New slot context and endpoint 0 context are valid*/
-       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
-
        /* 3) Only the control endpoint is valid - one endpoint context */
        slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
        switch (udev->speed) {
index 9f51f88cc0f5461f8bfd9da57ff15c020850a99f..ef98b38626fbb5910aa6c486aecb856f1f4b7df5 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "xhci.h"
 
index 940321b3ec68b477549a38d4016ee047fb7a72a7..9f1d4b15d818553fc488c8651a14d0e4b3301f66 100644 (file)
@@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        struct xhci_ring *ring;
        struct xhci_td *cur_td;
        int ret, i, j;
+       unsigned long flags;
 
        ep = (struct xhci_virt_ep *) arg;
        xhci = ep->xhci;
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
 
        ep->stop_cmds_pending--;
        if (xhci->xhc_state & XHCI_STATE_DYING) {
                xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "
                                "xHCI as DYING, exiting.\n");
-               spin_unlock(&xhci->lock);
+               spin_unlock_irqrestore(&xhci->lock, flags);
                return;
        }
        if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
                xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "
                                "exiting.\n");
-               spin_unlock(&xhci->lock);
+               spin_unlock_irqrestore(&xhci->lock, flags);
                return;
        }
 
@@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
        xhci->xhc_state |= XHCI_STATE_DYING;
        /* Disable interrupts from the host controller and start halting it */
        xhci_quiesce(xhci);
-       spin_unlock(&xhci->lock);
+       spin_unlock_irqrestore(&xhci->lock, flags);
 
        ret = xhci_halt(xhci);
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
        if (ret < 0) {
                /* This is bad; the host is not responding to commands and it's
                 * not allowing itself to be halted.  At least interrupts are
@@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
                        }
                }
        }
-       spin_unlock(&xhci->lock);
+       spin_unlock_irqrestore(&xhci->lock, flags);
        xhci_dbg(xhci, "Calling usb_hc_died()\n");
        usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
        xhci_dbg(xhci, "xHCI host controller is dead.\n");
index 1ff95a0df576762000796440a9b82aae53832718..a1afb7c39f7e70c36c12a8bccdc0a0b64b7f29d3 100644 (file)
@@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
        ring = xhci->cmd_ring;
        seg = ring->deq_seg;
        do {
-               memset(seg->trbs, 0, SEGMENT_SIZE);
+               memset(seg->trbs, 0,
+                       sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
+               seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
+                       cpu_to_le32(~TRB_CYCLE);
                seg = seg->next;
        } while (seg != ring->deq_seg);
 
@@ -799,7 +802,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        u32                     command, temp = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct usb_hcd          *secondary_hcd;
-       int                     retval;
+       int                     retval = 0;
 
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
@@ -809,6 +812,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                                xhci->bus_state[1].next_statechange))
                msleep(100);
 
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
+
        spin_lock_irq(&xhci->lock);
        if (xhci->quirks & XHCI_RESET_ON_RESUME)
                hibernated = true;
@@ -878,20 +884,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                        return retval;
                xhci_dbg(xhci, "Start the primary HCD\n");
                retval = xhci_run(hcd->primary_hcd);
-               if (retval)
-                       goto failed_restart;
-
-               xhci_dbg(xhci, "Start the secondary HCD\n");
-               retval = xhci_run(secondary_hcd);
                if (!retval) {
-                       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-                       set_bit(HCD_FLAG_HW_ACCESSIBLE,
-                                       &xhci->shared_hcd->flags);
+                       xhci_dbg(xhci, "Start the secondary HCD\n");
+                       retval = xhci_run(secondary_hcd);
                }
-failed_restart:
                hcd->state = HC_STATE_SUSPENDED;
                xhci->shared_hcd->state = HC_STATE_SUSPENDED;
-               return retval;
+               goto done;
        }
 
        /* step 4: set Run/Stop bit */
@@ -910,11 +909,14 @@ failed_restart:
         * Running endpoints by ringing their doorbells
         */
 
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
-
        spin_unlock_irq(&xhci->lock);
-       return 0;
+
+ done:
+       if (retval == 0) {
+               usb_hcd_resume_root_hub(hcd);
+               usb_hcd_resume_root_hub(xhci->shared_hcd);
+       }
+       return retval;
 }
 #endif /* CONFIG_PM */
 
@@ -3504,6 +3506,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        /* Otherwise, update the control endpoint ring enqueue pointer. */
        else
                xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
+       ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+       ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
+       ctrl_ctx->drop_flags = 0;
+
        xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
        xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
 
@@ -3585,7 +3591,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)
                + 1;
        /* Zero the input context control for later use */
-       ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
        ctrl_ctx->add_flags = 0;
        ctrl_ctx->drop_flags = 0;
 
index a04b2ff9dd83263083f51fceb703655721e081bb..91cd85076a44b1b22a3cd93f4fcb96d743228bc5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
+#include <linux/export.h>
 #include <linux/usb.h>
 #include <linux/poll.h>
 #include <linux/compat.h>
index e5ce42bd316e5c68d29a72ffdc2d805b6a575f37..ebd6189a5014ec2beff3580c0b98c3e61d140134 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/usb.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
index 1c3afcc11bd91584d87c49e62f89498d52c68d21..ad408251d9557c2504bd35dcd53ae416344bf08d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/usb.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
 #include <linux/scatterlist.h>
index fc34b8b1191055bcb568a171a518d389b4266f25..07a03460a598c3bcea675494a2a9009312b5d57b 100644 (file)
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC
        select TWL4030_USB if MACH_OMAP_3430SDP
        select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
+       select USB_GADGET_DUALSPEED
        tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        help
          Say Y here if your system has a dual role high speed USB
@@ -60,7 +61,7 @@ config USB_MUSB_BLACKFIN
 
 config USB_MUSB_UX500
        tristate "U8500 and U5500"
-       depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500)
+       depends on (ARCH_U8500 && AB8500_USB)
 
 endchoice
 
index 08f1d0b662a37b64558e70777bf13f609da1bb47..e233d2b7d335713a3af128258f8634014aa3c5fe 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
index 4da7492ddbdba25768f4acbce91c1802195f48da..2613bfdb09b65da2ecb274edbf160b237bfde066 100644 (file)
@@ -27,6 +27,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
index 20a28731c338e8aa9dbf2bac295ce8ddda426e3a..b63ab1570103f2219afc5b44bdea08acd0531054 100644 (file)
@@ -1477,8 +1477,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
-       defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \
-       defined(CONFIG_ARCH_U5500)
+       defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
 
 static irqreturn_t generic_interrupt(int irq, void *__hci)
 {
@@ -2302,18 +2301,12 @@ static int musb_suspend(struct device *dev)
                 */
        }
 
-       musb_save_context(musb);
-
        spin_unlock_irqrestore(&musb->lock, flags);
        return 0;
 }
 
 static int musb_resume_noirq(struct device *dev)
 {
-       struct musb     *musb = dev_to_musb(dev);
-
-       musb_restore_context(musb);
-
        /* for static cmos like DaVinci, register values were preserved
         * unless for some reason the whole soc powered down or the USB
         * module got reset through the PSC (vs just being disabled).
index ae4a20acef6c6e1265f2666d00c09cdee4d19032..922148ff8d2969de64a808046f7ce06c6115ace1 100644 (file)
@@ -1903,7 +1903,7 @@ static int musb_gadget_start(struct usb_gadget *g,
        unsigned long           flags;
        int                     retval = -EINVAL;
 
-       if (driver->speed != USB_SPEED_HIGH)
+       if (driver->speed < USB_SPEED_HIGH)
                goto err0;
 
        pm_runtime_get_sync(musb->controller);
@@ -1999,10 +1999,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
                                        nuke(&hw_ep->ep_out, -ESHUTDOWN);
                        }
                }
-
-               spin_unlock(&musb->lock);
-               driver->disconnect(&musb->g);
-               spin_lock(&musb->lock);
        }
 }
 
index 52733d9959b4c51b33564d61b0421fb540689030..fb644c107ded74930105d23b70e4e4c2b591f8ea 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
index fb7adeff9ffa42ce39a1290f2d3a18f408165a8c..307c27bc51eb34e62a07dc627dcbcdedd4de2843 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/device.h>
 
 #include <linux/usb/otg.h>
index 770d799d5afb8ec0eadd650dc2c1f348dc7648c5..0b0466728fdc38e63a29a5c5375b712c6347df54 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
index d2e2efaba658c6c20c485e2de2d839b8a926d005..08c679c0dde5ae110a56ec70af33819fdd20cfeb 100644 (file)
@@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
 /*
  *             platform functions
  */
-static int __devinit usbhs_probe(struct platform_device *pdev)
+static int usbhs_probe(struct platform_device *pdev)
 {
        struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;
        struct renesas_usbhs_driver_callback *dfunc;
index 8da685e796d1484cadbb3bcda67a5ee26ac64c44..ffdf5d15085ebbe845dbd54474c8a0e5b9464061 100644 (file)
@@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
        if (len % 4) /* 32bit alignment */
                goto usbhsf_pio_prepare_push;
 
-       if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
+       if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
                goto usbhsf_pio_prepare_push;
 
        /* get enable DMA fifo */
@@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)
        if (!fifo)
                goto usbhsf_pio_prepare_pop;
 
-       if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
+       if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
                goto usbhsf_pio_prepare_pop;
 
        ret = usbhsf_fifo_select(pipe, fifo, 0);
index 8ae3733031cdb8fa17ec146d31e5d42e9eea120a..6c6875533f019096af0518e6c92d9f430c4edc49 100644 (file)
@@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod);
  */
 #if    defined(CONFIG_USB_RENESAS_USBHS_HCD) || \
        defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE)
-extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv);
-extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv);
+extern int usbhs_mod_host_probe(struct usbhs_priv *priv);
+extern int usbhs_mod_host_remove(struct usbhs_priv *priv);
 #else
 static inline int usbhs_mod_host_probe(struct usbhs_priv *priv)
 {
@@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv)
 
 #if    defined(CONFIG_USB_RENESAS_USBHS_UDC) || \
        defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE)
-extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv);
-extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv);
+extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv);
+extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv);
 #else
 static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
index 4cc7ee0babc60441914ac69ca20a2fe1d857c5e6..7f4e803385702499b70e4a40fce377bc28a1e45f 100644 (file)
@@ -751,53 +751,32 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
-       struct usbhs_priv *priv;
-       struct device *dev;
-       int ret;
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
        if (!driver             ||
            !driver->setup      ||
-           driver->speed != USB_SPEED_HIGH)
+           driver->speed < USB_SPEED_FULL)
                return -EINVAL;
 
-       dev  = usbhsg_gpriv_to_dev(gpriv);
-       priv = usbhsg_gpriv_to_priv(gpriv);
-
        /* first hook up the driver ... */
        gpriv->driver = driver;
        gpriv->gadget.dev.driver = &driver->driver;
 
-       ret = device_add(&gpriv->gadget.dev);
-       if (ret) {
-               dev_err(dev, "device_add error %d\n", ret);
-               goto add_fail;
-       }
-
        return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD);
-
-add_fail:
-       gpriv->driver = NULL;
-       gpriv->gadget.dev.driver = NULL;
-
-       return ret;
 }
 
 static int usbhsg_gadget_stop(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
-       struct usbhs_priv *priv;
-       struct device *dev;
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
        if (!driver             ||
            !driver->unbind)
                return -EINVAL;
 
-       dev  = usbhsg_gpriv_to_dev(gpriv);
-       priv = usbhsg_gpriv_to_priv(gpriv);
-
        usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD);
-       device_del(&gpriv->gadget.dev);
+       gpriv->gadget.dev.driver = NULL;
        gpriv->driver = NULL;
 
        return 0;
@@ -827,10 +806,17 @@ static int usbhsg_start(struct usbhs_priv *priv)
 
 static int usbhsg_stop(struct usbhs_priv *priv)
 {
+       struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
+
+       /* cable disconnect */
+       if (gpriv->driver &&
+           gpriv->driver->disconnect)
+               gpriv->driver->disconnect(&gpriv->gadget);
+
        return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
 }
 
-int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
+int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv;
        struct usbhsg_uep *uep;
@@ -876,12 +862,14 @@ int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
        /*
         * init gadget
         */
-       device_initialize(&gpriv->gadget.dev);
        dev_set_name(&gpriv->gadget.dev, "gadget");
        gpriv->gadget.dev.parent        = dev;
        gpriv->gadget.name              = "renesas_usbhs_udc";
        gpriv->gadget.ops               = &usbhsg_gadget_ops;
        gpriv->gadget.is_dualspeed      = 1;
+       ret = device_register(&gpriv->gadget.dev);
+       if (ret < 0)
+               goto err_add_udc;
 
        INIT_LIST_HEAD(&gpriv->gadget.ep_list);
 
@@ -912,12 +900,15 @@ int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 
        ret = usb_add_gadget_udc(dev, &gpriv->gadget);
        if (ret)
-               goto err_add_udc;
+               goto err_register;
 
 
        dev_info(dev, "gadget probed\n");
 
        return 0;
+
+err_register:
+       device_unregister(&gpriv->gadget.dev);
 err_add_udc:
        kfree(gpriv->uep);
 
@@ -927,12 +918,14 @@ usbhs_mod_gadget_probe_err_gpriv:
        return ret;
 }
 
-void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
+void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 
        usb_del_gadget_udc(&gpriv->gadget);
 
+       device_unregister(&gpriv->gadget.dev);
+
        usbhsg_controller_unregister(gpriv);
 
        kfree(gpriv->uep);
index 1a7208a50afc15dc42de21b7bcbf6184ac204ff3..bade761a1e52b783a63dfb462f8b11ef4c111999 100644 (file)
@@ -103,7 +103,7 @@ struct usbhsh_hpriv {
 
        u32     port_stat;      /* USB_PORT_STAT_xxx */
 
-       struct completion       *done;
+       struct completion       setup_ack_done;
 
        /* see usbhsh_req_alloc/free */
        struct list_head        ureq_link_active;
@@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,
 struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
                                        struct usbhsh_device *udev,
                                        struct usb_host_endpoint *ep,
+                                       int dir_in_req,
                                        gfp_t mem_flags)
 {
        struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
@@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
        struct usbhs_pipe *pipe, *best_pipe;
        struct device *dev = usbhsh_hcd_to_dev(hcd);
        struct usb_endpoint_descriptor *desc = &ep->desc;
-       int type, i;
+       int type, i, dir_in;
        unsigned int min_usr;
 
+       dir_in_req = !!dir_in_req;
+
        uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
        if (!uep) {
                dev_err(dev, "usbhsh_ep alloc fail\n");
                return NULL;
        }
-       type = usb_endpoint_type(desc);
+
+       if (usb_endpoint_xfer_control(desc)) {
+               best_pipe = usbhsh_hpriv_to_dcp(hpriv);
+               goto usbhsh_endpoint_alloc_find_pipe;
+       }
 
        /*
         * find best pipe for endpoint
         * see
         *      HARDWARE LIMITATION
         */
+       type = usb_endpoint_type(desc);
        min_usr = ~0;
        best_pipe = NULL;
-       usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
+       usbhs_for_each_pipe(pipe, priv, i) {
                if (!usbhs_pipe_type_is(pipe, type))
                        continue;
 
+               dir_in = !!usbhs_pipe_is_dir_in(pipe);
+               if (0 != (dir_in - dir_in_req))
+                       continue;
+
                info = usbhsh_pipe_info(pipe);
 
                if (min_usr > info->usr_cnt) {
@@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
                kfree(uep);
                return NULL;
        }
-
+usbhsh_endpoint_alloc_find_pipe:
        /*
         * init uep
         */
@@ -423,6 +435,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
         * see
         *  DCPMAXP/PIPEMAXP
         */
+       usbhs_pipe_sequence_data0(uep->pipe);
        usbhs_pipe_config_update(uep->pipe,
                                 usbhsh_device_number(hpriv, udev),
                                 usb_endpoint_num(desc),
@@ -430,7 +443,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
 
        dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
                usbhsh_device_number(hpriv, udev),
-               usbhs_pipe_name(pipe), uep);
+               usbhs_pipe_name(uep->pipe), uep);
 
        return uep;
 }
@@ -549,8 +562,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
         *      usbhsh_irq_setup_ack()
         *      usbhsh_irq_setup_err()
         */
-       DECLARE_COMPLETION(done);
-       hpriv->done = &done;
+       init_completion(&hpriv->setup_ack_done);
 
        /* copy original request */
        memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest));
@@ -572,8 +584,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
        /*
         * wait setup packet ACK
         */
-       wait_for_completion(&done);
-       hpriv->done = NULL;
+       wait_for_completion(&hpriv->setup_ack_done);
 
        dev_dbg(dev, "%s done\n", __func__);
 }
@@ -724,11 +735,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
        struct usbhsh_device *udev, *new_udev = NULL;
        struct usbhs_pipe *pipe;
        struct usbhsh_ep *uep;
+       int is_dir_in = usb_pipein(urb->pipe);
 
        int ret;
 
-       dev_dbg(dev, "%s (%s)\n",
-               __func__, usb_pipein(urb->pipe) ? "in" : "out");
+       dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
 
        ret = usb_hcd_link_urb_to_ep(hcd, urb);
        if (ret)
@@ -751,7 +762,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
         */
        uep = usbhsh_ep_to_uep(ep);
        if (!uep) {
-               uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags);
+               uep = usbhsh_endpoint_alloc(hpriv, udev, ep,
+                                           is_dir_in, mem_flags);
                if (!uep)
                        goto usbhsh_urb_enqueue_error_free_device;
        }
@@ -1095,10 +1107,7 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv,
 
        dev_dbg(dev, "setup packet OK\n");
 
-       if (unlikely(!hpriv->done))
-               dev_err(dev, "setup ack happen without necessary data\n");
-       else
-               complete(hpriv->done); /* see usbhsh_urb_enqueue() */
+       complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
 
        return 0;
 }
@@ -1111,10 +1120,7 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv,
 
        dev_dbg(dev, "setup packet Err\n");
 
-       if (unlikely(!hpriv->done))
-               dev_err(dev, "setup err happen without necessary data\n");
-       else
-               complete(hpriv->done); /* see usbhsh_urb_enqueue() */
+       complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
 
        return 0;
 }
@@ -1221,8 +1227,18 @@ static int usbhsh_stop(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
        struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
+       struct usbhs_mod *mod = usbhs_mod_get_current(priv);
        struct device *dev = usbhs_priv_to_dev(priv);
 
+       /*
+        * disable irq callback
+        */
+       mod->irq_attch  = NULL;
+       mod->irq_dtch   = NULL;
+       mod->irq_sack   = NULL;
+       mod->irq_sign   = NULL;
+       usbhs_irq_callback_update(priv, mod);
+
        usb_remove_hcd(hcd);
 
        /* disable sys */
@@ -1235,7 +1251,7 @@ static int usbhsh_stop(struct usbhs_priv *priv)
        return 0;
 }
 
-int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
+int usbhs_mod_host_probe(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv;
        struct usb_hcd *hcd;
@@ -1279,7 +1295,6 @@ int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
        hpriv->mod.stop         = usbhsh_stop;
        hpriv->pipe_info        = pipe_info;
        hpriv->pipe_size        = pipe_size;
-       hpriv->done             = NULL;
        usbhsh_req_list_init(hpriv);
        usbhsh_port_stat_init(hpriv);
 
@@ -1299,7 +1314,7 @@ usbhs_mod_host_probe_err:
        return -ENOMEM;
 }
 
-int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv)
+int usbhs_mod_host_remove(struct usbhs_priv *priv)
 {
        struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
        struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
index aba201cb872c44af5ba253484b73d07668aa098d..b43d07df4c44ac3c38d0b31997389669a6943613 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/unaligned.h>
 #include <linux/tty.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/tty_flip.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
index 5cdb9d912275193bd7f5a8929742c4199a45c5c4..18e875b92e001d1c290f2b95e498eea77c6b72cb 100644 (file)
@@ -42,7 +42,7 @@ static int debug;
  * Version information
  */
 
-#define DRIVER_VERSION "v0.6"
+#define DRIVER_VERSION "v0.7"
 #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
 #define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
 #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
@@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
                goto err_out;
        }
 
-       /* setup termios */
-       if (tty)
-               ark3116_set_termios(tty, port, NULL);
-
        /* remove any data still left: also clears error state */
        ark3116_read_reg(serial, UART_RX, buf);
 
@@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
        /* enable DMA */
        ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
 
+       /* setup termios */
+       if (tty)
+               ark3116_set_termios(tty, port, NULL);
+
 err_out:
        kfree(buf);
        return result;
index 8fe034d2d3e7b1bf1c4b0471a1bfaff96ab218a7..ff3db5d056a56484fe594039f5817ac7d6ec4024 100644 (file)
@@ -736,6 +736,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
        { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
@@ -2104,13 +2105,19 @@ static void ftdi_set_termios(struct tty_struct *tty,
 
        cflag = termios->c_cflag;
 
-       /* FIXME -For this cut I don't care if the line is really changing or
-          not  - so just do the change regardless  - should be able to
-          compare old_termios and tty->termios */
+       if (old_termios->c_cflag == termios->c_cflag
+           && old_termios->c_ispeed == termios->c_ispeed
+           && old_termios->c_ospeed == termios->c_ospeed)
+               goto no_c_cflag_changes;
+
        /* NOTE These routines can get interrupted by
           ftdi_sio_read_bulk_callback  - need to examine what this means -
           don't see any problems yet */
 
+       if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
+           (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
+               goto no_data_parity_stop_changes;
+
        /* Set number of data bits, parity, stop bits */
 
        urb_value = 0;
@@ -2151,6 +2158,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
        }
 
        /* Now do the baudrate */
+no_data_parity_stop_changes:
        if ((cflag & CBAUD) == B0) {
                /* Disable flow control */
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2178,6 +2186,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
 
        /* Set flow control */
        /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
+no_c_cflag_changes:
        if (cflag & CRTSCTS) {
                dbg("%s Setting to CRTSCTS flow control", __func__);
                if (usb_control_msg(dev,
index 571fa96b49c7749b983c8d4a8f8228f3500f975c..055b64ef0bbad7ad6dd20200860c6874dd120f1e 100644 (file)
 
 /* Propox devices */
 #define FTDI_PROPOX_JTAGCABLEII_PID    0xD738
+#define FTDI_PROPOX_ISPCABLEIII_PID    0xD739
 
 /* Lenz LI-USB Computer Interface. */
 #define FTDI_LENZ_LIUSB_PID    0xD780
index 89ae1f65e1b18bc46d8b8ccc0004cd94edb4ee40..e3426602dc8274dc5536f26e80f74a481eeaacd3 100644 (file)
@@ -156,6 +156,7 @@ static void option_instat_callback(struct urb *urb);
 #define HUAWEI_PRODUCT_K4511                   0x14CC
 #define HUAWEI_PRODUCT_ETS1220                 0x1803
 #define HUAWEI_PRODUCT_E353                    0x1506
+#define HUAWEI_PRODUCT_E173S                   0x1C05
 
 #define QUANTA_VENDOR_ID                       0x0408
 #define QUANTA_PRODUCT_Q101                    0xEA02
@@ -316,6 +317,9 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_AC8710                     0xfff1
 #define ZTE_PRODUCT_AC2726                     0xfff5
 #define ZTE_PRODUCT_AC8710T                    0xffff
+#define ZTE_PRODUCT_MC2718                     0xffe8
+#define ZTE_PRODUCT_AD3812                     0xffeb
+#define ZTE_PRODUCT_MC2716                     0xffed
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -468,6 +472,10 @@ static void option_instat_callback(struct urb *urb);
 #define YUGA_PRODUCT_CLU528                    0x260D
 #define YUGA_PRODUCT_CLU526                    0x260F
 
+/* Viettel products */
+#define VIETTEL_VENDOR_ID                      0x2262
+#define VIETTEL_PRODUCT_VT1000                 0x0002
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -500,6 +508,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
        .reserved = BIT(4),
 };
 
+static const struct option_blacklist_info zte_ad3812_z_blacklist = {
+       .sendsetup = BIT(0) | BIT(1) | BIT(2),
+};
+
+static const struct option_blacklist_info zte_mc2718_z_blacklist = {
+       .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
+};
+
+static const struct option_blacklist_info zte_mc2716_z_blacklist = {
+       .sendsetup = BIT(1) | BIT(2) | BIT(3),
+};
+
 static const struct option_blacklist_info huawei_cdc12_blacklist = {
        .reserved = BIT(1) | BIT(2),
 };
@@ -622,6 +642,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
@@ -640,6 +661,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
@@ -726,6 +750,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
@@ -1043,6 +1068,12 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
+        .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
        { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
@@ -1141,6 +1172,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
        { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
+       { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 9083d1e616b4b48c30661ecd4261dfff3c127c14..fc2d66f7f4eb0ce3410a066e3877155651398eff 100644 (file)
@@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
        { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
        { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
-       { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
        { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
index 3d10d7f02072d10250f80802b7130fb941fb6793..c38b8c00c06fddd4c71f3508df13f592d2b4480b 100644 (file)
 #define ADLINK_VENDOR_ID               0x0b63
 #define ADLINK_ND6530_PRODUCT_ID       0x6530
 
-/* WinChipHead USB->RS 232 adapter */
-#define WINCHIPHEAD_VENDOR_ID          0x4348
-#define WINCHIPHEAD_USBSER_PRODUCT_ID  0x5523
-
 /* SMART USB Serial Adapter */
 #define SMART_VENDOR_ID        0x0b8c
 #define SMART_PRODUCT_ID       0x2303
index b9bb24729c99e43dd40cfa4af6ae95b9ac4f8385..aa9367f5b42143b0db23035a879355448a605528 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/slab.h>
index 4dca3ef0668c9963448289c3ab1160633865a6b9..9fbe742343c6cb6d023706bd7d5bd8170191d49e 100644 (file)
@@ -1762,10 +1762,9 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb)
                result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
        } else {
                void *buf;
-               int offset;
+               int offset = 0;
                u16 PhyBlockAddr;
                u8 PageNum;
-               u32 result;
                u16 len, oldphy, newphy;
 
                buf = kmalloc(blenByte, GFP_KERNEL);
index 89460181d122759ba00ff064b49b2ff3c8b28268..e0f76bb05915cb63647a5470c71714c61e0a52ce 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/usb.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "usb.h"
 #include "transport.h"
index fc310f75eada97c0c64da9d5886882eef9631dbf..82dd834709c78f7627b82a53d5e268fb006744a2 100644 (file)
@@ -43,6 +43,7 @@
  */
 
 #include <linux/highmem.h>
+#include <linux/export.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 
@@ -58,7 +59,9 @@
 
 void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
 {
-       /* Pad the SCSI command with zeros out to 12 bytes
+       /*
+        * Pad the SCSI command with zeros out to 12 bytes.  If the
+        * command already is 12 bytes or longer, leave it alone.
         *
         * NOTE: This only works because a scsi_cmnd struct field contains
         * a unsigned char cmnd[16], so we know we have storage available
@@ -66,9 +69,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
        for (; srb->cmd_len<12; srb->cmd_len++)
                srb->cmnd[srb->cmd_len] = 0;
 
-       /* set command length to 12 bytes */
-       srb->cmd_len = 12;
-
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
 }
index 1deca07c82658e79a492fd49fa3f94004ccb7923..37539c89e3ba0cf3ab0fa9a8b43dcd073e05acee 100644 (file)
@@ -3,6 +3,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <linux/usb.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "usb.h"
index ff32390d61e5d489314b72bec6ff3e3d178b5b01..0e5c91c6187f1a8f45d3a873f05507c09ab795da 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/sched.h>
 #include <linux/gfp.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 
 #include <linux/usb/quirks.h>
 
index 23f0dd9c36d4df92fe08b88dd679f65194dbf135..1d10d5b8204c641289a0150649ea7bf694c53ae2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/storage.h>
 
index 3041a974faf39278ef8fad4033e089f8e64b7b9c..24caba79d722a74fd2dba94f9560a7168e4bb26c 100644 (file)
@@ -1854,6 +1854,13 @@ UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Qinglin Ye <yestyle@gmail.com> */
+UNUSUAL_DEV(  0x13fe, 0x3600, 0x0100, 0x0100,
+               "Kingston",
+               "DT 101 G2",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BULK_IGNORE_TAG ),
+
 /* Reported by Francesco Foresti <frafore@tiscali.it> */
 UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                "Super Top",
index 7ec24e46b34bef5269b220b71b8382eaa9140c16..231009af65a3a05712dfd34d8484a7b0a02da18e 100644 (file)
@@ -90,6 +90,7 @@
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/export.h>
 #include "wusbhc.h"
 
 static void wusbhc_devconnect_acked_work(struct work_struct *work);
index 0a57ff0a0b0c6df4b802f5ff5316ceb77ae7a2a1..b8c72583c0405f6d2cac23ea5884b14bc2427672 100644 (file)
@@ -38,6 +38,7 @@
  */
 #include <linux/usb/wusb.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "wusbhc.h"
 
 /* Initialize the MMCIEs handling mechanism */
index 39de3900ad20df04dc821e58f0db676c27bbe5be..59ff254dfb6fc294108824da98cf36b2883f753f 100644 (file)
@@ -70,6 +70,7 @@
  * wusbhc_rh_start_port_reset() ??? unimplemented
  */
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "wusbhc.h"
 
 /*
index b60799b811c144e5513e9e201f2f6fb38b5a709b..371f61733f0538e9cda6d0be0d919727fc28e08a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/usb/ch9.h>
 #include <linux/random.h>
+#include <linux/export.h>
 #include "wusbhc.h"
 
 static void wusbhc_set_gtk_callback(struct urb *urb);
index 0d1863c9eddefedcd34fc19daa2ee45bc1dde82a..9e4a924616884d7152497bb465e67c1c2167b2bb 100644 (file)
@@ -23,6 +23,7 @@
  * FIXME: docs
  */
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "wusbhc.h"
 #include "wa-hc.h"
 
index 2acc7f504c516e60459bcba34a25907180996fbf..f0d546c5a089d3513f037b2eb4c63c841fff8cb5 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/atomic.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "wusbhc.h"
 #include "wa-hc.h"
index 419334568be6806eacece838fd37e1168c9a1606..57c01ab09ad85209cedc966e90a3be2d94cb90f7 100644 (file)
@@ -84,6 +84,7 @@
 #include <linux/slab.h>
 #include <linux/hash.h>
 #include <linux/ratelimit.h>
+#include <linux/export.h>
 
 #include "wa-hc.h"
 #include "wusbhc.h"
index a2eaa3c33b0b2b90a870bf775aeb274213eacc47..de81ebf51784d086085e12f869dac022946caf0f 100644 (file)
@@ -41,6 +41,7 @@
  */
 #include <linux/spinlock.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index da7b1d08003c6a222f1cb07d44c2c4716ef65bda..b08d1c2ee3fa6990d7ef04909c003fd4cb5dfff3 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/uwb.h>
 #include <linux/random.h>
+#include <linux/export.h>
 
 /*
  * i1480_rceb_check - Check RCEB for expected field values
index 30acec740425e48ea48c1e11d32028bbd837d710..902b0f2f961ef9b1e3c7b00b928a4509c86c990e 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "uwb-internal.h"
 
 /**
index 90113bafefca8dafbd4aa210fc2ef81887238cae..5241f1d0ef7a3d3b3bb878a1729c6f93b98144c1 100644 (file)
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/kdev_t.h>
 #include <linux/random.h>
+#include <linux/stat.h>
 #include "uwb-internal.h"
 
 /* We initialize addresses to 0xff (invalid, as it is bcast) */
index b4395f41a00743768bc4c44a66dddf1e29ec5df6..4d688c7508012b2f54629dfd8545059589c7d03f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/etherdevice.h>
 #include <linux/usb.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index 697e56a5bcdd0c7e4233774ce2670b70ae8a9373..a269937be1b8230898f991eb5f430e3f79ac9824 100644 (file)
@@ -85,6 +85,7 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index 99a19c199095fd817ceb519922389a6a424abba9..8ee7d90a8c68ac04b97f82a99f1097a114087e01 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 #include <linux/uwb.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index f0d55495f5e983190eac44bd95b2b08e4e9a38c7..d58dfecf9a7981950477a5f9995109c0764f932a 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/uwb.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index 3de630b0f6913510233113b8e52f30889e494cf1..703228559e89fcff0b849df2ec724335c4c655e0 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index 78c892233cf1d9acb2eac33e87b5e41f8a3bb79e..0b0d8bce842e0313889048644021fec1195870fc 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/uwb.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/export.h>
 
 #include "uwb-internal.h"
 
index 367aa12786b9b25e3f14430724b1a8366ad71898..cbb6a5e703d255002450442ecf32cd83a4008952 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include "uwb-internal.h"
 
 
index 5fad4e791b3ed348da0ae2b93ab4b4cd8e2f16b3..82a84d53120f27f2a1734fcef5ab5774d5fbc0a3 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
 #include <linux/workqueue.h>
+#include <linux/module.h>
 #include <linux/uwb/umc.h>
 #include <linux/pci.h>
 
index b2948ec578784b30f2a6fd740fb098196876af7a..4613c13cd8511e8d6036c256a8789e831dfda13c 100644 (file)
@@ -6,6 +6,7 @@
  * This file is released under the GNU GPL v2.
  */
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/uwb/umc.h>
 
index 367b5eb85d607db8aec9e2a92ca3db565040b74d..26d0ae1816bdd08fc34b86d89ea0ffe3b799946d 100644 (file)
@@ -6,6 +6,7 @@
  * This file is released under the GNU GPL v2.
  */
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/uwb/umc.h>
 
 int __umc_driver_register(struct umc_driver *umc_drv, struct module *module,
index b221142446a29d5690d332628389cd763856fa32..f48093e649e4203ecb9408406b44e42f936e9ff2 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/delay.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
index 4ac48d9ee66584a797393fd5e836ee82a5024957..63409c122ae804ec9fea9dd684cfac1b516a32ef 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/backlight.h>
 #include <linux/gfp.h>
+#include <linux/module.h>
 
 #include <mach/board.h>
 #include <mach/cpu.h>
index c04b94da81f7544ff776507fd809ae09a6a98365..1105fa1ed7f4a47faf5e26e0796588d4dcaef585 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/backlight.h>
 #include <linux/mfd/88pm860x.h>
+#include <linux/module.h>
 
 #define MAX_BRIGHTNESS         (0xFF)
 #define MIN_BRIGHTNESS         (0)
index d1aee730d7d80e7dd674dce346e27c812cc3e8d3..dfb763e9147ff923676e9ff2778116e3677f61ea 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/backlight.h>
 #include <linux/mfd/adp5520.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct adp5520_bl {
        struct device *master;
index 9f0a491e2a05adeefd802e9fb05c0076946e869b..7838a23fbdd124fb8c2b639092708a35892f8bb9 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/wait.h>
+#include <linux/module.h>
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
index 62043f12a5a4845d35ee4d338693ed23193c7d36..d68f14bbb687d8391b60f72f8949c3d2c396fbcf 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/backlight.h>
 #include <linux/mfd/da903x.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define DA9030_WLED_CONTROL    0x25
 #define DA9030_WLED_CP_EN      (1 << 6)
index b0582917f0c8f71e879ed1be66e84897fb00ca38..c74a6f4baa127a313ea8eea5bf16adde62856b2a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
index 3543f1b7d5f1cbcd42e0393d9791588196fba247..4f5d1c4cb6aba0a53c7bb75c2605bf9c000241f3 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/lcd.h>
 #include <linux/slab.h>
index 5934655eb1ffa8480558353cea82eea66113521a..da9a5ce0ccb8463dcb85b18c708738b483383352 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/lcd.h>
 #include <linux/backlight.h>
+#include <linux/module.h>
 
 #include "ld9040_gamma.h"
 
index 5d3cf33953ac299cd759fb19bfd5a1d53205cc0b..4ec78cfe26eaf160f8c5746e019da9cd68327127 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/spi/spi.h>
 #include <linux/spi/lms283gf05.h>
+#include <linux/module.h>
 
 struct lms283gf05_state {
        struct spi_device       *spi;
index 07e8e273ced0b98898e0509dcc1de30424142eda..7bbc802560ea0473229e74ce89b2da299e140fce 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/backlight.h>
 #include <linux/mfd/max8925.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define MAX_BRIGHTNESS         (0xff)
 #define MIN_BRIGHTNESS         (0)
index 694e5aab0d69b5ff5a66ba6f102d609bd70828a9..e132157d8545e8dfc1c9a189c0d75b545ebb61e2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/lcd.h>
 #include <linux/backlight.h>
+#include <linux/module.h>
 
 #include "s6e63m0_gamma.h"
 
index d4c6eb248ff997893499a13dd2d824fe4abebabc..fbe9e9316f3b51a09e5de299a9a544d878bf5b33 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
 #include <linux/slab.h>
index cb09aa1fa138618c13278de877d5ecfb9b845582..2c76fdf23f2ac5347989e1783beed7789872aac0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "carminefb.h"
 #include "carminefb_regs.h"
index e02764319ff77e3590b04ec0297651b5672e6258..f56699d8122a381047bdcb345d44e1cabbb4414f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/uaccess.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 
 /*
  * Cursor position address
index 55f91d9ab00bd18bd01df877eab846a310595956..29577bf1f559070044ee2c9f50d300d86745f78e 100644 (file)
 /* Clock registers available only on Version 2 */
 #define  LCD_CLK_ENABLE_REG                    0x6c
 #define  LCD_CLK_RESET_REG                     0x70
+#define  LCD_CLK_MAIN_RESET                    BIT(3)
 
 #define LCD_NUM_BUFFERS        2
 
@@ -244,6 +245,10 @@ static inline void lcd_enable_raster(void)
 {
        u32 reg;
 
+       /* Bring LCDC out of reset */
+       if (lcd_revision == LCD_VERSION_2)
+               lcdc_write(0, LCD_CLK_RESET_REG);
+
        reg = lcdc_read(LCD_RASTER_CTRL_REG);
        if (!(reg & LCD_RASTER_ENABLE))
                lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
@@ -257,6 +262,10 @@ static inline void lcd_disable_raster(void)
        reg = lcdc_read(LCD_RASTER_CTRL_REG);
        if (reg & LCD_RASTER_ENABLE)
                lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
+
+       if (lcd_revision == LCD_VERSION_2)
+               /* Write 1 to reset LCDC */
+               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
 }
 
 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -584,8 +593,12 @@ static void lcd_reset(struct da8xx_fb_par *par)
        lcdc_write(0, LCD_DMA_CTRL_REG);
        lcdc_write(0, LCD_RASTER_CTRL_REG);
 
-       if (lcd_revision == LCD_VERSION_2)
+       if (lcd_revision == LCD_VERSION_2) {
                lcdc_write(0, LCD_INT_ENABLE_SET_REG);
+               /* Write 1 to reset */
+               lcdc_write(LCD_CLK_MAIN_RESET, LCD_CLK_RESET_REG);
+               lcdc_write(0, LCD_CLK_RESET_REG);
+       }
 }
 
 static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
index 40e5f17d1e4bda1ccdb59ac156a8b02b41d91cbd..2e830ec52a5a91664527c32b3108a521e4c6c1c5 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
index 4a874c8d039c2867246d6e58c749b9d6f8170dbf..2b106f046fdee80b3b49ba43977bfa7ce09697f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * driver/vide/fb_ddc.c - DDC/EDID read support.
+ * drivers/video/fb_ddc.c - DDC/EDID read support.
  *
  *  Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
  *
@@ -10,6 +10,7 @@
 
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/fb.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/slab.h>
index 8c020389e4fa96c31e07b8cf5c45af5f41e8136e..74c2da5288848a99a410958c6bca1a7922d3dbd0 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <linux/fb.h>
 #include <linux/notifier.h>
+#include <linux/export.h>
 
 static BLOCKING_NOTIFIER_HEAD(fb_notifier_list);
 
index 934081d2b7ae7f199e7631e98a46025bb2e0e5c2..273769bb8debce1e53704ae4c864e6d221a583a6 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include "mb862xxfb.h"
 #include "mb862xx_reg.h"
index c16ff1d62e9183edb9098a40a9f17d7ecaa975af..11a7a333701d3abc7da2aa57573344dc0576645c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
index b9344772bac9bb4422e192bed355eab65ca685a9..cb2ddf164c98cfb527181d46de66e489102c4a1f 100644 (file)
@@ -28,6 +28,7 @@
 #include <mach/msm_iomap.h>
 #include <mach/msm_fb.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 
 #include "mdp_hw.h"
 
index 0ccd7adf47bb2db54312287fb5191ac8ed4b2b94..6f61e781f15afa94ae4ebbca32b57407b648a47a 100644 (file)
@@ -19,6 +19,7 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
index 90e3bdd1b7ab933de67123ec0deca8650bd9f114..eb381db7fe519dcd449f919515cc2a9513d8c969 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
+#include <linux/module.h>
 
 #include <plat/lcd_mipid.h>
 
index b3ddd743d8a6f59e5b7154ff1a6233202440b43d..25d8e51031937c98ae5c05597f660d0cad363d98 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <plat/dma.h>
 
index 6892cfd2e3b7043755441165c8554245cb425a6d..5c81533eacaa6224c3aed27d0c1e72a60616c3d7 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
@@ -1719,12 +1720,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
        unsigned long fclk = 0;
 
-       if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
-               if (width != out_width || height != out_height)
-                       return -EINVAL;
-               else
-                       return 0;
-       }
+       if (width == out_width && height == out_height)
+               return 0;
+
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
+               return -EINVAL;
 
        if (out_width < width / maxdownscale ||
                        out_width > width * 8)
index 483888a85cfdbb78d5101193f67d171cc21ca451..976ac23dcd0cc3e25f3b400d62e20899911b966d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
index 43c04a9889c46214819781126d841e38bf004e62..5abf8e7e74565fb1f70794dd21b7be9d65c97dc4 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/semaphore.h>
 #include <linux/seq_file.h>
 #include <linux/platform_device.h>
index 3e09726d32c7ae1f5a86e51830191a09d7574955..17033457ee89baa2e557b4dbd0d53215977ee6ce 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
index 3262f0f1fa35f395aec7637dc4e61f4fdf5766b1..c56378c555b0907255048e32384c1b5b191bc14f 100644 (file)
@@ -269,7 +269,7 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
 unsigned long hdmi_get_pixel_clock(void)
 {
        /* HDMI Pixel Clock in Mhz */
-       return hdmi.ip_data.cfg.timings.timings.pixel_clock * 10000;
+       return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000;
 }
 
 static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
index 1bd3703e42ffef0c7e8368564a0c2f97007023fc..1130c608a5619637b33a8b85e140031f3ae4a2e8 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <linux/vmalloc.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index 695dc04cabbae4a5ec42acda1dbf35850cb2d078..40305ad7841e26971ca8e88035af7385a85ce260 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/regulator/consumer.h>
+#include <linux/export.h>
 
 #include <video/omapdss.h>
 #include "dss.h"
index 6b1ac23dbbd36910f5185bf78cc0f4357bb60c08..df7bcce5b107d82dcbc46803cffcade9178cea67 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mm.h>
 #include <linux/omapfb.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 
 #include <video/omapdss.h>
 #include <plat/vrfb.h>
index bbcc055d3bb75a28b15d249b9207f7e8b49104ff..bfefa6234cf0c46fc3f51bdba62461395be88fec 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
+#include <linux/module.h>
 
 #include "savagefb.h"
 
index 24640c8458ab7f6e861c9c39b41c42c5726d7c00..72ee96bc6b3e4ca20f68bef852b0c498c2408cc9 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/module.h>
 
 #include <video/mipi_display.h>
 #include <video/sh_mipi_dsi.h>
index 3a41c013d031678243df462e5c2d60e87c07db44..facffc2549766e3ebefd5b8a13e78721523946eb 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/console.h>
 #include <linux/backlight.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <video/sh_mobile_lcdc.h>
 #include <video/sh_mobile_meram.h>
 #include <linux/atomic.h>
index 69d882cbe7095f0acde27c9e61e12ea3236948d8..c01c1c162726137e19197c112313aa7458a91e0b 100644 (file)
 #define M1200X720_R60_VSP       POSITIVE
 
 /* 1200x900@60 Sync Polarity (DCON) */
-#define M1200X900_R60_HSP       NEGATIVE
-#define M1200X900_R60_VSP       NEGATIVE
+#define M1200X900_R60_HSP       POSITIVE
+#define M1200X900_R60_VSP       POSITIVE
 
 /* 1280x600@60 Sync Polarity (GTF Mode) */
 #define M1280x600_R60_HSP       NEGATIVE
index ab5341814c741af49674ca407f6dea0080776602..d69cfef7c338551cf73524c29a18b99233308158 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/via-core.h>
 #include <linux/via-gpio.h>
+#include <linux/export.h>
 
 /*
  * The ports we know about.  Note that the port-25 gpios are not
index c8be8af0cc6d5331983c814d2f9ad159ee6ee1aa..2375e5bbf572e8c55d0e65d1a94ddca813634ce9 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <video/w100fb.h>
index 3d9162151fd2ab34c734a3cd59142ced8413db4f..4939e0ccc4e5414fafb422c53a8e7ccdb742e136 100644 (file)
@@ -706,6 +706,7 @@ static const struct file_operations fsl_hv_fops = {
        .poll = fsl_hv_poll,
        .read = fsl_hv_read,
        .unlocked_ioctl = fsl_hv_ioctl,
+       .compat_ioctl = fsl_hv_ioctl,
 };
 
 static struct miscdevice fsl_hv_misc_dev = {
index 816ed08e7cf3c504f4ce5377b327964a30daa8e9..1a61939b85fce4f3a1269b7915b1e9c3760efe26 100644 (file)
@@ -37,7 +37,7 @@ config VIRTIO_BALLOON
 
  config VIRTIO_MMIO
        tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       depends on HAS_IOMEM && EXPERIMENTAL
        select VIRTIO
        select VIRTIO_RING
        ---help---
index efb35aa8309abe0397bc8f1c7fd8f88da6ded96d..984c501c258ffa8bc6f7ad1ad14be741494ba5ee 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/virtio.h>
 #include <linux/spinlock.h>
 #include <linux/virtio_config.h>
+#include <linux/module.h>
 
 /* Unique numbering for virtio devices. */
 static unsigned int dev_index;
index e058ace2a4ad4af69b6ec198ad01fbe8f07362f8..94fd738a7741d046c76f53477d2487e94cde97ff 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 struct virtio_balloon
 {
index acc5e43c373eb25c3d24410a70a39392caf551f4..7317dc2ec426e495d54b27a46839e15b429400f2 100644 (file)
@@ -118,7 +118,7 @@ static void vm_finalize_features(struct virtio_device *vdev)
        vring_transport_features(vdev);
 
        for (i = 0; i < ARRAY_SIZE(vdev->features); i++) {
-               writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET);
+               writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SEL);
                writel(vdev->features[i],
                                vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES);
        }
index 79a31e5b4b68143a43a370ee422453ac723b2af6..03d1984bd3635042b6bbe19f9966dfe89068e1ff 100644 (file)
@@ -169,11 +169,29 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
        iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
 }
 
+/* wait for pending irq handlers */
+static void vp_synchronize_vectors(struct virtio_device *vdev)
+{
+       struct virtio_pci_device *vp_dev = to_vp_device(vdev);
+       int i;
+
+       if (vp_dev->intx_enabled)
+               synchronize_irq(vp_dev->pci_dev->irq);
+
+       for (i = 0; i < vp_dev->msix_vectors; ++i)
+               synchronize_irq(vp_dev->msix_entries[i].vector);
+}
+
 static void vp_reset(struct virtio_device *vdev)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        /* 0 status means a reset. */
        iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       /* Flush out the status write, and flush in device writes,
+        * including MSi-X interrupts, if any. */
+       ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS);
+       /* Flush pending VQ/configuration callbacks. */
+       vp_synchronize_vectors(vdev);
 }
 
 /* the notify function used when creating a virt queue */
@@ -594,11 +612,11 @@ static struct virtio_config_ops virtio_pci_config_ops = {
 
 static void virtio_pci_release_dev(struct device *_d)
 {
-       struct virtio_device *dev = container_of(_d, struct virtio_device,
-                                                dev);
-       struct virtio_pci_device *vp_dev = to_vp_device(dev);
-
-       kfree(vp_dev);
+       /*
+        * No need for a release method as we allocate/free
+        * all devices together with the pci devices.
+        * Provide an empty one to avoid getting a warning from core.
+        */
 }
 
 /* the PCI probing function */
@@ -686,6 +704,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
        pci_iounmap(pci_dev, vp_dev->ioaddr);
        pci_release_regions(pci_dev);
        pci_disable_device(pci_dev);
+       kfree(vp_dev);
 }
 
 #ifdef CONFIG_PM
index 4acf88884f9b2ee6517c70b619be7524ab026b06..c7a2c208f6eaded137c1f0d9ea73ea0a14100e65 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/virtio_config.h>
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 /* virtio guest is communicating with a virtual "device" that actually runs on
  * a host processor.  Memory barriers are used to control SMP effects. */
index 63359797c8b199abcf62d09122f37981bca7cc41..e9309778ee72c84e72581b5e3ae54c88816cbb64 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/sched.h>       /* schedule_timeout() */
 #include <linux/delay.h>
+#include <linux/export.h>
 
 #include "w1_family.h"
 #include "w1.h"
index f79e62e54e8d25bf21b6bba2850ae9b4b9e6c184..68288355727a13377d97652727c97d448431b0b2 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 
 #include "w1.h"
 #include "w1_log.h"
index 64c6752ea2c66bfb57a5adf59ed20465eb43ad10..79fd606b7cd5cad60f487120db2e3ebf408ddedb 100644 (file)
@@ -66,6 +66,7 @@ config SOFT_WATCHDOG
 config WM831X_WATCHDOG
        tristate "WM831x watchdog"
        depends on MFD_WM831X
+       select WATCHDOG_CORE
        help
          Support for the watchdog in the WM831x AudioPlus PMICs.  When
          the watchdog triggers the system will be reset.
@@ -170,6 +171,7 @@ config HAVE_S3C2410_WATCHDOG
 config S3C2410_WATCHDOG
        tristate "S3C2410 Watchdog"
        depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG
+       select WATCHDOG_CORE
        help
          Watchdog timer block in the Samsung SoCs. This will reboot
          the system when the timer expires with the watchdog enabled.
@@ -312,13 +314,6 @@ config NUC900_WATCHDOG
          To compile this driver as a module, choose M here: the
          module will be called nuc900_wdt.
 
-config ADX_WATCHDOG
-       tristate "Avionic Design Xanthos watchdog"
-       depends on ARCH_PXA_ADX
-       help
-         Say Y here if you want support for the watchdog timer on Avionic
-         Design Xanthos boards.
-
 config TS72XX_WATCHDOG
        tristate "TS-72XX SBC Watchdog"
        depends on MACH_TS72XX
index 55bd5740e91000f1616da7ad0a4adf5eb4c33ac7..fe893e91935b6652e680b3b722ab3bb7b71bf3b3 100644 (file)
@@ -51,7 +51,6 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
 obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
 obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
-obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
 obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
 obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
 
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c
deleted file mode 100644 (file)
index af6e6b1..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Avionic Design GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/fs.h>
-#include <linux/gfp.h>
-#include <linux/io.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/watchdog.h>
-
-#define WATCHDOG_NAME "adx-wdt"
-
-/* register offsets */
-#define        ADX_WDT_CONTROL         0x00
-#define        ADX_WDT_CONTROL_ENABLE  (1 << 0)
-#define        ADX_WDT_CONTROL_nRESET  (1 << 1)
-#define        ADX_WDT_TIMEOUT         0x08
-
-static struct platform_device *adx_wdt_dev;
-static unsigned long driver_open;
-
-#define        WDT_STATE_STOP  0
-#define        WDT_STATE_START 1
-
-struct adx_wdt {
-       void __iomem *base;
-       unsigned long timeout;
-       unsigned int state;
-       unsigned int wake;
-       spinlock_t lock;
-};
-
-static const struct watchdog_info adx_wdt_info = {
-       .identity = "Avionic Design Xanthos Watchdog",
-       .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
-};
-
-static void adx_wdt_start_locked(struct adx_wdt *wdt)
-{
-       u32 ctrl;
-
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl |= ADX_WDT_CONTROL_ENABLE;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-       wdt->state = WDT_STATE_START;
-}
-
-static void adx_wdt_start(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       adx_wdt_start_locked(wdt);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_stop_locked(struct adx_wdt *wdt)
-{
-       u32 ctrl;
-
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl &= ~ADX_WDT_CONTROL_ENABLE;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-       wdt->state = WDT_STATE_STOP;
-}
-
-static void adx_wdt_stop(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       adx_wdt_stop_locked(wdt);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds)
-{
-       unsigned long timeout = seconds * 1000;
-       unsigned long flags;
-       unsigned int state;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       state = wdt->state;
-       adx_wdt_stop_locked(wdt);
-       writel(timeout, wdt->base + ADX_WDT_TIMEOUT);
-
-       if (state == WDT_STATE_START)
-               adx_wdt_start_locked(wdt);
-
-       wdt->timeout = timeout;
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds)
-{
-       *seconds = wdt->timeout / 1000;
-}
-
-static void adx_wdt_keepalive(struct adx_wdt *wdt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&wdt->lock, flags);
-       writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT);
-       spin_unlock_irqrestore(&wdt->lock, flags);
-}
-
-static int adx_wdt_open(struct inode *inode, struct file *file)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev);
-
-       if (test_and_set_bit(0, &driver_open))
-               return -EBUSY;
-
-       file->private_data = wdt;
-       adx_wdt_set_timeout(wdt, 30);
-       adx_wdt_start(wdt);
-
-       return nonseekable_open(inode, file);
-}
-
-static int adx_wdt_release(struct inode *inode, struct file *file)
-{
-       struct adx_wdt *wdt = file->private_data;
-
-       adx_wdt_stop(wdt);
-       clear_bit(0, &driver_open);
-
-       return 0;
-}
-
-static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct adx_wdt *wdt = file->private_data;
-       void __user *argp = (void __user *)arg;
-       unsigned long __user *p = argp;
-       unsigned long seconds = 0;
-       unsigned int options;
-       long ret = -EINVAL;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info)))
-                       return -EFAULT;
-               else
-                       return 0;
-
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               return put_user(0, p);
-
-       case WDIOC_KEEPALIVE:
-               adx_wdt_keepalive(wdt);
-               return 0;
-
-       case WDIOC_SETTIMEOUT:
-               if (get_user(seconds, p))
-                       return -EFAULT;
-
-               adx_wdt_set_timeout(wdt, seconds);
-
-               /* fallthrough */
-       case WDIOC_GETTIMEOUT:
-               adx_wdt_get_timeout(wdt, &seconds);
-               return put_user(seconds, p);
-
-       case WDIOC_SETOPTIONS:
-               if (copy_from_user(&options, argp, sizeof(options)))
-                       return -EFAULT;
-
-               if (options & WDIOS_DISABLECARD) {
-                       adx_wdt_stop(wdt);
-                       ret = 0;
-               }
-
-               if (options & WDIOS_ENABLECARD) {
-                       adx_wdt_start(wdt);
-                       ret = 0;
-               }
-
-               return ret;
-
-       default:
-               break;
-       }
-
-       return -ENOTTY;
-}
-
-static ssize_t adx_wdt_write(struct file *file, const char __user *data,
-               size_t len, loff_t *ppos)
-{
-       struct adx_wdt *wdt = file->private_data;
-
-       if (len)
-               adx_wdt_keepalive(wdt);
-
-       return len;
-}
-
-static const struct file_operations adx_wdt_fops = {
-       .owner = THIS_MODULE,
-       .llseek = no_llseek,
-       .open = adx_wdt_open,
-       .release = adx_wdt_release,
-       .unlocked_ioctl = adx_wdt_ioctl,
-       .write = adx_wdt_write,
-};
-
-static struct miscdevice adx_wdt_miscdev = {
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &adx_wdt_fops,
-};
-
-static int __devinit adx_wdt_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct adx_wdt *wdt;
-       int ret = 0;
-       u32 ctrl;
-
-       wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
-       if (!wdt) {
-               dev_err(&pdev->dev, "cannot allocate WDT structure\n");
-               return -ENOMEM;
-       }
-
-       spin_lock_init(&wdt->lock);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "cannot obtain I/O memory region\n");
-               return -ENXIO;
-       }
-
-       res = devm_request_mem_region(&pdev->dev, res->start,
-                       resource_size(res), res->name);
-       if (!res) {
-               dev_err(&pdev->dev, "cannot request I/O memory region\n");
-               return -ENXIO;
-       }
-
-       wdt->base = devm_ioremap_nocache(&pdev->dev, res->start,
-                       resource_size(res));
-       if (!wdt->base) {
-               dev_err(&pdev->dev, "cannot remap I/O memory region\n");
-               return -ENXIO;
-       }
-
-       /* disable watchdog and reboot on timeout */
-       ctrl = readl(wdt->base + ADX_WDT_CONTROL);
-       ctrl &= ~ADX_WDT_CONTROL_ENABLE;
-       ctrl &= ~ADX_WDT_CONTROL_nRESET;
-       writel(ctrl, wdt->base + ADX_WDT_CONTROL);
-
-       platform_set_drvdata(pdev, wdt);
-       adx_wdt_dev = pdev;
-
-       ret = misc_register(&adx_wdt_miscdev);
-       if (ret) {
-               dev_err(&pdev->dev, "cannot register miscdev on minor %d "
-                               "(err=%d)\n", WATCHDOG_MINOR, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int __devexit adx_wdt_remove(struct platform_device *pdev)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       misc_deregister(&adx_wdt_miscdev);
-       adx_wdt_stop(wdt);
-       platform_set_drvdata(pdev, NULL);
-
-       return 0;
-}
-
-static void adx_wdt_shutdown(struct platform_device *pdev)
-{
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-       adx_wdt_stop(wdt);
-}
-
-#ifdef CONFIG_PM
-static int adx_wdt_suspend(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0;
-       adx_wdt_stop(wdt);
-
-       return 0;
-}
-
-static int adx_wdt_resume(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct adx_wdt *wdt = platform_get_drvdata(pdev);
-
-       if (wdt->wake)
-               adx_wdt_start(wdt);
-
-       return 0;
-}
-
-static const struct dev_pm_ops adx_wdt_pm_ops = {
-       .suspend = adx_wdt_suspend,
-       .resume = adx_wdt_resume,
-};
-
-#  define ADX_WDT_PM_OPS       (&adx_wdt_pm_ops)
-#else
-#  define ADX_WDT_PM_OPS       NULL
-#endif
-
-static struct platform_driver adx_wdt_driver = {
-       .probe = adx_wdt_probe,
-       .remove = __devexit_p(adx_wdt_remove),
-       .shutdown = adx_wdt_shutdown,
-       .driver = {
-               .name = WATCHDOG_NAME,
-               .owner = THIS_MODULE,
-               .pm = ADX_WDT_PM_OPS,
-       },
-};
-
-static int __init adx_wdt_init(void)
-{
-       return platform_driver_register(&adx_wdt_driver);
-}
-
-static void __exit adx_wdt_exit(void)
-{
-       platform_driver_unregister(&adx_wdt_driver);
-}
-
-module_init(adx_wdt_init);
-module_exit(adx_wdt_exit);
-
-MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index 9291506b8b235012fd9825f42bc2c6dad6c26f1b..03f449a430d253ca997f0e84e721748707fb674f 100644 (file)
@@ -429,7 +429,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
        writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR);
 
        irq = platform_get_irq(pdev, 0);
-       if (request_irq(irq, coh901327_interrupt, IRQF_DISABLED,
+       if (request_irq(irq, coh901327_interrupt, 0,
                        DRV_NAME " Bark", pdev)) {
                ret = -EIO;
                goto out_no_irq;
index f1d1da662fbec73262f98e9289884184f67a30d0..41018d429abb14ff80b0309d2b85bd6f53b745af 100644 (file)
@@ -427,7 +427,7 @@ static int __init eurwdt_init(void)
 {
        int ret;
 
-       ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL);
+       ret = request_irq(irq, eurwdt_interrupt, 0, "eurwdt", NULL);
        if (ret) {
                printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
                goto out;
index 751a591684da73fc9a969fbe9717e51e43474cf2..ba6ad662635ae97776cf51c16b5fba482cc8a8c8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     intel TCO Watchdog Driver
  *
- *     (c) Copyright 2006-2010 Wim Van Sebroeck <wim@iguana.be>.
+ *     (c) Copyright 2006-2011 Wim Van Sebroeck <wim@iguana.be>.
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -44,7 +44,7 @@
 
 /* Module and version information */
 #define DRV_NAME       "iTCO_wdt"
-#define DRV_VERSION    "1.06"
+#define DRV_VERSION    "1.07"
 #define PFX            DRV_NAME ": "
 
 /* Includes */
@@ -384,6 +384,11 @@ MODULE_PARM_DESC(nowayout,
        "Watchdog cannot be stopped once started (default="
                                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
+static int turn_SMI_watchdog_clear_off = 0;
+module_param(turn_SMI_watchdog_clear_off, int, 0);
+MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
+       "Turn off SMI clearing watchdog (default=0)");
+
 /*
  * Some TCO specific functions
  */
@@ -808,10 +813,12 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
                ret = -EIO;
                goto out_unmap;
        }
-       /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
-       val32 = inl(SMI_EN);
-       val32 &= 0xffffdfff;    /* Turn off SMI clearing watchdog */
-       outl(val32, SMI_EN);
+       if (turn_SMI_watchdog_clear_off) {
+               /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
+               val32 = inl(SMI_EN);
+               val32 &= 0xffffdfff;    /* Turn off SMI clearing watchdog */
+               outl(val32, SMI_EN);
+       }
 
        /* The TCO I/O registers reside in a 32-byte range pointed to
           by the TCOBASE value */
index 4dc31024d26c409e4b1593ee30ba78f2f50812a6..82ccd36e2c901489aa911c5f2dab68d29729fcfc 100644 (file)
@@ -367,8 +367,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
                goto err_misc;
        }
 
-       ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
-                                                       "mpcore_wdt", wdt);
+       ret = request_irq(wdt->irq, mpcore_wdt_fire, 0, "mpcore_wdt", wdt);
        if (ret) {
                dev_printk(KERN_ERR, wdt->dev,
                        "cannot register IRQ%d for watchdog\n", wdt->irq);
index 945ee8300306c0e322cd69a26180231879f02acc..7c0d8630e64102f52992ec52b5e35f95da82deda 100644 (file)
@@ -402,7 +402,7 @@ static void octeon_wdt_setup_interrupt(int cpu)
        irq = OCTEON_IRQ_WDOG0 + core;
 
        if (request_irq(irq, octeon_wdt_poke_irq,
-                       IRQF_DISABLED, "octeon_wdt", octeon_wdt_poke_irq))
+                       IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq))
                panic("octeon_wdt: Couldn't obtain irq %d", irq);
 
        cpumask_set_cpu(cpu, &irq_enabled_cpus);
index 30da88f47cd350885c58e9704a3c37735ff3323c..a79e3840782ad3f286f0971b4a3cd7f6d5a1ff0b 100644 (file)
@@ -27,9 +27,8 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/timer.h>
-#include <linux/miscdevice.h>
+#include <linux/miscdevice.h> /* for MODULE_ALIAS_MISCDEV */
 #include <linux/watchdog.h>
-#include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
@@ -38,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #include <mach/map.h>
 
@@ -74,14 +74,12 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
                        "0 to reboot (default 0)");
 MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)");
 
-static unsigned long open_lock;
 static struct device    *wdt_dev;      /* platform device attached to */
 static struct resource *wdt_mem;
 static struct resource *wdt_irq;
 static struct clk      *wdt_clock;
 static void __iomem    *wdt_base;
 static unsigned int     wdt_count;
-static char             expect_close;
 static DEFINE_SPINLOCK(wdt_lock);
 
 /* watchdog control routines */
@@ -93,11 +91,13 @@ static DEFINE_SPINLOCK(wdt_lock);
 
 /* functions */
 
-static void s3c2410wdt_keepalive(void)
+static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
 {
        spin_lock(&wdt_lock);
        writel(wdt_count, wdt_base + S3C2410_WTCNT);
        spin_unlock(&wdt_lock);
+
+       return 0;
 }
 
 static void __s3c2410wdt_stop(void)
@@ -109,14 +109,16 @@ static void __s3c2410wdt_stop(void)
        writel(wtcon, wdt_base + S3C2410_WTCON);
 }
 
-static void s3c2410wdt_stop(void)
+static int s3c2410wdt_stop(struct watchdog_device *wdd)
 {
        spin_lock(&wdt_lock);
        __s3c2410wdt_stop();
        spin_unlock(&wdt_lock);
+
+       return 0;
 }
 
-static void s3c2410wdt_start(void)
+static int s3c2410wdt_start(struct watchdog_device *wdd)
 {
        unsigned long wtcon;
 
@@ -142,6 +144,8 @@ static void s3c2410wdt_start(void)
        writel(wdt_count, wdt_base + S3C2410_WTCNT);
        writel(wtcon, wdt_base + S3C2410_WTCON);
        spin_unlock(&wdt_lock);
+
+       return 0;
 }
 
 static inline int s3c2410wdt_is_running(void)
@@ -149,7 +153,7 @@ static inline int s3c2410wdt_is_running(void)
        return readl(wdt_base + S3C2410_WTCON) & S3C2410_WTCON_ENABLE;
 }
 
-static int s3c2410wdt_set_heartbeat(int timeout)
+static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeout)
 {
        unsigned long freq = clk_get_rate(wdt_clock);
        unsigned int count;
@@ -182,8 +186,6 @@ static int s3c2410wdt_set_heartbeat(int timeout)
                }
        }
 
-       tmr_margin = timeout;
-
        DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n",
            __func__, timeout, divisor, count, count/divisor);
 
@@ -201,70 +203,6 @@ static int s3c2410wdt_set_heartbeat(int timeout)
        return 0;
 }
 
-/*
- *     /dev/watchdog handling
- */
-
-static int s3c2410wdt_open(struct inode *inode, struct file *file)
-{
-       if (test_and_set_bit(0, &open_lock))
-               return -EBUSY;
-
-       if (nowayout)
-               __module_get(THIS_MODULE);
-
-       expect_close = 0;
-
-       /* start the timer */
-       s3c2410wdt_start();
-       return nonseekable_open(inode, file);
-}
-
-static int s3c2410wdt_release(struct inode *inode, struct file *file)
-{
-       /*
-        *      Shut off the timer.
-        *      Lock it in if it's a module and we set nowayout
-        */
-
-       if (expect_close == 42)
-               s3c2410wdt_stop();
-       else {
-               dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n");
-               s3c2410wdt_keepalive();
-       }
-       expect_close = 0;
-       clear_bit(0, &open_lock);
-       return 0;
-}
-
-static ssize_t s3c2410wdt_write(struct file *file, const char __user *data,
-                               size_t len, loff_t *ppos)
-{
-       /*
-        *      Refresh the timer.
-        */
-       if (len) {
-               if (!nowayout) {
-                       size_t i;
-
-                       /* In case it was set long ago */
-                       expect_close = 0;
-
-                       for (i = 0; i != len; i++) {
-                               char c;
-
-                               if (get_user(c, data + i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       expect_close = 42;
-                       }
-               }
-               s3c2410wdt_keepalive();
-       }
-       return len;
-}
-
 #define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
 
 static const struct watchdog_info s3c2410_wdt_ident = {
@@ -273,53 +211,17 @@ static const struct watchdog_info s3c2410_wdt_ident = {
        .identity         =     "S3C2410 Watchdog",
 };
 
-
-static long s3c2410wdt_ioctl(struct file *file,        unsigned int cmd,
-                                                       unsigned long arg)
-{
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-       int new_margin;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               return copy_to_user(argp, &s3c2410_wdt_ident,
-                       sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               return put_user(0, p);
-       case WDIOC_KEEPALIVE:
-               s3c2410wdt_keepalive();
-               return 0;
-       case WDIOC_SETTIMEOUT:
-               if (get_user(new_margin, p))
-                       return -EFAULT;
-               if (s3c2410wdt_set_heartbeat(new_margin))
-                       return -EINVAL;
-               s3c2410wdt_keepalive();
-               return put_user(tmr_margin, p);
-       case WDIOC_GETTIMEOUT:
-               return put_user(tmr_margin, p);
-       default:
-               return -ENOTTY;
-       }
-}
-
-/* kernel interface */
-
-static const struct file_operations s3c2410wdt_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = s3c2410wdt_write,
-       .unlocked_ioctl = s3c2410wdt_ioctl,
-       .open           = s3c2410wdt_open,
-       .release        = s3c2410wdt_release,
+static struct watchdog_ops s3c2410wdt_ops = {
+       .owner = THIS_MODULE,
+       .start = s3c2410wdt_start,
+       .stop = s3c2410wdt_stop,
+       .ping = s3c2410wdt_keepalive,
+       .set_timeout = s3c2410wdt_set_heartbeat,
 };
 
-static struct miscdevice s3c2410wdt_miscdev = {
-       .minor          = WATCHDOG_MINOR,
-       .name           = "watchdog",
-       .fops           = &s3c2410wdt_fops,
+static struct watchdog_device s3c2410_wdd = {
+       .info = &s3c2410_wdt_ident,
+       .ops = &s3c2410wdt_ops,
 };
 
 /* interrupt handler code */
@@ -328,7 +230,7 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
 {
        dev_info(wdt_dev, "watchdog timer expired (irq)\n");
 
-       s3c2410wdt_keepalive();
+       s3c2410wdt_keepalive(&s3c2410_wdd);
        return IRQ_HANDLED;
 }
 
@@ -349,14 +251,14 @@ static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
                 * the watchdog is running.
                 */
 
-               s3c2410wdt_keepalive();
+               s3c2410wdt_keepalive(&s3c2410_wdd);
        } else if (val == CPUFREQ_POSTCHANGE) {
-               s3c2410wdt_stop();
+               s3c2410wdt_stop(&s3c2410_wdd);
 
-               ret = s3c2410wdt_set_heartbeat(tmr_margin);
+               ret = s3c2410wdt_set_heartbeat(&s3c2410_wdd, s3c2410_wdd.timeout);
 
                if (ret >= 0)
-                       s3c2410wdt_start();
+                       s3c2410wdt_start(&s3c2410_wdd);
                else
                        goto err;
        }
@@ -365,7 +267,8 @@ done:
        return 0;
 
  err:
-       dev_err(wdt_dev, "cannot set new value for timeout %d\n", tmr_margin);
+       dev_err(wdt_dev, "cannot set new value for timeout %d\n",
+                               s3c2410_wdd.timeout);
        return ret;
 }
 
@@ -396,10 +299,6 @@ static inline void s3c2410wdt_cpufreq_deregister(void)
 }
 #endif
 
-
-
-/* device interface */
-
 static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 {
        struct device *dev;
@@ -466,8 +365,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
        /* see if we can actually set the requested timer margin, and if
         * not, try the default value */
 
-       if (s3c2410wdt_set_heartbeat(tmr_margin)) {
-               started = s3c2410wdt_set_heartbeat(
+       if (s3c2410wdt_set_heartbeat(&s3c2410_wdd, tmr_margin)) {
+               started = s3c2410wdt_set_heartbeat(&s3c2410_wdd,
                                        CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
 
                if (started == 0)
@@ -479,22 +378,21 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
                                                        "cannot start\n");
        }
 
-       ret = misc_register(&s3c2410wdt_miscdev);
+       ret = watchdog_register_device(&s3c2410_wdd);
        if (ret) {
-               dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",
-                       WATCHDOG_MINOR, ret);
+               dev_err(dev, "cannot register watchdog (%d)\n", ret);
                goto err_cpufreq;
        }
 
        if (tmr_atboot && started == 0) {
                dev_info(dev, "starting watchdog timer\n");
-               s3c2410wdt_start();
+               s3c2410wdt_start(&s3c2410_wdd);
        } else if (!tmr_atboot) {
                /* if we're not enabling the watchdog, then ensure it is
                 * disabled if it has been left running from the bootloader
                 * or other source */
 
-               s3c2410wdt_stop();
+               s3c2410wdt_stop(&s3c2410_wdd);
        }
 
        /* print out a statement of readiness */
@@ -503,8 +401,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 
        dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n",
                 (wtcon & S3C2410_WTCON_ENABLE) ?  "" : "in",
-                (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis",
-                (wtcon & S3C2410_WTCON_INTEN) ? "" : "en");
+                (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis",
+                (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis");
 
        return 0;
 
@@ -530,7 +428,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 
 static int __devexit s3c2410wdt_remove(struct platform_device *dev)
 {
-       misc_deregister(&s3c2410wdt_miscdev);
+       watchdog_unregister_device(&s3c2410_wdd);
 
        s3c2410wdt_cpufreq_deregister();
 
@@ -550,7 +448,7 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
 
 static void s3c2410wdt_shutdown(struct platform_device *dev)
 {
-       s3c2410wdt_stop();
+       s3c2410wdt_stop(&s3c2410_wdd);
 }
 
 #ifdef CONFIG_PM
@@ -565,7 +463,7 @@ static int s3c2410wdt_suspend(struct platform_device *dev, pm_message_t state)
        wtdat_save = readl(wdt_base + S3C2410_WTDAT);
 
        /* Note that WTCNT doesn't need to be saved. */
-       s3c2410wdt_stop();
+       s3c2410wdt_stop(&s3c2410_wdd);
 
        return 0;
 }
index f31493e65b380cd63fef6d55132dd96e7af32d63..b01a30e5a66315ef809e5038f27aef4f40782a5a 100644 (file)
@@ -300,7 +300,7 @@ static int __init sbwdog_init(void)
         * get the resources
         */
 
-       ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
+       ret = request_irq(1, sbwdog_interrupt, IRQF_SHARED,
                ident.identity, (void *)user_dog);
        if (ret) {
                printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
@@ -350,7 +350,7 @@ void platform_wd_setup(void)
 {
        int ret;
 
-       ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
+       ret = request_irq(1, sbwdog_interrupt, IRQF_SHARED,
                "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
        if (ret) {
                printk(KERN_CRIT
index 52b63f2f0dac3f2e803af4482ef7b4b1fd4f1c76..b2840409ebc72ca5ba6a6f30dc96bc12b00f7b73 100644 (file)
@@ -398,7 +398,7 @@ static int __init sc520_wdt_init(void)
                                                        WATCHDOG_TIMEOUT);
        }
 
-       wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2);
+       wdtmrctl = ioremap(MMCR_BASE + OFFS_WDTMRCTL, 2);
        if (!wdtmrctl) {
                printk(KERN_ERR PFX "Unable to remap memory\n");
                rc = -ENOMEM;
index b3421fd2cda80760a0015ee2af75ce3d89bcf985..ac2346a452e571468a23db6905e975018d2169a4 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 
 #include <mach/platform.h>
 #include <mach/regs-rtc.h>
index e5c91d4404edfdb244e6a70c3e87edf63b163a63..dd5d675487583254caaf679609b2ca310f5edb7a 100644 (file)
@@ -142,7 +142,7 @@ static void w83627hf_init(void)
        w83627hf_unselect_wd_register();
 }
 
-static void wdt_ctrl(int timeout)
+static void wdt_set_time(int timeout)
 {
        spin_lock(&io_lock);
 
@@ -158,13 +158,13 @@ static void wdt_ctrl(int timeout)
 
 static int wdt_ping(void)
 {
-       wdt_ctrl(timeout);
+       wdt_set_time(timeout);
        return 0;
 }
 
 static int wdt_disable(void)
 {
-       wdt_ctrl(0);
+       wdt_set_time(0);
        return 0;
 }
 
@@ -176,6 +176,24 @@ static int wdt_set_heartbeat(int t)
        return 0;
 }
 
+static int wdt_get_time(void)
+{
+       int timeleft;
+
+       spin_lock(&io_lock);
+
+       w83627hf_select_wd_register();
+
+       outb_p(0xF6, WDT_EFER);    /* Select CRF6 */
+       timeleft = inb_p(WDT_EFDR); /* Read Timeout counter to CRF6 */
+
+       w83627hf_unselect_wd_register();
+
+       spin_unlock(&io_lock);
+
+       return timeleft;
+}
+
 static ssize_t wdt_write(struct file *file, const char __user *buf,
                                                size_t count, loff_t *ppos)
 {
@@ -202,7 +220,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
-       int new_timeout;
+       int timeval;
        static const struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
                                                        WDIOF_MAGICCLOSE,
@@ -238,14 +256,17 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                wdt_ping();
                break;
        case WDIOC_SETTIMEOUT:
-               if (get_user(new_timeout, p))
+               if (get_user(timeval, p))
                        return -EFAULT;
-               if (wdt_set_heartbeat(new_timeout))
+               if (wdt_set_heartbeat(timeval))
                        return -EINVAL;
                wdt_ping();
                /* Fall */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
+       case WDIOC_GETTIMELEFT:
+               timeval = wdt_get_time();
+               return put_user(timeval, p);
        default:
                return -ENOTTY;
        }
index bb03e151a1d01fb34fd6fbed8e413c44f7da677d..d2ef002be96b5f6346b9c5236678a74181330d32 100644 (file)
@@ -612,7 +612,7 @@ static int __init wdt_init(void)
                goto out;
        }
 
-       ret = request_irq(irq, wdt_interrupt, IRQF_DISABLED, "wdt501p", NULL);
+       ret = request_irq(irq, wdt_interrupt, 0, "wdt501p", NULL);
        if (ret) {
                printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq);
                goto outreg;
index 172dad6c7693a1399e53d001e46876662f7ac27b..e0fc3baa91972f03967e5e2843350dab011c76d8 100644 (file)
@@ -643,7 +643,7 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
        irq = dev->irq;
        io = pci_resource_start(dev, 2);
 
-       if (request_irq(irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED,
+       if (request_irq(irq, wdtpci_interrupt, IRQF_SHARED,
                         "wdt_pci", &wdtpci_miscdev)) {
                printk(KERN_ERR PFX "IRQ %d is not free\n", irq);
                goto out_reg;
index 871caea4e1c62d7a868cfb24593d1de7c1f244c2..e789a47db41f4dc1c618efaba3c8e189851c42bb 100644 (file)
@@ -12,8 +12,7 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
 #include <linux/uaccess.h>
@@ -29,19 +28,19 @@ MODULE_PARM_DESC(nowayout,
                 "Watchdog cannot be stopped once started (default="
                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
-static unsigned long wm831x_wdt_users;
-static struct miscdevice wm831x_wdt_miscdev;
-static int wm831x_wdt_expect_close;
-static DEFINE_MUTEX(wdt_mutex);
-static struct wm831x *wm831x;
-static unsigned int update_gpio;
-static unsigned int update_state;
+struct wm831x_wdt_drvdata {
+       struct watchdog_device wdt;
+       struct wm831x *wm831x;
+       struct mutex lock;
+       int update_gpio;
+       int update_state;
+};
 
 /* We can't use the sub-second values here but they're included
  * for completeness.  */
 static struct {
-       int time;  /* Seconds */
-       u16 val;   /* WDOG_TO value */
+       unsigned int time;  /* Seconds */
+       u16 val;            /* WDOG_TO value */
 } wm831x_wdt_cfgs[] = {
        {  1, 2 },
        {  2, 3 },
@@ -52,32 +51,13 @@ static struct {
        { 33, 7 },  /* Actually 32.768s so include both, others round down */
 };
 
-static int wm831x_wdt_set_timeout(struct wm831x *wm831x, u16 value)
-{
-       int ret;
-
-       mutex_lock(&wdt_mutex);
-
-       ret = wm831x_reg_unlock(wm831x);
-       if (ret == 0) {
-               ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
-                                     WM831X_WDOG_TO_MASK, value);
-               wm831x_reg_lock(wm831x);
-       } else {
-               dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
-                       ret);
-       }
-
-       mutex_unlock(&wdt_mutex);
-
-       return ret;
-}
-
-static int wm831x_wdt_start(struct wm831x *wm831x)
+static int wm831x_wdt_start(struct watchdog_device *wdt_dev)
 {
+       struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
+       struct wm831x *wm831x = driver_data->wm831x;
        int ret;
 
-       mutex_lock(&wdt_mutex);
+       mutex_lock(&driver_data->lock);
 
        ret = wm831x_reg_unlock(wm831x);
        if (ret == 0) {
@@ -89,16 +69,18 @@ static int wm831x_wdt_start(struct wm831x *wm831x)
                        ret);
        }
 
-       mutex_unlock(&wdt_mutex);
+       mutex_unlock(&driver_data->lock);
 
        return ret;
 }
 
-static int wm831x_wdt_stop(struct wm831x *wm831x)
+static int wm831x_wdt_stop(struct watchdog_device *wdt_dev)
 {
+       struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
+       struct wm831x *wm831x = driver_data->wm831x;
        int ret;
 
-       mutex_lock(&wdt_mutex);
+       mutex_lock(&driver_data->lock);
 
        ret = wm831x_reg_unlock(wm831x);
        if (ret == 0) {
@@ -110,26 +92,28 @@ static int wm831x_wdt_stop(struct wm831x *wm831x)
                        ret);
        }
 
-       mutex_unlock(&wdt_mutex);
+       mutex_unlock(&driver_data->lock);
 
        return ret;
 }
 
-static int wm831x_wdt_kick(struct wm831x *wm831x)
+static int wm831x_wdt_ping(struct watchdog_device *wdt_dev)
 {
+       struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
+       struct wm831x *wm831x = driver_data->wm831x;
        int ret;
        u16 reg;
 
-       mutex_lock(&wdt_mutex);
+       mutex_lock(&driver_data->lock);
 
-       if (update_gpio) {
-               gpio_set_value_cansleep(update_gpio, update_state);
-               update_state = !update_state;
+       if (driver_data->update_gpio) {
+               gpio_set_value_cansleep(driver_data->update_gpio,
+                                       driver_data->update_state);
+               driver_data->update_state = !driver_data->update_state;
                ret = 0;
                goto out;
        }
 
-
        reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
 
        if (!(reg & WM831X_WDOG_RST_SRC)) {
@@ -150,182 +134,59 @@ static int wm831x_wdt_kick(struct wm831x *wm831x)
        }
 
 out:
-       mutex_unlock(&wdt_mutex);
+       mutex_unlock(&driver_data->lock);
 
        return ret;
 }
 
-static int wm831x_wdt_open(struct inode *inode, struct file *file)
+static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev,
+                                 unsigned int timeout)
 {
-       int ret;
-
-       if (!wm831x)
-               return -ENODEV;
-
-       if (test_and_set_bit(0, &wm831x_wdt_users))
-               return -EBUSY;
+       struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev);
+       struct wm831x *wm831x = driver_data->wm831x;
+       int ret, i;
 
-       ret = wm831x_wdt_start(wm831x);
-       if (ret != 0)
-               return ret;
-
-       return nonseekable_open(inode, file);
-}
+       for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
+               if (wm831x_wdt_cfgs[i].time == timeout)
+                       break;
+       if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
+               return -EINVAL;
 
-static int wm831x_wdt_release(struct inode *inode, struct file *file)
-{
-       if (wm831x_wdt_expect_close)
-               wm831x_wdt_stop(wm831x);
-       else {
-               dev_warn(wm831x->dev, "Watchdog device closed uncleanly\n");
-               wm831x_wdt_kick(wm831x);
+       ret = wm831x_reg_unlock(wm831x);
+       if (ret == 0) {
+               ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
+                                     WM831X_WDOG_TO_MASK,
+                                     wm831x_wdt_cfgs[i].val);
+               wm831x_reg_lock(wm831x);
+       } else {
+               dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
+                       ret);
        }
 
-       clear_bit(0, &wm831x_wdt_users);
-
-       return 0;
-}
-
-static ssize_t wm831x_wdt_write(struct file *file,
-                               const char __user *data, size_t count,
-                               loff_t *ppos)
-{
-       size_t i;
-
-       if (count) {
-               wm831x_wdt_kick(wm831x);
-
-               if (!nowayout) {
-                       /* In case it was set long ago */
-                       wm831x_wdt_expect_close = 0;
-
-                       /* scan to see whether or not we got the magic
-                          character */
-                       for (i = 0; i != count; i++) {
-                               char c;
-                               if (get_user(c, data + i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       wm831x_wdt_expect_close = 42;
-                       }
-               }
-       }
-       return count;
+       return ret;
 }
 
-static const struct watchdog_info ident = {
+static const struct watchdog_info wm831x_wdt_info = {
        .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
        .identity = "WM831x Watchdog",
 };
 
-static long wm831x_wdt_ioctl(struct file *file, unsigned int cmd,
-                            unsigned long arg)
-{
-       int ret = -ENOTTY, time, i;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-       u16 reg;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
-               break;
-
-       case WDIOC_GETSTATUS:
-       case WDIOC_GETBOOTSTATUS:
-               ret = put_user(0, p);
-               break;
-
-       case WDIOC_SETOPTIONS:
-       {
-               int options;
-
-               if (get_user(options, p))
-                       return -EFAULT;
-
-               ret = -EINVAL;
-
-               /* Setting both simultaneously means at least one must fail */
-               if (options == WDIOS_DISABLECARD)
-                       ret = wm831x_wdt_start(wm831x);
-
-               if (options == WDIOS_ENABLECARD)
-                       ret = wm831x_wdt_stop(wm831x);
-               break;
-       }
-
-       case WDIOC_KEEPALIVE:
-               ret = wm831x_wdt_kick(wm831x);
-               break;
-
-       case WDIOC_SETTIMEOUT:
-               ret = get_user(time, p);
-               if (ret)
-                       break;
-
-               if (time == 0) {
-                       if (nowayout)
-                               ret = -EINVAL;
-                       else
-                               wm831x_wdt_stop(wm831x);
-                       break;
-               }
-
-               for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
-                       if (wm831x_wdt_cfgs[i].time == time)
-                               break;
-               if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
-                       ret = -EINVAL;
-               else
-                       ret = wm831x_wdt_set_timeout(wm831x,
-                                                    wm831x_wdt_cfgs[i].val);
-               break;
-
-       case WDIOC_GETTIMEOUT:
-               reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
-               reg &= WM831X_WDOG_TO_MASK;
-               for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
-                       if (wm831x_wdt_cfgs[i].val == reg)
-                               break;
-               if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) {
-                       dev_warn(wm831x->dev,
-                                "Unknown watchdog configuration: %x\n", reg);
-                       ret = -EINVAL;
-               } else
-                       ret = put_user(wm831x_wdt_cfgs[i].time, p);
-
-       }
-
-       return ret;
-}
-
-static const struct file_operations wm831x_wdt_fops = {
+static const struct watchdog_ops wm831x_wdt_ops = {
        .owner = THIS_MODULE,
-       .llseek = no_llseek,
-       .write = wm831x_wdt_write,
-       .unlocked_ioctl = wm831x_wdt_ioctl,
-       .open = wm831x_wdt_open,
-       .release = wm831x_wdt_release,
-};
-
-static struct miscdevice wm831x_wdt_miscdev = {
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &wm831x_wdt_fops,
+       .start = wm831x_wdt_start,
+       .stop = wm831x_wdt_stop,
+       .ping = wm831x_wdt_ping,
+       .set_timeout = wm831x_wdt_set_timeout,
 };
 
 static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
 {
+       struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *chip_pdata;
        struct wm831x_watchdog_pdata *pdata;
-       int reg, ret;
-
-       if (wm831x) {
-               dev_err(&pdev->dev, "wm831x watchdog already registered\n");
-               return -EBUSY;
-       }
-
-       wm831x = dev_get_drvdata(pdev->dev.parent);
+       struct wm831x_wdt_drvdata *driver_data;
+       struct watchdog_device *wm831x_wdt;
+       int reg, ret, i;
 
        ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
        if (ret < 0) {
@@ -338,6 +199,36 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
        if (reg & WM831X_WDOG_DEBUG)
                dev_warn(wm831x->dev, "Watchdog is paused\n");
 
+       driver_data = kzalloc(sizeof(*driver_data), GFP_KERNEL);
+       if (!driver_data) {
+               dev_err(wm831x->dev, "Unable to alloacate watchdog device\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       mutex_init(&driver_data->lock);
+       driver_data->wm831x = wm831x;
+
+       wm831x_wdt = &driver_data->wdt;
+
+       wm831x_wdt->info = &wm831x_wdt_info;
+       wm831x_wdt->ops = &wm831x_wdt_ops;
+       watchdog_set_drvdata(wm831x_wdt, driver_data);
+
+       if (nowayout)
+               wm831x_wdt->status |= WDOG_NO_WAY_OUT;
+
+       reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
+       reg &= WM831X_WDOG_TO_MASK;
+       for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
+               if (wm831x_wdt_cfgs[i].val == reg)
+                       break;
+       if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
+               dev_warn(wm831x->dev,
+                        "Unknown watchdog timeout: %x\n", reg);
+       else
+               wm831x_wdt->timeout = wm831x_wdt_cfgs[i].time;
+
        /* Apply any configuration */
        if (pdev->dev.parent->platform_data) {
                chip_pdata = pdev->dev.parent->platform_data;
@@ -361,7 +252,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
                                dev_err(wm831x->dev,
                                        "Failed to request update GPIO: %d\n",
                                        ret);
-                               goto err;
+                               goto err_alloc;
                        }
 
                        ret = gpio_direction_output(pdata->update_gpio, 0);
@@ -372,7 +263,7 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
                                goto err_gpio;
                        }
 
-                       update_gpio = pdata->update_gpio;
+                       driver_data->update_gpio = pdata->update_gpio;
 
                        /* Make sure the watchdog takes hardware updates */
                        reg |= WM831X_WDOG_RST_SRC;
@@ -389,33 +280,34 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
                }
        }
 
-       wm831x_wdt_miscdev.parent = &pdev->dev;
-
-       ret = misc_register(&wm831x_wdt_miscdev);
+       ret = watchdog_register_device(&driver_data->wdt);
        if (ret != 0) {
-               dev_err(wm831x->dev, "Failed to register miscdev: %d\n", ret);
+               dev_err(wm831x->dev, "watchdog_register_device() failed: %d\n",
+                       ret);
                goto err_gpio;
        }
 
+       dev_set_drvdata(&pdev->dev, driver_data);
+
        return 0;
 
 err_gpio:
-       if (update_gpio) {
-               gpio_free(update_gpio);
-               update_gpio = 0;
-       }
+       if (driver_data->update_gpio)
+               gpio_free(driver_data->update_gpio);
+err_alloc:
+       kfree(driver_data);
 err:
        return ret;
 }
 
 static int __devexit wm831x_wdt_remove(struct platform_device *pdev)
 {
-       if (update_gpio) {
-               gpio_free(update_gpio);
-               update_gpio = 0;
-       }
+       struct wm831x_wdt_drvdata *driver_data = dev_get_drvdata(&pdev->dev);
+
+       watchdog_unregister_device(&driver_data->wdt);
 
-       misc_deregister(&wm831x_wdt_miscdev);
+       if (driver_data->update_gpio)
+               gpio_free(driver_data->update_gpio);
 
        return 0;
 }
index 5876e1ae6c2d63be7151a6ff5cfcc7bd5b442465..31ab82fda38a264cd045c4b52c117eb375f8e80e 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/pagemap.h>
@@ -93,8 +94,8 @@ static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
 #define inc_totalhigh_pages() (totalhigh_pages++)
 #define dec_totalhigh_pages() (totalhigh_pages--)
 #else
-#define inc_totalhigh_pages() do {} while(0)
-#define dec_totalhigh_pages() do {} while(0)
+#define inc_totalhigh_pages() do {} while (0)
+#define dec_totalhigh_pages() do {} while (0)
 #endif
 
 /* List of ballooned pages, threaded through the mem_map array. */
@@ -154,8 +155,7 @@ static struct page *balloon_retrieve(bool prefer_highmem)
        if (PageHighMem(page)) {
                balloon_stats.balloon_high--;
                inc_totalhigh_pages();
-       }
-       else
+       } else
                balloon_stats.balloon_low--;
 
        totalram_pages++;
@@ -422,7 +422,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
                                (unsigned long)__va(pfn << PAGE_SHIFT),
                                __pte_ma(0), 0);
                        BUG_ON(ret);
-                }
+               }
 
        }
 
@@ -501,17 +501,17 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
  * alloc_xenballooned_pages - get pages that have been ballooned out
  * @nr_pages: Number of pages to get
  * @pages: pages returned
- * @highmem: highmem or lowmem pages
+ * @highmem: allow highmem pages
  * @return 0 on success, error otherwise
  */
 int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
 {
        int pgno = 0;
-       struct pagepage;
+       struct page *page;
        mutex_lock(&balloon_mutex);
        while (pgno < nr_pages) {
                page = balloon_retrieve(highmem);
-               if (page && PageHighMem(page) == highmem) {
+               if (page && (highmem || !PageHighMem(page))) {
                        pages[pgno++] = page;
                } else {
                        enum bp_state st;
@@ -540,7 +540,7 @@ EXPORT_SYMBOL(alloc_xenballooned_pages);
  * @nr_pages: Number of pages
  * @pages: pages to return
  */
-void free_xenballooned_pages(int nr_pages, struct page** pages)
+void free_xenballooned_pages(int nr_pages, struct page **pages)
 {
        int i;
 
index 0eb8a57cc808e0d789c6f1477ba9d699297db377..6e075cdd0c6bf56ff8daacf986d443de23c49998 100644 (file)
@@ -85,8 +85,7 @@ enum xen_irq_type {
  *    IPI - IPI vector
  *    EVTCHN -
  */
-struct irq_info
-{
+struct irq_info {
        struct list_head list;
        enum xen_irq_type type; /* type */
        unsigned irq;
@@ -282,9 +281,9 @@ static inline unsigned long active_evtchns(unsigned int cpu,
                                           struct shared_info *sh,
                                           unsigned int idx)
 {
-       return (sh->evtchn_pending[idx] &
+       return sh->evtchn_pending[idx] &
                per_cpu(cpu_evtchn_mask, cpu)[idx] &
-               ~sh->evtchn_mask[idx]);
+               ~sh->evtchn_mask[idx];
 }
 
 static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
@@ -1180,7 +1179,7 @@ static void __xen_evtchn_do_upcall(void)
        int cpu = get_cpu();
        struct shared_info *s = HYPERVISOR_shared_info;
        struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
-       unsigned count;
+       unsigned count;
 
        do {
                unsigned long pending_words;
index f6832f46aea4a4861368465321cc8423f997cdfc..e1c4c6e5b469c44449f68e9e841d264eb08dbc48 100644 (file)
@@ -135,7 +135,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
                /* Grant foreign access to the page. */
                gref->gref_id = gnttab_grant_foreign_access(op->domid,
                        pfn_to_mfn(page_to_pfn(gref->page)), readonly);
-               if (gref->gref_id < 0) {
+               if ((int)gref->gref_id < 0) {
                        rc = gref->gref_id;
                        goto undo;
                }
@@ -280,7 +280,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv,
                goto out;
        }
 
-       gref_ids = kzalloc(sizeof(gref_ids[0]) * op.count, GFP_TEMPORARY);
+       gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY);
        if (!gref_ids) {
                rc = -ENOMEM;
                goto out;
index 880798aae2f2ae868bc9cc3206517901c1560afa..afca14d9042e6cd2ae03f238143ac8188aaf35fb 100644 (file)
@@ -114,11 +114,11 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
        if (NULL == add)
                return NULL;
 
-       add->grants    = kzalloc(sizeof(add->grants[0])    * count, GFP_KERNEL);
-       add->map_ops   = kzalloc(sizeof(add->map_ops[0])   * count, GFP_KERNEL);
-       add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL);
-       add->kmap_ops  = kzalloc(sizeof(add->kmap_ops[0])  * count, GFP_KERNEL);
-       add->pages     = kzalloc(sizeof(add->pages[0])     * count, GFP_KERNEL);
+       add->grants    = kcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
+       add->map_ops   = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
+       add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
+       add->kmap_ops  = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
+       add->pages     = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
        if (NULL == add->grants    ||
            NULL == add->map_ops   ||
            NULL == add->unmap_ops ||
@@ -193,9 +193,8 @@ static void gntdev_put_map(struct grant_map *map)
 
        atomic_sub(map->count, &pages_mapped);
 
-       if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
+       if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
                notify_remote_via_evtchn(map->notify.event);
-       }
 
        if (map->pages) {
                if (!use_ptemod)
index 8c71ab80175653827d0ceb966b74b7aef73287d3..bf1c094f4ebf12ea234b9a60fdaea118d6217d8e 100644 (file)
@@ -193,7 +193,7 @@ int gnttab_query_foreign_access(grant_ref_t ref)
 
        nflags = shared[ref].flags;
 
-       return (nflags & (GTF_reading|GTF_writing));
+       return nflags & (GTF_reading|GTF_writing);
 }
 EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
 
index 0b5366b5be2017dc90aab1c6ed869908556fd954..ce4fa0831860175dedd4b53d3cd22e168474f7b9 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/stop_machine.h>
 #include <linux/freezer.h>
 #include <linux/syscore_ops.h>
+#include <linux/export.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
index 66057075d6e2664c4411b5168c17ba3ac1828938..b84bf0b6cc34c4fd34bfd35015bd8057f0ddf6b9 100644 (file)
@@ -116,7 +116,7 @@ static int xen_add_device(struct device *dev)
                        &manage_pci_ext);
        } else {
                struct physdev_manage_pci manage_pci = {
-                       .bus    = pci_dev->bus->number,
+                       .bus    = pci_dev->bus->number,
                        .devfn  = pci_dev->devfn,
                };
 
index c984768d98ca95d430b88d4af537183600ce4c53..8e964b91c447b117b7d4d17731201254a79365d5 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/bootmem.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <xen/swiotlb-xen.h>
 #include <xen/page.h>
 #include <xen/xen-ops.h>
index 5c9dc43c1e94240cf3f25c674a047df4f9f93ea7..9cc2259c9992799dca480245b018ffb971541ed9 100644 (file)
@@ -50,11 +50,6 @@ static struct sys_device balloon_sysdev;
 
 static int register_balloon(struct sys_device *sysdev);
 
-static struct xenbus_watch target_watch =
-{
-       .node = "memory/target"
-};
-
 /* React to a change in the target key */
 static void watch_target(struct xenbus_watch *watch,
                         const char **vec, unsigned int len)
@@ -73,6 +68,11 @@ static void watch_target(struct xenbus_watch *watch,
         */
        balloon_set_new_target(new_target >> (PAGE_SHIFT - 10));
 }
+static struct xenbus_watch target_watch = {
+       .node = "memory/target",
+       .callback = watch_target,
+};
+
 
 static int balloon_init_watcher(struct notifier_block *notifier,
                                unsigned long event,
@@ -87,7 +87,9 @@ static int balloon_init_watcher(struct notifier_block *notifier,
        return NOTIFY_DONE;
 }
 
-static struct notifier_block xenstore_notifier;
+static struct notifier_block xenstore_notifier = {
+       .notifier_call = balloon_init_watcher,
+};
 
 static int __init balloon_init(void)
 {
@@ -100,9 +102,6 @@ static int __init balloon_init(void)
 
        register_xen_selfballooning(&balloon_sysdev);
 
-       target_watch.callback = watch_target;
-       xenstore_notifier.notifier_call = balloon_init_watcher;
-
        register_xenstore_notifier(&xenstore_notifier);
 
        return 0;
index 444345afbd5cfa92b8a1b3b9877ab14108bbf73c..52fed16d870161c781c23275e8aeaedb9cef9b7c 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include "pciback.h"
 #include "conf_space.h"
index cdacf923e0730d42c05b46befd97494d6be2a550..1906125eab491bb384293c4424c27b8f0477e6f0 100644 (file)
@@ -33,7 +33,9 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/xen/page.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/event_channel.h>
 #include <xen/events.h>
@@ -435,25 +437,26 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
 int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
 {
        struct gnttab_map_grant_ref op = {
-               .flags = GNTMAP_host_map,
+               .flags = GNTMAP_host_map | GNTMAP_contains_pte,
                .ref   = gnt_ref,
                .dom   = dev->otherend_id,
        };
        struct vm_struct *area;
+       pte_t *pte;
 
        *vaddr = NULL;
 
-       area = xen_alloc_vm_area(PAGE_SIZE);
+       area = alloc_vm_area(PAGE_SIZE, &pte);
        if (!area)
                return -ENOMEM;
 
-       op.host_addr = (unsigned long)area->addr;
+       op.host_addr = arbitrary_virt_to_machine(pte).maddr;
 
        if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
                BUG();
 
        if (op.status != GNTST_okay) {
-               xen_free_vm_area(area);
+               free_vm_area(area);
                xenbus_dev_fatal(dev, op.status,
                                 "mapping in shared page %d from domain %d",
                                 gnt_ref, dev->otherend_id);
@@ -526,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
        struct gnttab_unmap_grant_ref op = {
                .host_addr = (unsigned long)vaddr,
        };
+       unsigned int level;
 
        /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
         * method so that we don't have to muck with vmalloc internals here.
@@ -547,12 +551,14 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
        }
 
        op.handle = (grant_handle_t)area->phys_addr;
+       op.host_addr = arbitrary_virt_to_machine(
+               lookup_address((unsigned long)vaddr, &level)).maddr;
 
        if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
                BUG();
 
        if (op.status == GNTST_okay)
-               xen_free_vm_area(area);
+               free_vm_area(area);
        else
                xenbus_dev_error(dev, op.status,
                                 "unmapping page at handle %d error %d",
index cef9b0bf63d527f8a10b3cdc5d5016f281b80e59..1b178c6e893796c2807d8a5a1992c9cc27a7b97a 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/mutex.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -309,8 +310,7 @@ void xenbus_unregister_driver(struct xenbus_driver *drv)
 }
 EXPORT_SYMBOL_GPL(xenbus_unregister_driver);
 
-struct xb_find_info
-{
+struct xb_find_info {
        struct xenbus_device *dev;
        const char *nodename;
 };
@@ -639,7 +639,7 @@ int xenbus_dev_cancel(struct device *dev)
 EXPORT_SYMBOL_GPL(xenbus_dev_cancel);
 
 /* A flag to determine if xenstored is 'ready' (i.e. has started) */
-int xenstored_ready = 0;
+int xenstored_ready;
 
 
 int register_xenstore_notifier(struct notifier_block *nb)
@@ -770,7 +770,7 @@ static int __init xenbus_init(void)
        proc_mkdir("xen", NULL);
 #endif
 
- out_error:
+out_error:
        return err;
 }
 
index b814935378c7a4739fce949f70961505997381b7..9b1de4e34c64db2eae45798765bf81f45af1a84b 100644 (file)
@@ -36,8 +36,7 @@
 
 #define XEN_BUS_ID_SIZE                        20
 
-struct xen_bus_type
-{
+struct xen_bus_type {
        char *root;
        unsigned int levels;
        int (*get_bus_id)(char bus_id[XEN_BUS_ID_SIZE], const char *nodename);
index 32417b5064fd71dc760d284ed992047babd28d9f..c3c7cd195c115026e3c4c495f8f7d88a3526d1e9 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/fcntl.h>
 #include <linux/mm.h>
 #include <linux/notifier.h>
+#include <linux/export.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index 540587e18a941dfc9c38bca64f8d61ed58a4e4c1..2f73195512b4dbddad51176cee02e358f1f024b0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
index e0c84725d3e94e05a33482349dc90f45f59099a9..988880dcee751a20309250227bd5dbf1f67db23e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <asm/uaccess.h>
 #include <asm/amigahw.h>
 #include <asm/setup.h>
index 9c5e6b2cd11a84fa3f04611b35cebb6e2232b186..c2183f3917cdd07647ca48493ce14c97c024b4c2 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/mempool.h>
+#include <linux/export.h>
 #include <linux/bio.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
index 41c93c72224457179bda4ca18798b6f2add617c9..b1fe82cf88cfe0864a2d9603b713f8caacecde4e 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -337,7 +337,7 @@ static void bio_fs_destructor(struct bio *bio)
  *     RETURNS:
  *     Pointer to new bio on success, NULL on failure.
  */
-struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
+struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 {
        struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
 
@@ -365,7 +365,7 @@ static void bio_kmalloc_destructor(struct bio *bio)
  *   %__GFP_WAIT, the allocation is guaranteed to succeed.
  *
  **/
-struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
+struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
 {
        struct bio *bio;
 
@@ -696,7 +696,8 @@ static void bio_free_map_data(struct bio_map_data *bmd)
        kfree(bmd);
 }
 
-static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
+static struct bio_map_data *bio_alloc_map_data(int nr_segs,
+                                              unsigned int iov_count,
                                               gfp_t gfp_mask)
 {
        struct bio_map_data *bmd;
index 40e6ac08c21ffb3f5603c559de6d2fcf5f56d8f4..c0ddfd29c5e5a348464d5c3d15a77a7708fd8d79 100644 (file)
@@ -7,6 +7,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
           extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \
           extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
           export.o tree-log.o free-space-cache.o zlib.o lzo.o \
-          compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o
+          compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
+          reada.o backref.o
 
 btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
index eb159aaa5a1139204e2d24333bc32eae8433261d..89b156d85d63c9f29b66413e1558e85a758d0e12 100644 (file)
@@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
                if (!value)
                        return ERR_PTR(-ENOMEM);
                size = __btrfs_getxattr(inode, name, value, size);
-               if (size > 0) {
-                       acl = posix_acl_from_xattr(value, size);
-                       if (IS_ERR(acl)) {
-                               kfree(value);
-                               return acl;
-                       }
-                       set_cached_acl(inode, type, acl);
-               }
-               kfree(value);
+       }
+       if (size > 0) {
+               acl = posix_acl_from_xattr(value, size);
        } else if (size == -ENOENT || size == -ENODATA || size == 0) {
                /* FIXME, who returns -ENOENT?  I think nobody */
                acl = NULL;
-               set_cached_acl(inode, type, acl);
        } else {
                acl = ERR_PTR(-EIO);
        }
+       kfree(value);
+
+       if (!IS_ERR(acl))
+               set_cached_acl(inode, type, acl);
 
        return acl;
 }
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
new file mode 100644 (file)
index 0000000..22c64ff
--- /dev/null
@@ -0,0 +1,776 @@
+/*
+ * Copyright (C) 2011 STRATO.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "ctree.h"
+#include "disk-io.h"
+#include "backref.h"
+
+struct __data_ref {
+       struct list_head list;
+       u64 inum;
+       u64 root;
+       u64 extent_data_item_offset;
+};
+
+struct __shared_ref {
+       struct list_head list;
+       u64 disk_byte;
+};
+
+static int __inode_info(u64 inum, u64 ioff, u8 key_type,
+                       struct btrfs_root *fs_root, struct btrfs_path *path,
+                       struct btrfs_key *found_key)
+{
+       int ret;
+       struct btrfs_key key;
+       struct extent_buffer *eb;
+
+       key.type = key_type;
+       key.objectid = inum;
+       key.offset = ioff;
+
+       ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
+       if (ret < 0)
+               return ret;
+
+       eb = path->nodes[0];
+       if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
+               ret = btrfs_next_leaf(fs_root, path);
+               if (ret)
+                       return ret;
+               eb = path->nodes[0];
+       }
+
+       btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
+       if (found_key->type != key.type || found_key->objectid != key.objectid)
+               return 1;
+
+       return 0;
+}
+
+/*
+ * this makes the path point to (inum INODE_ITEM ioff)
+ */
+int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
+                       struct btrfs_path *path)
+{
+       struct btrfs_key key;
+       return __inode_info(inum, ioff, BTRFS_INODE_ITEM_KEY, fs_root, path,
+                               &key);
+}
+
+static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
+                               struct btrfs_path *path,
+                               struct btrfs_key *found_key)
+{
+       return __inode_info(inum, ioff, BTRFS_INODE_REF_KEY, fs_root, path,
+                               found_key);
+}
+
+/*
+ * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
+ * of the path are separated by '/' and the path is guaranteed to be
+ * 0-terminated. the path is only given within the current file system.
+ * Therefore, it never starts with a '/'. the caller is responsible to provide
+ * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
+ * the start point of the resulting string is returned. this pointer is within
+ * dest, normally.
+ * in case the path buffer would overflow, the pointer is decremented further
+ * as if output was written to the buffer, though no more output is actually
+ * generated. that way, the caller can determine how much space would be
+ * required for the path to fit into the buffer. in that case, the returned
+ * value will be smaller than dest. callers must check this!
+ */
+static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
+                               struct btrfs_inode_ref *iref,
+                               struct extent_buffer *eb_in, u64 parent,
+                               char *dest, u32 size)
+{
+       u32 len;
+       int slot;
+       u64 next_inum;
+       int ret;
+       s64 bytes_left = size - 1;
+       struct extent_buffer *eb = eb_in;
+       struct btrfs_key found_key;
+
+       if (bytes_left >= 0)
+               dest[bytes_left] = '\0';
+
+       while (1) {
+               len = btrfs_inode_ref_name_len(eb, iref);
+               bytes_left -= len;
+               if (bytes_left >= 0)
+                       read_extent_buffer(eb, dest + bytes_left,
+                                               (unsigned long)(iref + 1), len);
+               if (eb != eb_in)
+                       free_extent_buffer(eb);
+               ret = inode_ref_info(parent, 0, fs_root, path, &found_key);
+               if (ret)
+                       break;
+               next_inum = found_key.offset;
+
+               /* regular exit ahead */
+               if (parent == next_inum)
+                       break;
+
+               slot = path->slots[0];
+               eb = path->nodes[0];
+               /* make sure we can use eb after releasing the path */
+               if (eb != eb_in)
+                       atomic_inc(&eb->refs);
+               btrfs_release_path(path);
+
+               iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+               parent = next_inum;
+               --bytes_left;
+               if (bytes_left >= 0)
+                       dest[bytes_left] = '/';
+       }
+
+       btrfs_release_path(path);
+
+       if (ret)
+               return ERR_PTR(ret);
+
+       return dest + bytes_left;
+}
+
+/*
+ * this makes the path point to (logical EXTENT_ITEM *)
+ * returns BTRFS_EXTENT_FLAG_DATA for data, BTRFS_EXTENT_FLAG_TREE_BLOCK for
+ * tree blocks and <0 on error.
+ */
+int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
+                       struct btrfs_path *path, struct btrfs_key *found_key)
+{
+       int ret;
+       u64 flags;
+       u32 item_size;
+       struct extent_buffer *eb;
+       struct btrfs_extent_item *ei;
+       struct btrfs_key key;
+
+       key.type = BTRFS_EXTENT_ITEM_KEY;
+       key.objectid = logical;
+       key.offset = (u64)-1;
+
+       ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
+       if (ret < 0)
+               return ret;
+       ret = btrfs_previous_item(fs_info->extent_root, path,
+                                       0, BTRFS_EXTENT_ITEM_KEY);
+       if (ret < 0)
+               return ret;
+
+       btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
+       if (found_key->type != BTRFS_EXTENT_ITEM_KEY ||
+           found_key->objectid > logical ||
+           found_key->objectid + found_key->offset <= logical)
+               return -ENOENT;
+
+       eb = path->nodes[0];
+       item_size = btrfs_item_size_nr(eb, path->slots[0]);
+       BUG_ON(item_size < sizeof(*ei));
+
+       ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
+       flags = btrfs_extent_flags(eb, ei);
+
+       if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+               return BTRFS_EXTENT_FLAG_TREE_BLOCK;
+       if (flags & BTRFS_EXTENT_FLAG_DATA)
+               return BTRFS_EXTENT_FLAG_DATA;
+
+       return -EIO;
+}
+
+/*
+ * helper function to iterate extent inline refs. ptr must point to a 0 value
+ * for the first call and may be modified. it is used to track state.
+ * if more refs exist, 0 is returned and the next call to
+ * __get_extent_inline_ref must pass the modified ptr parameter to get the
+ * next ref. after the last ref was processed, 1 is returned.
+ * returns <0 on error
+ */
+static int __get_extent_inline_ref(unsigned long *ptr, struct extent_buffer *eb,
+                               struct btrfs_extent_item *ei, u32 item_size,
+                               struct btrfs_extent_inline_ref **out_eiref,
+                               int *out_type)
+{
+       unsigned long end;
+       u64 flags;
+       struct btrfs_tree_block_info *info;
+
+       if (!*ptr) {
+               /* first call */
+               flags = btrfs_extent_flags(eb, ei);
+               if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+                       info = (struct btrfs_tree_block_info *)(ei + 1);
+                       *out_eiref =
+                               (struct btrfs_extent_inline_ref *)(info + 1);
+               } else {
+                       *out_eiref = (struct btrfs_extent_inline_ref *)(ei + 1);
+               }
+               *ptr = (unsigned long)*out_eiref;
+               if ((void *)*ptr >= (void *)ei + item_size)
+                       return -ENOENT;
+       }
+
+       end = (unsigned long)ei + item_size;
+       *out_eiref = (struct btrfs_extent_inline_ref *)*ptr;
+       *out_type = btrfs_extent_inline_ref_type(eb, *out_eiref);
+
+       *ptr += btrfs_extent_inline_ref_size(*out_type);
+       WARN_ON(*ptr > end);
+       if (*ptr == end)
+               return 1; /* last */
+
+       return 0;
+}
+
+/*
+ * reads the tree block backref for an extent. tree level and root are returned
+ * through out_level and out_root. ptr must point to a 0 value for the first
+ * call and may be modified (see __get_extent_inline_ref comment).
+ * returns 0 if data was provided, 1 if there was no more data to provide or
+ * <0 on error.
+ */
+int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
+                               struct btrfs_extent_item *ei, u32 item_size,
+                               u64 *out_root, u8 *out_level)
+{
+       int ret;
+       int type;
+       struct btrfs_tree_block_info *info;
+       struct btrfs_extent_inline_ref *eiref;
+
+       if (*ptr == (unsigned long)-1)
+               return 1;
+
+       while (1) {
+               ret = __get_extent_inline_ref(ptr, eb, ei, item_size,
+                                               &eiref, &type);
+               if (ret < 0)
+                       return ret;
+
+               if (type == BTRFS_TREE_BLOCK_REF_KEY ||
+                   type == BTRFS_SHARED_BLOCK_REF_KEY)
+                       break;
+
+               if (ret == 1)
+                       return 1;
+       }
+
+       /* we can treat both ref types equally here */
+       info = (struct btrfs_tree_block_info *)(ei + 1);
+       *out_root = btrfs_extent_inline_ref_offset(eb, eiref);
+       *out_level = btrfs_tree_block_level(eb, info);
+
+       if (ret == 1)
+               *ptr = (unsigned long)-1;
+
+       return 0;
+}
+
+static int __data_list_add(struct list_head *head, u64 inum,
+                               u64 extent_data_item_offset, u64 root)
+{
+       struct __data_ref *ref;
+
+       ref = kmalloc(sizeof(*ref), GFP_NOFS);
+       if (!ref)
+               return -ENOMEM;
+
+       ref->inum = inum;
+       ref->extent_data_item_offset = extent_data_item_offset;
+       ref->root = root;
+       list_add_tail(&ref->list, head);
+
+       return 0;
+}
+
+static int __data_list_add_eb(struct list_head *head, struct extent_buffer *eb,
+                               struct btrfs_extent_data_ref *dref)
+{
+       return __data_list_add(head, btrfs_extent_data_ref_objectid(eb, dref),
+                               btrfs_extent_data_ref_offset(eb, dref),
+                               btrfs_extent_data_ref_root(eb, dref));
+}
+
+static int __shared_list_add(struct list_head *head, u64 disk_byte)
+{
+       struct __shared_ref *ref;
+
+       ref = kmalloc(sizeof(*ref), GFP_NOFS);
+       if (!ref)
+               return -ENOMEM;
+
+       ref->disk_byte = disk_byte;
+       list_add_tail(&ref->list, head);
+
+       return 0;
+}
+
+static int __iter_shared_inline_ref_inodes(struct btrfs_fs_info *fs_info,
+                                          u64 logical, u64 inum,
+                                          u64 extent_data_item_offset,
+                                          u64 extent_offset,
+                                          struct btrfs_path *path,
+                                          struct list_head *data_refs,
+                                          iterate_extent_inodes_t *iterate,
+                                          void *ctx)
+{
+       u64 ref_root;
+       u32 item_size;
+       struct btrfs_key key;
+       struct extent_buffer *eb;
+       struct btrfs_extent_item *ei;
+       struct btrfs_extent_inline_ref *eiref;
+       struct __data_ref *ref;
+       int ret;
+       int type;
+       int last;
+       unsigned long ptr = 0;
+
+       WARN_ON(!list_empty(data_refs));
+       ret = extent_from_logical(fs_info, logical, path, &key);
+       if (ret & BTRFS_EXTENT_FLAG_DATA)
+               ret = -EIO;
+       if (ret < 0)
+               goto out;
+
+       eb = path->nodes[0];
+       ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
+       item_size = btrfs_item_size_nr(eb, path->slots[0]);
+
+       ret = 0;
+       ref_root = 0;
+       /*
+        * as done in iterate_extent_inodes, we first build a list of refs to
+        * iterate, then free the path and then iterate them to avoid deadlocks.
+        */
+       do {
+               last = __get_extent_inline_ref(&ptr, eb, ei, item_size,
+                                               &eiref, &type);
+               if (last < 0) {
+                       ret = last;
+                       goto out;
+               }
+               if (type == BTRFS_TREE_BLOCK_REF_KEY ||
+                   type == BTRFS_SHARED_BLOCK_REF_KEY) {
+                       ref_root = btrfs_extent_inline_ref_offset(eb, eiref);
+                       ret = __data_list_add(data_refs, inum,
+                                               extent_data_item_offset,
+                                               ref_root);
+               }
+       } while (!ret && !last);
+
+       btrfs_release_path(path);
+
+       if (ref_root == 0) {
+               printk(KERN_ERR "btrfs: failed to find tree block ref "
+                       "for shared data backref %llu\n", logical);
+               WARN_ON(1);
+               ret = -EIO;
+       }
+
+out:
+       while (!list_empty(data_refs)) {
+               ref = list_first_entry(data_refs, struct __data_ref, list);
+               list_del(&ref->list);
+               if (!ret)
+                       ret = iterate(ref->inum, extent_offset +
+                                       ref->extent_data_item_offset,
+                                       ref->root, ctx);
+               kfree(ref);
+       }
+
+       return ret;
+}
+
+static int __iter_shared_inline_ref(struct btrfs_fs_info *fs_info,
+                                   u64 logical, u64 orig_extent_item_objectid,
+                                   u64 extent_offset, struct btrfs_path *path,
+                                   struct list_head *data_refs,
+                                   iterate_extent_inodes_t *iterate,
+                                   void *ctx)
+{
+       u64 disk_byte;
+       struct btrfs_key key;
+       struct btrfs_file_extent_item *fi;
+       struct extent_buffer *eb;
+       int slot;
+       int nritems;
+       int ret;
+       int found = 0;
+
+       eb = read_tree_block(fs_info->tree_root, logical,
+                               fs_info->tree_root->leafsize, 0);
+       if (!eb)
+               return -EIO;
+
+       /*
+        * from the shared data ref, we only have the leaf but we need
+        * the key. thus, we must look into all items and see that we
+        * find one (some) with a reference to our extent item.
+        */
+       nritems = btrfs_header_nritems(eb);
+       for (slot = 0; slot < nritems; ++slot) {
+               btrfs_item_key_to_cpu(eb, &key, slot);
+               if (key.type != BTRFS_EXTENT_DATA_KEY)
+                       continue;
+               fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
+               if (!fi) {
+                       free_extent_buffer(eb);
+                       return -EIO;
+               }
+               disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+               if (disk_byte != orig_extent_item_objectid) {
+                       if (found)
+                               break;
+                       else
+                               continue;
+               }
+               ++found;
+               ret = __iter_shared_inline_ref_inodes(fs_info, logical,
+                                                       key.objectid,
+                                                       key.offset,
+                                                       extent_offset, path,
+                                                       data_refs,
+                                                       iterate, ctx);
+               if (ret)
+                       break;
+       }
+
+       if (!found) {
+               printk(KERN_ERR "btrfs: failed to follow shared data backref "
+                       "to parent %llu\n", logical);
+               WARN_ON(1);
+               ret = -EIO;
+       }
+
+       free_extent_buffer(eb);
+       return ret;
+}
+
+/*
+ * calls iterate() for every inode that references the extent identified by
+ * the given parameters. will use the path given as a parameter and return it
+ * released.
+ * when the iterator function returns a non-zero value, iteration stops.
+ */
+int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
+                               struct btrfs_path *path,
+                               u64 extent_item_objectid,
+                               u64 extent_offset,
+                               iterate_extent_inodes_t *iterate, void *ctx)
+{
+       unsigned long ptr = 0;
+       int last;
+       int ret;
+       int type;
+       u64 logical;
+       u32 item_size;
+       struct btrfs_extent_inline_ref *eiref;
+       struct btrfs_extent_data_ref *dref;
+       struct extent_buffer *eb;
+       struct btrfs_extent_item *ei;
+       struct btrfs_key key;
+       struct list_head data_refs = LIST_HEAD_INIT(data_refs);
+       struct list_head shared_refs = LIST_HEAD_INIT(shared_refs);
+       struct __data_ref *ref_d;
+       struct __shared_ref *ref_s;
+
+       eb = path->nodes[0];
+       ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
+       item_size = btrfs_item_size_nr(eb, path->slots[0]);
+
+       /* first we iterate the inline refs, ... */
+       do {
+               last = __get_extent_inline_ref(&ptr, eb, ei, item_size,
+                                               &eiref, &type);
+               if (last == -ENOENT) {
+                       ret = 0;
+                       break;
+               }
+               if (last < 0) {
+                       ret = last;
+                       break;
+               }
+
+               if (type == BTRFS_EXTENT_DATA_REF_KEY) {
+                       dref = (struct btrfs_extent_data_ref *)(&eiref->offset);
+                       ret = __data_list_add_eb(&data_refs, eb, dref);
+               } else if (type == BTRFS_SHARED_DATA_REF_KEY) {
+                       logical = btrfs_extent_inline_ref_offset(eb, eiref);
+                       ret = __shared_list_add(&shared_refs, logical);
+               }
+       } while (!ret && !last);
+
+       /* ... then we proceed to in-tree references and ... */
+       while (!ret) {
+               ++path->slots[0];
+               if (path->slots[0] > btrfs_header_nritems(eb)) {
+                       ret = btrfs_next_leaf(fs_info->extent_root, path);
+                       if (ret) {
+                               if (ret == 1)
+                                       ret = 0; /* we're done */
+                               break;
+                       }
+                       eb = path->nodes[0];
+               }
+               btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
+               if (key.objectid != extent_item_objectid)
+                       break;
+               if (key.type == BTRFS_EXTENT_DATA_REF_KEY) {
+                       dref = btrfs_item_ptr(eb, path->slots[0],
+                                               struct btrfs_extent_data_ref);
+                       ret = __data_list_add_eb(&data_refs, eb, dref);
+               } else if (key.type == BTRFS_SHARED_DATA_REF_KEY) {
+                       ret = __shared_list_add(&shared_refs, key.offset);
+               }
+       }
+
+       btrfs_release_path(path);
+
+       /*
+        * ... only at the very end we can process the refs we found. this is
+        * because the iterator function we call is allowed to make tree lookups
+        * and we have to avoid deadlocks. additionally, we need more tree
+        * lookups ourselves for shared data refs.
+        */
+       while (!list_empty(&data_refs)) {
+               ref_d = list_first_entry(&data_refs, struct __data_ref, list);
+               list_del(&ref_d->list);
+               if (!ret)
+                       ret = iterate(ref_d->inum, extent_offset +
+                                       ref_d->extent_data_item_offset,
+                                       ref_d->root, ctx);
+               kfree(ref_d);
+       }
+
+       while (!list_empty(&shared_refs)) {
+               ref_s = list_first_entry(&shared_refs, struct __shared_ref,
+                                       list);
+               list_del(&ref_s->list);
+               if (!ret)
+                       ret = __iter_shared_inline_ref(fs_info,
+                                                       ref_s->disk_byte,
+                                                       extent_item_objectid,
+                                                       extent_offset, path,
+                                                       &data_refs,
+                                                       iterate, ctx);
+               kfree(ref_s);
+       }
+
+       return ret;
+}
+
+int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
+                               struct btrfs_path *path,
+                               iterate_extent_inodes_t *iterate, void *ctx)
+{
+       int ret;
+       u64 offset;
+       struct btrfs_key found_key;
+
+       ret = extent_from_logical(fs_info, logical, path,
+                                       &found_key);
+       if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+               ret = -EINVAL;
+       if (ret < 0)
+               return ret;
+
+       offset = logical - found_key.objectid;
+       ret = iterate_extent_inodes(fs_info, path, found_key.objectid,
+                                       offset, iterate, ctx);
+
+       return ret;
+}
+
+static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
+                               struct btrfs_path *path,
+                               iterate_irefs_t *iterate, void *ctx)
+{
+       int ret;
+       int slot;
+       u32 cur;
+       u32 len;
+       u32 name_len;
+       u64 parent = 0;
+       int found = 0;
+       struct extent_buffer *eb;
+       struct btrfs_item *item;
+       struct btrfs_inode_ref *iref;
+       struct btrfs_key found_key;
+
+       while (1) {
+               ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,
+                                       &found_key);
+               if (ret < 0)
+                       break;
+               if (ret) {
+                       ret = found ? 0 : -ENOENT;
+                       break;
+               }
+               ++found;
+
+               parent = found_key.offset;
+               slot = path->slots[0];
+               eb = path->nodes[0];
+               /* make sure we can use eb after releasing the path */
+               atomic_inc(&eb->refs);
+               btrfs_release_path(path);
+
+               item = btrfs_item_nr(eb, slot);
+               iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+
+               for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) {
+                       name_len = btrfs_inode_ref_name_len(eb, iref);
+                       /* path must be released before calling iterate()! */
+                       ret = iterate(parent, iref, eb, ctx);
+                       if (ret) {
+                               free_extent_buffer(eb);
+                               break;
+                       }
+                       len = sizeof(*iref) + name_len;
+                       iref = (struct btrfs_inode_ref *)((char *)iref + len);
+               }
+               free_extent_buffer(eb);
+       }
+
+       btrfs_release_path(path);
+
+       return ret;
+}
+
+/*
+ * returns 0 if the path could be dumped (probably truncated)
+ * returns <0 in case of an error
+ */
+static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
+                               struct extent_buffer *eb, void *ctx)
+{
+       struct inode_fs_paths *ipath = ctx;
+       char *fspath;
+       char *fspath_min;
+       int i = ipath->fspath->elem_cnt;
+       const int s_ptr = sizeof(char *);
+       u32 bytes_left;
+
+       bytes_left = ipath->fspath->bytes_left > s_ptr ?
+                                       ipath->fspath->bytes_left - s_ptr : 0;
+
+       fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
+       fspath = iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb,
+                               inum, fspath_min, bytes_left);
+       if (IS_ERR(fspath))
+               return PTR_ERR(fspath);
+
+       if (fspath > fspath_min) {
+               ipath->fspath->val[i] = (u64)(unsigned long)fspath;
+               ++ipath->fspath->elem_cnt;
+               ipath->fspath->bytes_left = fspath - fspath_min;
+       } else {
+               ++ipath->fspath->elem_missed;
+               ipath->fspath->bytes_missing += fspath_min - fspath;
+               ipath->fspath->bytes_left = 0;
+       }
+
+       return 0;
+}
+
+/*
+ * this dumps all file system paths to the inode into the ipath struct, provided
+ * is has been created large enough. each path is zero-terminated and accessed
+ * from ipath->fspath->val[i].
+ * when it returns, there are ipath->fspath->elem_cnt number of paths available
+ * in ipath->fspath->val[]. when the allocated space wasn't sufficient, the
+ * number of missed paths in recored in ipath->fspath->elem_missed, otherwise,
+ * it's zero. ipath->fspath->bytes_missing holds the number of bytes that would
+ * have been needed to return all paths.
+ */
+int paths_from_inode(u64 inum, struct inode_fs_paths *ipath)
+{
+       return iterate_irefs(inum, ipath->fs_root, ipath->btrfs_path,
+                               inode_to_path, ipath);
+}
+
+/*
+ * allocates space to return multiple file system paths for an inode.
+ * total_bytes to allocate are passed, note that space usable for actual path
+ * information will be total_bytes - sizeof(struct inode_fs_paths).
+ * the returned pointer must be freed with free_ipath() in the end.
+ */
+struct btrfs_data_container *init_data_container(u32 total_bytes)
+{
+       struct btrfs_data_container *data;
+       size_t alloc_bytes;
+
+       alloc_bytes = max_t(size_t, total_bytes, sizeof(*data));
+       data = kmalloc(alloc_bytes, GFP_NOFS);
+       if (!data)
+               return ERR_PTR(-ENOMEM);
+
+       if (total_bytes >= sizeof(*data)) {
+               data->bytes_left = total_bytes - sizeof(*data);
+               data->bytes_missing = 0;
+       } else {
+               data->bytes_missing = sizeof(*data) - total_bytes;
+               data->bytes_left = 0;
+       }
+
+       data->elem_cnt = 0;
+       data->elem_missed = 0;
+
+       return data;
+}
+
+/*
+ * allocates space to return multiple file system paths for an inode.
+ * total_bytes to allocate are passed, note that space usable for actual path
+ * information will be total_bytes - sizeof(struct inode_fs_paths).
+ * the returned pointer must be freed with free_ipath() in the end.
+ */
+struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
+                                       struct btrfs_path *path)
+{
+       struct inode_fs_paths *ifp;
+       struct btrfs_data_container *fspath;
+
+       fspath = init_data_container(total_bytes);
+       if (IS_ERR(fspath))
+               return (void *)fspath;
+
+       ifp = kmalloc(sizeof(*ifp), GFP_NOFS);
+       if (!ifp) {
+               kfree(fspath);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ifp->btrfs_path = path;
+       ifp->fspath = fspath;
+       ifp->fs_root = fs_root;
+
+       return ifp;
+}
+
+void free_ipath(struct inode_fs_paths *ipath)
+{
+       kfree(ipath);
+}
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
new file mode 100644 (file)
index 0000000..9261883
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 STRATO.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef __BTRFS_BACKREF__
+#define __BTRFS_BACKREF__
+
+#include "ioctl.h"
+
+struct inode_fs_paths {
+       struct btrfs_path               *btrfs_path;
+       struct btrfs_root               *fs_root;
+       struct btrfs_data_container     *fspath;
+};
+
+typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
+               void *ctx);
+typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
+                               struct extent_buffer *eb, void *ctx);
+
+int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
+                       struct btrfs_path *path);
+
+int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
+                       struct btrfs_path *path, struct btrfs_key *found_key);
+
+int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
+                               struct btrfs_extent_item *ei, u32 item_size,
+                               u64 *out_root, u8 *out_level);
+
+int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
+                               struct btrfs_path *path,
+                               u64 extent_item_objectid,
+                               u64 extent_offset,
+                               iterate_extent_inodes_t *iterate, void *ctx);
+
+int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
+                               struct btrfs_path *path,
+                               iterate_extent_inodes_t *iterate, void *ctx);
+
+int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
+
+struct btrfs_data_container *init_data_container(u32 total_bytes);
+struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
+                                       struct btrfs_path *path);
+void free_ipath(struct inode_fs_paths *ipath);
+
+#endif
index d9f99a16edd6d85a9eb5fbe892f195f0ca00eeb3..634608d2a6d03b5d8741e573de0b142ff8cb6310 100644 (file)
@@ -103,11 +103,6 @@ struct btrfs_inode {
         */
        u64 delalloc_bytes;
 
-       /* total number of bytes that may be used for this inode for
-        * delalloc
-        */
-       u64 reserved_bytes;
-
        /*
         * the size of the file stored in the metadata on disk.  data=ordered
         * means the in-memory i_size might be larger than the size on disk
@@ -115,9 +110,6 @@ struct btrfs_inode {
         */
        u64 disk_i_size;
 
-       /* flags field from the on disk inode */
-       u32 flags;
-
        /*
         * if this is a directory then index_cnt is the counter for the index
         * number for new files that are created
@@ -131,6 +123,15 @@ struct btrfs_inode {
         */
        u64 last_unlink_trans;
 
+       /*
+        * Number of bytes outstanding that are going to need csums.  This is
+        * used in ENOSPC accounting.
+        */
+       u64 csum_bytes;
+
+       /* flags field from the on disk inode */
+       u32 flags;
+
        /*
         * Counters to keep track of the number of extent item's we may use due
         * to delalloc and such.  outstanding_extents is the number of extent
@@ -146,14 +147,12 @@ struct btrfs_inode {
         * the btrfs file release call will add this inode to the
         * ordered operations list so that we make sure to flush out any
         * new data the application may have written before commit.
-        *
-        * yes, its silly to have a single bitflag, but we might grow more
-        * of these.
         */
        unsigned ordered_data_close:1;
        unsigned orphan_meta_reserved:1;
        unsigned dummy_inode:1;
        unsigned in_defrag:1;
+       unsigned delalloc_meta_reserved:1;
 
        /*
         * always compress this one file
index 8ec5d86f173471a7c51177ae7473fb494dcc8f29..14f1c5a0b2d29f187955e9327cac6243715409f0 100644 (file)
@@ -85,7 +85,8 @@ struct compressed_bio {
 static inline int compressed_bio_size(struct btrfs_root *root,
                                      unsigned long disk_size)
 {
-       u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
+
        return sizeof(struct compressed_bio) +
                ((disk_size + root->sectorsize - 1) / root->sectorsize) *
                csum_size;
index 011cab3aca8d9ffeba2690f642badec7e36471c9..dede441bdeee2678225187bece170710abe1a9b4 100644 (file)
@@ -514,10 +514,25 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root,
                                   struct extent_buffer *buf)
 {
+       /* ensure we can see the force_cow */
+       smp_rmb();
+
+       /*
+        * We do not need to cow a block if
+        * 1) this block is not created or changed in this transaction;
+        * 2) this block does not belong to TREE_RELOC tree;
+        * 3) the root is not forced COW.
+        *
+        * What is forced COW:
+        *    when we create snapshot during commiting the transaction,
+        *    after we've finished coping src root, we must COW the shared
+        *    block to ensure the metadata consistency.
+        */
        if (btrfs_header_generation(buf) == trans->transid &&
            !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
            !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
-             btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
+             btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
+           !root->force_cow)
                return 0;
        return 1;
 }
@@ -902,9 +917,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
        orig_ptr = btrfs_node_blockptr(mid, orig_slot);
 
-       if (level < BTRFS_MAX_LEVEL - 1)
+       if (level < BTRFS_MAX_LEVEL - 1) {
                parent = path->nodes[level + 1];
-       pslot = path->slots[level + 1];
+               pslot = path->slots[level + 1];
+       }
 
        /*
         * deal with the case where there is only one pointer in the root
@@ -1107,9 +1123,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
        mid = path->nodes[level];
        WARN_ON(btrfs_header_generation(mid) != trans->transid);
 
-       if (level < BTRFS_MAX_LEVEL - 1)
+       if (level < BTRFS_MAX_LEVEL - 1) {
                parent = path->nodes[level + 1];
-       pslot = path->slots[level + 1];
+               pslot = path->slots[level + 1];
+       }
 
        if (!parent)
                return 1;
index 03912c5c6f498221b965baef0fafed10904677e6..50634abef9b4a51336e95b8bc2aafb4edb7844a0 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kobject.h>
 #include <trace/events/btrfs.h>
 #include <asm/kmap_types.h>
+#include <linux/pagemap.h>
 #include "extent_io.h"
 #include "extent_map.h"
 #include "async-thread.h"
@@ -359,6 +360,47 @@ struct btrfs_header {
 #define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
 #define BTRFS_LABEL_SIZE 256
 
+/*
+ * just in case we somehow lose the roots and are not able to mount,
+ * we store an array of the roots from previous transactions
+ * in the super.
+ */
+#define BTRFS_NUM_BACKUP_ROOTS 4
+struct btrfs_root_backup {
+       __le64 tree_root;
+       __le64 tree_root_gen;
+
+       __le64 chunk_root;
+       __le64 chunk_root_gen;
+
+       __le64 extent_root;
+       __le64 extent_root_gen;
+
+       __le64 fs_root;
+       __le64 fs_root_gen;
+
+       __le64 dev_root;
+       __le64 dev_root_gen;
+
+       __le64 csum_root;
+       __le64 csum_root_gen;
+
+       __le64 total_bytes;
+       __le64 bytes_used;
+       __le64 num_devices;
+       /* future */
+       __le64 unsed_64[4];
+
+       u8 tree_root_level;
+       u8 chunk_root_level;
+       u8 extent_root_level;
+       u8 fs_root_level;
+       u8 dev_root_level;
+       u8 csum_root_level;
+       /* future and to align */
+       u8 unused_8[10];
+} __attribute__ ((__packed__));
+
 /*
  * the super block basically lists the main trees of the FS
  * it currently lacks any block count etc etc
@@ -405,6 +447,7 @@ struct btrfs_super_block {
        /* future expansion */
        __le64 reserved[31];
        u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
+       struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
 } __attribute__ ((__packed__));
 
 /*
@@ -772,14 +815,8 @@ struct btrfs_space_info {
 struct btrfs_block_rsv {
        u64 size;
        u64 reserved;
-       u64 freed[2];
        struct btrfs_space_info *space_info;
-       struct list_head list;
        spinlock_t lock;
-       atomic_t usage;
-       unsigned int priority:8;
-       unsigned int durable:1;
-       unsigned int refill_used:1;
        unsigned int full:1;
 };
 
@@ -811,7 +848,8 @@ struct btrfs_free_cluster {
 enum btrfs_caching_type {
        BTRFS_CACHE_NO          = 0,
        BTRFS_CACHE_STARTED     = 1,
-       BTRFS_CACHE_FINISHED    = 2,
+       BTRFS_CACHE_FAST        = 2,
+       BTRFS_CACHE_FINISHED    = 3,
 };
 
 enum btrfs_disk_cache_state {
@@ -840,10 +878,10 @@ struct btrfs_block_group_cache {
        spinlock_t lock;
        u64 pinned;
        u64 reserved;
-       u64 reserved_pinned;
        u64 bytes_super;
        u64 flags;
        u64 sectorsize;
+       u64 cache_generation;
        unsigned int ro:1;
        unsigned int dirty:1;
        unsigned int iref:1;
@@ -899,6 +937,10 @@ struct btrfs_fs_info {
        spinlock_t block_group_cache_lock;
        struct rb_root block_group_cache_tree;
 
+       /* keep track of unallocated space */
+       spinlock_t free_chunk_lock;
+       u64 free_chunk_space;
+
        struct extent_io_tree freed_extents[2];
        struct extent_io_tree *pinned_extents;
 
@@ -916,14 +958,11 @@ struct btrfs_fs_info {
        struct btrfs_block_rsv trans_block_rsv;
        /* block reservation for chunk tree */
        struct btrfs_block_rsv chunk_block_rsv;
+       /* block reservation for delayed operations */
+       struct btrfs_block_rsv delayed_block_rsv;
 
        struct btrfs_block_rsv empty_block_rsv;
 
-       /* list of block reservations that cross multiple transactions */
-       struct list_head durable_block_rsv_list;
-
-       struct mutex durable_block_rsv_mutex;
-
        u64 generation;
        u64 last_trans_committed;
 
@@ -942,8 +981,8 @@ struct btrfs_fs_info {
        wait_queue_head_t transaction_blocked_wait;
        wait_queue_head_t async_submit_wait;
 
-       struct btrfs_super_block super_copy;
-       struct btrfs_super_block super_for_commit;
+       struct btrfs_super_block *super_copy;
+       struct btrfs_super_block *super_for_commit;
        struct block_device *__bdev;
        struct super_block *sb;
        struct inode *btree_inode;
@@ -1036,6 +1075,7 @@ struct btrfs_fs_info {
        struct btrfs_workers endio_freespace_worker;
        struct btrfs_workers submit_workers;
        struct btrfs_workers caching_workers;
+       struct btrfs_workers readahead_workers;
 
        /*
         * fixup workers take dirty pages that didn't properly go through
@@ -1119,6 +1159,13 @@ struct btrfs_fs_info {
        u64 fs_state;
 
        struct btrfs_delayed_root *delayed_root;
+
+       /* readahead tree */
+       spinlock_t reada_lock;
+       struct radix_tree_root reada_tree;
+
+       /* next backup root to be overwritten */
+       int backup_root_index;
 };
 
 /*
@@ -1225,6 +1272,8 @@ struct btrfs_root {
         * for stat.  It may be used for more later
         */
        dev_t anon_dev;
+
+       int force_cow;
 };
 
 struct btrfs_ioctl_defrag_range_args {
@@ -1363,6 +1412,7 @@ struct btrfs_ioctl_defrag_range_args {
 #define BTRFS_MOUNT_ENOSPC_DEBUG        (1 << 15)
 #define BTRFS_MOUNT_AUTO_DEFRAG                (1 << 16)
 #define BTRFS_MOUNT_INODE_MAP_CACHE    (1 << 17)
+#define BTRFS_MOUNT_RECOVERY           (1 << 18)
 
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
@@ -1978,6 +2028,55 @@ static inline bool btrfs_root_readonly(struct btrfs_root *root)
        return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY;
 }
 
+/* struct btrfs_root_backup */
+BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup,
+                  tree_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_tree_root_gen, struct btrfs_root_backup,
+                  tree_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_tree_root_level, struct btrfs_root_backup,
+                  tree_root_level, 8);
+
+BTRFS_SETGET_STACK_FUNCS(backup_chunk_root, struct btrfs_root_backup,
+                  chunk_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_chunk_root_gen, struct btrfs_root_backup,
+                  chunk_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_chunk_root_level, struct btrfs_root_backup,
+                  chunk_root_level, 8);
+
+BTRFS_SETGET_STACK_FUNCS(backup_extent_root, struct btrfs_root_backup,
+                  extent_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_extent_root_gen, struct btrfs_root_backup,
+                  extent_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_extent_root_level, struct btrfs_root_backup,
+                  extent_root_level, 8);
+
+BTRFS_SETGET_STACK_FUNCS(backup_fs_root, struct btrfs_root_backup,
+                  fs_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_fs_root_gen, struct btrfs_root_backup,
+                  fs_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_fs_root_level, struct btrfs_root_backup,
+                  fs_root_level, 8);
+
+BTRFS_SETGET_STACK_FUNCS(backup_dev_root, struct btrfs_root_backup,
+                  dev_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_dev_root_gen, struct btrfs_root_backup,
+                  dev_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_dev_root_level, struct btrfs_root_backup,
+                  dev_root_level, 8);
+
+BTRFS_SETGET_STACK_FUNCS(backup_csum_root, struct btrfs_root_backup,
+                  csum_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_csum_root_gen, struct btrfs_root_backup,
+                  csum_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_csum_root_level, struct btrfs_root_backup,
+                  csum_root_level, 8);
+BTRFS_SETGET_STACK_FUNCS(backup_total_bytes, struct btrfs_root_backup,
+                  total_bytes, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
+                  bytes_used, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
+                  num_devices, 64);
+
 /* struct btrfs_super_block */
 
 BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64);
@@ -2129,6 +2228,11 @@ static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info)
                (space_info->flags & BTRFS_BLOCK_GROUP_DATA));
 }
 
+static inline gfp_t btrfs_alloc_write_mask(struct address_space *mapping)
+{
+       return mapping_gfp_mask(mapping) & ~__GFP_FS;
+}
+
 /* extent-tree.c */
 static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_root *root,
                                                 unsigned num_items)
@@ -2137,6 +2241,17 @@ static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_root *root,
                3 * num_items;
 }
 
+/*
+ * Doing a truncate won't result in new nodes or leaves, just what we need for
+ * COW.
+ */
+static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_root *root,
+                                                unsigned num_items)
+{
+       return (root->leafsize + root->nodesize * (BTRFS_MAX_LEVEL - 1)) *
+               num_items;
+}
+
 void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
 int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root, unsigned long count);
@@ -2146,6 +2261,9 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
                             u64 num_bytes, u64 *refs, u64 *flags);
 int btrfs_pin_extent(struct btrfs_root *root,
                     u64 bytenr, u64 num, int reserved);
+int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
+                                   struct btrfs_root *root,
+                                   u64 bytenr, u64 num_bytes);
 int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root,
                          u64 objectid, u64 offset, u64 bytenr);
@@ -2196,8 +2314,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
                      u64 root_objectid, u64 owner, u64 offset);
 
 int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len);
-int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
-                               u64 num_bytes, int reserve, int sinfo);
+int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
+                                      u64 start, u64 len);
 int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root);
 int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
@@ -2240,25 +2358,26 @@ void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv);
 struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root);
 void btrfs_free_block_rsv(struct btrfs_root *root,
                          struct btrfs_block_rsv *rsv);
-void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info,
-                                struct btrfs_block_rsv *rsv);
-int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
-                       struct btrfs_root *root,
+int btrfs_block_rsv_add(struct btrfs_root *root,
                        struct btrfs_block_rsv *block_rsv,
                        u64 num_bytes);
-int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
-                         struct btrfs_root *root,
+int btrfs_block_rsv_add_noflush(struct btrfs_root *root,
+                               struct btrfs_block_rsv *block_rsv,
+                               u64 num_bytes);
+int btrfs_block_rsv_check(struct btrfs_root *root,
+                         struct btrfs_block_rsv *block_rsv, int min_factor);
+int btrfs_block_rsv_refill(struct btrfs_root *root,
                          struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved, int min_factor);
+                         u64 min_reserved);
+int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
+                                  struct btrfs_block_rsv *block_rsv,
+                                  u64 min_reserved);
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
                            struct btrfs_block_rsv *dst_rsv,
                            u64 num_bytes);
 void btrfs_block_rsv_release(struct btrfs_root *root,
                             struct btrfs_block_rsv *block_rsv,
                             u64 num_bytes);
-int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
-                                   struct btrfs_root *root,
-                                   struct btrfs_block_rsv *rsv);
 int btrfs_set_block_group_ro(struct btrfs_root *root,
                             struct btrfs_block_group_cache *cache);
 int btrfs_set_block_group_rw(struct btrfs_root *root,
@@ -2379,6 +2498,18 @@ static inline int btrfs_fs_closing(struct btrfs_fs_info *fs_info)
        smp_mb();
        return fs_info->closing;
 }
+static inline void free_fs_info(struct btrfs_fs_info *fs_info)
+{
+       kfree(fs_info->delayed_root);
+       kfree(fs_info->extent_root);
+       kfree(fs_info->tree_root);
+       kfree(fs_info->chunk_root);
+       kfree(fs_info->dev_root);
+       kfree(fs_info->csum_root);
+       kfree(fs_info->super_copy);
+       kfree(fs_info->super_for_commit);
+       kfree(fs_info);
+}
 
 /* root-item.c */
 int btrfs_find_root_ref(struct btrfs_root *tree_root,
@@ -2579,11 +2710,6 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans,
 int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
 int btrfs_orphan_cleanup(struct btrfs_root *root);
-void btrfs_orphan_pre_snapshot(struct btrfs_trans_handle *trans,
-                               struct btrfs_pending_snapshot *pending,
-                               u64 *bytes_to_reserve);
-void btrfs_orphan_post_snapshot(struct btrfs_trans_handle *trans,
-                               struct btrfs_pending_snapshot *pending);
 void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans,
                              struct btrfs_root *root);
 int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size);
@@ -2697,4 +2823,20 @@ int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid);
 int btrfs_scrub_progress(struct btrfs_root *root, u64 devid,
                         struct btrfs_scrub_progress *progress);
 
+/* reada.c */
+struct reada_control {
+       struct btrfs_root       *root;          /* tree to prefetch */
+       struct btrfs_key        key_start;
+       struct btrfs_key        key_end;        /* exclusive */
+       atomic_t                elems;
+       struct kref             refcnt;
+       wait_queue_head_t       wait;
+};
+struct reada_control *btrfs_reada_add(struct btrfs_root *root,
+                             struct btrfs_key *start, struct btrfs_key *end);
+int btrfs_reada_wait(void *handle);
+void btrfs_reada_detach(void *handle);
+int btree_readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
+                        u64 start, int err);
+
 #endif
index ae4d9cd10961d488dae63cc196187f95f6611ee9..5b163572e0ca7ddd6d5f8ef6ff6783dbd5871c4d 100644 (file)
@@ -591,7 +591,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
                return 0;
 
        src_rsv = trans->block_rsv;
-       dst_rsv = &root->fs_info->global_block_rsv;
+       dst_rsv = &root->fs_info->delayed_block_rsv;
 
        num_bytes = btrfs_calc_trans_metadata_size(root, 1);
        ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
@@ -609,7 +609,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
        if (!item->bytes_reserved)
                return;
 
-       rsv = &root->fs_info->global_block_rsv;
+       rsv = &root->fs_info->delayed_block_rsv;
        btrfs_block_rsv_release(root, rsv,
                                item->bytes_reserved);
 }
@@ -617,24 +617,102 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
 static int btrfs_delayed_inode_reserve_metadata(
                                        struct btrfs_trans_handle *trans,
                                        struct btrfs_root *root,
+                                       struct inode *inode,
                                        struct btrfs_delayed_node *node)
 {
        struct btrfs_block_rsv *src_rsv;
        struct btrfs_block_rsv *dst_rsv;
        u64 num_bytes;
        int ret;
-
-       if (!trans->bytes_reserved)
-               return 0;
+       int release = false;
 
        src_rsv = trans->block_rsv;
-       dst_rsv = &root->fs_info->global_block_rsv;
+       dst_rsv = &root->fs_info->delayed_block_rsv;
 
        num_bytes = btrfs_calc_trans_metadata_size(root, 1);
+
+       /*
+        * btrfs_dirty_inode will update the inode under btrfs_join_transaction
+        * which doesn't reserve space for speed.  This is a problem since we
+        * still need to reserve space for this update, so try to reserve the
+        * space.
+        *
+        * Now if src_rsv == delalloc_block_rsv we'll let it just steal since
+        * we're accounted for.
+        */
+       if (!trans->bytes_reserved &&
+           src_rsv != &root->fs_info->delalloc_block_rsv) {
+               ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
+               /*
+                * Since we're under a transaction reserve_metadata_bytes could
+                * try to commit the transaction which will make it return
+                * EAGAIN to make us stop the transaction we have, so return
+                * ENOSPC instead so that btrfs_dirty_inode knows what to do.
+                */
+               if (ret == -EAGAIN)
+                       ret = -ENOSPC;
+               if (!ret)
+                       node->bytes_reserved = num_bytes;
+               return ret;
+       } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
+               spin_lock(&BTRFS_I(inode)->lock);
+               if (BTRFS_I(inode)->delalloc_meta_reserved) {
+                       BTRFS_I(inode)->delalloc_meta_reserved = 0;
+                       spin_unlock(&BTRFS_I(inode)->lock);
+                       release = true;
+                       goto migrate;
+               }
+               spin_unlock(&BTRFS_I(inode)->lock);
+
+               /* Ok we didn't have space pre-reserved.  This shouldn't happen
+                * too often but it can happen if we do delalloc to an existing
+                * inode which gets dirtied because of the time update, and then
+                * isn't touched again until after the transaction commits and
+                * then we try to write out the data.  First try to be nice and
+                * reserve something strictly for us.  If not be a pain and try
+                * to steal from the delalloc block rsv.
+                */
+               ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
+               if (!ret)
+                       goto out;
+
+               ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
+               if (!ret)
+                       goto out;
+
+               /*
+                * Ok this is a problem, let's just steal from the global rsv
+                * since this really shouldn't happen that often.
+                */
+               WARN_ON(1);
+               ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv,
+                                             dst_rsv, num_bytes);
+               goto out;
+       }
+
+migrate:
        ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
+
+out:
+       /*
+        * Migrate only takes a reservation, it doesn't touch the size of the
+        * block_rsv.  This is to simplify people who don't normally have things
+        * migrated from their block rsv.  If they go to release their
+        * reservation, that will decrease the size as well, so if migrate
+        * reduced size we'd end up with a negative size.  But for the
+        * delalloc_meta_reserved stuff we will only know to drop 1 reservation,
+        * but we could in fact do this reserve/migrate dance several times
+        * between the time we did the original reservation and we'd clean it
+        * up.  So to take care of this, release the space for the meta
+        * reservation here.  I think it may be time for a documentation page on
+        * how block rsvs. work.
+        */
        if (!ret)
                node->bytes_reserved = num_bytes;
 
+       if (release)
+               btrfs_block_rsv_release(root, src_rsv, num_bytes);
+
        return ret;
 }
 
@@ -646,7 +724,7 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_root *root,
        if (!node->bytes_reserved)
                return;
 
-       rsv = &root->fs_info->global_block_rsv;
+       rsv = &root->fs_info->delayed_block_rsv;
        btrfs_block_rsv_release(root, rsv,
                                node->bytes_reserved);
        node->bytes_reserved = 0;
@@ -1026,7 +1104,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
        path->leave_spinning = 1;
 
        block_rsv = trans->block_rsv;
-       trans->block_rsv = &root->fs_info->global_block_rsv;
+       trans->block_rsv = &root->fs_info->delayed_block_rsv;
 
        delayed_root = btrfs_get_delayed_root(root);
 
@@ -1069,7 +1147,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
        path->leave_spinning = 1;
 
        block_rsv = trans->block_rsv;
-       trans->block_rsv = &node->root->fs_info->global_block_rsv;
+       trans->block_rsv = &node->root->fs_info->delayed_block_rsv;
 
        ret = btrfs_insert_delayed_items(trans, path, node->root, node);
        if (!ret)
@@ -1149,7 +1227,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
                goto free_path;
 
        block_rsv = trans->block_rsv;
-       trans->block_rsv = &root->fs_info->global_block_rsv;
+       trans->block_rsv = &root->fs_info->delayed_block_rsv;
 
        ret = btrfs_insert_delayed_items(trans, path, root, delayed_node);
        if (!ret)
@@ -1685,12 +1763,10 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
                goto release_node;
        }
 
-       ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node);
-       /*
-        * we must reserve enough space when we start a new transaction,
-        * so reserving metadata failure is impossible
-        */
-       BUG_ON(ret);
+       ret = btrfs_delayed_inode_reserve_metadata(trans, root, inode,
+                                                  delayed_node);
+       if (ret)
+               goto release_node;
 
        fill_stack_inode_item(trans, &delayed_node->inode_item, inode);
        delayed_node->inode_dirty = 1;
index 07ea91879a91a35d99f2ca6e1cbffd52bdbcae82..632f8f3cc9db67f4173ca591b1b66d9ed898627f 100644 (file)
@@ -256,8 +256,7 @@ void btrfs_csum_final(u32 crc, char *result)
 static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
                           int verify)
 {
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        char *result = NULL;
        unsigned long len;
        unsigned long cur_len;
@@ -367,7 +366,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
        clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
        io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
        while (1) {
-               ret = read_extent_buffer_pages(io_tree, eb, start, 1,
+               ret = read_extent_buffer_pages(io_tree, eb, start,
+                                              WAIT_COMPLETE,
                                               btree_get_extent, mirror_num);
                if (!ret &&
                    !verify_parent_transid(io_tree, eb, parent_transid))
@@ -608,11 +608,48 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
        end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
        end = eb->start + end - 1;
 err:
+       if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
+               clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
+               btree_readahead_hook(root, eb, eb->start, ret);
+       }
+
        free_extent_buffer(eb);
 out:
        return ret;
 }
 
+static int btree_io_failed_hook(struct bio *failed_bio,
+                        struct page *page, u64 start, u64 end,
+                        int mirror_num, struct extent_state *state)
+{
+       struct extent_io_tree *tree;
+       unsigned long len;
+       struct extent_buffer *eb;
+       struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
+
+       tree = &BTRFS_I(page->mapping->host)->io_tree;
+       if (page->private == EXTENT_PAGE_PRIVATE)
+               goto out;
+       if (!page->private)
+               goto out;
+
+       len = page->private >> 2;
+       WARN_ON(len == 0);
+
+       eb = alloc_extent_buffer(tree, start, len, page);
+       if (eb == NULL)
+               goto out;
+
+       if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
+               clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
+               btree_readahead_hook(root, eb, eb->start, -EIO);
+       }
+       free_extent_buffer(eb);
+
+out:
+       return -EIO;    /* we fixed nothing */
+}
+
 static void end_workqueue_bio(struct bio *bio, int err)
 {
        struct end_io_wq *end_io_wq = bio->bi_private;
@@ -908,7 +945,7 @@ static int btree_readpage(struct file *file, struct page *page)
 {
        struct extent_io_tree *tree;
        tree = &BTRFS_I(page->mapping->host)->io_tree;
-       return extent_read_full_page(tree, page, btree_get_extent);
+       return extent_read_full_page(tree, page, btree_get_extent, 0);
 }
 
 static int btree_releasepage(struct page *page, gfp_t gfp_flags)
@@ -974,11 +1011,43 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
        if (!buf)
                return 0;
        read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
-                                buf, 0, 0, btree_get_extent, 0);
+                                buf, 0, WAIT_NONE, btree_get_extent, 0);
        free_extent_buffer(buf);
        return ret;
 }
 
+int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
+                        int mirror_num, struct extent_buffer **eb)
+{
+       struct extent_buffer *buf = NULL;
+       struct inode *btree_inode = root->fs_info->btree_inode;
+       struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree;
+       int ret;
+
+       buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
+       if (!buf)
+               return 0;
+
+       set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
+
+       ret = read_extent_buffer_pages(io_tree, buf, 0, WAIT_PAGE_LOCK,
+                                      btree_get_extent, mirror_num);
+       if (ret) {
+               free_extent_buffer(buf);
+               return ret;
+       }
+
+       if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) {
+               free_extent_buffer(buf);
+               return -EIO;
+       } else if (extent_buffer_uptodate(io_tree, buf, NULL)) {
+               *eb = buf;
+       } else {
+               free_extent_buffer(buf);
+       }
+       return 0;
+}
+
 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
                                            u64 bytenr, u32 blocksize)
 {
@@ -1135,10 +1204,12 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
 
        generation = btrfs_root_generation(&root->root_item);
        blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
+       root->commit_root = NULL;
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
        if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
                free_extent_buffer(root->node);
+               root->node = NULL;
                return -EIO;
        }
        root->commit_root = btrfs_root_node(root);
@@ -1577,6 +1648,235 @@ sleep:
        return 0;
 }
 
+/*
+ * this will find the highest generation in the array of
+ * root backups.  The index of the highest array is returned,
+ * or -1 if we can't find anything.
+ *
+ * We check to make sure the array is valid by comparing the
+ * generation of the latest  root in the array with the generation
+ * in the super block.  If they don't match we pitch it.
+ */
+static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen)
+{
+       u64 cur;
+       int newest_index = -1;
+       struct btrfs_root_backup *root_backup;
+       int i;
+
+       for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
+               root_backup = info->super_copy->super_roots + i;
+               cur = btrfs_backup_tree_root_gen(root_backup);
+               if (cur == newest_gen)
+                       newest_index = i;
+       }
+
+       /* check to see if we actually wrapped around */
+       if (newest_index == BTRFS_NUM_BACKUP_ROOTS - 1) {
+               root_backup = info->super_copy->super_roots;
+               cur = btrfs_backup_tree_root_gen(root_backup);
+               if (cur == newest_gen)
+                       newest_index = 0;
+       }
+       return newest_index;
+}
+
+
+/*
+ * find the oldest backup so we know where to store new entries
+ * in the backup array.  This will set the backup_root_index
+ * field in the fs_info struct
+ */
+static void find_oldest_super_backup(struct btrfs_fs_info *info,
+                                    u64 newest_gen)
+{
+       int newest_index = -1;
+
+       newest_index = find_newest_super_backup(info, newest_gen);
+       /* if there was garbage in there, just move along */
+       if (newest_index == -1) {
+               info->backup_root_index = 0;
+       } else {
+               info->backup_root_index = (newest_index + 1) % BTRFS_NUM_BACKUP_ROOTS;
+       }
+}
+
+/*
+ * copy all the root pointers into the super backup array.
+ * this will bump the backup pointer by one when it is
+ * done
+ */
+static void backup_super_roots(struct btrfs_fs_info *info)
+{
+       int next_backup;
+       struct btrfs_root_backup *root_backup;
+       int last_backup;
+
+       next_backup = info->backup_root_index;
+       last_backup = (next_backup + BTRFS_NUM_BACKUP_ROOTS - 1) %
+               BTRFS_NUM_BACKUP_ROOTS;
+
+       /*
+        * just overwrite the last backup if we're at the same generation
+        * this happens only at umount
+        */
+       root_backup = info->super_for_commit->super_roots + last_backup;
+       if (btrfs_backup_tree_root_gen(root_backup) ==
+           btrfs_header_generation(info->tree_root->node))
+               next_backup = last_backup;
+
+       root_backup = info->super_for_commit->super_roots + next_backup;
+
+       /*
+        * make sure all of our padding and empty slots get zero filled
+        * regardless of which ones we use today
+        */
+       memset(root_backup, 0, sizeof(*root_backup));
+
+       info->backup_root_index = (next_backup + 1) % BTRFS_NUM_BACKUP_ROOTS;
+
+       btrfs_set_backup_tree_root(root_backup, info->tree_root->node->start);
+       btrfs_set_backup_tree_root_gen(root_backup,
+                              btrfs_header_generation(info->tree_root->node));
+
+       btrfs_set_backup_tree_root_level(root_backup,
+                              btrfs_header_level(info->tree_root->node));
+
+       btrfs_set_backup_chunk_root(root_backup, info->chunk_root->node->start);
+       btrfs_set_backup_chunk_root_gen(root_backup,
+                              btrfs_header_generation(info->chunk_root->node));
+       btrfs_set_backup_chunk_root_level(root_backup,
+                              btrfs_header_level(info->chunk_root->node));
+
+       btrfs_set_backup_extent_root(root_backup, info->extent_root->node->start);
+       btrfs_set_backup_extent_root_gen(root_backup,
+                              btrfs_header_generation(info->extent_root->node));
+       btrfs_set_backup_extent_root_level(root_backup,
+                              btrfs_header_level(info->extent_root->node));
+
+       /*
+        * we might commit during log recovery, which happens before we set
+        * the fs_root.  Make sure it is valid before we fill it in.
+        */
+       if (info->fs_root && info->fs_root->node) {
+               btrfs_set_backup_fs_root(root_backup,
+                                        info->fs_root->node->start);
+               btrfs_set_backup_fs_root_gen(root_backup,
+                              btrfs_header_generation(info->fs_root->node));
+               btrfs_set_backup_fs_root_level(root_backup,
+                              btrfs_header_level(info->fs_root->node));
+       }
+
+       btrfs_set_backup_dev_root(root_backup, info->dev_root->node->start);
+       btrfs_set_backup_dev_root_gen(root_backup,
+                              btrfs_header_generation(info->dev_root->node));
+       btrfs_set_backup_dev_root_level(root_backup,
+                                      btrfs_header_level(info->dev_root->node));
+
+       btrfs_set_backup_csum_root(root_backup, info->csum_root->node->start);
+       btrfs_set_backup_csum_root_gen(root_backup,
+                              btrfs_header_generation(info->csum_root->node));
+       btrfs_set_backup_csum_root_level(root_backup,
+                              btrfs_header_level(info->csum_root->node));
+
+       btrfs_set_backup_total_bytes(root_backup,
+                            btrfs_super_total_bytes(info->super_copy));
+       btrfs_set_backup_bytes_used(root_backup,
+                            btrfs_super_bytes_used(info->super_copy));
+       btrfs_set_backup_num_devices(root_backup,
+                            btrfs_super_num_devices(info->super_copy));
+
+       /*
+        * if we don't copy this out to the super_copy, it won't get remembered
+        * for the next commit
+        */
+       memcpy(&info->super_copy->super_roots,
+              &info->super_for_commit->super_roots,
+              sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS);
+}
+
+/*
+ * this copies info out of the root backup array and back into
+ * the in-memory super block.  It is meant to help iterate through
+ * the array, so you send it the number of backups you've already
+ * tried and the last backup index you used.
+ *
+ * this returns -1 when it has tried all the backups
+ */
+static noinline int next_root_backup(struct btrfs_fs_info *info,
+                                    struct btrfs_super_block *super,
+                                    int *num_backups_tried, int *backup_index)
+{
+       struct btrfs_root_backup *root_backup;
+       int newest = *backup_index;
+
+       if (*num_backups_tried == 0) {
+               u64 gen = btrfs_super_generation(super);
+
+               newest = find_newest_super_backup(info, gen);
+               if (newest == -1)
+                       return -1;
+
+               *backup_index = newest;
+               *num_backups_tried = 1;
+       } else if (*num_backups_tried == BTRFS_NUM_BACKUP_ROOTS) {
+               /* we've tried all the backups, all done */
+               return -1;
+       } else {
+               /* jump to the next oldest backup */
+               newest = (*backup_index + BTRFS_NUM_BACKUP_ROOTS - 1) %
+                       BTRFS_NUM_BACKUP_ROOTS;
+               *backup_index = newest;
+               *num_backups_tried += 1;
+       }
+       root_backup = super->super_roots + newest;
+
+       btrfs_set_super_generation(super,
+                                  btrfs_backup_tree_root_gen(root_backup));
+       btrfs_set_super_root(super, btrfs_backup_tree_root(root_backup));
+       btrfs_set_super_root_level(super,
+                                  btrfs_backup_tree_root_level(root_backup));
+       btrfs_set_super_bytes_used(super, btrfs_backup_bytes_used(root_backup));
+
+       /*
+        * fixme: the total bytes and num_devices need to match or we should
+        * need a fsck
+        */
+       btrfs_set_super_total_bytes(super, btrfs_backup_total_bytes(root_backup));
+       btrfs_set_super_num_devices(super, btrfs_backup_num_devices(root_backup));
+       return 0;
+}
+
+/* helper to cleanup tree roots */
+static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
+{
+       free_extent_buffer(info->tree_root->node);
+       free_extent_buffer(info->tree_root->commit_root);
+       free_extent_buffer(info->dev_root->node);
+       free_extent_buffer(info->dev_root->commit_root);
+       free_extent_buffer(info->extent_root->node);
+       free_extent_buffer(info->extent_root->commit_root);
+       free_extent_buffer(info->csum_root->node);
+       free_extent_buffer(info->csum_root->commit_root);
+
+       info->tree_root->node = NULL;
+       info->tree_root->commit_root = NULL;
+       info->dev_root->node = NULL;
+       info->dev_root->commit_root = NULL;
+       info->extent_root->node = NULL;
+       info->extent_root->commit_root = NULL;
+       info->csum_root->node = NULL;
+       info->csum_root->commit_root = NULL;
+
+       if (chunk_root) {
+               free_extent_buffer(info->chunk_root->node);
+               free_extent_buffer(info->chunk_root->commit_root);
+               info->chunk_root->node = NULL;
+               info->chunk_root->commit_root = NULL;
+       }
+}
+
+
 struct btrfs_root *open_ctree(struct super_block *sb,
                              struct btrfs_fs_devices *fs_devices,
                              char *options)
@@ -1590,29 +1890,32 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        u64 features;
        struct btrfs_key location;
        struct buffer_head *bh;
-       struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root),
-                                                GFP_NOFS);
-       struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root),
-                                                GFP_NOFS);
+       struct btrfs_super_block *disk_super;
        struct btrfs_root *tree_root = btrfs_sb(sb);
-       struct btrfs_fs_info *fs_info = NULL;
-       struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root),
-                                               GFP_NOFS);
-       struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root),
-                                             GFP_NOFS);
+       struct btrfs_fs_info *fs_info = tree_root->fs_info;
+       struct btrfs_root *extent_root;
+       struct btrfs_root *csum_root;
+       struct btrfs_root *chunk_root;
+       struct btrfs_root *dev_root;
        struct btrfs_root *log_tree_root;
-
        int ret;
        int err = -EINVAL;
-
-       struct btrfs_super_block *disk_super;
-
-       if (!extent_root || !tree_root || !tree_root->fs_info ||
-           !chunk_root || !dev_root || !csum_root) {
+       int num_backups_tried = 0;
+       int backup_index = 0;
+
+       extent_root = fs_info->extent_root =
+               kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       csum_root = fs_info->csum_root =
+               kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       chunk_root = fs_info->chunk_root =
+               kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       dev_root = fs_info->dev_root =
+               kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+
+       if (!extent_root || !csum_root || !chunk_root || !dev_root) {
                err = -ENOMEM;
                goto fail;
        }
-       fs_info = tree_root->fs_info;
 
        ret = init_srcu_struct(&fs_info->subvol_srcu);
        if (ret) {
@@ -1648,15 +1951,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        spin_lock_init(&fs_info->fs_roots_radix_lock);
        spin_lock_init(&fs_info->delayed_iput_lock);
        spin_lock_init(&fs_info->defrag_inodes_lock);
+       spin_lock_init(&fs_info->free_chunk_lock);
        mutex_init(&fs_info->reloc_mutex);
 
        init_completion(&fs_info->kobj_unregister);
-       fs_info->tree_root = tree_root;
-       fs_info->extent_root = extent_root;
-       fs_info->csum_root = csum_root;
-       fs_info->chunk_root = chunk_root;
-       fs_info->dev_root = dev_root;
-       fs_info->fs_devices = fs_devices;
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
        INIT_LIST_HEAD(&fs_info->space_info);
        btrfs_mapping_init(&fs_info->mapping_tree);
@@ -1665,8 +1963,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_init_block_rsv(&fs_info->trans_block_rsv);
        btrfs_init_block_rsv(&fs_info->chunk_block_rsv);
        btrfs_init_block_rsv(&fs_info->empty_block_rsv);
-       INIT_LIST_HEAD(&fs_info->durable_block_rsv_list);
-       mutex_init(&fs_info->durable_block_rsv_mutex);
+       btrfs_init_block_rsv(&fs_info->delayed_block_rsv);
        atomic_set(&fs_info->nr_async_submits, 0);
        atomic_set(&fs_info->async_delalloc_pages, 0);
        atomic_set(&fs_info->async_submit_draining, 0);
@@ -1677,6 +1974,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        fs_info->metadata_ratio = 0;
        fs_info->defrag_inodes = RB_ROOT;
        fs_info->trans_no_join = 0;
+       fs_info->free_chunk_space = 0;
+
+       /* readahead state */
+       INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);
+       spin_lock_init(&fs_info->reada_lock);
 
        fs_info->thread_pool_size = min_t(unsigned long,
                                          num_online_cpus() + 2, 8);
@@ -1766,14 +2068,14 @@ struct btrfs_root *open_ctree(struct super_block *sb,
                goto fail_alloc;
        }
 
-       memcpy(&fs_info->super_copy, bh->b_data, sizeof(fs_info->super_copy));
-       memcpy(&fs_info->super_for_commit, &fs_info->super_copy,
-              sizeof(fs_info->super_for_commit));
+       memcpy(fs_info->super_copy, bh->b_data, sizeof(*fs_info->super_copy));
+       memcpy(fs_info->super_for_commit, fs_info->super_copy,
+              sizeof(*fs_info->super_for_commit));
        brelse(bh);
 
-       memcpy(fs_info->fsid, fs_info->super_copy.fsid, BTRFS_FSID_SIZE);
+       memcpy(fs_info->fsid, fs_info->super_copy->fsid, BTRFS_FSID_SIZE);
 
-       disk_super = &fs_info->super_copy;
+       disk_super = fs_info->super_copy;
        if (!btrfs_super_root(disk_super))
                goto fail_alloc;
 
@@ -1782,6 +2084,13 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
        btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
 
+       /*
+        * run through our array of backup supers and setup
+        * our ring pointer to the oldest one
+        */
+       generation = btrfs_super_generation(disk_super);
+       find_oldest_super_backup(fs_info, generation);
+
        /*
         * In the long term, we'll store the compression type in the super
         * block, and it'll be used for per file compression control.
@@ -1870,6 +2179,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta",
                           fs_info->thread_pool_size,
                           &fs_info->generic_worker);
+       btrfs_init_workers(&fs_info->readahead_workers, "readahead",
+                          fs_info->thread_pool_size,
+                          &fs_info->generic_worker);
 
        /*
         * endios are largely parallel and should have a very
@@ -1880,6 +2192,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
        fs_info->endio_write_workers.idle_thresh = 2;
        fs_info->endio_meta_write_workers.idle_thresh = 2;
+       fs_info->readahead_workers.idle_thresh = 2;
 
        btrfs_start_workers(&fs_info->workers, 1);
        btrfs_start_workers(&fs_info->generic_worker, 1);
@@ -1893,6 +2206,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_start_workers(&fs_info->endio_freespace_worker, 1);
        btrfs_start_workers(&fs_info->delayed_workers, 1);
        btrfs_start_workers(&fs_info->caching_workers, 1);
+       btrfs_start_workers(&fs_info->readahead_workers, 1);
 
        fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
        fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -1939,7 +2253,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) {
                printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n",
                       sb->s_id);
-               goto fail_chunk_root;
+               goto fail_tree_roots;
        }
        btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
        chunk_root->commit_root = btrfs_root_node(chunk_root);
@@ -1954,11 +2268,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        if (ret) {
                printk(KERN_WARNING "btrfs: failed to read chunk tree on %s\n",
                       sb->s_id);
-               goto fail_chunk_root;
+               goto fail_tree_roots;
        }
 
        btrfs_close_extra_devices(fs_devices);
 
+retry_root_backup:
        blocksize = btrfs_level_size(tree_root,
                                     btrfs_super_root_level(disk_super));
        generation = btrfs_super_generation(disk_super);
@@ -1966,32 +2281,33 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        tree_root->node = read_tree_block(tree_root,
                                          btrfs_super_root(disk_super),
                                          blocksize, generation);
-       if (!tree_root->node)
-               goto fail_chunk_root;
-       if (!test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
+       if (!tree_root->node ||
+           !test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
                printk(KERN_WARNING "btrfs: failed to read tree root on %s\n",
                       sb->s_id);
-               goto fail_tree_root;
+
+               goto recovery_tree_root;
        }
+
        btrfs_set_root_node(&tree_root->root_item, tree_root->node);
        tree_root->commit_root = btrfs_root_node(tree_root);
 
        ret = find_and_setup_root(tree_root, fs_info,
                                  BTRFS_EXTENT_TREE_OBJECTID, extent_root);
        if (ret)
-               goto fail_tree_root;
+               goto recovery_tree_root;
        extent_root->track_dirty = 1;
 
        ret = find_and_setup_root(tree_root, fs_info,
                                  BTRFS_DEV_TREE_OBJECTID, dev_root);
        if (ret)
-               goto fail_extent_root;
+               goto recovery_tree_root;
        dev_root->track_dirty = 1;
 
        ret = find_and_setup_root(tree_root, fs_info,
                                  BTRFS_CSUM_TREE_OBJECTID, csum_root);
        if (ret)
-               goto fail_dev_root;
+               goto recovery_tree_root;
 
        csum_root->track_dirty = 1;
 
@@ -2124,22 +2440,13 @@ fail_cleaner:
 
 fail_block_groups:
        btrfs_free_block_groups(fs_info);
-       free_extent_buffer(csum_root->node);
-       free_extent_buffer(csum_root->commit_root);
-fail_dev_root:
-       free_extent_buffer(dev_root->node);
-       free_extent_buffer(dev_root->commit_root);
-fail_extent_root:
-       free_extent_buffer(extent_root->node);
-       free_extent_buffer(extent_root->commit_root);
-fail_tree_root:
-       free_extent_buffer(tree_root->node);
-       free_extent_buffer(tree_root->commit_root);
-fail_chunk_root:
-       free_extent_buffer(chunk_root->node);
-       free_extent_buffer(chunk_root->commit_root);
+
+fail_tree_roots:
+       free_root_pointers(fs_info, 1);
+
 fail_sb_buffer:
        btrfs_stop_workers(&fs_info->generic_worker);
+       btrfs_stop_workers(&fs_info->readahead_workers);
        btrfs_stop_workers(&fs_info->fixup_workers);
        btrfs_stop_workers(&fs_info->delalloc_workers);
        btrfs_stop_workers(&fs_info->workers);
@@ -2152,25 +2459,37 @@ fail_sb_buffer:
        btrfs_stop_workers(&fs_info->delayed_workers);
        btrfs_stop_workers(&fs_info->caching_workers);
 fail_alloc:
-       kfree(fs_info->delayed_root);
 fail_iput:
+       btrfs_mapping_tree_free(&fs_info->mapping_tree);
+
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
        iput(fs_info->btree_inode);
-
-       btrfs_close_devices(fs_info->fs_devices);
-       btrfs_mapping_tree_free(&fs_info->mapping_tree);
 fail_bdi:
        bdi_destroy(&fs_info->bdi);
 fail_srcu:
        cleanup_srcu_struct(&fs_info->subvol_srcu);
 fail:
-       kfree(extent_root);
-       kfree(tree_root);
-       kfree(fs_info);
-       kfree(chunk_root);
-       kfree(dev_root);
-       kfree(csum_root);
+       btrfs_close_devices(fs_info->fs_devices);
+       free_fs_info(fs_info);
        return ERR_PTR(err);
+
+recovery_tree_root:
+       if (!btrfs_test_opt(tree_root, RECOVERY))
+               goto fail_tree_roots;
+
+       free_root_pointers(fs_info, 0);
+
+       /* don't use the log in recovery mode, it won't be valid */
+       btrfs_set_super_log_root(disk_super, 0);
+
+       /* we can't trust the free space cache either */
+       btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE);
+
+       ret = next_root_backup(fs_info, fs_info->super_copy,
+                              &num_backups_tried, &backup_index);
+       if (ret == -1)
+               goto fail_block_groups;
+       goto retry_root_backup;
 }
 
 static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
@@ -2254,22 +2573,10 @@ static int write_dev_supers(struct btrfs_device *device,
        int errors = 0;
        u32 crc;
        u64 bytenr;
-       int last_barrier = 0;
 
        if (max_mirrors == 0)
                max_mirrors = BTRFS_SUPER_MIRROR_MAX;
 
-       /* make sure only the last submit_bh does a barrier */
-       if (do_barriers) {
-               for (i = 0; i < max_mirrors; i++) {
-                       bytenr = btrfs_sb_offset(i);
-                       if (bytenr + BTRFS_SUPER_INFO_SIZE >=
-                           device->total_bytes)
-                               break;
-                       last_barrier = i;
-               }
-       }
-
        for (i = 0; i < max_mirrors; i++) {
                bytenr = btrfs_sb_offset(i);
                if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes)
@@ -2315,17 +2622,136 @@ static int write_dev_supers(struct btrfs_device *device,
                        bh->b_end_io = btrfs_end_buffer_write_sync;
                }
 
-               if (i == last_barrier && do_barriers)
-                       ret = submit_bh(WRITE_FLUSH_FUA, bh);
-               else
-                       ret = submit_bh(WRITE_SYNC, bh);
-
+               /*
+                * we fua the first super.  The others we allow
+                * to go down lazy.
+                */
+               ret = submit_bh(WRITE_FUA, bh);
                if (ret)
                        errors++;
        }
        return errors < i ? 0 : -1;
 }
 
+/*
+ * endio for the write_dev_flush, this will wake anyone waiting
+ * for the barrier when it is done
+ */
+static void btrfs_end_empty_barrier(struct bio *bio, int err)
+{
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+               clear_bit(BIO_UPTODATE, &bio->bi_flags);
+       }
+       if (bio->bi_private)
+               complete(bio->bi_private);
+       bio_put(bio);
+}
+
+/*
+ * trigger flushes for one the devices.  If you pass wait == 0, the flushes are
+ * sent down.  With wait == 1, it waits for the previous flush.
+ *
+ * any device where the flush fails with eopnotsupp are flagged as not-barrier
+ * capable
+ */
+static int write_dev_flush(struct btrfs_device *device, int wait)
+{
+       struct bio *bio;
+       int ret = 0;
+
+       if (device->nobarriers)
+               return 0;
+
+       if (wait) {
+               bio = device->flush_bio;
+               if (!bio)
+                       return 0;
+
+               wait_for_completion(&device->flush_wait);
+
+               if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
+                       printk("btrfs: disabling barriers on dev %s\n",
+                              device->name);
+                       device->nobarriers = 1;
+               }
+               if (!bio_flagged(bio, BIO_UPTODATE)) {
+                       ret = -EIO;
+               }
+
+               /* drop the reference from the wait == 0 run */
+               bio_put(bio);
+               device->flush_bio = NULL;
+
+               return ret;
+       }
+
+       /*
+        * one reference for us, and we leave it for the
+        * caller
+        */
+       device->flush_bio = NULL;;
+       bio = bio_alloc(GFP_NOFS, 0);
+       if (!bio)
+               return -ENOMEM;
+
+       bio->bi_end_io = btrfs_end_empty_barrier;
+       bio->bi_bdev = device->bdev;
+       init_completion(&device->flush_wait);
+       bio->bi_private = &device->flush_wait;
+       device->flush_bio = bio;
+
+       bio_get(bio);
+       submit_bio(WRITE_FLUSH, bio);
+
+       return 0;
+}
+
+/*
+ * send an empty flush down to each device in parallel,
+ * then wait for them
+ */
+static int barrier_all_devices(struct btrfs_fs_info *info)
+{
+       struct list_head *head;
+       struct btrfs_device *dev;
+       int errors = 0;
+       int ret;
+
+       /* send down all the barriers */
+       head = &info->fs_devices->devices;
+       list_for_each_entry_rcu(dev, head, dev_list) {
+               if (!dev->bdev) {
+                       errors++;
+                       continue;
+               }
+               if (!dev->in_fs_metadata || !dev->writeable)
+                       continue;
+
+               ret = write_dev_flush(dev, 0);
+               if (ret)
+                       errors++;
+       }
+
+       /* wait for all the barriers */
+       list_for_each_entry_rcu(dev, head, dev_list) {
+               if (!dev->bdev) {
+                       errors++;
+                       continue;
+               }
+               if (!dev->in_fs_metadata || !dev->writeable)
+                       continue;
+
+               ret = write_dev_flush(dev, 1);
+               if (ret)
+                       errors++;
+       }
+       if (errors)
+               return -EIO;
+       return 0;
+}
+
 int write_all_supers(struct btrfs_root *root, int max_mirrors)
 {
        struct list_head *head;
@@ -2338,14 +2764,19 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors)
        int total_errors = 0;
        u64 flags;
 
-       max_errors = btrfs_super_num_devices(&root->fs_info->super_copy) - 1;
+       max_errors = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
        do_barriers = !btrfs_test_opt(root, NOBARRIER);
+       backup_super_roots(root->fs_info);
 
-       sb = &root->fs_info->super_for_commit;
+       sb = root->fs_info->super_for_commit;
        dev_item = &sb->dev_item;
 
        mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
        head = &root->fs_info->fs_devices->devices;
+
+       if (do_barriers)
+               barrier_all_devices(root->fs_info);
+
        list_for_each_entry_rcu(dev, head, dev_list) {
                if (!dev->bdev) {
                        total_errors++;
@@ -2545,8 +2976,6 @@ int close_ctree(struct btrfs_root *root)
        /* clear out the rbtree of defraggable inodes */
        btrfs_run_defrag_inodes(root->fs_info);
 
-       btrfs_put_block_group_cache(fs_info);
-
        /*
         * Here come 2 situations when btrfs is broken to flip readonly:
         *
@@ -2572,6 +3001,8 @@ int close_ctree(struct btrfs_root *root)
                        printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
        }
 
+       btrfs_put_block_group_cache(fs_info);
+
        kthread_stop(root->fs_info->transaction_kthread);
        kthread_stop(root->fs_info->cleaner_kthread);
 
@@ -2603,7 +3034,6 @@ int close_ctree(struct btrfs_root *root)
        del_fs_roots(fs_info);
 
        iput(fs_info->btree_inode);
-       kfree(fs_info->delayed_root);
 
        btrfs_stop_workers(&fs_info->generic_worker);
        btrfs_stop_workers(&fs_info->fixup_workers);
@@ -2617,6 +3047,7 @@ int close_ctree(struct btrfs_root *root)
        btrfs_stop_workers(&fs_info->submit_workers);
        btrfs_stop_workers(&fs_info->delayed_workers);
        btrfs_stop_workers(&fs_info->caching_workers);
+       btrfs_stop_workers(&fs_info->readahead_workers);
 
        btrfs_close_devices(fs_info->fs_devices);
        btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@ -2624,12 +3055,7 @@ int close_ctree(struct btrfs_root *root)
        bdi_destroy(&fs_info->bdi);
        cleanup_srcu_struct(&fs_info->subvol_srcu);
 
-       kfree(fs_info->extent_root);
-       kfree(fs_info->tree_root);
-       kfree(fs_info->chunk_root);
-       kfree(fs_info->dev_root);
-       kfree(fs_info->csum_root);
-       kfree(fs_info);
+       free_fs_info(fs_info);
 
        return 0;
 }
@@ -2735,7 +3161,8 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
        return ret;
 }
 
-int btree_lock_page_hook(struct page *page)
+static int btree_lock_page_hook(struct page *page, void *data,
+                               void (*flush_fn)(void *))
 {
        struct inode *inode = page->mapping->host;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -2752,7 +3179,10 @@ int btree_lock_page_hook(struct page *page)
        if (!eb)
                goto out;
 
-       btrfs_tree_lock(eb);
+       if (!btrfs_try_tree_write_lock(eb)) {
+               flush_fn(data);
+               btrfs_tree_lock(eb);
+       }
        btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
 
        if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
@@ -2767,7 +3197,10 @@ int btree_lock_page_hook(struct page *page)
        btrfs_tree_unlock(eb);
        free_extent_buffer(eb);
 out:
-       lock_page(page);
+       if (!trylock_page(page)) {
+               flush_fn(data);
+               lock_page(page);
+       }
        return 0;
 }
 
@@ -3123,6 +3556,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
 static struct extent_io_ops btree_extent_io_ops = {
        .write_cache_pages_lock_hook = btree_lock_page_hook,
        .readpage_end_io_hook = btree_readpage_end_io_hook,
+       .readpage_io_failed_hook = btree_io_failed_hook,
        .submit_bio_hook = btree_submit_bio_hook,
        /* note we're sharing with inode.c for the merge bio hook */
        .merge_bio_hook = btrfs_merge_bio_hook,
index bec3ea4bd67fd465a8a5e008fcae1e7353f573ad..c99d0a8f13fa2f38642f7826cb00c45070ac95ae 100644 (file)
@@ -40,6 +40,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
                                      u32 blocksize, u64 parent_transid);
 int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
                         u64 parent_transid);
+int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
+                        int mirror_num, struct extent_buffer **eb);
 struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
                                                   u64 bytenr, u32 blocksize);
 int clean_tree_block(struct btrfs_trans_handle *trans,
@@ -83,8 +85,6 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
                             struct btrfs_fs_info *fs_info);
 int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
                       struct btrfs_root *root);
-int btree_lock_page_hook(struct page *page);
-
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 void btrfs_init_lockdep(void);
index f5be06a2462f4b01b5bba3834c1527a3a0c5bf18..2ad813674d77e3cb119fa5049c6e5b7407832645 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rcupdate.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
+#include <linux/ratelimit.h>
 #include "compat.h"
 #include "hash.h"
 #include "ctree.h"
@@ -52,6 +53,21 @@ enum {
        CHUNK_ALLOC_LIMITED = 2,
 };
 
+/*
+ * Control how reservations are dealt with.
+ *
+ * RESERVE_FREE - freeing a reservation.
+ * RESERVE_ALLOC - allocating space and we need to update bytes_may_use for
+ *   ENOSPC accounting
+ * RESERVE_ALLOC_NO_ACCOUNT - allocating space and we should not update
+ *   bytes_may_use as the ENOSPC accounting is done elsewhere
+ */
+enum {
+       RESERVE_FREE = 0,
+       RESERVE_ALLOC = 1,
+       RESERVE_ALLOC_NO_ACCOUNT = 2,
+};
+
 static int update_block_group(struct btrfs_trans_handle *trans,
                              struct btrfs_root *root,
                              u64 bytenr, u64 num_bytes, int alloc);
@@ -81,6 +97,8 @@ static int find_next_key(struct btrfs_path *path, int level,
                         struct btrfs_key *key);
 static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
                            int dump_block_groups);
+static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
+                                      u64 num_bytes, int reserve);
 
 static noinline int
 block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -104,7 +122,6 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache)
        if (atomic_dec_and_test(&cache->count)) {
                WARN_ON(cache->pinned > 0);
                WARN_ON(cache->reserved > 0);
-               WARN_ON(cache->reserved_pinned > 0);
                kfree(cache->free_space_ctl);
                kfree(cache);
        }
@@ -450,13 +467,59 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
                             struct btrfs_root *root,
                             int load_cache_only)
 {
+       DEFINE_WAIT(wait);
        struct btrfs_fs_info *fs_info = cache->fs_info;
        struct btrfs_caching_control *caching_ctl;
        int ret = 0;
 
-       smp_mb();
-       if (cache->cached != BTRFS_CACHE_NO)
+       caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
+       BUG_ON(!caching_ctl);
+
+       INIT_LIST_HEAD(&caching_ctl->list);
+       mutex_init(&caching_ctl->mutex);
+       init_waitqueue_head(&caching_ctl->wait);
+       caching_ctl->block_group = cache;
+       caching_ctl->progress = cache->key.objectid;
+       atomic_set(&caching_ctl->count, 1);
+       caching_ctl->work.func = caching_thread;
+
+       spin_lock(&cache->lock);
+       /*
+        * This should be a rare occasion, but this could happen I think in the
+        * case where one thread starts to load the space cache info, and then
+        * some other thread starts a transaction commit which tries to do an
+        * allocation while the other thread is still loading the space cache
+        * info.  The previous loop should have kept us from choosing this block
+        * group, but if we've moved to the state where we will wait on caching
+        * block groups we need to first check if we're doing a fast load here,
+        * so we can wait for it to finish, otherwise we could end up allocating
+        * from a block group who's cache gets evicted for one reason or
+        * another.
+        */
+       while (cache->cached == BTRFS_CACHE_FAST) {
+               struct btrfs_caching_control *ctl;
+
+               ctl = cache->caching_ctl;
+               atomic_inc(&ctl->count);
+               prepare_to_wait(&ctl->wait, &wait, TASK_UNINTERRUPTIBLE);
+               spin_unlock(&cache->lock);
+
+               schedule();
+
+               finish_wait(&ctl->wait, &wait);
+               put_caching_control(ctl);
+               spin_lock(&cache->lock);
+       }
+
+       if (cache->cached != BTRFS_CACHE_NO) {
+               spin_unlock(&cache->lock);
+               kfree(caching_ctl);
                return 0;
+       }
+       WARN_ON(cache->caching_ctl);
+       cache->caching_ctl = caching_ctl;
+       cache->cached = BTRFS_CACHE_FAST;
+       spin_unlock(&cache->lock);
 
        /*
         * We can't do the read from on-disk cache during a commit since we need
@@ -465,57 +528,53 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
         * we likely hold important locks.
         */
        if (trans && (!trans->transaction->in_commit) &&
-           (root && root != root->fs_info->tree_root)) {
-               spin_lock(&cache->lock);
-               if (cache->cached != BTRFS_CACHE_NO) {
-                       spin_unlock(&cache->lock);
-                       return 0;
-               }
-               cache->cached = BTRFS_CACHE_STARTED;
-               spin_unlock(&cache->lock);
-
+           (root && root != root->fs_info->tree_root) &&
+           btrfs_test_opt(root, SPACE_CACHE)) {
                ret = load_free_space_cache(fs_info, cache);
 
                spin_lock(&cache->lock);
                if (ret == 1) {
+                       cache->caching_ctl = NULL;
                        cache->cached = BTRFS_CACHE_FINISHED;
                        cache->last_byte_to_unpin = (u64)-1;
                } else {
-                       cache->cached = BTRFS_CACHE_NO;
+                       if (load_cache_only) {
+                               cache->caching_ctl = NULL;
+                               cache->cached = BTRFS_CACHE_NO;
+                       } else {
+                               cache->cached = BTRFS_CACHE_STARTED;
+                       }
                }
                spin_unlock(&cache->lock);
+               wake_up(&caching_ctl->wait);
                if (ret == 1) {
+                       put_caching_control(caching_ctl);
                        free_excluded_extents(fs_info->extent_root, cache);
                        return 0;
                }
+       } else {
+               /*
+                * We are not going to do the fast caching, set cached to the
+                * appropriate value and wakeup any waiters.
+                */
+               spin_lock(&cache->lock);
+               if (load_cache_only) {
+                       cache->caching_ctl = NULL;
+                       cache->cached = BTRFS_CACHE_NO;
+               } else {
+                       cache->cached = BTRFS_CACHE_STARTED;
+               }
+               spin_unlock(&cache->lock);
+               wake_up(&caching_ctl->wait);
        }
 
-       if (load_cache_only)
-               return 0;
-
-       caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
-       BUG_ON(!caching_ctl);
-
-       INIT_LIST_HEAD(&caching_ctl->list);
-       mutex_init(&caching_ctl->mutex);
-       init_waitqueue_head(&caching_ctl->wait);
-       caching_ctl->block_group = cache;
-       caching_ctl->progress = cache->key.objectid;
-       /* one for caching kthread, one for caching block group list */
-       atomic_set(&caching_ctl->count, 2);
-       caching_ctl->work.func = caching_thread;
-
-       spin_lock(&cache->lock);
-       if (cache->cached != BTRFS_CACHE_NO) {
-               spin_unlock(&cache->lock);
-               kfree(caching_ctl);
+       if (load_cache_only) {
+               put_caching_control(caching_ctl);
                return 0;
        }
-       cache->caching_ctl = caching_ctl;
-       cache->cached = BTRFS_CACHE_STARTED;
-       spin_unlock(&cache->lock);
 
        down_write(&fs_info->extent_commit_sem);
+       atomic_inc(&caching_ctl->count);
        list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups);
        up_write(&fs_info->extent_commit_sem);
 
@@ -1770,18 +1829,18 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
 {
        int ret;
        u64 discarded_bytes = 0;
-       struct btrfs_multi_bio *multi = NULL;
+       struct btrfs_bio *bbio = NULL;
 
 
        /* Tell the block device(s) that the sectors can be discarded */
        ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD,
-                             bytenr, &num_bytes, &multi, 0);
+                             bytenr, &num_bytes, &bbio, 0);
        if (!ret) {
-               struct btrfs_bio_stripe *stripe = multi->stripes;
+               struct btrfs_bio_stripe *stripe = bbio->stripes;
                int i;
 
 
-               for (i = 0; i < multi->num_stripes; i++, stripe++) {
+               for (i = 0; i < bbio->num_stripes; i++, stripe++) {
                        if (!stripe->dev->can_discard)
                                continue;
 
@@ -1800,7 +1859,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
                         */
                        ret = 0;
                }
-               kfree(multi);
+               kfree(bbio);
        }
 
        if (actual_bytes)
@@ -2700,6 +2759,13 @@ again:
                goto again;
        }
 
+       /* We've already setup this transaction, go ahead and exit */
+       if (block_group->cache_generation == trans->transid &&
+           i_size_read(inode)) {
+               dcs = BTRFS_DC_SETUP;
+               goto out_put;
+       }
+
        /*
         * We want to set the generation to 0, that way if anything goes wrong
         * from here on out we know not to trust this cache when we load up next
@@ -2749,12 +2815,15 @@ again:
        if (!ret)
                dcs = BTRFS_DC_SETUP;
        btrfs_free_reserved_data_space(inode, num_pages);
+
 out_put:
        iput(inode);
 out_free:
        btrfs_release_path(path);
 out:
        spin_lock(&block_group->lock);
+       if (!ret)
+               block_group->cache_generation = trans->transid;
        block_group->disk_cache_state = dcs;
        spin_unlock(&block_group->lock);
 
@@ -3122,16 +3191,13 @@ commit_trans:
                return -ENOSPC;
        }
        data_sinfo->bytes_may_use += bytes;
-       BTRFS_I(inode)->reserved_bytes += bytes;
        spin_unlock(&data_sinfo->lock);
 
        return 0;
 }
 
 /*
- * called when we are clearing an delalloc extent from the
- * inode's io_tree or there was an error for whatever reason
- * after calling btrfs_check_data_free_space
+ * Called if we need to clear a data reservation for this inode.
  */
 void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
 {
@@ -3144,7 +3210,6 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
        data_sinfo = BTRFS_I(inode)->space_info;
        spin_lock(&data_sinfo->lock);
        data_sinfo->bytes_may_use -= bytes;
-       BTRFS_I(inode)->reserved_bytes -= bytes;
        spin_unlock(&data_sinfo->lock);
 }
 
@@ -3165,6 +3230,7 @@ static int should_alloc_chunk(struct btrfs_root *root,
                              struct btrfs_space_info *sinfo, u64 alloc_bytes,
                              int force)
 {
+       struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
        u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
        u64 num_allocated = sinfo->bytes_used + sinfo->bytes_reserved;
        u64 thresh;
@@ -3172,12 +3238,19 @@ static int should_alloc_chunk(struct btrfs_root *root,
        if (force == CHUNK_ALLOC_FORCE)
                return 1;
 
+       /*
+        * We need to take into account the global rsv because for all intents
+        * and purposes it's used space.  Don't worry about locking the
+        * global_rsv, it doesn't change except when the transaction commits.
+        */
+       num_allocated += global_rsv->size;
+
        /*
         * in limited mode, we want to have some free space up to
         * about 1% of the FS size.
         */
        if (force == CHUNK_ALLOC_LIMITED) {
-               thresh = btrfs_super_total_bytes(&root->fs_info->super_copy);
+               thresh = btrfs_super_total_bytes(root->fs_info->super_copy);
                thresh = max_t(u64, 64 * 1024 * 1024,
                               div_factor_fine(thresh, 1));
 
@@ -3199,7 +3272,7 @@ static int should_alloc_chunk(struct btrfs_root *root,
        if (num_allocated + alloc_bytes < div_factor(num_bytes, 8))
                return 0;
 
-       thresh = btrfs_super_total_bytes(&root->fs_info->super_copy);
+       thresh = btrfs_super_total_bytes(root->fs_info->super_copy);
 
        /* 256MB or 5% of the FS */
        thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5));
@@ -3302,24 +3375,26 @@ out:
 /*
  * shrink metadata reservation for delalloc
  */
-static int shrink_delalloc(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root, u64 to_reclaim, int sync)
+static int shrink_delalloc(struct btrfs_root *root, u64 to_reclaim,
+                          bool wait_ordered)
 {
        struct btrfs_block_rsv *block_rsv;
        struct btrfs_space_info *space_info;
+       struct btrfs_trans_handle *trans;
        u64 reserved;
        u64 max_reclaim;
        u64 reclaimed = 0;
        long time_left;
-       int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
+       unsigned long nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
        int loops = 0;
        unsigned long progress;
 
+       trans = (struct btrfs_trans_handle *)current->journal_info;
        block_rsv = &root->fs_info->delalloc_block_rsv;
        space_info = block_rsv->space_info;
 
        smp_mb();
-       reserved = space_info->bytes_reserved;
+       reserved = space_info->bytes_may_use;
        progress = space_info->reservation_progress;
 
        if (reserved == 0)
@@ -3334,18 +3409,20 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
        }
 
        max_reclaim = min(reserved, to_reclaim);
-
+       nr_pages = max_t(unsigned long, nr_pages,
+                        max_reclaim >> PAGE_CACHE_SHIFT);
        while (loops < 1024) {
                /* have the flusher threads jump in and do some IO */
                smp_mb();
                nr_pages = min_t(unsigned long, nr_pages,
                       root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT);
-               writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
+               writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages,
+                                               WB_REASON_FS_FREE_SPACE);
 
                spin_lock(&space_info->lock);
-               if (reserved > space_info->bytes_reserved)
-                       reclaimed += reserved - space_info->bytes_reserved;
-               reserved = space_info->bytes_reserved;
+               if (reserved > space_info->bytes_may_use)
+                       reclaimed += reserved - space_info->bytes_may_use;
+               reserved = space_info->bytes_may_use;
                spin_unlock(&space_info->lock);
 
                loops++;
@@ -3356,11 +3433,15 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
                if (trans && trans->transaction->blocked)
                        return -EAGAIN;
 
-               time_left = schedule_timeout_interruptible(1);
+               if (wait_ordered && !trans) {
+                       btrfs_wait_ordered_extents(root, 0, 0);
+               } else {
+                       time_left = schedule_timeout_interruptible(1);
 
-               /* We were interrupted, exit */
-               if (time_left)
-                       break;
+                       /* We were interrupted, exit */
+                       if (time_left)
+                               break;
+               }
 
                /* we've kicked the IO a few times, if anything has been freed,
                 * exit.  There is no sense in looping here for a long time
@@ -3375,34 +3456,90 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
                }
 
        }
-       if (reclaimed >= to_reclaim && !trans)
-               btrfs_wait_ordered_extents(root, 0, 0);
+
        return reclaimed >= to_reclaim;
 }
 
-/*
- * Retries tells us how many times we've called reserve_metadata_bytes.  The
- * idea is if this is the first call (retries == 0) then we will add to our
- * reserved count if we can't make the allocation in order to hold our place
- * while we go and try and free up space.  That way for retries > 1 we don't try
- * and add space, we just check to see if the amount of unused space is >= the
- * total space, meaning that our reservation is valid.
+/**
+ * maybe_commit_transaction - possibly commit the transaction if its ok to
+ * @root - the root we're allocating for
+ * @bytes - the number of bytes we want to reserve
+ * @force - force the commit
  *
- * However if we don't intend to retry this reservation, pass -1 as retries so
- * that it short circuits this logic.
+ * This will check to make sure that committing the transaction will actually
+ * get us somewhere and then commit the transaction if it does.  Otherwise it
+ * will return -ENOSPC.
  */
-static int reserve_metadata_bytes(struct btrfs_trans_handle *trans,
-                                 struct btrfs_root *root,
+static int may_commit_transaction(struct btrfs_root *root,
+                                 struct btrfs_space_info *space_info,
+                                 u64 bytes, int force)
+{
+       struct btrfs_block_rsv *delayed_rsv = &root->fs_info->delayed_block_rsv;
+       struct btrfs_trans_handle *trans;
+
+       trans = (struct btrfs_trans_handle *)current->journal_info;
+       if (trans)
+               return -EAGAIN;
+
+       if (force)
+               goto commit;
+
+       /* See if there is enough pinned space to make this reservation */
+       spin_lock(&space_info->lock);
+       if (space_info->bytes_pinned >= bytes) {
+               spin_unlock(&space_info->lock);
+               goto commit;
+       }
+       spin_unlock(&space_info->lock);
+
+       /*
+        * See if there is some space in the delayed insertion reservation for
+        * this reservation.
+        */
+       if (space_info != delayed_rsv->space_info)
+               return -ENOSPC;
+
+       spin_lock(&delayed_rsv->lock);
+       if (delayed_rsv->size < bytes) {
+               spin_unlock(&delayed_rsv->lock);
+               return -ENOSPC;
+       }
+       spin_unlock(&delayed_rsv->lock);
+
+commit:
+       trans = btrfs_join_transaction(root);
+       if (IS_ERR(trans))
+               return -ENOSPC;
+
+       return btrfs_commit_transaction(trans, root);
+}
+
+/**
+ * reserve_metadata_bytes - try to reserve bytes from the block_rsv's space
+ * @root - the root we're allocating for
+ * @block_rsv - the block_rsv we're allocating for
+ * @orig_bytes - the number of bytes we want
+ * @flush - wether or not we can flush to make our reservation
+ *
+ * This will reserve orgi_bytes number of bytes from the space info associated
+ * with the block_rsv.  If there is not enough space it will make an attempt to
+ * flush out space to make room.  It will do this by flushing delalloc if
+ * possible or committing the transaction.  If flush is 0 then no attempts to
+ * regain reservations will be made and this will fail if there is not enough
+ * space already.
+ */
+static int reserve_metadata_bytes(struct btrfs_root *root,
                                  struct btrfs_block_rsv *block_rsv,
                                  u64 orig_bytes, int flush)
 {
        struct btrfs_space_info *space_info = block_rsv->space_info;
-       u64 unused;
+       u64 used;
        u64 num_bytes = orig_bytes;
        int retries = 0;
        int ret = 0;
        bool committed = false;
        bool flushing = false;
+       bool wait_ordered = false;
 
 again:
        ret = 0;
@@ -3419,7 +3556,7 @@ again:
                 * deadlock since we are waiting for the flusher to finish, but
                 * hold the current transaction open.
                 */
-               if (trans)
+               if (current->journal_info)
                        return -EAGAIN;
                ret = wait_event_interruptible(space_info->wait,
                                               !space_info->flush);
@@ -3431,9 +3568,9 @@ again:
        }
 
        ret = -ENOSPC;
-       unused = space_info->bytes_used + space_info->bytes_reserved +
-                space_info->bytes_pinned + space_info->bytes_readonly +
-                space_info->bytes_may_use;
+       used = space_info->bytes_used + space_info->bytes_reserved +
+               space_info->bytes_pinned + space_info->bytes_readonly +
+               space_info->bytes_may_use;
 
        /*
         * The idea here is that we've not already over-reserved the block group
@@ -3442,10 +3579,9 @@ again:
         * lets start flushing stuff first and then come back and try to make
         * our reservation.
         */
-       if (unused <= space_info->total_bytes) {
-               unused = space_info->total_bytes - unused;
-               if (unused >= num_bytes) {
-                       space_info->bytes_reserved += orig_bytes;
+       if (used <= space_info->total_bytes) {
+               if (used + orig_bytes <= space_info->total_bytes) {
+                       space_info->bytes_may_use += orig_bytes;
                        ret = 0;
                } else {
                        /*
@@ -3461,10 +3597,64 @@ again:
                 * amount plus the amount of bytes that we need for this
                 * reservation.
                 */
-               num_bytes = unused - space_info->total_bytes +
+               wait_ordered = true;
+               num_bytes = used - space_info->total_bytes +
                        (orig_bytes * (retries + 1));
        }
 
+       if (ret) {
+               u64 profile = btrfs_get_alloc_profile(root, 0);
+               u64 avail;
+
+               /*
+                * If we have a lot of space that's pinned, don't bother doing
+                * the overcommit dance yet and just commit the transaction.
+                */
+               avail = (space_info->total_bytes - space_info->bytes_used) * 8;
+               do_div(avail, 10);
+               if (space_info->bytes_pinned >= avail && flush && !committed) {
+                       space_info->flush = 1;
+                       flushing = true;
+                       spin_unlock(&space_info->lock);
+                       ret = may_commit_transaction(root, space_info,
+                                                    orig_bytes, 1);
+                       if (ret)
+                               goto out;
+                       committed = true;
+                       goto again;
+               }
+
+               spin_lock(&root->fs_info->free_chunk_lock);
+               avail = root->fs_info->free_chunk_space;
+
+               /*
+                * If we have dup, raid1 or raid10 then only half of the free
+                * space is actually useable.
+                */
+               if (profile & (BTRFS_BLOCK_GROUP_DUP |
+                              BTRFS_BLOCK_GROUP_RAID1 |
+                              BTRFS_BLOCK_GROUP_RAID10))
+                       avail >>= 1;
+
+               /*
+                * If we aren't flushing don't let us overcommit too much, say
+                * 1/8th of the space.  If we can flush, let it overcommit up to
+                * 1/2 of the space.
+                */
+               if (flush)
+                       avail >>= 3;
+               else
+                       avail >>= 1;
+                spin_unlock(&root->fs_info->free_chunk_lock);
+
+               if (used + num_bytes < space_info->total_bytes + avail) {
+                       space_info->bytes_may_use += orig_bytes;
+                       ret = 0;
+               } else {
+                       wait_ordered = true;
+               }
+       }
+
        /*
         * Couldn't make our reservation, save our place so while we're trying
         * to reclaim space we can actually use it instead of somebody else
@@ -3484,7 +3674,7 @@ again:
         * We do synchronous shrinking since we don't actually unreserve
         * metadata until after the IO is completed.
         */
-       ret = shrink_delalloc(trans, root, num_bytes, 1);
+       ret = shrink_delalloc(root, num_bytes, wait_ordered);
        if (ret < 0)
                goto out;
 
@@ -3496,35 +3686,17 @@ again:
         * so go back around and try again.
         */
        if (retries < 2) {
+               wait_ordered = true;
                retries++;
                goto again;
        }
 
-       /*
-        * Not enough space to be reclaimed, don't bother committing the
-        * transaction.
-        */
-       spin_lock(&space_info->lock);
-       if (space_info->bytes_pinned < orig_bytes)
-               ret = -ENOSPC;
-       spin_unlock(&space_info->lock);
-       if (ret)
-               goto out;
-
-       ret = -EAGAIN;
-       if (trans)
-               goto out;
-
        ret = -ENOSPC;
        if (committed)
                goto out;
 
-       trans = btrfs_join_transaction(root);
-       if (IS_ERR(trans))
-               goto out;
-       ret = btrfs_commit_transaction(trans, root);
+       ret = may_commit_transaction(root, space_info, orig_bytes, 0);
        if (!ret) {
-               trans = NULL;
                committed = true;
                goto again;
        }
@@ -3542,10 +3714,12 @@ out:
 static struct btrfs_block_rsv *get_block_rsv(struct btrfs_trans_handle *trans,
                                             struct btrfs_root *root)
 {
-       struct btrfs_block_rsv *block_rsv;
-       if (root->ref_cows)
+       struct btrfs_block_rsv *block_rsv = NULL;
+
+       if (root->ref_cows || root == root->fs_info->csum_root)
                block_rsv = trans->block_rsv;
-       else
+
+       if (!block_rsv)
                block_rsv = root->block_rsv;
 
        if (!block_rsv)
@@ -3616,7 +3790,7 @@ static void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
                }
                if (num_bytes) {
                        spin_lock(&space_info->lock);
-                       space_info->bytes_reserved -= num_bytes;
+                       space_info->bytes_may_use -= num_bytes;
                        space_info->reservation_progress++;
                        spin_unlock(&space_info->lock);
                }
@@ -3640,9 +3814,6 @@ void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv)
 {
        memset(rsv, 0, sizeof(*rsv));
        spin_lock_init(&rsv->lock);
-       atomic_set(&rsv->usage, 1);
-       rsv->priority = 6;
-       INIT_LIST_HEAD(&rsv->list);
 }
 
 struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
@@ -3663,38 +3834,20 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
 void btrfs_free_block_rsv(struct btrfs_root *root,
                          struct btrfs_block_rsv *rsv)
 {
-       if (rsv && atomic_dec_and_test(&rsv->usage)) {
-               btrfs_block_rsv_release(root, rsv, (u64)-1);
-               if (!rsv->durable)
-                       kfree(rsv);
-       }
-}
-
-/*
- * make the block_rsv struct be able to capture freed space.
- * the captured space will re-add to the the block_rsv struct
- * after transaction commit
- */
-void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info,
-                                struct btrfs_block_rsv *block_rsv)
-{
-       block_rsv->durable = 1;
-       mutex_lock(&fs_info->durable_block_rsv_mutex);
-       list_add_tail(&block_rsv->list, &fs_info->durable_block_rsv_list);
-       mutex_unlock(&fs_info->durable_block_rsv_mutex);
+       btrfs_block_rsv_release(root, rsv, (u64)-1);
+       kfree(rsv);
 }
 
-int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
-                       struct btrfs_root *root,
-                       struct btrfs_block_rsv *block_rsv,
-                       u64 num_bytes)
+static inline int __block_rsv_add(struct btrfs_root *root,
+                                 struct btrfs_block_rsv *block_rsv,
+                                 u64 num_bytes, int flush)
 {
        int ret;
 
        if (num_bytes == 0)
                return 0;
 
-       ret = reserve_metadata_bytes(trans, root, block_rsv, num_bytes, 1);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 1);
                return 0;
@@ -3703,55 +3856,80 @@ int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
-                         struct btrfs_root *root,
-                         struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved, int min_factor)
+int btrfs_block_rsv_add(struct btrfs_root *root,
+                       struct btrfs_block_rsv *block_rsv,
+                       u64 num_bytes)
+{
+       return __block_rsv_add(root, block_rsv, num_bytes, 1);
+}
+
+int btrfs_block_rsv_add_noflush(struct btrfs_root *root,
+                               struct btrfs_block_rsv *block_rsv,
+                               u64 num_bytes)
+{
+       return __block_rsv_add(root, block_rsv, num_bytes, 0);
+}
+
+int btrfs_block_rsv_check(struct btrfs_root *root,
+                         struct btrfs_block_rsv *block_rsv, int min_factor)
 {
        u64 num_bytes = 0;
-       int commit_trans = 0;
        int ret = -ENOSPC;
 
        if (!block_rsv)
                return 0;
 
        spin_lock(&block_rsv->lock);
-       if (min_factor > 0)
-               num_bytes = div_factor(block_rsv->size, min_factor);
-       if (min_reserved > num_bytes)
-               num_bytes = min_reserved;
+       num_bytes = div_factor(block_rsv->size, min_factor);
+       if (block_rsv->reserved >= num_bytes)
+               ret = 0;
+       spin_unlock(&block_rsv->lock);
 
-       if (block_rsv->reserved >= num_bytes) {
+       return ret;
+}
+
+static inline int __btrfs_block_rsv_refill(struct btrfs_root *root,
+                                          struct btrfs_block_rsv *block_rsv,
+                                          u64 min_reserved, int flush)
+{
+       u64 num_bytes = 0;
+       int ret = -ENOSPC;
+
+       if (!block_rsv)
+               return 0;
+
+       spin_lock(&block_rsv->lock);
+       num_bytes = min_reserved;
+       if (block_rsv->reserved >= num_bytes)
                ret = 0;
-       } else {
+       else
                num_bytes -= block_rsv->reserved;
-               if (block_rsv->durable &&
-                   block_rsv->freed[0] + block_rsv->freed[1] >= num_bytes)
-                       commit_trans = 1;
-       }
        spin_unlock(&block_rsv->lock);
+
        if (!ret)
                return 0;
 
-       if (block_rsv->refill_used) {
-               ret = reserve_metadata_bytes(trans, root, block_rsv,
-                                            num_bytes, 0);
-               if (!ret) {
-                       block_rsv_add_bytes(block_rsv, num_bytes, 0);
-                       return 0;
-               }
-       }
-
-       if (commit_trans) {
-               if (trans)
-                       return -EAGAIN;
-               trans = btrfs_join_transaction(root);
-               BUG_ON(IS_ERR(trans));
-               ret = btrfs_commit_transaction(trans, root);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
+       if (!ret) {
+               block_rsv_add_bytes(block_rsv, num_bytes, 0);
                return 0;
        }
 
-       return -ENOSPC;
+       return ret;
+}
+
+int btrfs_block_rsv_refill(struct btrfs_root *root,
+                          struct btrfs_block_rsv *block_rsv,
+                          u64 min_reserved)
+{
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 1);
+}
+
+int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
+                                  struct btrfs_block_rsv *block_rsv,
+                                  u64 min_reserved)
+{
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 0);
 }
 
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
@@ -3783,7 +3961,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
        u64 num_bytes;
        u64 meta_used;
        u64 data_used;
-       int csum_size = btrfs_super_csum_size(&fs_info->super_copy);
+       int csum_size = btrfs_super_csum_size(fs_info->super_copy);
 
        sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA);
        spin_lock(&sinfo->lock);
@@ -3827,12 +4005,12 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
        if (sinfo->total_bytes > num_bytes) {
                num_bytes = sinfo->total_bytes - num_bytes;
                block_rsv->reserved += num_bytes;
-               sinfo->bytes_reserved += num_bytes;
+               sinfo->bytes_may_use += num_bytes;
        }
 
        if (block_rsv->reserved >= block_rsv->size) {
                num_bytes = block_rsv->reserved - block_rsv->size;
-               sinfo->bytes_reserved -= num_bytes;
+               sinfo->bytes_may_use -= num_bytes;
                sinfo->reservation_progress++;
                block_rsv->reserved = block_rsv->size;
                block_rsv->full = 1;
@@ -3848,16 +4026,13 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
 
        space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
        fs_info->chunk_block_rsv.space_info = space_info;
-       fs_info->chunk_block_rsv.priority = 10;
 
        space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
        fs_info->global_block_rsv.space_info = space_info;
-       fs_info->global_block_rsv.priority = 10;
-       fs_info->global_block_rsv.refill_used = 1;
        fs_info->delalloc_block_rsv.space_info = space_info;
        fs_info->trans_block_rsv.space_info = space_info;
        fs_info->empty_block_rsv.space_info = space_info;
-       fs_info->empty_block_rsv.priority = 10;
+       fs_info->delayed_block_rsv.space_info = space_info;
 
        fs_info->extent_root->block_rsv = &fs_info->global_block_rsv;
        fs_info->csum_root->block_rsv = &fs_info->global_block_rsv;
@@ -3865,10 +4040,6 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
        fs_info->tree_root->block_rsv = &fs_info->global_block_rsv;
        fs_info->chunk_root->block_rsv = &fs_info->chunk_block_rsv;
 
-       btrfs_add_durable_block_rsv(fs_info, &fs_info->global_block_rsv);
-
-       btrfs_add_durable_block_rsv(fs_info, &fs_info->delalloc_block_rsv);
-
        update_global_block_rsv(fs_info);
 }
 
@@ -3881,37 +4052,8 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
        WARN_ON(fs_info->trans_block_rsv.reserved > 0);
        WARN_ON(fs_info->chunk_block_rsv.size > 0);
        WARN_ON(fs_info->chunk_block_rsv.reserved > 0);
-}
-
-int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
-                                   struct btrfs_root *root,
-                                   struct btrfs_block_rsv *rsv)
-{
-       struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv;
-       u64 num_bytes;
-       int ret;
-
-       /*
-        * Truncate should be freeing data, but give us 2 items just in case it
-        * needs to use some space.  We may want to be smarter about this in the
-        * future.
-        */
-       num_bytes = btrfs_calc_trans_metadata_size(root, 2);
-
-       /* We already have enough bytes, just return */
-       if (rsv->reserved >= num_bytes)
-               return 0;
-
-       num_bytes -= rsv->reserved;
-
-       /*
-        * You should have reserved enough space before hand to do this, so this
-        * should not fail.
-        */
-       ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes);
-       BUG_ON(ret);
-
-       return 0;
+       WARN_ON(fs_info->delayed_block_rsv.size > 0);
+       WARN_ON(fs_info->delayed_block_rsv.reserved > 0);
 }
 
 void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
@@ -3920,9 +4062,7 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
        if (!trans->bytes_reserved)
                return;
 
-       BUG_ON(trans->block_rsv != &root->fs_info->trans_block_rsv);
-       btrfs_block_rsv_release(root, trans->block_rsv,
-                               trans->bytes_reserved);
+       btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
        trans->bytes_reserved = 0;
 }
 
@@ -3964,33 +4104,99 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans,
        return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
 }
 
+/**
+ * drop_outstanding_extent - drop an outstanding extent
+ * @inode: the inode we're dropping the extent for
+ *
+ * This is called when we are freeing up an outstanding extent, either called
+ * after an error or after an extent is written.  This will return the number of
+ * reserved extents that need to be freed.  This must be called with
+ * BTRFS_I(inode)->lock held.
+ */
 static unsigned drop_outstanding_extent(struct inode *inode)
 {
+       unsigned drop_inode_space = 0;
        unsigned dropped_extents = 0;
 
-       spin_lock(&BTRFS_I(inode)->lock);
        BUG_ON(!BTRFS_I(inode)->outstanding_extents);
        BTRFS_I(inode)->outstanding_extents--;
 
+       if (BTRFS_I(inode)->outstanding_extents == 0 &&
+           BTRFS_I(inode)->delalloc_meta_reserved) {
+               drop_inode_space = 1;
+               BTRFS_I(inode)->delalloc_meta_reserved = 0;
+       }
+
        /*
         * If we have more or the same amount of outsanding extents than we have
         * reserved then we need to leave the reserved extents count alone.
         */
        if (BTRFS_I(inode)->outstanding_extents >=
            BTRFS_I(inode)->reserved_extents)
-               goto out;
+               return drop_inode_space;
 
        dropped_extents = BTRFS_I(inode)->reserved_extents -
                BTRFS_I(inode)->outstanding_extents;
        BTRFS_I(inode)->reserved_extents -= dropped_extents;
-out:
-       spin_unlock(&BTRFS_I(inode)->lock);
-       return dropped_extents;
+       return dropped_extents + drop_inode_space;
 }
 
-static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes)
+/**
+ * calc_csum_metadata_size - return the amount of metada space that must be
+ *     reserved/free'd for the given bytes.
+ * @inode: the inode we're manipulating
+ * @num_bytes: the number of bytes in question
+ * @reserve: 1 if we are reserving space, 0 if we are freeing space
+ *
+ * This adjusts the number of csum_bytes in the inode and then returns the
+ * correct amount of metadata that must either be reserved or freed.  We
+ * calculate how many checksums we can fit into one leaf and then divide the
+ * number of bytes that will need to be checksumed by this value to figure out
+ * how many checksums will be required.  If we are adding bytes then the number
+ * may go up and we will return the number of additional bytes that must be
+ * reserved.  If it is going down we will return the number of bytes that must
+ * be freed.
+ *
+ * This must be called with BTRFS_I(inode)->lock held.
+ */
+static u64 calc_csum_metadata_size(struct inode *inode, u64 num_bytes,
+                                  int reserve)
 {
-       return num_bytes >>= 3;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       u64 csum_size;
+       int num_csums_per_leaf;
+       int num_csums;
+       int old_csums;
+
+       if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM &&
+           BTRFS_I(inode)->csum_bytes == 0)
+               return 0;
+
+       old_csums = (int)div64_u64(BTRFS_I(inode)->csum_bytes, root->sectorsize);
+       if (reserve)
+               BTRFS_I(inode)->csum_bytes += num_bytes;
+       else
+               BTRFS_I(inode)->csum_bytes -= num_bytes;
+       csum_size = BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item);
+       num_csums_per_leaf = (int)div64_u64(csum_size,
+                                           sizeof(struct btrfs_csum_item) +
+                                           sizeof(struct btrfs_disk_key));
+       num_csums = (int)div64_u64(BTRFS_I(inode)->csum_bytes, root->sectorsize);
+       num_csums = num_csums + num_csums_per_leaf - 1;
+       num_csums = num_csums / num_csums_per_leaf;
+
+       old_csums = old_csums + num_csums_per_leaf - 1;
+       old_csums = old_csums / num_csums_per_leaf;
+
+       /* No change, no need to reserve more */
+       if (old_csums == num_csums)
+               return 0;
+
+       if (reserve)
+               return btrfs_calc_trans_metadata_size(root,
+                                                     num_csums - old_csums);
+
+       return btrfs_calc_trans_metadata_size(root, old_csums - num_csums);
 }
 
 int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
@@ -3999,9 +4205,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv;
        u64 to_reserve = 0;
        unsigned nr_extents = 0;
+       int flush = 1;
        int ret;
 
-       if (btrfs_transaction_in_commit(root->fs_info))
+       if (btrfs_is_free_space_inode(root, inode))
+               flush = 0;
+
+       if (flush && btrfs_transaction_in_commit(root->fs_info))
                schedule_timeout(1);
 
        num_bytes = ALIGN(num_bytes, root->sectorsize);
@@ -4014,21 +4224,41 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
                nr_extents = BTRFS_I(inode)->outstanding_extents -
                        BTRFS_I(inode)->reserved_extents;
                BTRFS_I(inode)->reserved_extents += nr_extents;
+       }
 
-               to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
+       /*
+        * Add an item to reserve for updating the inode when we complete the
+        * delalloc io.
+        */
+       if (!BTRFS_I(inode)->delalloc_meta_reserved) {
+               nr_extents++;
+               BTRFS_I(inode)->delalloc_meta_reserved = 1;
        }
+
+       to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents);
+       to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
        spin_unlock(&BTRFS_I(inode)->lock);
 
-       to_reserve += calc_csum_metadata_size(inode, num_bytes);
-       ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1);
+       ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
        if (ret) {
+               u64 to_free = 0;
                unsigned dropped;
+
+               spin_lock(&BTRFS_I(inode)->lock);
+               dropped = drop_outstanding_extent(inode);
+               to_free = calc_csum_metadata_size(inode, num_bytes, 0);
+               spin_unlock(&BTRFS_I(inode)->lock);
+               to_free += btrfs_calc_trans_metadata_size(root, dropped);
+
                /*
-                * We don't need the return value since our reservation failed,
-                * we just need to clean up our counter.
+                * Somebody could have come in and twiddled with the
+                * reservation, so if we have to free more than we would have
+                * reserved from this reservation go ahead and release those
+                * bytes.
                 */
-               dropped = drop_outstanding_extent(inode);
-               WARN_ON(dropped > 1);
+               to_free -= to_reserve;
+               if (to_free)
+                       btrfs_block_rsv_release(root, block_rsv, to_free);
                return ret;
        }
 
@@ -4037,6 +4267,15 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        return 0;
 }
 
+/**
+ * btrfs_delalloc_release_metadata - release a metadata reservation for an inode
+ * @inode: the inode to release the reservation for
+ * @num_bytes: the number of bytes we're releasing
+ *
+ * This will release the metadata reservation for an inode.  This can be called
+ * once we complete IO for a given set of bytes to release their metadata
+ * reservations.
+ */
 void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -4044,9 +4283,11 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
        unsigned dropped;
 
        num_bytes = ALIGN(num_bytes, root->sectorsize);
+       spin_lock(&BTRFS_I(inode)->lock);
        dropped = drop_outstanding_extent(inode);
 
-       to_free = calc_csum_metadata_size(inode, num_bytes);
+       to_free = calc_csum_metadata_size(inode, num_bytes, 0);
+       spin_unlock(&BTRFS_I(inode)->lock);
        if (dropped > 0)
                to_free += btrfs_calc_trans_metadata_size(root, dropped);
 
@@ -4054,6 +4295,21 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
                                to_free);
 }
 
+/**
+ * btrfs_delalloc_reserve_space - reserve data and metadata space for delalloc
+ * @inode: inode we're writing to
+ * @num_bytes: the number of bytes we want to allocate
+ *
+ * This will do the following things
+ *
+ * o reserve space in the data space info for num_bytes
+ * o reserve space in the metadata space info based on number of outstanding
+ *   extents and how much csums will be needed
+ * o add to the inodes ->delalloc_bytes
+ * o add it to the fs_info's delalloc inodes list.
+ *
+ * This will return 0 for success and -ENOSPC if there is no space left.
+ */
 int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes)
 {
        int ret;
@@ -4071,6 +4327,19 @@ int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes)
        return 0;
 }
 
+/**
+ * btrfs_delalloc_release_space - release data and metadata space for delalloc
+ * @inode: inode we're releasing space for
+ * @num_bytes: the number of bytes we want to free up
+ *
+ * This must be matched with a call to btrfs_delalloc_reserve_space.  This is
+ * called in the case that we don't need the metadata AND data reservations
+ * anymore.  So if there is an error or we insert an inline extent.
+ *
+ * This function will release the metadata space that was not used and will
+ * decrement ->delalloc_bytes and remove it from the fs_info delalloc_inodes
+ * list if there are no delalloc bytes left.
+ */
 void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes)
 {
        btrfs_delalloc_release_metadata(inode, num_bytes);
@@ -4090,12 +4359,12 @@ static int update_block_group(struct btrfs_trans_handle *trans,
 
        /* block accounting for super block */
        spin_lock(&info->delalloc_lock);
-       old_val = btrfs_super_bytes_used(&info->super_copy);
+       old_val = btrfs_super_bytes_used(info->super_copy);
        if (alloc)
                old_val += num_bytes;
        else
                old_val -= num_bytes;
-       btrfs_set_super_bytes_used(&info->super_copy, old_val);
+       btrfs_set_super_bytes_used(info->super_copy, old_val);
        spin_unlock(&info->delalloc_lock);
 
        while (total) {
@@ -4123,7 +4392,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                spin_lock(&cache->space_info->lock);
                spin_lock(&cache->lock);
 
-               if (btrfs_super_cache_generation(&info->super_copy) != 0 &&
+               if (btrfs_test_opt(root, SPACE_CACHE) &&
                    cache->disk_cache_state < BTRFS_DC_CLEAR)
                        cache->disk_cache_state = BTRFS_DC_CLEAR;
 
@@ -4135,7 +4404,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                        btrfs_set_block_group_used(&cache->item, old_val);
                        cache->reserved -= num_bytes;
                        cache->space_info->bytes_reserved -= num_bytes;
-                       cache->space_info->reservation_progress++;
                        cache->space_info->bytes_used += num_bytes;
                        cache->space_info->disk_used += num_bytes * factor;
                        spin_unlock(&cache->lock);
@@ -4187,7 +4455,6 @@ static int pin_down_extent(struct btrfs_root *root,
        if (reserved) {
                cache->reserved -= num_bytes;
                cache->space_info->bytes_reserved -= num_bytes;
-               cache->space_info->reservation_progress++;
        }
        spin_unlock(&cache->lock);
        spin_unlock(&cache->space_info->lock);
@@ -4215,45 +4482,82 @@ int btrfs_pin_extent(struct btrfs_root *root,
 }
 
 /*
- * update size of reserved extents. this function may return -EAGAIN
- * if 'reserve' is true or 'sinfo' is false.
+ * this function must be called within transaction
+ */
+int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
+                                   struct btrfs_root *root,
+                                   u64 bytenr, u64 num_bytes)
+{
+       struct btrfs_block_group_cache *cache;
+
+       cache = btrfs_lookup_block_group(root->fs_info, bytenr);
+       BUG_ON(!cache);
+
+       /*
+        * pull in the free space cache (if any) so that our pin
+        * removes the free space from the cache.  We have load_only set
+        * to one because the slow code to read in the free extents does check
+        * the pinned extents.
+        */
+       cache_block_group(cache, trans, root, 1);
+
+       pin_down_extent(root, cache, bytenr, num_bytes, 0);
+
+       /* remove us from the free space cache (if we're there at all) */
+       btrfs_remove_free_space(cache, bytenr, num_bytes);
+       btrfs_put_block_group(cache);
+       return 0;
+}
+
+/**
+ * btrfs_update_reserved_bytes - update the block_group and space info counters
+ * @cache:     The cache we are manipulating
+ * @num_bytes: The number of bytes in question
+ * @reserve:   One of the reservation enums
+ *
+ * This is called by the allocator when it reserves space, or by somebody who is
+ * freeing space that was never actually used on disk.  For example if you
+ * reserve some space for a new leaf in transaction A and before transaction A
+ * commits you free that leaf, you call this with reserve set to 0 in order to
+ * clear the reservation.
+ *
+ * Metadata reservations should be called with RESERVE_ALLOC so we do the proper
+ * ENOSPC accounting.  For data we handle the reservation through clearing the
+ * delalloc bits in the io_tree.  We have to do this since we could end up
+ * allocating less disk space for the amount of data we have reserved in the
+ * case of compression.
+ *
+ * If this is a reservation and the block group has become read only we cannot
+ * make the reservation and return -EAGAIN, otherwise this function always
+ * succeeds.
  */
-int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
-                               u64 num_bytes, int reserve, int sinfo)
+static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
+                                      u64 num_bytes, int reserve)
 {
+       struct btrfs_space_info *space_info = cache->space_info;
        int ret = 0;
-       if (sinfo) {
-               struct btrfs_space_info *space_info = cache->space_info;
-               spin_lock(&space_info->lock);
-               spin_lock(&cache->lock);
-               if (reserve) {
-                       if (cache->ro) {
-                               ret = -EAGAIN;
-                       } else {
-                               cache->reserved += num_bytes;
-                               space_info->bytes_reserved += num_bytes;
-                       }
-               } else {
-                       if (cache->ro)
-                               space_info->bytes_readonly += num_bytes;
-                       cache->reserved -= num_bytes;
-                       space_info->bytes_reserved -= num_bytes;
-                       space_info->reservation_progress++;
-               }
-               spin_unlock(&cache->lock);
-               spin_unlock(&space_info->lock);
-       } else {
-               spin_lock(&cache->lock);
+       spin_lock(&space_info->lock);
+       spin_lock(&cache->lock);
+       if (reserve != RESERVE_FREE) {
                if (cache->ro) {
                        ret = -EAGAIN;
                } else {
-                       if (reserve)
-                               cache->reserved += num_bytes;
-                       else
-                               cache->reserved -= num_bytes;
+                       cache->reserved += num_bytes;
+                       space_info->bytes_reserved += num_bytes;
+                       if (reserve == RESERVE_ALLOC) {
+                               BUG_ON(space_info->bytes_may_use < num_bytes);
+                               space_info->bytes_may_use -= num_bytes;
+                       }
                }
-               spin_unlock(&cache->lock);
+       } else {
+               if (cache->ro)
+                       space_info->bytes_readonly += num_bytes;
+               cache->reserved -= num_bytes;
+               space_info->bytes_reserved -= num_bytes;
+               space_info->reservation_progress++;
        }
+       spin_unlock(&cache->lock);
+       spin_unlock(&space_info->lock);
        return ret;
 }
 
@@ -4319,13 +4623,8 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
                spin_lock(&cache->lock);
                cache->pinned -= len;
                cache->space_info->bytes_pinned -= len;
-               if (cache->ro) {
+               if (cache->ro)
                        cache->space_info->bytes_readonly += len;
-               } else if (cache->reserved_pinned > 0) {
-                       len = min(len, cache->reserved_pinned);
-                       cache->reserved_pinned -= len;
-                       cache->space_info->bytes_reserved += len;
-               }
                spin_unlock(&cache->lock);
                spin_unlock(&cache->space_info->lock);
        }
@@ -4340,11 +4639,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct extent_io_tree *unpin;
-       struct btrfs_block_rsv *block_rsv;
-       struct btrfs_block_rsv *next_rsv;
        u64 start;
        u64 end;
-       int idx;
        int ret;
 
        if (fs_info->pinned_extents == &fs_info->freed_extents[0])
@@ -4367,30 +4663,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
                cond_resched();
        }
 
-       mutex_lock(&fs_info->durable_block_rsv_mutex);
-       list_for_each_entry_safe(block_rsv, next_rsv,
-                                &fs_info->durable_block_rsv_list, list) {
-
-               idx = trans->transid & 0x1;
-               if (block_rsv->freed[idx] > 0) {
-                       block_rsv_add_bytes(block_rsv,
-                                           block_rsv->freed[idx], 0);
-                       block_rsv->freed[idx] = 0;
-               }
-               if (atomic_read(&block_rsv->usage) == 0) {
-                       btrfs_block_rsv_release(root, block_rsv, (u64)-1);
-
-                       if (block_rsv->freed[0] == 0 &&
-                           block_rsv->freed[1] == 0) {
-                               list_del_init(&block_rsv->list);
-                               kfree(block_rsv);
-                       }
-               } else {
-                       btrfs_block_rsv_release(root, block_rsv, 0);
-               }
-       }
-       mutex_unlock(&fs_info->durable_block_rsv_mutex);
-
        return 0;
 }
 
@@ -4668,7 +4940,6 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
                           struct extent_buffer *buf,
                           u64 parent, int last_ref)
 {
-       struct btrfs_block_rsv *block_rsv;
        struct btrfs_block_group_cache *cache = NULL;
        int ret;
 
@@ -4683,64 +4954,24 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
        if (!last_ref)
                return;
 
-       block_rsv = get_block_rsv(trans, root);
        cache = btrfs_lookup_block_group(root->fs_info, buf->start);
-       if (block_rsv->space_info != cache->space_info)
-               goto out;
 
        if (btrfs_header_generation(buf) == trans->transid) {
                if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
                        ret = check_ref_cleanup(trans, root, buf->start);
                        if (!ret)
-                               goto pin;
+                               goto out;
                }
 
                if (btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
                        pin_down_extent(root, cache, buf->start, buf->len, 1);
-                       goto pin;
+                       goto out;
                }
 
                WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags));
 
                btrfs_add_free_space(cache, buf->start, buf->len);
-               ret = btrfs_update_reserved_bytes(cache, buf->len, 0, 0);
-               if (ret == -EAGAIN) {
-                       /* block group became read-only */
-                       btrfs_update_reserved_bytes(cache, buf->len, 0, 1);
-                       goto out;
-               }
-
-               ret = 1;
-               spin_lock(&block_rsv->lock);
-               if (block_rsv->reserved < block_rsv->size) {
-                       block_rsv->reserved += buf->len;
-                       ret = 0;
-               }
-               spin_unlock(&block_rsv->lock);
-
-               if (ret) {
-                       spin_lock(&cache->space_info->lock);
-                       cache->space_info->bytes_reserved -= buf->len;
-                       cache->space_info->reservation_progress++;
-                       spin_unlock(&cache->space_info->lock);
-               }
-               goto out;
-       }
-pin:
-       if (block_rsv->durable && !cache->ro) {
-               ret = 0;
-               spin_lock(&cache->lock);
-               if (!cache->ro) {
-                       cache->reserved_pinned += buf->len;
-                       ret = 1;
-               }
-               spin_unlock(&cache->lock);
-
-               if (ret) {
-                       spin_lock(&block_rsv->lock);
-                       block_rsv->freed[trans->transid & 0x1] += buf->len;
-                       spin_unlock(&block_rsv->lock);
-               }
+               btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE);
        }
 out:
        /*
@@ -4876,17 +5107,20 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
        struct btrfs_root *root = orig_root->fs_info->extent_root;
        struct btrfs_free_cluster *last_ptr = NULL;
        struct btrfs_block_group_cache *block_group = NULL;
+       struct btrfs_block_group_cache *used_block_group;
        int empty_cluster = 2 * 1024 * 1024;
        int allowed_chunk_alloc = 0;
        int done_chunk_alloc = 0;
        struct btrfs_space_info *space_info;
-       int last_ptr_loop = 0;
        int loop = 0;
        int index = 0;
+       int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ?
+               RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC;
        bool found_uncached_bg = false;
        bool failed_cluster_refill = false;
        bool failed_alloc = false;
        bool use_cluster = true;
+       bool have_caching_bg = false;
        u64 ideal_cache_percent = 0;
        u64 ideal_cache_offset = 0;
 
@@ -4939,6 +5173,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
 ideal_cache:
                block_group = btrfs_lookup_block_group(root->fs_info,
                                                       search_start);
+               used_block_group = block_group;
                /*
                 * we don't want to use the block group if it doesn't match our
                 * allocation bits, or if its not cached.
@@ -4969,12 +5204,14 @@ ideal_cache:
                }
        }
 search:
+       have_caching_bg = false;
        down_read(&space_info->groups_sem);
        list_for_each_entry(block_group, &space_info->block_groups[index],
                            list) {
                u64 offset;
                int cached;
 
+               used_block_group = block_group;
                btrfs_get_block_group(block_group);
                search_start = block_group->key.objectid;
 
@@ -4998,13 +5235,15 @@ search:
                }
 
 have_block_group:
-               if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
+               cached = block_group_cache_done(block_group);
+               if (unlikely(!cached)) {
                        u64 free_percent;
 
+                       found_uncached_bg = true;
                        ret = cache_block_group(block_group, trans,
                                                orig_root, 1);
                        if (block_group->cached == BTRFS_CACHE_FINISHED)
-                               goto have_block_group;
+                               goto alloc;
 
                        free_percent = btrfs_block_group_used(&block_group->item);
                        free_percent *= 100;
@@ -5026,7 +5265,6 @@ have_block_group:
                                                        orig_root, 0);
                                BUG_ON(ret);
                        }
-                       found_uncached_bg = true;
 
                        /*
                         * If loop is set for cached only, try the next block
@@ -5036,94 +5274,80 @@ have_block_group:
                                goto loop;
                }
 
-               cached = block_group_cache_done(block_group);
-               if (unlikely(!cached))
-                       found_uncached_bg = true;
-
+alloc:
                if (unlikely(block_group->ro))
                        goto loop;
 
                spin_lock(&block_group->free_space_ctl->tree_lock);
                if (cached &&
                    block_group->free_space_ctl->free_space <
-                   num_bytes + empty_size) {
+                   num_bytes + empty_cluster + empty_size) {
                        spin_unlock(&block_group->free_space_ctl->tree_lock);
                        goto loop;
                }
                spin_unlock(&block_group->free_space_ctl->tree_lock);
 
                /*
-                * Ok we want to try and use the cluster allocator, so lets look
-                * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will
-                * have tried the cluster allocator plenty of times at this
-                * point and not have found anything, so we are likely way too
-                * fragmented for the clustering stuff to find anything, so lets
-                * just skip it and let the allocator find whatever block it can
-                * find
+                * Ok we want to try and use the cluster allocator, so
+                * lets look there
                 */
-               if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) {
+               if (last_ptr) {
                        /*
                         * the refill lock keeps out other
                         * people trying to start a new cluster
                         */
                        spin_lock(&last_ptr->refill_lock);
-                       if (last_ptr->block_group &&
-                           (last_ptr->block_group->ro ||
-                           !block_group_bits(last_ptr->block_group, data))) {
-                               offset = 0;
+                       used_block_group = last_ptr->block_group;
+                       if (used_block_group != block_group &&
+                           (!used_block_group ||
+                            used_block_group->ro ||
+                            !block_group_bits(used_block_group, data))) {
+                               used_block_group = block_group;
                                goto refill_cluster;
                        }
 
-                       offset = btrfs_alloc_from_cluster(block_group, last_ptr,
-                                                num_bytes, search_start);
+                       if (used_block_group != block_group)
+                               btrfs_get_block_group(used_block_group);
+
+                       offset = btrfs_alloc_from_cluster(used_block_group,
+                         last_ptr, num_bytes, used_block_group->key.objectid);
                        if (offset) {
                                /* we have a block, we're done */
                                spin_unlock(&last_ptr->refill_lock);
                                goto checks;
                        }
 
-                       spin_lock(&last_ptr->lock);
-                       /*
-                        * whoops, this cluster doesn't actually point to
-                        * this block group.  Get a ref on the block
-                        * group is does point to and try again
-                        */
-                       if (!last_ptr_loop && last_ptr->block_group &&
-                           last_ptr->block_group != block_group &&
-                           index <=
-                                get_block_group_index(last_ptr->block_group)) {
-
-                               btrfs_put_block_group(block_group);
-                               block_group = last_ptr->block_group;
-                               btrfs_get_block_group(block_group);
-                               spin_unlock(&last_ptr->lock);
-                               spin_unlock(&last_ptr->refill_lock);
-
-                               last_ptr_loop = 1;
-                               search_start = block_group->key.objectid;
-                               /*
-                                * we know this block group is properly
-                                * in the list because
-                                * btrfs_remove_block_group, drops the
-                                * cluster before it removes the block
-                                * group from the list
-                                */
-                               goto have_block_group;
+                       WARN_ON(last_ptr->block_group != used_block_group);
+                       if (used_block_group != block_group) {
+                               btrfs_put_block_group(used_block_group);
+                               used_block_group = block_group;
                        }
-                       spin_unlock(&last_ptr->lock);
 refill_cluster:
+                       BUG_ON(used_block_group != block_group);
+                       /* If we are on LOOP_NO_EMPTY_SIZE, we can't
+                        * set up a new clusters, so lets just skip it
+                        * and let the allocator find whatever block
+                        * it can find.  If we reach this point, we
+                        * will have tried the cluster allocator
+                        * plenty of times and not have found
+                        * anything, so we are likely way too
+                        * fragmented for the clustering stuff to find
+                        * anything.  */
+                       if (loop >= LOOP_NO_EMPTY_SIZE) {
+                               spin_unlock(&last_ptr->refill_lock);
+                               goto unclustered_alloc;
+                       }
+
                        /*
                         * this cluster didn't work out, free it and
                         * start over
                         */
                        btrfs_return_cluster_to_free_space(NULL, last_ptr);
 
-                       last_ptr_loop = 0;
-
                        /* allocate a cluster in this block group */
                        ret = btrfs_find_space_cluster(trans, root,
                                               block_group, last_ptr,
-                                              offset, num_bytes,
+                                              search_start, num_bytes,
                                               empty_cluster + empty_size);
                        if (ret == 0) {
                                /*
@@ -5159,6 +5383,7 @@ refill_cluster:
                        goto loop;
                }
 
+unclustered_alloc:
                offset = btrfs_find_space_for_alloc(block_group, search_start,
                                                    num_bytes, empty_size);
                /*
@@ -5177,20 +5402,22 @@ refill_cluster:
                        failed_alloc = true;
                        goto have_block_group;
                } else if (!offset) {
+                       if (!cached)
+                               have_caching_bg = true;
                        goto loop;
                }
 checks:
                search_start = stripe_align(root, offset);
                /* move on to the next group */
                if (search_start + num_bytes >= search_end) {
-                       btrfs_add_free_space(block_group, offset, num_bytes);
+                       btrfs_add_free_space(used_block_group, offset, num_bytes);
                        goto loop;
                }
 
                /* move on to the next group */
                if (search_start + num_bytes >
-                   block_group->key.objectid + block_group->key.offset) {
-                       btrfs_add_free_space(block_group, offset, num_bytes);
+                   used_block_group->key.objectid + used_block_group->key.offset) {
+                       btrfs_add_free_space(used_block_group, offset, num_bytes);
                        goto loop;
                }
 
@@ -5198,14 +5425,14 @@ checks:
                ins->offset = num_bytes;
 
                if (offset < search_start)
-                       btrfs_add_free_space(block_group, offset,
+                       btrfs_add_free_space(used_block_group, offset,
                                             search_start - offset);
                BUG_ON(offset > search_start);
 
-               ret = btrfs_update_reserved_bytes(block_group, num_bytes, 1,
-                                           (data & BTRFS_BLOCK_GROUP_DATA));
+               ret = btrfs_update_reserved_bytes(used_block_group, num_bytes,
+                                                 alloc_type);
                if (ret == -EAGAIN) {
-                       btrfs_add_free_space(block_group, offset, num_bytes);
+                       btrfs_add_free_space(used_block_group, offset, num_bytes);
                        goto loop;
                }
 
@@ -5214,19 +5441,26 @@ checks:
                ins->offset = num_bytes;
 
                if (offset < search_start)
-                       btrfs_add_free_space(block_group, offset,
+                       btrfs_add_free_space(used_block_group, offset,
                                             search_start - offset);
                BUG_ON(offset > search_start);
+               if (used_block_group != block_group)
+                       btrfs_put_block_group(used_block_group);
                btrfs_put_block_group(block_group);
                break;
 loop:
                failed_cluster_refill = false;
                failed_alloc = false;
                BUG_ON(index != get_block_group_index(block_group));
+               if (used_block_group != block_group)
+                       btrfs_put_block_group(used_block_group);
                btrfs_put_block_group(block_group);
        }
        up_read(&space_info->groups_sem);
 
+       if (!ins->objectid && loop >= LOOP_CACHING_WAIT && have_caching_bg)
+               goto search;
+
        if (!ins->objectid && ++index < BTRFS_NR_RAID_TYPES)
                goto search;
 
@@ -5325,7 +5559,8 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
        int index = 0;
 
        spin_lock(&info->lock);
-       printk(KERN_INFO "space_info has %llu free, is %sfull\n",
+       printk(KERN_INFO "space_info %llu has %llu free, is %sfull\n",
+              (unsigned long long)info->flags,
               (unsigned long long)(info->total_bytes - info->bytes_used -
                                    info->bytes_pinned - info->bytes_reserved -
                                    info->bytes_readonly),
@@ -5411,7 +5646,8 @@ again:
        return ret;
 }
 
-int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
+static int __btrfs_free_reserved_extent(struct btrfs_root *root,
+                                       u64 start, u64 len, int pin)
 {
        struct btrfs_block_group_cache *cache;
        int ret = 0;
@@ -5426,8 +5662,12 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
        if (btrfs_test_opt(root, DISCARD))
                ret = btrfs_discard_extent(root, start, len, NULL);
 
-       btrfs_add_free_space(cache, start, len);
-       btrfs_update_reserved_bytes(cache, len, 0, 1);
+       if (pin)
+               pin_down_extent(root, cache, start, len, 1);
+       else {
+               btrfs_add_free_space(cache, start, len);
+               btrfs_update_reserved_bytes(cache, len, RESERVE_FREE);
+       }
        btrfs_put_block_group(cache);
 
        trace_btrfs_reserved_extent_free(root, start, len);
@@ -5435,6 +5675,18 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
        return ret;
 }
 
+int btrfs_free_reserved_extent(struct btrfs_root *root,
+                                       u64 start, u64 len)
+{
+       return __btrfs_free_reserved_extent(root, start, len, 0);
+}
+
+int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
+                                      u64 start, u64 len)
+{
+       return __btrfs_free_reserved_extent(root, start, len, 1);
+}
+
 static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
                                      struct btrfs_root *root,
                                      u64 parent, u64 root_objectid,
@@ -5630,7 +5882,8 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                put_caching_control(caching_ctl);
        }
 
-       ret = btrfs_update_reserved_bytes(block_group, ins->offset, 1, 1);
+       ret = btrfs_update_reserved_bytes(block_group, ins->offset,
+                                         RESERVE_ALLOC_NO_ACCOUNT);
        BUG_ON(ret);
        btrfs_put_block_group(block_group);
        ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
@@ -5687,8 +5940,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        block_rsv = get_block_rsv(trans, root);
 
        if (block_rsv->size == 0) {
-               ret = reserve_metadata_bytes(trans, root, block_rsv,
-                                            blocksize, 0);
+               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
                /*
                 * If we couldn't reserve metadata bytes try and use some from
                 * the global reserve.
@@ -5708,13 +5960,15 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        if (!ret)
                return block_rsv;
        if (ret) {
-               WARN_ON(1);
-               ret = reserve_metadata_bytes(trans, root, block_rsv, blocksize,
-                                            0);
+               static DEFINE_RATELIMIT_STATE(_rs,
+                               DEFAULT_RATELIMIT_INTERVAL,
+                               /*DEFAULT_RATELIMIT_BURST*/ 2);
+               if (__ratelimit(&_rs)) {
+                       printk(KERN_DEBUG "btrfs: block rsv returned %d\n", ret);
+                       WARN_ON(1);
+               }
+               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
                if (!ret) {
-                       spin_lock(&block_rsv->lock);
-                       block_rsv->size += blocksize;
-                       spin_unlock(&block_rsv->lock);
                        return block_rsv;
                } else if (ret && block_rsv != global_rsv) {
                        ret = block_rsv_use_bytes(global_rsv, blocksize);
@@ -6592,12 +6846,9 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache, int force)
                    cache->bytes_super - btrfs_block_group_used(&cache->item);
 
        if (sinfo->bytes_used + sinfo->bytes_reserved + sinfo->bytes_pinned +
-           sinfo->bytes_may_use + sinfo->bytes_readonly +
-           cache->reserved_pinned + num_bytes + min_allocable_bytes <=
-           sinfo->total_bytes) {
+           sinfo->bytes_may_use + sinfo->bytes_readonly + num_bytes +
+           min_allocable_bytes <= sinfo->total_bytes) {
                sinfo->bytes_readonly += num_bytes;
-               sinfo->bytes_reserved += cache->reserved_pinned;
-               cache->reserved_pinned = 0;
                cache->ro = 1;
                ret = 0;
        }
@@ -6964,7 +7215,8 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
                                        struct btrfs_space_info,
                                        list);
                if (space_info->bytes_pinned > 0 ||
-                   space_info->bytes_reserved > 0) {
+                   space_info->bytes_reserved > 0 ||
+                   space_info->bytes_may_use > 0) {
                        WARN_ON(1);
                        dump_space_info(space_info, 0, 0);
                }
@@ -7006,14 +7258,12 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                return -ENOMEM;
        path->reada = 1;
 
-       cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy);
-       if (cache_gen != 0 &&
-           btrfs_super_generation(&root->fs_info->super_copy) != cache_gen)
+       cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
+       if (btrfs_test_opt(root, SPACE_CACHE) &&
+           btrfs_super_generation(root->fs_info->super_copy) != cache_gen)
                need_clear = 1;
        if (btrfs_test_opt(root, CLEAR_CACHE))
                need_clear = 1;
-       if (!btrfs_test_opt(root, SPACE_CACHE) && cache_gen)
-               printk(KERN_INFO "btrfs: disk space caching is enabled\n");
 
        while (1) {
                ret = find_first_block_group(root, path, &key);
@@ -7252,7 +7502,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       inode = lookup_free_space_inode(root, block_group, path);
+       inode = lookup_free_space_inode(tree_root, block_group, path);
        if (!IS_ERR(inode)) {
                ret = btrfs_orphan_add(trans, inode);
                BUG_ON(ret);
@@ -7268,7 +7518,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                        spin_unlock(&block_group->lock);
                }
                /* One for our lookup ref */
-               iput(inode);
+               btrfs_add_delayed_iput(inode);
        }
 
        key.objectid = BTRFS_FREE_SPACE_OBJECTID;
@@ -7339,7 +7589,7 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
        int mixed = 0;
        int ret;
 
-       disk_super = &fs_info->super_copy;
+       disk_super = fs_info->super_copy;
        if (!btrfs_super_root(disk_super))
                return 1;
 
index d418164a35f134842ed3af4cfd5f43666b37c89d..49f3c9dc09f4c81902299fd81c62da1ed8423250 100644 (file)
@@ -17,6 +17,7 @@
 #include "compat.h"
 #include "ctree.h"
 #include "btrfs_inode.h"
+#include "volumes.h"
 
 static struct kmem_cache *extent_state_cache;
 static struct kmem_cache *extent_buffer_cache;
@@ -894,6 +895,202 @@ search_again:
        goto again;
 }
 
+/**
+ * convert_extent - convert all bits in a given range from one bit to another
+ * @tree:      the io tree to search
+ * @start:     the start offset in bytes
+ * @end:       the end offset in bytes (inclusive)
+ * @bits:      the bits to set in this range
+ * @clear_bits:        the bits to clear in this range
+ * @mask:      the allocation mask
+ *
+ * This will go through and set bits for the given range.  If any states exist
+ * already in this range they are set with the given bit and cleared of the
+ * clear_bits.  This is only meant to be used by things that are mergeable, ie
+ * converting from say DELALLOC to DIRTY.  This is not meant to be used with
+ * boundary bits like LOCK.
+ */
+int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
+                      int bits, int clear_bits, gfp_t mask)
+{
+       struct extent_state *state;
+       struct extent_state *prealloc = NULL;
+       struct rb_node *node;
+       int err = 0;
+       u64 last_start;
+       u64 last_end;
+
+again:
+       if (!prealloc && (mask & __GFP_WAIT)) {
+               prealloc = alloc_extent_state(mask);
+               if (!prealloc)
+                       return -ENOMEM;
+       }
+
+       spin_lock(&tree->lock);
+       /*
+        * this search will find all the extents that end after
+        * our range starts.
+        */
+       node = tree_search(tree, start);
+       if (!node) {
+               prealloc = alloc_extent_state_atomic(prealloc);
+               if (!prealloc) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+               err = insert_state(tree, prealloc, start, end, &bits);
+               prealloc = NULL;
+               BUG_ON(err == -EEXIST);
+               goto out;
+       }
+       state = rb_entry(node, struct extent_state, rb_node);
+hit_next:
+       last_start = state->start;
+       last_end = state->end;
+
+       /*
+        * | ---- desired range ---- |
+        * | state |
+        *
+        * Just lock what we found and keep going
+        */
+       if (state->start == start && state->end <= end) {
+               struct rb_node *next_node;
+
+               set_state_bits(tree, state, &bits);
+               clear_state_bit(tree, state, &clear_bits, 0);
+
+               merge_state(tree, state);
+               if (last_end == (u64)-1)
+                       goto out;
+
+               start = last_end + 1;
+               next_node = rb_next(&state->rb_node);
+               if (next_node && start < end && prealloc && !need_resched()) {
+                       state = rb_entry(next_node, struct extent_state,
+                                        rb_node);
+                       if (state->start == start)
+                               goto hit_next;
+               }
+               goto search_again;
+       }
+
+       /*
+        *     | ---- desired range ---- |
+        * | state |
+        *   or
+        * | ------------- state -------------- |
+        *
+        * We need to split the extent we found, and may flip bits on
+        * second half.
+        *
+        * If the extent we found extends past our
+        * range, we just split and search again.  It'll get split
+        * again the next time though.
+        *
+        * If the extent we found is inside our range, we set the
+        * desired bit on it.
+        */
+       if (state->start < start) {
+               prealloc = alloc_extent_state_atomic(prealloc);
+               if (!prealloc) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+               err = split_state(tree, state, prealloc, start);
+               BUG_ON(err == -EEXIST);
+               prealloc = NULL;
+               if (err)
+                       goto out;
+               if (state->end <= end) {
+                       set_state_bits(tree, state, &bits);
+                       clear_state_bit(tree, state, &clear_bits, 0);
+                       merge_state(tree, state);
+                       if (last_end == (u64)-1)
+                               goto out;
+                       start = last_end + 1;
+               }
+               goto search_again;
+       }
+       /*
+        * | ---- desired range ---- |
+        *     | state | or               | state |
+        *
+        * There's a hole, we need to insert something in it and
+        * ignore the extent we found.
+        */
+       if (state->start > start) {
+               u64 this_end;
+               if (end < last_start)
+                       this_end = end;
+               else
+                       this_end = last_start - 1;
+
+               prealloc = alloc_extent_state_atomic(prealloc);
+               if (!prealloc) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+
+               /*
+                * Avoid to free 'prealloc' if it can be merged with
+                * the later extent.
+                */
+               err = insert_state(tree, prealloc, start, this_end,
+                                  &bits);
+               BUG_ON(err == -EEXIST);
+               if (err) {
+                       free_extent_state(prealloc);
+                       prealloc = NULL;
+                       goto out;
+               }
+               prealloc = NULL;
+               start = this_end + 1;
+               goto search_again;
+       }
+       /*
+        * | ---- desired range ---- |
+        *                        | state |
+        * We need to split the extent, and set the bit
+        * on the first half
+        */
+       if (state->start <= end && state->end > end) {
+               prealloc = alloc_extent_state_atomic(prealloc);
+               if (!prealloc) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+
+               err = split_state(tree, state, prealloc, end + 1);
+               BUG_ON(err == -EEXIST);
+
+               set_state_bits(tree, prealloc, &bits);
+               clear_state_bit(tree, prealloc, &clear_bits, 0);
+
+               merge_state(tree, prealloc);
+               prealloc = NULL;
+               goto out;
+       }
+
+       goto search_again;
+
+out:
+       spin_unlock(&tree->lock);
+       if (prealloc)
+               free_extent_state(prealloc);
+
+       return err;
+
+search_again:
+       if (start > end)
+               goto out;
+       spin_unlock(&tree->lock);
+       if (mask & __GFP_WAIT)
+               cond_resched();
+       goto again;
+}
+
 /* wrappers around set/clear extent bit */
 int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
                     gfp_t mask)
@@ -919,7 +1116,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
                        struct extent_state **cached_state, gfp_t mask)
 {
        return set_extent_bit(tree, start, end,
-                             EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE,
+                             EXTENT_DELALLOC | EXTENT_UPTODATE,
                              0, NULL, cached_state, mask);
 }
 
@@ -1599,6 +1796,368 @@ static int check_page_writeback(struct extent_io_tree *tree,
        return 0;
 }
 
+/*
+ * When IO fails, either with EIO or csum verification fails, we
+ * try other mirrors that might have a good copy of the data.  This
+ * io_failure_record is used to record state as we go through all the
+ * mirrors.  If another mirror has good data, the page is set up to date
+ * and things continue.  If a good mirror can't be found, the original
+ * bio end_io callback is called to indicate things have failed.
+ */
+struct io_failure_record {
+       struct page *page;
+       u64 start;
+       u64 len;
+       u64 logical;
+       unsigned long bio_flags;
+       int this_mirror;
+       int failed_mirror;
+       int in_validation;
+};
+
+static int free_io_failure(struct inode *inode, struct io_failure_record *rec,
+                               int did_repair)
+{
+       int ret;
+       int err = 0;
+       struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree;
+
+       set_state_private(failure_tree, rec->start, 0);
+       ret = clear_extent_bits(failure_tree, rec->start,
+                               rec->start + rec->len - 1,
+                               EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS);
+       if (ret)
+               err = ret;
+
+       if (did_repair) {
+               ret = clear_extent_bits(&BTRFS_I(inode)->io_tree, rec->start,
+                                       rec->start + rec->len - 1,
+                                       EXTENT_DAMAGED, GFP_NOFS);
+               if (ret && !err)
+                       err = ret;
+       }
+
+       kfree(rec);
+       return err;
+}
+
+static void repair_io_failure_callback(struct bio *bio, int err)
+{
+       complete(bio->bi_private);
+}
+
+/*
+ * this bypasses the standard btrfs submit functions deliberately, as
+ * the standard behavior is to write all copies in a raid setup. here we only
+ * want to write the one bad copy. so we do the mapping for ourselves and issue
+ * submit_bio directly.
+ * to avoid any synchonization issues, wait for the data after writing, which
+ * actually prevents the read that triggered the error from finishing.
+ * currently, there can be no more than two copies of every data bit. thus,
+ * exactly one rewrite is required.
+ */
+int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
+                       u64 length, u64 logical, struct page *page,
+                       int mirror_num)
+{
+       struct bio *bio;
+       struct btrfs_device *dev;
+       DECLARE_COMPLETION_ONSTACK(compl);
+       u64 map_length = 0;
+       u64 sector;
+       struct btrfs_bio *bbio = NULL;
+       int ret;
+
+       BUG_ON(!mirror_num);
+
+       bio = bio_alloc(GFP_NOFS, 1);
+       if (!bio)
+               return -EIO;
+       bio->bi_private = &compl;
+       bio->bi_end_io = repair_io_failure_callback;
+       bio->bi_size = 0;
+       map_length = length;
+
+       ret = btrfs_map_block(map_tree, WRITE, logical,
+                             &map_length, &bbio, mirror_num);
+       if (ret) {
+               bio_put(bio);
+               return -EIO;
+       }
+       BUG_ON(mirror_num != bbio->mirror_num);
+       sector = bbio->stripes[mirror_num-1].physical >> 9;
+       bio->bi_sector = sector;
+       dev = bbio->stripes[mirror_num-1].dev;
+       kfree(bbio);
+       if (!dev || !dev->bdev || !dev->writeable) {
+               bio_put(bio);
+               return -EIO;
+       }
+       bio->bi_bdev = dev->bdev;
+       bio_add_page(bio, page, length, start-page_offset(page));
+       submit_bio(WRITE_SYNC, bio);
+       wait_for_completion(&compl);
+
+       if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+               /* try to remap that extent elsewhere? */
+               bio_put(bio);
+               return -EIO;
+       }
+
+       printk(KERN_INFO "btrfs read error corrected: ino %lu off %llu (dev %s "
+                       "sector %llu)\n", page->mapping->host->i_ino, start,
+                       dev->name, sector);
+
+       bio_put(bio);
+       return 0;
+}
+
+/*
+ * each time an IO finishes, we do a fast check in the IO failure tree
+ * to see if we need to process or clean up an io_failure_record
+ */
+static int clean_io_failure(u64 start, struct page *page)
+{
+       u64 private;
+       u64 private_failure;
+       struct io_failure_record *failrec;
+       struct btrfs_mapping_tree *map_tree;
+       struct extent_state *state;
+       int num_copies;
+       int did_repair = 0;
+       int ret;
+       struct inode *inode = page->mapping->host;
+
+       private = 0;
+       ret = count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private,
+                               (u64)-1, 1, EXTENT_DIRTY, 0);
+       if (!ret)
+               return 0;
+
+       ret = get_state_private(&BTRFS_I(inode)->io_failure_tree, start,
+                               &private_failure);
+       if (ret)
+               return 0;
+
+       failrec = (struct io_failure_record *)(unsigned long) private_failure;
+       BUG_ON(!failrec->this_mirror);
+
+       if (failrec->in_validation) {
+               /* there was no real error, just free the record */
+               pr_debug("clean_io_failure: freeing dummy error at %llu\n",
+                        failrec->start);
+               did_repair = 1;
+               goto out;
+       }
+
+       spin_lock(&BTRFS_I(inode)->io_tree.lock);
+       state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree,
+                                           failrec->start,
+                                           EXTENT_LOCKED);
+       spin_unlock(&BTRFS_I(inode)->io_tree.lock);
+
+       if (state && state->start == failrec->start) {
+               map_tree = &BTRFS_I(inode)->root->fs_info->mapping_tree;
+               num_copies = btrfs_num_copies(map_tree, failrec->logical,
+                                               failrec->len);
+               if (num_copies > 1)  {
+                       ret = repair_io_failure(map_tree, start, failrec->len,
+                                               failrec->logical, page,
+                                               failrec->failed_mirror);
+                       did_repair = !ret;
+               }
+       }
+
+out:
+       if (!ret)
+               ret = free_io_failure(inode, failrec, did_repair);
+
+       return ret;
+}
+
+/*
+ * this is a generic handler for readpage errors (default
+ * readpage_io_failed_hook). if other copies exist, read those and write back
+ * good data to the failed position. does not investigate in remapping the
+ * failed extent elsewhere, hoping the device will be smart enough to do this as
+ * needed
+ */
+
+static int bio_readpage_error(struct bio *failed_bio, struct page *page,
+                               u64 start, u64 end, int failed_mirror,
+                               struct extent_state *state)
+{
+       struct io_failure_record *failrec = NULL;
+       u64 private;
+       struct extent_map *em;
+       struct inode *inode = page->mapping->host;
+       struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree;
+       struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
+       struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+       struct bio *bio;
+       int num_copies;
+       int ret;
+       int read_mode;
+       u64 logical;
+
+       BUG_ON(failed_bio->bi_rw & REQ_WRITE);
+
+       ret = get_state_private(failure_tree, start, &private);
+       if (ret) {
+               failrec = kzalloc(sizeof(*failrec), GFP_NOFS);
+               if (!failrec)
+                       return -ENOMEM;
+               failrec->start = start;
+               failrec->len = end - start + 1;
+               failrec->this_mirror = 0;
+               failrec->bio_flags = 0;
+               failrec->in_validation = 0;
+
+               read_lock(&em_tree->lock);
+               em = lookup_extent_mapping(em_tree, start, failrec->len);
+               if (!em) {
+                       read_unlock(&em_tree->lock);
+                       kfree(failrec);
+                       return -EIO;
+               }
+
+               if (em->start > start || em->start + em->len < start) {
+                       free_extent_map(em);
+                       em = NULL;
+               }
+               read_unlock(&em_tree->lock);
+
+               if (!em || IS_ERR(em)) {
+                       kfree(failrec);
+                       return -EIO;
+               }
+               logical = start - em->start;
+               logical = em->block_start + logical;
+               if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
+                       logical = em->block_start;
+                       failrec->bio_flags = EXTENT_BIO_COMPRESSED;
+                       extent_set_compress_type(&failrec->bio_flags,
+                                                em->compress_type);
+               }
+               pr_debug("bio_readpage_error: (new) logical=%llu, start=%llu, "
+                        "len=%llu\n", logical, start, failrec->len);
+               failrec->logical = logical;
+               free_extent_map(em);
+
+               /* set the bits in the private failure tree */
+               ret = set_extent_bits(failure_tree, start, end,
+                                       EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS);
+               if (ret >= 0)
+                       ret = set_state_private(failure_tree, start,
+                                               (u64)(unsigned long)failrec);
+               /* set the bits in the inode's tree */
+               if (ret >= 0)
+                       ret = set_extent_bits(tree, start, end, EXTENT_DAMAGED,
+                                               GFP_NOFS);
+               if (ret < 0) {
+                       kfree(failrec);
+                       return ret;
+               }
+       } else {
+               failrec = (struct io_failure_record *)(unsigned long)private;
+               pr_debug("bio_readpage_error: (found) logical=%llu, "
+                        "start=%llu, len=%llu, validation=%d\n",
+                        failrec->logical, failrec->start, failrec->len,
+                        failrec->in_validation);
+               /*
+                * when data can be on disk more than twice, add to failrec here
+                * (e.g. with a list for failed_mirror) to make
+                * clean_io_failure() clean all those errors at once.
+                */
+       }
+       num_copies = btrfs_num_copies(
+                             &BTRFS_I(inode)->root->fs_info->mapping_tree,
+                             failrec->logical, failrec->len);
+       if (num_copies == 1) {
+               /*
+                * we only have a single copy of the data, so don't bother with
+                * all the retry and error correction code that follows. no
+                * matter what the error is, it is very likely to persist.
+                */
+               pr_debug("bio_readpage_error: cannot repair, num_copies == 1. "
+                        "state=%p, num_copies=%d, next_mirror %d, "
+                        "failed_mirror %d\n", state, num_copies,
+                        failrec->this_mirror, failed_mirror);
+               free_io_failure(inode, failrec, 0);
+               return -EIO;
+       }
+
+       if (!state) {
+               spin_lock(&tree->lock);
+               state = find_first_extent_bit_state(tree, failrec->start,
+                                                   EXTENT_LOCKED);
+               if (state && state->start != failrec->start)
+                       state = NULL;
+               spin_unlock(&tree->lock);
+       }
+
+       /*
+        * there are two premises:
+        *      a) deliver good data to the caller
+        *      b) correct the bad sectors on disk
+        */
+       if (failed_bio->bi_vcnt > 1) {
+               /*
+                * to fulfill b), we need to know the exact failing sectors, as
+                * we don't want to rewrite any more than the failed ones. thus,
+                * we need separate read requests for the failed bio
+                *
+                * if the following BUG_ON triggers, our validation request got
+                * merged. we need separate requests for our algorithm to work.
+                */
+               BUG_ON(failrec->in_validation);
+               failrec->in_validation = 1;
+               failrec->this_mirror = failed_mirror;
+               read_mode = READ_SYNC | REQ_FAILFAST_DEV;
+       } else {
+               /*
+                * we're ready to fulfill a) and b) alongside. get a good copy
+                * of the failed sector and if we succeed, we have setup
+                * everything for repair_io_failure to do the rest for us.
+                */
+               if (failrec->in_validation) {
+                       BUG_ON(failrec->this_mirror != failed_mirror);
+                       failrec->in_validation = 0;
+                       failrec->this_mirror = 0;
+               }
+               failrec->failed_mirror = failed_mirror;
+               failrec->this_mirror++;
+               if (failrec->this_mirror == failed_mirror)
+                       failrec->this_mirror++;
+               read_mode = READ_SYNC;
+       }
+
+       if (!state || failrec->this_mirror > num_copies) {
+               pr_debug("bio_readpage_error: (fail) state=%p, num_copies=%d, "
+                        "next_mirror %d, failed_mirror %d\n", state,
+                        num_copies, failrec->this_mirror, failed_mirror);
+               free_io_failure(inode, failrec, 0);
+               return -EIO;
+       }
+
+       bio = bio_alloc(GFP_NOFS, 1);
+       bio->bi_private = state;
+       bio->bi_end_io = failed_bio->bi_end_io;
+       bio->bi_sector = failrec->logical >> 9;
+       bio->bi_bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
+       bio->bi_size = 0;
+
+       bio_add_page(bio, page, failrec->len, start - page_offset(page));
+
+       pr_debug("bio_readpage_error: submitting new read[%#x] to "
+                "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode,
+                failrec->this_mirror, num_copies, failrec->in_validation);
+
+       tree->ops->submit_bio_hook(inode, read_mode, bio, failrec->this_mirror,
+                                       failrec->bio_flags, 0);
+       return 0;
+}
+
 /* lots and lots of room for performance fixes in the end_bio funcs */
 
 /*
@@ -1697,6 +2256,9 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                struct extent_state *cached = NULL;
                struct extent_state *state;
 
+               pr_debug("end_bio_extent_readpage: bi_vcnt=%d, idx=%d, err=%d, "
+                        "mirror=%ld\n", bio->bi_vcnt, bio->bi_idx, err,
+                        (long int)bio->bi_bdev);
                tree = &BTRFS_I(page->mapping->host)->io_tree;
 
                start = ((u64)page->index << PAGE_CACHE_SHIFT) +
@@ -1727,12 +2289,26 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                                                              state);
                        if (ret)
                                uptodate = 0;
+                       else
+                               clean_io_failure(start, page);
                }
-               if (!uptodate && tree->ops &&
-                   tree->ops->readpage_io_failed_hook) {
-                       ret = tree->ops->readpage_io_failed_hook(bio, page,
-                                                        start, end, NULL);
+               if (!uptodate) {
+                       int failed_mirror;
+                       failed_mirror = (int)(unsigned long)bio->bi_bdev;
+                       /*
+                        * The generic bio_readpage_error handles errors the
+                        * following way: If possible, new read requests are
+                        * created and submitted and will end up in
+                        * end_bio_extent_readpage as well (if we're lucky, not
+                        * in the !uptodate case). In that case it returns 0 and
+                        * we just go on with the next page in our bio. If it
+                        * can't handle the error it will return -EIO and we
+                        * remain responsible for that page.
+                        */
+                       ret = bio_readpage_error(bio, page, start, end,
+                                                       failed_mirror, NULL);
                        if (ret == 0) {
+error_handled:
                                uptodate =
                                        test_bit(BIO_UPTODATE, &bio->bi_flags);
                                if (err)
@@ -1740,6 +2316,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
                                uncache_state(&cached);
                                continue;
                        }
+                       if (tree->ops && tree->ops->readpage_io_failed_hook) {
+                               ret = tree->ops->readpage_io_failed_hook(
+                                                       bio, page, start, end,
+                                                       failed_mirror, state);
+                               if (ret == 0)
+                                       goto error_handled;
+                       }
                }
 
                if (uptodate) {
@@ -1811,6 +2394,7 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num,
                                           mirror_num, bio_flags, start);
        else
                submit_bio(rw, bio);
+
        if (bio_flagged(bio, BIO_EOPNOTSUPP))
                ret = -EOPNOTSUPP;
        bio_put(bio);
@@ -2076,16 +2660,16 @@ out:
 }
 
 int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
-                           get_extent_t *get_extent)
+                           get_extent_t *get_extent, int mirror_num)
 {
        struct bio *bio = NULL;
        unsigned long bio_flags = 0;
        int ret;
 
-       ret = __extent_read_full_page(tree, page, get_extent, &bio, 0,
+       ret = __extent_read_full_page(tree, page, get_extent, &bio, mirror_num,
                                      &bio_flags);
        if (bio)
-               ret = submit_one_bio(READ, bio, 0, bio_flags);
+               ret = submit_one_bio(READ, bio, mirror_num, bio_flags);
        return ret;
 }
 
@@ -2136,6 +2720,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
        int compressed;
        int write_flags;
        unsigned long nr_written = 0;
+       bool fill_delalloc = true;
 
        if (wbc->sync_mode == WB_SYNC_ALL)
                write_flags = WRITE_SYNC;
@@ -2145,6 +2730,9 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
        trace___extent_writepage(page, inode, wbc);
 
        WARN_ON(!PageLocked(page));
+
+       ClearPageError(page);
+
        pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
        if (page->index > end_index ||
           (page->index == end_index && !pg_offset)) {
@@ -2166,10 +2754,13 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
 
        set_page_extent_mapped(page);
 
+       if (!tree->ops || !tree->ops->fill_delalloc)
+               fill_delalloc = false;
+
        delalloc_start = start;
        delalloc_end = 0;
        page_started = 0;
-       if (!epd->extent_locked) {
+       if (!epd->extent_locked && fill_delalloc) {
                u64 delalloc_to_write = 0;
                /*
                 * make sure the wbc mapping index is at least updated
@@ -2421,10 +3012,16 @@ retry:
                         * swizzled back from swapper_space to tmpfs file
                         * mapping
                         */
-                       if (tree->ops && tree->ops->write_cache_pages_lock_hook)
-                               tree->ops->write_cache_pages_lock_hook(page);
-                       else
-                               lock_page(page);
+                       if (tree->ops &&
+                           tree->ops->write_cache_pages_lock_hook) {
+                               tree->ops->write_cache_pages_lock_hook(page,
+                                                              data, flush_fn);
+                       } else {
+                               if (!trylock_page(page)) {
+                                       flush_fn(data);
+                                       lock_page(page);
+                               }
+                       }
 
                        if (unlikely(page->mapping != mapping)) {
                                unlock_page(page);
@@ -2790,6 +3387,9 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                return -ENOMEM;
        path->leave_spinning = 1;
 
+       start = ALIGN(start, BTRFS_I(inode)->root->sectorsize);
+       len = ALIGN(len, BTRFS_I(inode)->root->sectorsize);
+
        /*
         * lookup the last file extent.  We're not using i_size here
         * because there might be preallocation past i_size
@@ -2837,7 +3437,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0,
                         &cached_state, GFP_NOFS);
 
-       em = get_extent_skip_holes(inode, off, last_for_get_extent,
+       em = get_extent_skip_holes(inode, start, last_for_get_extent,
                                   get_extent);
        if (!em)
                goto out;
@@ -2926,7 +3526,7 @@ out:
        return ret;
 }
 
-static inline struct page *extent_buffer_page(struct extent_buffer *eb,
+inline struct page *extent_buffer_page(struct extent_buffer *eb,
                                              unsigned long i)
 {
        struct page *p;
@@ -2951,7 +3551,7 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb,
        return p;
 }
 
-static inline unsigned long num_extent_pages(u64 start, u64 len)
+inline unsigned long num_extent_pages(u64 start, u64 len)
 {
        return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
                (start >> PAGE_CACHE_SHIFT);
@@ -3204,6 +3804,7 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree,
                                                PAGECACHE_TAG_DIRTY);
                }
                spin_unlock_irq(&page->mapping->tree_lock);
+               ClearPageError(page);
                unlock_page(page);
        }
        return 0;
@@ -3349,8 +3950,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree,
 }
 
 int read_extent_buffer_pages(struct extent_io_tree *tree,
-                            struct extent_buffer *eb,
-                            u64 start, int wait,
+                            struct extent_buffer *eb, u64 start, int wait,
                             get_extent_t *get_extent, int mirror_num)
 {
        unsigned long i;
@@ -3386,7 +3986,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
        num_pages = num_extent_pages(eb->start, eb->len);
        for (i = start_i; i < num_pages; i++) {
                page = extent_buffer_page(eb, i);
-               if (!wait) {
+               if (wait == WAIT_NONE) {
                        if (!trylock_page(page))
                                goto unlock_exit;
                } else {
@@ -3430,7 +4030,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
        if (bio)
                submit_one_bio(READ, bio, mirror_num, bio_flags);
 
-       if (ret || !wait)
+       if (ret || wait != WAIT_COMPLETE)
                return ret;
 
        for (i = start_i; i < num_pages; i++) {
index 7b2f0c3e79292a2f73aec86ed112e46b1a438c69..7604c30013227fd823b1523503f8faaeccf283c4 100644 (file)
@@ -17,6 +17,8 @@
 #define EXTENT_NODATASUM (1 << 10)
 #define EXTENT_DO_ACCOUNTING (1 << 11)
 #define EXTENT_FIRST_DELALLOC (1 << 12)
+#define EXTENT_NEED_WAIT (1 << 13)
+#define EXTENT_DAMAGED (1 << 14)
 #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
 #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC)
 
@@ -32,6 +34,7 @@
 #define EXTENT_BUFFER_BLOCKING 1
 #define EXTENT_BUFFER_DIRTY 2
 #define EXTENT_BUFFER_CORRUPT 3
+#define EXTENT_BUFFER_READAHEAD 4      /* this got triggered by readahead */
 
 /* these are flags for extent_clear_unlock_delalloc */
 #define EXTENT_CLEAR_UNLOCK_PAGE 0x1
@@ -67,7 +70,7 @@ struct extent_io_ops {
                              unsigned long bio_flags);
        int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
        int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
-                                      u64 start, u64 end,
+                                      u64 start, u64 end, int failed_mirror,
                                       struct extent_state *state);
        int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
                                        u64 start, u64 end,
@@ -85,7 +88,8 @@ struct extent_io_ops {
                                  struct extent_state *other);
        void (*split_extent_hook)(struct inode *inode,
                                  struct extent_state *orig, u64 split);
-       int (*write_cache_pages_lock_hook)(struct page *page);
+       int (*write_cache_pages_lock_hook)(struct page *page, void *data,
+                                          void (*flush_fn)(void *));
 };
 
 struct extent_io_tree {
@@ -185,7 +189,7 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
 int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end,
                    gfp_t mask);
 int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
-                         get_extent_t *get_extent);
+                         get_extent_t *get_extent, int mirror_num);
 int __init extent_io_init(void);
 void extent_io_exit(void);
 
@@ -214,6 +218,8 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
                     gfp_t mask);
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
                       gfp_t mask);
+int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
+                      int bits, int clear_bits, gfp_t mask);
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
                        struct extent_state **cached_state, gfp_t mask);
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
@@ -248,9 +254,14 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
 struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
                                         u64 start, unsigned long len);
 void free_extent_buffer(struct extent_buffer *eb);
+#define WAIT_NONE      0
+#define WAIT_COMPLETE  1
+#define WAIT_PAGE_LOCK 2
 int read_extent_buffer_pages(struct extent_io_tree *tree,
                             struct extent_buffer *eb, u64 start, int wait,
                             get_extent_t *get_extent, int mirror_num);
+unsigned long num_extent_pages(u64 start, u64 len);
+struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i);
 
 static inline void extent_buffer_get(struct extent_buffer *eb)
 {
@@ -300,4 +311,10 @@ int extent_clear_unlock_delalloc(struct inode *inode,
 struct bio *
 btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
                gfp_t gfp_flags);
+
+struct btrfs_mapping_tree;
+
+int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
+                       u64 length, u64 logical, struct page *page,
+                       int mirror_num);
 #endif
index a1cb7821becda9229d1e68712cd7a93a1e8d6fcc..c7fb3a4247d3a766ab07cec511b6f0001e8f5e9f 100644 (file)
@@ -91,8 +91,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
        struct btrfs_csum_item *item;
        struct extent_buffer *leaf;
        u64 csum_offset = 0;
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        int csums_in_item;
 
        file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
@@ -162,8 +161,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
        u64 item_last_offset = 0;
        u64 disk_bytenr;
        u32 diff;
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        int ret;
        struct btrfs_path *path;
        struct btrfs_csum_item *item = NULL;
@@ -290,7 +288,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
        int ret;
        size_t size;
        u64 csum_end;
-       u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
 
        path = btrfs_alloc_path();
        if (!path)
@@ -492,8 +490,7 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans,
                                      u64 bytenr, u64 len)
 {
        struct extent_buffer *leaf;
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        u64 csum_end;
        u64 end_byte = bytenr + len;
        u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits;
@@ -549,8 +546,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
        u64 csum_end;
        struct extent_buffer *leaf;
        int ret;
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
        int blocksize_bits = root->fs_info->sb->s_blocksize_bits;
 
        root = root->fs_info->csum_root;
@@ -676,8 +672,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
        struct btrfs_sector_sum *sector_sum;
        u32 nritems;
        u32 ins_size;
-       u16 csum_size =
-               btrfs_super_csum_size(&root->fs_info->super_copy);
+       u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
 
        path = btrfs_alloc_path();
        if (!path)
index 1266f6e9cdb22a309d7da8893963fc3765824b65..dafdfa059bf66a489bd3d858990b9025fd50a72f 100644 (file)
@@ -1069,6 +1069,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
        int i;
        unsigned long index = pos >> PAGE_CACHE_SHIFT;
        struct inode *inode = fdentry(file)->d_inode;
+       gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
        int err = 0;
        int faili = 0;
        u64 start_pos;
@@ -1080,7 +1081,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
 again:
        for (i = 0; i < num_pages; i++) {
                pages[i] = find_or_create_page(inode->i_mapping, index + i,
-                                              GFP_NOFS);
+                                              mask);
                if (!pages[i]) {
                        faili = i - 1;
                        err = -ENOMEM;
@@ -1615,10 +1616,6 @@ static long btrfs_fallocate(struct file *file, int mode,
                        goto out;
        }
 
-       ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
-       if (ret)
-               goto out;
-
        locked_end = alloc_end - 1;
        while (1) {
                struct btrfs_ordered_extent *ordered;
@@ -1664,11 +1661,27 @@ static long btrfs_fallocate(struct file *file, int mode,
                if (em->block_start == EXTENT_MAP_HOLE ||
                    (cur_offset >= inode->i_size &&
                     !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
+
+                       /*
+                        * Make sure we have enough space before we do the
+                        * allocation.
+                        */
+                       ret = btrfs_check_data_free_space(inode, last_byte -
+                                                         cur_offset);
+                       if (ret) {
+                               free_extent_map(em);
+                               break;
+                       }
+
                        ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
                                                        last_byte - cur_offset,
                                                        1 << inode->i_blkbits,
                                                        offset + len,
                                                        &alloc_hint);
+
+                       /* Let go of our reservation. */
+                       btrfs_free_reserved_data_space(inode, last_byte -
+                                                      cur_offset);
                        if (ret < 0) {
                                free_extent_map(em);
                                break;
@@ -1694,8 +1707,6 @@ static long btrfs_fallocate(struct file *file, int mode,
        }
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
                             &cached_state, GFP_NOFS);
-
-       btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
 out:
        mutex_unlock(&inode->i_mutex);
        return ret;
index 41ac927401d06bc14a2214e245d1cdfbb2d7b603..ec23d43d0c357870a14bf6e79a0ce5baeb93a43d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/math64.h>
+#include <linux/ratelimit.h>
 #include "ctree.h"
 #include "free-space-cache.h"
 #include "transaction.h"
@@ -84,6 +85,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root,
                                      *block_group, struct btrfs_path *path)
 {
        struct inode *inode = NULL;
+       u32 flags = BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW;
 
        spin_lock(&block_group->lock);
        if (block_group->inode)
@@ -98,13 +100,14 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root,
                return inode;
 
        spin_lock(&block_group->lock);
-       if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) {
+       if (!((BTRFS_I(inode)->flags & flags) == flags)) {
                printk(KERN_INFO "Old style space inode found, converting.\n");
-               BTRFS_I(inode)->flags &= ~BTRFS_INODE_NODATASUM;
+               BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM |
+                       BTRFS_INODE_NODATACOW;
                block_group->disk_cache_state = BTRFS_DC_CLEAR;
        }
 
-       if (!btrfs_fs_closing(root->fs_info)) {
+       if (!block_group->iref) {
                block_group->inode = igrab(inode);
                block_group->iref = 1;
        }
@@ -122,12 +125,17 @@ int __create_free_space_inode(struct btrfs_root *root,
        struct btrfs_free_space_header *header;
        struct btrfs_inode_item *inode_item;
        struct extent_buffer *leaf;
+       u64 flags = BTRFS_INODE_NOCOMPRESS | BTRFS_INODE_PREALLOC;
        int ret;
 
        ret = btrfs_insert_empty_inode(trans, root, path, ino);
        if (ret)
                return ret;
 
+       /* We inline crc's for the free disk space cache */
+       if (ino != BTRFS_FREE_INO_OBJECTID)
+               flags |= BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW;
+
        leaf = path->nodes[0];
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_inode_item);
@@ -140,8 +148,7 @@ int __create_free_space_inode(struct btrfs_root *root,
        btrfs_set_inode_uid(leaf, inode_item, 0);
        btrfs_set_inode_gid(leaf, inode_item, 0);
        btrfs_set_inode_mode(leaf, inode_item, S_IFREG | 0600);
-       btrfs_set_inode_flags(leaf, inode_item, BTRFS_INODE_NOCOMPRESS |
-                             BTRFS_INODE_PREALLOC);
+       btrfs_set_inode_flags(leaf, inode_item, flags);
        btrfs_set_inode_nlink(leaf, inode_item, 1);
        btrfs_set_inode_transid(leaf, inode_item, trans->transid);
        btrfs_set_inode_block_group(leaf, inode_item, offset);
@@ -191,16 +198,24 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
                                    struct inode *inode)
 {
        struct btrfs_block_rsv *rsv;
+       u64 needed_bytes;
        loff_t oldsize;
        int ret = 0;
 
        rsv = trans->block_rsv;
-       trans->block_rsv = root->orphan_block_rsv;
-       ret = btrfs_block_rsv_check(trans, root,
-                                   root->orphan_block_rsv,
-                                   0, 5);
-       if (ret)
-               return ret;
+       trans->block_rsv = &root->fs_info->global_block_rsv;
+
+       /* 1 for slack space, 1 for updating the inode */
+       needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) +
+               btrfs_calc_trans_metadata_size(root, 1);
+
+       spin_lock(&trans->block_rsv->lock);
+       if (trans->block_rsv->reserved < needed_bytes) {
+               spin_unlock(&trans->block_rsv->lock);
+               trans->block_rsv = rsv;
+               return -ENOSPC;
+       }
+       spin_unlock(&trans->block_rsv->lock);
 
        oldsize = i_size_read(inode);
        btrfs_i_size_write(inode, 0);
@@ -213,13 +228,15 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
        ret = btrfs_truncate_inode_items(trans, root, inode,
                                         0, BTRFS_EXTENT_DATA_KEY);
 
-       trans->block_rsv = rsv;
        if (ret) {
+               trans->block_rsv = rsv;
                WARN_ON(1);
                return ret;
        }
 
        ret = btrfs_update_inode(trans, root, inode);
+       trans->block_rsv = rsv;
+
        return ret;
 }
 
@@ -242,26 +259,348 @@ static int readahead_cache(struct inode *inode)
        return 0;
 }
 
+struct io_ctl {
+       void *cur, *orig;
+       struct page *page;
+       struct page **pages;
+       struct btrfs_root *root;
+       unsigned long size;
+       int index;
+       int num_pages;
+       unsigned check_crcs:1;
+};
+
+static int io_ctl_init(struct io_ctl *io_ctl, struct inode *inode,
+                      struct btrfs_root *root)
+{
+       memset(io_ctl, 0, sizeof(struct io_ctl));
+       io_ctl->num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
+               PAGE_CACHE_SHIFT;
+       io_ctl->pages = kzalloc(sizeof(struct page *) * io_ctl->num_pages,
+                               GFP_NOFS);
+       if (!io_ctl->pages)
+               return -ENOMEM;
+       io_ctl->root = root;
+       if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID)
+               io_ctl->check_crcs = 1;
+       return 0;
+}
+
+static void io_ctl_free(struct io_ctl *io_ctl)
+{
+       kfree(io_ctl->pages);
+}
+
+static void io_ctl_unmap_page(struct io_ctl *io_ctl)
+{
+       if (io_ctl->cur) {
+               kunmap(io_ctl->page);
+               io_ctl->cur = NULL;
+               io_ctl->orig = NULL;
+       }
+}
+
+static void io_ctl_map_page(struct io_ctl *io_ctl, int clear)
+{
+       WARN_ON(io_ctl->cur);
+       BUG_ON(io_ctl->index >= io_ctl->num_pages);
+       io_ctl->page = io_ctl->pages[io_ctl->index++];
+       io_ctl->cur = kmap(io_ctl->page);
+       io_ctl->orig = io_ctl->cur;
+       io_ctl->size = PAGE_CACHE_SIZE;
+       if (clear)
+               memset(io_ctl->cur, 0, PAGE_CACHE_SIZE);
+}
+
+static void io_ctl_drop_pages(struct io_ctl *io_ctl)
+{
+       int i;
+
+       io_ctl_unmap_page(io_ctl);
+
+       for (i = 0; i < io_ctl->num_pages; i++) {
+               ClearPageChecked(io_ctl->pages[i]);
+               unlock_page(io_ctl->pages[i]);
+               page_cache_release(io_ctl->pages[i]);
+       }
+}
+
+static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode,
+                               int uptodate)
+{
+       struct page *page;
+       gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
+       int i;
+
+       for (i = 0; i < io_ctl->num_pages; i++) {
+               page = find_or_create_page(inode->i_mapping, i, mask);
+               if (!page) {
+                       io_ctl_drop_pages(io_ctl);
+                       return -ENOMEM;
+               }
+               io_ctl->pages[i] = page;
+               if (uptodate && !PageUptodate(page)) {
+                       btrfs_readpage(NULL, page);
+                       lock_page(page);
+                       if (!PageUptodate(page)) {
+                               printk(KERN_ERR "btrfs: error reading free "
+                                      "space cache\n");
+                               io_ctl_drop_pages(io_ctl);
+                               return -EIO;
+                       }
+               }
+       }
+
+       for (i = 0; i < io_ctl->num_pages; i++) {
+               clear_page_dirty_for_io(io_ctl->pages[i]);
+               set_page_extent_mapped(io_ctl->pages[i]);
+       }
+
+       return 0;
+}
+
+static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation)
+{
+       u64 *val;
+
+       io_ctl_map_page(io_ctl, 1);
+
+       /*
+        * Skip the csum areas.  If we don't check crcs then we just have a
+        * 64bit chunk at the front of the first page.
+        */
+       if (io_ctl->check_crcs) {
+               io_ctl->cur += (sizeof(u32) * io_ctl->num_pages);
+               io_ctl->size -= sizeof(u64) + (sizeof(u32) * io_ctl->num_pages);
+       } else {
+               io_ctl->cur += sizeof(u64);
+               io_ctl->size -= sizeof(u64) * 2;
+       }
+
+       val = io_ctl->cur;
+       *val = cpu_to_le64(generation);
+       io_ctl->cur += sizeof(u64);
+}
+
+static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation)
+{
+       u64 *gen;
+
+       /*
+        * Skip the crc area.  If we don't check crcs then we just have a 64bit
+        * chunk at the front of the first page.
+        */
+       if (io_ctl->check_crcs) {
+               io_ctl->cur += sizeof(u32) * io_ctl->num_pages;
+               io_ctl->size -= sizeof(u64) +
+                       (sizeof(u32) * io_ctl->num_pages);
+       } else {
+               io_ctl->cur += sizeof(u64);
+               io_ctl->size -= sizeof(u64) * 2;
+       }
+
+       gen = io_ctl->cur;
+       if (le64_to_cpu(*gen) != generation) {
+               printk_ratelimited(KERN_ERR "btrfs: space cache generation "
+                                  "(%Lu) does not match inode (%Lu)\n", *gen,
+                                  generation);
+               io_ctl_unmap_page(io_ctl);
+               return -EIO;
+       }
+       io_ctl->cur += sizeof(u64);
+       return 0;
+}
+
+static void io_ctl_set_crc(struct io_ctl *io_ctl, int index)
+{
+       u32 *tmp;
+       u32 crc = ~(u32)0;
+       unsigned offset = 0;
+
+       if (!io_ctl->check_crcs) {
+               io_ctl_unmap_page(io_ctl);
+               return;
+       }
+
+       if (index == 0)
+               offset = sizeof(u32) * io_ctl->num_pages;;
+
+       crc = btrfs_csum_data(io_ctl->root, io_ctl->orig + offset, crc,
+                             PAGE_CACHE_SIZE - offset);
+       btrfs_csum_final(crc, (char *)&crc);
+       io_ctl_unmap_page(io_ctl);
+       tmp = kmap(io_ctl->pages[0]);
+       tmp += index;
+       *tmp = crc;
+       kunmap(io_ctl->pages[0]);
+}
+
+static int io_ctl_check_crc(struct io_ctl *io_ctl, int index)
+{
+       u32 *tmp, val;
+       u32 crc = ~(u32)0;
+       unsigned offset = 0;
+
+       if (!io_ctl->check_crcs) {
+               io_ctl_map_page(io_ctl, 0);
+               return 0;
+       }
+
+       if (index == 0)
+               offset = sizeof(u32) * io_ctl->num_pages;
+
+       tmp = kmap(io_ctl->pages[0]);
+       tmp += index;
+       val = *tmp;
+       kunmap(io_ctl->pages[0]);
+
+       io_ctl_map_page(io_ctl, 0);
+       crc = btrfs_csum_data(io_ctl->root, io_ctl->orig + offset, crc,
+                             PAGE_CACHE_SIZE - offset);
+       btrfs_csum_final(crc, (char *)&crc);
+       if (val != crc) {
+               printk_ratelimited(KERN_ERR "btrfs: csum mismatch on free "
+                                  "space cache\n");
+               io_ctl_unmap_page(io_ctl);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int io_ctl_add_entry(struct io_ctl *io_ctl, u64 offset, u64 bytes,
+                           void *bitmap)
+{
+       struct btrfs_free_space_entry *entry;
+
+       if (!io_ctl->cur)
+               return -ENOSPC;
+
+       entry = io_ctl->cur;
+       entry->offset = cpu_to_le64(offset);
+       entry->bytes = cpu_to_le64(bytes);
+       entry->type = (bitmap) ? BTRFS_FREE_SPACE_BITMAP :
+               BTRFS_FREE_SPACE_EXTENT;
+       io_ctl->cur += sizeof(struct btrfs_free_space_entry);
+       io_ctl->size -= sizeof(struct btrfs_free_space_entry);
+
+       if (io_ctl->size >= sizeof(struct btrfs_free_space_entry))
+               return 0;
+
+       io_ctl_set_crc(io_ctl, io_ctl->index - 1);
+
+       /* No more pages to map */
+       if (io_ctl->index >= io_ctl->num_pages)
+               return 0;
+
+       /* map the next page */
+       io_ctl_map_page(io_ctl, 1);
+       return 0;
+}
+
+static int io_ctl_add_bitmap(struct io_ctl *io_ctl, void *bitmap)
+{
+       if (!io_ctl->cur)
+               return -ENOSPC;
+
+       /*
+        * If we aren't at the start of the current page, unmap this one and
+        * map the next one if there is any left.
+        */
+       if (io_ctl->cur != io_ctl->orig) {
+               io_ctl_set_crc(io_ctl, io_ctl->index - 1);
+               if (io_ctl->index >= io_ctl->num_pages)
+                       return -ENOSPC;
+               io_ctl_map_page(io_ctl, 0);
+       }
+
+       memcpy(io_ctl->cur, bitmap, PAGE_CACHE_SIZE);
+       io_ctl_set_crc(io_ctl, io_ctl->index - 1);
+       if (io_ctl->index < io_ctl->num_pages)
+               io_ctl_map_page(io_ctl, 0);
+       return 0;
+}
+
+static void io_ctl_zero_remaining_pages(struct io_ctl *io_ctl)
+{
+       /*
+        * If we're not on the boundary we know we've modified the page and we
+        * need to crc the page.
+        */
+       if (io_ctl->cur != io_ctl->orig)
+               io_ctl_set_crc(io_ctl, io_ctl->index - 1);
+       else
+               io_ctl_unmap_page(io_ctl);
+
+       while (io_ctl->index < io_ctl->num_pages) {
+               io_ctl_map_page(io_ctl, 1);
+               io_ctl_set_crc(io_ctl, io_ctl->index - 1);
+       }
+}
+
+static int io_ctl_read_entry(struct io_ctl *io_ctl,
+                           struct btrfs_free_space *entry, u8 *type)
+{
+       struct btrfs_free_space_entry *e;
+       int ret;
+
+       if (!io_ctl->cur) {
+               ret = io_ctl_check_crc(io_ctl, io_ctl->index);
+               if (ret)
+                       return ret;
+       }
+
+       e = io_ctl->cur;
+       entry->offset = le64_to_cpu(e->offset);
+       entry->bytes = le64_to_cpu(e->bytes);
+       *type = e->type;
+       io_ctl->cur += sizeof(struct btrfs_free_space_entry);
+       io_ctl->size -= sizeof(struct btrfs_free_space_entry);
+
+       if (io_ctl->size >= sizeof(struct btrfs_free_space_entry))
+               return 0;
+
+       io_ctl_unmap_page(io_ctl);
+
+       return 0;
+}
+
+static int io_ctl_read_bitmap(struct io_ctl *io_ctl,
+                             struct btrfs_free_space *entry)
+{
+       int ret;
+
+       ret = io_ctl_check_crc(io_ctl, io_ctl->index);
+       if (ret)
+               return ret;
+
+       memcpy(entry->bitmap, io_ctl->cur, PAGE_CACHE_SIZE);
+       io_ctl_unmap_page(io_ctl);
+
+       return 0;
+}
+
 int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
                            struct btrfs_free_space_ctl *ctl,
                            struct btrfs_path *path, u64 offset)
 {
        struct btrfs_free_space_header *header;
        struct extent_buffer *leaf;
-       struct page *page;
+       struct io_ctl io_ctl;
        struct btrfs_key key;
+       struct btrfs_free_space *e, *n;
        struct list_head bitmaps;
        u64 num_entries;
        u64 num_bitmaps;
        u64 generation;
-       pgoff_t index = 0;
+       u8 type;
        int ret = 0;
 
        INIT_LIST_HEAD(&bitmaps);
 
        /* Nothing in the space cache, goodbye */
        if (!i_size_read(inode))
-               goto out;
+               return 0;
 
        key.objectid = BTRFS_FREE_SPACE_OBJECTID;
        key.offset = offset;
@@ -269,11 +608,10 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
 
        ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
        if (ret < 0)
-               goto out;
+               return 0;
        else if (ret > 0) {
                btrfs_release_path(path);
-               ret = 0;
-               goto out;
+               return 0;
        }
 
        ret = -1;
@@ -291,169 +629,102 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
                       " not match free space cache generation (%llu)\n",
                       (unsigned long long)BTRFS_I(inode)->generation,
                       (unsigned long long)generation);
-               goto out;
+               return 0;
        }
 
        if (!num_entries)
-               goto out;
+               return 0;
 
+       io_ctl_init(&io_ctl, inode, root);
        ret = readahead_cache(inode);
        if (ret)
                goto out;
 
-       while (1) {
-               struct btrfs_free_space_entry *entry;
-               struct btrfs_free_space *e;
-               void *addr;
-               unsigned long offset = 0;
-               int need_loop = 0;
+       ret = io_ctl_prepare_pages(&io_ctl, inode, 1);
+       if (ret)
+               goto out;
 
-               if (!num_entries && !num_bitmaps)
-                       break;
+       ret = io_ctl_check_crc(&io_ctl, 0);
+       if (ret)
+               goto free_cache;
+
+       ret = io_ctl_check_generation(&io_ctl, generation);
+       if (ret)
+               goto free_cache;
 
-               page = find_or_create_page(inode->i_mapping, index, GFP_NOFS);
-               if (!page)
+       while (num_entries) {
+               e = kmem_cache_zalloc(btrfs_free_space_cachep,
+                                     GFP_NOFS);
+               if (!e)
                        goto free_cache;
 
-               if (!PageUptodate(page)) {
-                       btrfs_readpage(NULL, page);
-                       lock_page(page);
-                       if (!PageUptodate(page)) {
-                               unlock_page(page);
-                               page_cache_release(page);
-                               printk(KERN_ERR "btrfs: error reading free "
-                                      "space cache\n");
-                               goto free_cache;
-                       }
+               ret = io_ctl_read_entry(&io_ctl, e, &type);
+               if (ret) {
+                       kmem_cache_free(btrfs_free_space_cachep, e);
+                       goto free_cache;
                }
-               addr = kmap(page);
 
-               if (index == 0) {
-                       u64 *gen;
+               if (!e->bytes) {
+                       kmem_cache_free(btrfs_free_space_cachep, e);
+                       goto free_cache;
+               }
 
-                       /*
-                        * We put a bogus crc in the front of the first page in
-                        * case old kernels try to mount a fs with the new
-                        * format to make sure they discard the cache.
-                        */
-                       addr += sizeof(u64);
-                       offset += sizeof(u64);
-
-                       gen = addr;
-                       if (*gen != BTRFS_I(inode)->generation) {
-                               printk(KERN_ERR "btrfs: space cache generation"
-                                      " (%llu) does not match inode (%llu)\n",
-                                      (unsigned long long)*gen,
-                                      (unsigned long long)
-                                      BTRFS_I(inode)->generation);
-                               kunmap(page);
-                               unlock_page(page);
-                               page_cache_release(page);
+               if (type == BTRFS_FREE_SPACE_EXTENT) {
+                       spin_lock(&ctl->tree_lock);
+                       ret = link_free_space(ctl, e);
+                       spin_unlock(&ctl->tree_lock);
+                       if (ret) {
+                               printk(KERN_ERR "Duplicate entries in "
+                                      "free space cache, dumping\n");
+                               kmem_cache_free(btrfs_free_space_cachep, e);
                                goto free_cache;
                        }
-                       addr += sizeof(u64);
-                       offset += sizeof(u64);
-               }
-               entry = addr;
-
-               while (1) {
-                       if (!num_entries)
-                               break;
-
-                       need_loop = 1;
-                       e = kmem_cache_zalloc(btrfs_free_space_cachep,
-                                             GFP_NOFS);
-                       if (!e) {
-                               kunmap(page);
-                               unlock_page(page);
-                               page_cache_release(page);
+               } else {
+                       BUG_ON(!num_bitmaps);
+                       num_bitmaps--;
+                       e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
+                       if (!e->bitmap) {
+                               kmem_cache_free(
+                                       btrfs_free_space_cachep, e);
                                goto free_cache;
                        }
-
-                       e->offset = le64_to_cpu(entry->offset);
-                       e->bytes = le64_to_cpu(entry->bytes);
-                       if (!e->bytes) {
-                               kunmap(page);
+                       spin_lock(&ctl->tree_lock);
+                       ret = link_free_space(ctl, e);
+                       ctl->total_bitmaps++;
+                       ctl->op->recalc_thresholds(ctl);
+                       spin_unlock(&ctl->tree_lock);
+                       if (ret) {
+                               printk(KERN_ERR "Duplicate entries in "
+                                      "free space cache, dumping\n");
                                kmem_cache_free(btrfs_free_space_cachep, e);
-                               unlock_page(page);
-                               page_cache_release(page);
                                goto free_cache;
                        }
-
-                       if (entry->type == BTRFS_FREE_SPACE_EXTENT) {
-                               spin_lock(&ctl->tree_lock);
-                               ret = link_free_space(ctl, e);
-                               spin_unlock(&ctl->tree_lock);
-                               if (ret) {
-                                       printk(KERN_ERR "Duplicate entries in "
-                                              "free space cache, dumping\n");
-                                       kunmap(page);
-                                       unlock_page(page);
-                                       page_cache_release(page);
-                                       goto free_cache;
-                               }
-                       } else {
-                               e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
-                               if (!e->bitmap) {
-                                       kunmap(page);
-                                       kmem_cache_free(
-                                               btrfs_free_space_cachep, e);
-                                       unlock_page(page);
-                                       page_cache_release(page);
-                                       goto free_cache;
-                               }
-                               spin_lock(&ctl->tree_lock);
-                               ret = link_free_space(ctl, e);
-                               ctl->total_bitmaps++;
-                               ctl->op->recalc_thresholds(ctl);
-                               spin_unlock(&ctl->tree_lock);
-                               if (ret) {
-                                       printk(KERN_ERR "Duplicate entries in "
-                                              "free space cache, dumping\n");
-                                       kunmap(page);
-                                       unlock_page(page);
-                                       page_cache_release(page);
-                                       goto free_cache;
-                               }
-                               list_add_tail(&e->list, &bitmaps);
-                       }
-
-                       num_entries--;
-                       offset += sizeof(struct btrfs_free_space_entry);
-                       if (offset + sizeof(struct btrfs_free_space_entry) >=
-                           PAGE_CACHE_SIZE)
-                               break;
-                       entry++;
+                       list_add_tail(&e->list, &bitmaps);
                }
 
-               /*
-                * We read an entry out of this page, we need to move on to the
-                * next page.
-                */
-               if (need_loop) {
-                       kunmap(page);
-                       goto next;
-               }
+               num_entries--;
+       }
 
-               /*
-                * We add the bitmaps at the end of the entries in order that
-                * the bitmap entries are added to the cache.
-                */
-               e = list_entry(bitmaps.next, struct btrfs_free_space, list);
+       io_ctl_unmap_page(&io_ctl);
+
+       /*
+        * We add the bitmaps at the end of the entries in order that
+        * the bitmap entries are added to the cache.
+        */
+       list_for_each_entry_safe(e, n, &bitmaps, list) {
                list_del_init(&e->list);
-               memcpy(e->bitmap, addr, PAGE_CACHE_SIZE);
-               kunmap(page);
-               num_bitmaps--;
-next:
-               unlock_page(page);
-               page_cache_release(page);
-               index++;
+               ret = io_ctl_read_bitmap(&io_ctl, e);
+               if (ret)
+                       goto free_cache;
        }
 
+       io_ctl_drop_pages(&io_ctl);
        ret = 1;
 out:
+       io_ctl_free(&io_ctl);
        return ret;
 free_cache:
+       io_ctl_drop_pages(&io_ctl);
        __btrfs_remove_free_space_cache(ctl);
        goto out;
 }
@@ -465,7 +736,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
        struct btrfs_root *root = fs_info->tree_root;
        struct inode *inode;
        struct btrfs_path *path;
-       int ret;
+       int ret = 0;
        bool matched;
        u64 used = btrfs_block_group_used(&block_group->item);
 
@@ -497,6 +768,14 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
                return 0;
        }
 
+       /* We may have converted the inode and made the cache invalid. */
+       spin_lock(&block_group->lock);
+       if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) {
+               spin_unlock(&block_group->lock);
+               goto out;
+       }
+       spin_unlock(&block_group->lock);
+
        ret = __load_free_space_cache(fs_info->tree_root, inode, ctl,
                                      path, block_group->key.objectid);
        btrfs_free_path(path);
@@ -530,6 +809,19 @@ out:
        return ret;
 }
 
+/**
+ * __btrfs_write_out_cache - write out cached info to an inode
+ * @root - the root the inode belongs to
+ * @ctl - the free space cache we are going to write out
+ * @block_group - the block_group for this cache if it belongs to a block_group
+ * @trans - the trans handle
+ * @path - the path to use
+ * @offset - the offset for the key we'll insert
+ *
+ * This function writes out a free space cache struct to disk for quick recovery
+ * on mount.  This will return 0 if it was successfull in writing the cache out,
+ * and -1 if it was not.
+ */
 int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
                            struct btrfs_free_space_ctl *ctl,
                            struct btrfs_block_group_cache *block_group,
@@ -540,42 +832,24 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        struct extent_buffer *leaf;
        struct rb_node *node;
        struct list_head *pos, *n;
-       struct page **pages;
-       struct page *page;
        struct extent_state *cached_state = NULL;
        struct btrfs_free_cluster *cluster = NULL;
        struct extent_io_tree *unpin = NULL;
+       struct io_ctl io_ctl;
        struct list_head bitmap_list;
        struct btrfs_key key;
        u64 start, end, len;
-       u64 bytes = 0;
-       u32 crc = ~(u32)0;
-       int index = 0, num_pages = 0;
        int entries = 0;
        int bitmaps = 0;
-       int ret = -1;
-       bool next_page = false;
-       bool out_of_space = false;
+       int ret;
+       int err = -1;
 
        INIT_LIST_HEAD(&bitmap_list);
 
-       node = rb_first(&ctl->free_space_offset);
-       if (!node)
-               return 0;
-
        if (!i_size_read(inode))
                return -1;
 
-       num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
-               PAGE_CACHE_SHIFT;
-
-       filemap_write_and_wait(inode->i_mapping);
-       btrfs_wait_ordered_range(inode, inode->i_size &
-                                ~(root->sectorsize - 1), (u64)-1);
-
-       pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS);
-       if (!pages)
-               return -1;
+       io_ctl_init(&io_ctl, inode, root);
 
        /* Get the cluster for this block_group if it exists */
        if (block_group && !list_empty(&block_group->cluster_list))
@@ -589,30 +863,9 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
         */
        unpin = root->fs_info->pinned_extents;
 
-       /*
-        * Lock all pages first so we can lock the extent safely.
-        *
-        * NOTE: Because we hold the ref the entire time we're going to write to
-        * the page find_get_page should never fail, so we don't do a check
-        * after find_get_page at this point.  Just putting this here so people
-        * know and don't freak out.
-        */
-       while (index < num_pages) {
-               page = find_or_create_page(inode->i_mapping, index, GFP_NOFS);
-               if (!page) {
-                       int i;
+       /* Lock all pages first so we can lock the extent safely. */
+       io_ctl_prepare_pages(&io_ctl, inode, 0);
 
-                       for (i = 0; i < num_pages; i++) {
-                               unlock_page(pages[i]);
-                               page_cache_release(pages[i]);
-                       }
-                       goto out;
-               }
-               pages[index] = page;
-               index++;
-       }
-
-       index = 0;
        lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
                         0, &cached_state, GFP_NOFS);
 
@@ -623,189 +876,111 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        if (block_group)
                start = block_group->key.objectid;
 
-       /* Write out the extent entries */
-       do {
-               struct btrfs_free_space_entry *entry;
-               void *addr, *orig;
-               unsigned long offset = 0;
+       node = rb_first(&ctl->free_space_offset);
+       if (!node && cluster) {
+               node = rb_first(&cluster->root);
+               cluster = NULL;
+       }
 
-               next_page = false;
+       /* Make sure we can fit our crcs into the first page */
+       if (io_ctl.check_crcs &&
+           (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) {
+               WARN_ON(1);
+               goto out_nospc;
+       }
 
-               if (index >= num_pages) {
-                       out_of_space = true;
-                       break;
-               }
+       io_ctl_set_generation(&io_ctl, trans->transid);
 
-               page = pages[index];
+       /* Write out the extent entries */
+       while (node) {
+               struct btrfs_free_space *e;
 
-               orig = addr = kmap(page);
-               if (index == 0) {
-                       u64 *gen;
+               e = rb_entry(node, struct btrfs_free_space, offset_index);
+               entries++;
 
-                       /*
-                        * We're going to put in a bogus crc for this page to
-                        * make sure that old kernels who aren't aware of this
-                        * format will be sure to discard the cache.
-                        */
-                       addr += sizeof(u64);
-                       offset += sizeof(u64);
+               ret = io_ctl_add_entry(&io_ctl, e->offset, e->bytes,
+                                      e->bitmap);
+               if (ret)
+                       goto out_nospc;
 
-                       gen = addr;
-                       *gen = trans->transid;
-                       addr += sizeof(u64);
-                       offset += sizeof(u64);
+               if (e->bitmap) {
+                       list_add_tail(&e->list, &bitmap_list);
+                       bitmaps++;
                }
-               entry = addr;
-
-               memset(addr, 0, PAGE_CACHE_SIZE - offset);
-               while (node && !next_page) {
-                       struct btrfs_free_space *e;
-
-                       e = rb_entry(node, struct btrfs_free_space, offset_index);
-                       entries++;
-
-                       entry->offset = cpu_to_le64(e->offset);
-                       entry->bytes = cpu_to_le64(e->bytes);
-                       if (e->bitmap) {
-                               entry->type = BTRFS_FREE_SPACE_BITMAP;
-                               list_add_tail(&e->list, &bitmap_list);
-                               bitmaps++;
-                       } else {
-                               entry->type = BTRFS_FREE_SPACE_EXTENT;
-                       }
-                       node = rb_next(node);
-                       if (!node && cluster) {
-                               node = rb_first(&cluster->root);
-                               cluster = NULL;
-                       }
-                       offset += sizeof(struct btrfs_free_space_entry);
-                       if (offset + sizeof(struct btrfs_free_space_entry) >=
-                           PAGE_CACHE_SIZE)
-                               next_page = true;
-                       entry++;
+               node = rb_next(node);
+               if (!node && cluster) {
+                       node = rb_first(&cluster->root);
+                       cluster = NULL;
                }
+       }
 
-               /*
-                * We want to add any pinned extents to our free space cache
-                * so we don't leak the space
-                */
-               while (block_group && !next_page &&
-                      (start < block_group->key.objectid +
-                       block_group->key.offset)) {
-                       ret = find_first_extent_bit(unpin, start, &start, &end,
-                                                   EXTENT_DIRTY);
-                       if (ret) {
-                               ret = 0;
-                               break;
-                       }
-
-                       /* This pinned extent is out of our range */
-                       if (start >= block_group->key.objectid +
-                           block_group->key.offset)
-                               break;
-
-                       len = block_group->key.objectid +
-                               block_group->key.offset - start;
-                       len = min(len, end + 1 - start);
-
-                       entries++;
-                       entry->offset = cpu_to_le64(start);
-                       entry->bytes = cpu_to_le64(len);
-                       entry->type = BTRFS_FREE_SPACE_EXTENT;
-
-                       start = end + 1;
-                       offset += sizeof(struct btrfs_free_space_entry);
-                       if (offset + sizeof(struct btrfs_free_space_entry) >=
-                           PAGE_CACHE_SIZE)
-                               next_page = true;
-                       entry++;
+       /*
+        * We want to add any pinned extents to our free space cache
+        * so we don't leak the space
+        */
+       while (block_group && (start < block_group->key.objectid +
+                              block_group->key.offset)) {
+               ret = find_first_extent_bit(unpin, start, &start, &end,
+                                           EXTENT_DIRTY);
+               if (ret) {
+                       ret = 0;
+                       break;
                }
 
-               /* Generate bogus crc value */
-               if (index == 0) {
-                       u32 *tmp;
-                       crc = btrfs_csum_data(root, orig + sizeof(u64), crc,
-                                             PAGE_CACHE_SIZE - sizeof(u64));
-                       btrfs_csum_final(crc, (char *)&crc);
-                       crc++;
-                       tmp = orig;
-                       *tmp = crc;
-               }
+               /* This pinned extent is out of our range */
+               if (start >= block_group->key.objectid +
+                   block_group->key.offset)
+                       break;
 
-               kunmap(page);
+               len = block_group->key.objectid +
+                       block_group->key.offset - start;
+               len = min(len, end + 1 - start);
 
-               bytes += PAGE_CACHE_SIZE;
+               entries++;
+               ret = io_ctl_add_entry(&io_ctl, start, len, NULL);
+               if (ret)
+                       goto out_nospc;
 
-               index++;
-       } while (node || next_page);
+               start = end + 1;
+       }
 
        /* Write out the bitmaps */
        list_for_each_safe(pos, n, &bitmap_list) {
-               void *addr;
                struct btrfs_free_space *entry =
                        list_entry(pos, struct btrfs_free_space, list);
 
-               if (index >= num_pages) {
-                       out_of_space = true;
-                       break;
-               }
-               page = pages[index];
-
-               addr = kmap(page);
-               memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE);
-               kunmap(page);
-               bytes += PAGE_CACHE_SIZE;
-
+               ret = io_ctl_add_bitmap(&io_ctl, entry->bitmap);
+               if (ret)
+                       goto out_nospc;
                list_del_init(&entry->list);
-               index++;
-       }
-
-       if (out_of_space) {
-               btrfs_drop_pages(pages, num_pages);
-               unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
-                                    i_size_read(inode) - 1, &cached_state,
-                                    GFP_NOFS);
-               ret = 0;
-               goto out;
        }
 
        /* Zero out the rest of the pages just to make sure */
-       while (index < num_pages) {
-               void *addr;
+       io_ctl_zero_remaining_pages(&io_ctl);
 
-               page = pages[index];
-               addr = kmap(page);
-               memset(addr, 0, PAGE_CACHE_SIZE);
-               kunmap(page);
-               bytes += PAGE_CACHE_SIZE;
-               index++;
-       }
-
-       ret = btrfs_dirty_pages(root, inode, pages, num_pages, 0,
-                                           bytes, &cached_state);
-       btrfs_drop_pages(pages, num_pages);
+       ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages,
+                               0, i_size_read(inode), &cached_state);
+       io_ctl_drop_pages(&io_ctl);
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
                             i_size_read(inode) - 1, &cached_state, GFP_NOFS);
 
-       if (ret) {
-               ret = 0;
+       if (ret)
                goto out;
-       }
 
-       BTRFS_I(inode)->generation = trans->transid;
 
-       filemap_write_and_wait(inode->i_mapping);
+       ret = filemap_write_and_wait(inode->i_mapping);
+       if (ret)
+               goto out;
 
        key.objectid = BTRFS_FREE_SPACE_OBJECTID;
        key.offset = offset;
        key.type = 0;
 
-       ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
+       ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
        if (ret < 0) {
-               ret = -1;
-               clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
-                                EXTENT_DIRTY | EXTENT_DELALLOC |
-                                EXTENT_DO_ACCOUNTING, 0, 0, NULL, GFP_NOFS);
+               clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1,
+                                EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL,
+                                GFP_NOFS);
                goto out;
        }
        leaf = path->nodes[0];
@@ -816,15 +991,16 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
                if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID ||
                    found_key.offset != offset) {
-                       ret = -1;
-                       clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
-                                        EXTENT_DIRTY | EXTENT_DELALLOC |
-                                        EXTENT_DO_ACCOUNTING, 0, 0, NULL,
-                                        GFP_NOFS);
+                       clear_extent_bit(&BTRFS_I(inode)->io_tree, 0,
+                                        inode->i_size - 1,
+                                        EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0,
+                                        NULL, GFP_NOFS);
                        btrfs_release_path(path);
                        goto out;
                }
        }
+
+       BTRFS_I(inode)->generation = trans->transid;
        header = btrfs_item_ptr(leaf, path->slots[0],
                                struct btrfs_free_space_header);
        btrfs_set_free_space_entries(leaf, header, entries);
@@ -833,16 +1009,26 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode,
        btrfs_mark_buffer_dirty(leaf);
        btrfs_release_path(path);
 
-       ret = 1;
-
+       err = 0;
 out:
-       kfree(pages);
-       if (ret != 1) {
-               invalidate_inode_pages2_range(inode->i_mapping, 0, index);
+       io_ctl_free(&io_ctl);
+       if (err) {
+               invalidate_inode_pages2(inode->i_mapping);
                BTRFS_I(inode)->generation = 0;
        }
        btrfs_update_inode(trans, root, inode);
-       return ret;
+       return err;
+
+out_nospc:
+       list_for_each_safe(pos, n, &bitmap_list) {
+               struct btrfs_free_space *entry =
+                       list_entry(pos, struct btrfs_free_space, list);
+               list_del_init(&entry->list);
+       }
+       io_ctl_drop_pages(&io_ctl);
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
+                            i_size_read(inode) - 1, &cached_state, GFP_NOFS);
+       goto out;
 }
 
 int btrfs_write_out_cache(struct btrfs_root *root,
@@ -869,14 +1055,15 @@ int btrfs_write_out_cache(struct btrfs_root *root,
 
        ret = __btrfs_write_out_cache(root, inode, ctl, block_group, trans,
                                      path, block_group->key.objectid);
-       if (ret < 0) {
+       if (ret) {
                spin_lock(&block_group->lock);
                block_group->disk_cache_state = BTRFS_DC_ERROR;
                spin_unlock(&block_group->lock);
                ret = 0;
-
+#ifdef DEBUG
                printk(KERN_ERR "btrfs: failed to write free space cace "
                       "for block group %llu\n", block_group->key.objectid);
+#endif
        }
 
        iput(inode);
@@ -1283,6 +1470,7 @@ static void add_new_bitmap(struct btrfs_free_space_ctl *ctl,
 {
        info->offset = offset_to_bitmap(ctl, offset);
        info->bytes = 0;
+       INIT_LIST_HEAD(&info->list);
        link_free_space(ctl, info);
        ctl->total_bitmaps++;
 
@@ -1662,7 +1850,13 @@ again:
                info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),
                                          1, 0);
                if (!info) {
-                       WARN_ON(1);
+                       /* the tree logging code might be calling us before we
+                        * have fully loaded the free space rbtree for this
+                        * block group.  So it is possible the entry won't
+                        * be in the rbtree yet at all.  The caching code
+                        * will make sure not to put it in the rbtree if
+                        * the logging code has pinned it.
+                        */
                        goto out_lock;
                }
        }
@@ -1701,6 +1895,7 @@ again:
                        ctl->total_bitmaps--;
                }
                kmem_cache_free(btrfs_free_space_cachep, info);
+               ret = 0;
                goto out_lock;
        }
 
@@ -1708,7 +1903,8 @@ again:
                unlink_free_space(ctl, info);
                info->offset += bytes;
                info->bytes -= bytes;
-               link_free_space(ctl, info);
+               ret = link_free_space(ctl, info);
+               WARN_ON(ret);
                goto out_lock;
        }
 
@@ -2124,6 +2320,7 @@ again:
 
        if (!found) {
                start = i;
+               cluster->max_size = 0;
                found = true;
        }
 
@@ -2267,16 +2464,23 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
        struct btrfs_free_space *entry;
-       struct rb_node *node;
        int ret = -ENOSPC;
+       u64 bitmap_offset = offset_to_bitmap(ctl, offset);
 
        if (ctl->total_bitmaps == 0)
                return -ENOSPC;
 
        /*
-        * First check our cached list of bitmaps and see if there is an entry
-        * here that will work.
+        * The bitmap that covers offset won't be in the list unless offset
+        * is just its start offset.
         */
+       entry = list_first_entry(bitmaps, struct btrfs_free_space, list);
+       if (entry->offset != bitmap_offset) {
+               entry = tree_search_offset(ctl, bitmap_offset, 1, 0);
+               if (entry && list_empty(&entry->list))
+                       list_add(&entry->list, bitmaps);
+       }
+
        list_for_each_entry(entry, bitmaps, list) {
                if (entry->bytes < min_bytes)
                        continue;
@@ -2287,38 +2491,10 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
        }
 
        /*
-        * If we do have entries on our list and we are here then we didn't find
-        * anything, so go ahead and get the next entry after the last entry in
-        * this list and start the search from there.
+        * The bitmaps list has all the bitmaps that record free space
+        * starting after offset, so no more search is required.
         */
-       if (!list_empty(bitmaps)) {
-               entry = list_entry(bitmaps->prev, struct btrfs_free_space,
-                                  list);
-               node = rb_next(&entry->offset_index);
-               if (!node)
-                       return -ENOSPC;
-               entry = rb_entry(node, struct btrfs_free_space, offset_index);
-               goto search;
-       }
-
-       entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1);
-       if (!entry)
-               return -ENOSPC;
-
-search:
-       node = &entry->offset_index;
-       do {
-               entry = rb_entry(node, struct btrfs_free_space, offset_index);
-               node = rb_next(&entry->offset_index);
-               if (!entry->bitmap)
-                       continue;
-               if (entry->bytes < min_bytes)
-                       continue;
-               ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset,
-                                          bytes, min_bytes);
-       } while (ret && node);
-
-       return ret;
+       return -ENOSPC;
 }
 
 /*
@@ -2336,8 +2512,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
                             u64 offset, u64 bytes, u64 empty_size)
 {
        struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
-       struct list_head bitmaps;
        struct btrfs_free_space *entry, *tmp;
+       LIST_HEAD(bitmaps);
        u64 min_bytes;
        int ret;
 
@@ -2376,7 +2552,6 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       INIT_LIST_HEAD(&bitmaps);
        ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset,
                                      bytes, min_bytes);
        if (ret)
@@ -2472,9 +2647,19 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
                spin_unlock(&ctl->tree_lock);
 
                if (bytes >= minlen) {
-                       int update_ret;
-                       update_ret = btrfs_update_reserved_bytes(block_group,
-                                                                bytes, 1, 1);
+                       struct btrfs_space_info *space_info;
+                       int update = 0;
+
+                       space_info = block_group->space_info;
+                       spin_lock(&space_info->lock);
+                       spin_lock(&block_group->lock);
+                       if (!block_group->ro) {
+                               block_group->reserved += bytes;
+                               space_info->bytes_reserved += bytes;
+                               update = 1;
+                       }
+                       spin_unlock(&block_group->lock);
+                       spin_unlock(&space_info->lock);
 
                        ret = btrfs_error_discard_extent(fs_info->extent_root,
                                                         start,
@@ -2482,9 +2667,16 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
                                                         &actually_trimmed);
 
                        btrfs_add_free_space(block_group, start, bytes);
-                       if (!update_ret)
-                               btrfs_update_reserved_bytes(block_group,
-                                                           bytes, 0, 1);
+                       if (update) {
+                               spin_lock(&space_info->lock);
+                               spin_lock(&block_group->lock);
+                               if (block_group->ro)
+                                       space_info->bytes_readonly += bytes;
+                               block_group->reserved -= bytes;
+                               space_info->bytes_reserved -= bytes;
+                               spin_unlock(&space_info->lock);
+                               spin_unlock(&block_group->lock);
+                       }
 
                        if (ret)
                                break;
@@ -2643,9 +2835,13 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
                return 0;
 
        ret = __btrfs_write_out_cache(root, inode, ctl, NULL, trans, path, 0);
-       if (ret < 0)
+       if (ret) {
+               btrfs_delalloc_release_metadata(inode, inode->i_size);
+#ifdef DEBUG
                printk(KERN_ERR "btrfs: failed to write free ino cache "
                       "for root %llu\n", root->root_key.objectid);
+#endif
+       }
 
        iput(inode);
        return ret;
index b4087e0fa8714bca45e5fc026caf3491e212dd14..f8962a957d656b385d0f99d65f300598e419db4d 100644 (file)
@@ -398,6 +398,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
        struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
        struct btrfs_path *path;
        struct inode *inode;
+       struct btrfs_block_rsv *rsv;
+       u64 num_bytes;
        u64 alloc_hint = 0;
        int ret;
        int prealloc;
@@ -421,11 +423,26 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
        if (!path)
                return -ENOMEM;
 
+       rsv = trans->block_rsv;
+       trans->block_rsv = &root->fs_info->trans_block_rsv;
+
+       num_bytes = trans->bytes_reserved;
+       /*
+        * 1 item for inode item insertion if need
+        * 3 items for inode item update (in the worst case)
+        * 1 item for free space object
+        * 3 items for pre-allocation
+        */
+       trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8);
+       ret = btrfs_block_rsv_add_noflush(root, trans->block_rsv,
+                                         trans->bytes_reserved);
+       if (ret)
+               goto out;
 again:
        inode = lookup_free_ino_inode(root, path);
        if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
                ret = PTR_ERR(inode);
-               goto out;
+               goto out_release;
        }
 
        if (IS_ERR(inode)) {
@@ -434,7 +451,7 @@ again:
 
                ret = create_free_ino_inode(root, trans, path);
                if (ret)
-                       goto out;
+                       goto out_release;
                goto again;
        }
 
@@ -465,21 +482,26 @@ again:
        /* Just to make sure we have enough space */
        prealloc += 8 * PAGE_CACHE_SIZE;
 
-       ret = btrfs_check_data_free_space(inode, prealloc);
+       ret = btrfs_delalloc_reserve_space(inode, prealloc);
        if (ret)
                goto out_put;
 
        ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc,
                                              prealloc, prealloc, &alloc_hint);
-       if (ret)
+       if (ret) {
+               btrfs_delalloc_release_space(inode, prealloc);
                goto out_put;
+       }
        btrfs_free_reserved_data_space(inode, prealloc);
 
+       ret = btrfs_write_out_ino_cache(root, trans, path);
 out_put:
        iput(inode);
+out_release:
+       btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
 out:
-       if (ret == 0)
-               ret = btrfs_write_out_ino_cache(root, trans, path);
+       trans->block_rsv = rsv;
+       trans->bytes_reserved = num_bytes;
 
        btrfs_free_path(path);
        return ret;
index 75686a61bd4550c5adad9a9f56091ed42217de6d..2c984f7d4c2ac581787ecb6a11962d3e6fd1df75 100644 (file)
 #include "btrfs_inode.h"
 #include "ioctl.h"
 #include "print-tree.h"
-#include "volumes.h"
 #include "ordered-data.h"
 #include "xattr.h"
 #include "tree-log.h"
+#include "volumes.h"
 #include "compression.h"
 #include "locking.h"
 #include "free-space-cache.h"
@@ -93,6 +93,8 @@ static noinline int cow_file_range(struct inode *inode,
                                   struct page *locked_page,
                                   u64 start, u64 end, int *page_started,
                                   unsigned long *nr_written, int unlock);
+static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+                               struct btrfs_root *root, struct inode *inode);
 
 static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
                                     struct inode *inode,  struct inode *dir,
@@ -393,7 +395,10 @@ again:
             (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) {
                WARN_ON(pages);
                pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
-               BUG_ON(!pages);
+               if (!pages) {
+                       /* just bail out to the uncompressed code */
+                       goto cont;
+               }
 
                if (BTRFS_I(inode)->force_compress)
                        compress_type = BTRFS_I(inode)->force_compress;
@@ -424,6 +429,7 @@ again:
                        will_compress = 1;
                }
        }
+cont:
        if (start == 0) {
                trans = btrfs_join_transaction(root);
                BUG_ON(IS_ERR(trans));
@@ -820,7 +826,7 @@ static noinline int cow_file_range(struct inode *inode,
        }
 
        BUG_ON(disk_num_bytes >
-              btrfs_super_total_bytes(&root->fs_info->super_copy));
+              btrfs_super_total_bytes(root->fs_info->super_copy));
 
        alloc_hint = get_extent_allocation_hint(inode, start, num_bytes);
        btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
@@ -1737,7 +1743,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                                trans = btrfs_join_transaction(root);
                        BUG_ON(IS_ERR(trans));
                        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
-                       ret = btrfs_update_inode(trans, root, inode);
+                       ret = btrfs_update_inode_fallback(trans, root, inode);
                        BUG_ON(ret);
                }
                goto out;
@@ -1787,17 +1793,17 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
 
        ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
        if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
-               ret = btrfs_update_inode(trans, root, inode);
+               ret = btrfs_update_inode_fallback(trans, root, inode);
                BUG_ON(ret);
        }
        ret = 0;
 out:
-       if (nolock) {
-               if (trans)
-                       btrfs_end_transaction_nolock(trans, root);
-       } else {
+       if (root != root->fs_info->tree_root)
                btrfs_delalloc_release_metadata(inode, ordered_extent->len);
-               if (trans)
+       if (trans) {
+               if (nolock)
+                       btrfs_end_transaction_nolock(trans, root);
+               else
                        btrfs_end_transaction(trans, root);
        }
 
@@ -1818,154 +1824,10 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
        return btrfs_finish_ordered_io(page->mapping->host, start, end);
 }
 
-/*
- * When IO fails, either with EIO or csum verification fails, we
- * try other mirrors that might have a good copy of the data.  This
- * io_failure_record is used to record state as we go through all the
- * mirrors.  If another mirror has good data, the page is set up to date
- * and things continue.  If a good mirror can't be found, the original
- * bio end_io callback is called to indicate things have failed.
- */
-struct io_failure_record {
-       struct page *page;
-       u64 start;
-       u64 len;
-       u64 logical;
-       unsigned long bio_flags;
-       int last_mirror;
-};
-
-static int btrfs_io_failed_hook(struct bio *failed_bio,
-                        struct page *page, u64 start, u64 end,
-                        struct extent_state *state)
-{
-       struct io_failure_record *failrec = NULL;
-       u64 private;
-       struct extent_map *em;
-       struct inode *inode = page->mapping->host;
-       struct extent_io_tree *failure_tree = &BTRFS_I(inode)->io_failure_tree;
-       struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
-       struct bio *bio;
-       int num_copies;
-       int ret;
-       int rw;
-       u64 logical;
-
-       ret = get_state_private(failure_tree, start, &private);
-       if (ret) {
-               failrec = kmalloc(sizeof(*failrec), GFP_NOFS);
-               if (!failrec)
-                       return -ENOMEM;
-               failrec->start = start;
-               failrec->len = end - start + 1;
-               failrec->last_mirror = 0;
-               failrec->bio_flags = 0;
-
-               read_lock(&em_tree->lock);
-               em = lookup_extent_mapping(em_tree, start, failrec->len);
-               if (em->start > start || em->start + em->len < start) {
-                       free_extent_map(em);
-                       em = NULL;
-               }
-               read_unlock(&em_tree->lock);
-
-               if (IS_ERR_OR_NULL(em)) {
-                       kfree(failrec);
-                       return -EIO;
-               }
-               logical = start - em->start;
-               logical = em->block_start + logical;
-               if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
-                       logical = em->block_start;
-                       failrec->bio_flags = EXTENT_BIO_COMPRESSED;
-                       extent_set_compress_type(&failrec->bio_flags,
-                                                em->compress_type);
-               }
-               failrec->logical = logical;
-               free_extent_map(em);
-               set_extent_bits(failure_tree, start, end, EXTENT_LOCKED |
-                               EXTENT_DIRTY, GFP_NOFS);
-               set_state_private(failure_tree, start,
-                                (u64)(unsigned long)failrec);
-       } else {
-               failrec = (struct io_failure_record *)(unsigned long)private;
-       }
-       num_copies = btrfs_num_copies(
-                             &BTRFS_I(inode)->root->fs_info->mapping_tree,
-                             failrec->logical, failrec->len);
-       failrec->last_mirror++;
-       if (!state) {
-               spin_lock(&BTRFS_I(inode)->io_tree.lock);
-               state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree,
-                                                   failrec->start,
-                                                   EXTENT_LOCKED);
-               if (state && state->start != failrec->start)
-                       state = NULL;
-               spin_unlock(&BTRFS_I(inode)->io_tree.lock);
-       }
-       if (!state || failrec->last_mirror > num_copies) {
-               set_state_private(failure_tree, failrec->start, 0);
-               clear_extent_bits(failure_tree, failrec->start,
-                                 failrec->start + failrec->len - 1,
-                                 EXTENT_LOCKED | EXTENT_DIRTY, GFP_NOFS);
-               kfree(failrec);
-               return -EIO;
-       }
-       bio = bio_alloc(GFP_NOFS, 1);
-       bio->bi_private = state;
-       bio->bi_end_io = failed_bio->bi_end_io;
-       bio->bi_sector = failrec->logical >> 9;
-       bio->bi_bdev = failed_bio->bi_bdev;
-       bio->bi_size = 0;
-
-       bio_add_page(bio, page, failrec->len, start - page_offset(page));
-       if (failed_bio->bi_rw & REQ_WRITE)
-               rw = WRITE;
-       else
-               rw = READ;
-
-       ret = BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
-                                                     failrec->last_mirror,
-                                                     failrec->bio_flags, 0);
-       return ret;
-}
-
-/*
- * each time an IO finishes, we do a fast check in the IO failure tree
- * to see if we need to process or clean up an io_failure_record
- */
-static int btrfs_clean_io_failures(struct inode *inode, u64 start)
-{
-       u64 private;
-       u64 private_failure;
-       struct io_failure_record *failure;
-       int ret;
-
-       private = 0;
-       if (count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private,
-                            (u64)-1, 1, EXTENT_DIRTY, 0)) {
-               ret = get_state_private(&BTRFS_I(inode)->io_failure_tree,
-                                       start, &private_failure);
-               if (ret == 0) {
-                       failure = (struct io_failure_record *)(unsigned long)
-                                  private_failure;
-                       set_state_private(&BTRFS_I(inode)->io_failure_tree,
-                                         failure->start, 0);
-                       clear_extent_bits(&BTRFS_I(inode)->io_failure_tree,
-                                         failure->start,
-                                         failure->start + failure->len - 1,
-                                         EXTENT_DIRTY | EXTENT_LOCKED,
-                                         GFP_NOFS);
-                       kfree(failure);
-               }
-       }
-       return 0;
-}
-
 /*
  * when reads are done, we need to check csums to verify the data is correct
- * if there's a match, we allow the bio to finish.  If not, we go through
- * the io_failure_record routines to find good copies
+ * if there's a match, we allow the bio to finish.  If not, the code in
+ * extent_io.c will try to find good copies for us.
  */
 static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
                               struct extent_state *state)
@@ -2011,10 +1873,6 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
 
        kunmap_atomic(kaddr, KM_USER0);
 good:
-       /* if the io failure tree for this inode is non-empty,
-        * check to see if we've recovered from a failed IO
-        */
-       btrfs_clean_io_failures(inode, start);
        return 0;
 
 zeroit:
@@ -2079,89 +1937,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
        up_read(&root->fs_info->cleanup_work_sem);
 }
 
-/*
- * calculate extra metadata reservation when snapshotting a subvolume
- * contains orphan files.
- */
-void btrfs_orphan_pre_snapshot(struct btrfs_trans_handle *trans,
-                               struct btrfs_pending_snapshot *pending,
-                               u64 *bytes_to_reserve)
-{
-       struct btrfs_root *root;
-       struct btrfs_block_rsv *block_rsv;
-       u64 num_bytes;
-       int index;
-
-       root = pending->root;
-       if (!root->orphan_block_rsv || list_empty(&root->orphan_list))
-               return;
-
-       block_rsv = root->orphan_block_rsv;
-
-       /* orphan block reservation for the snapshot */
-       num_bytes = block_rsv->size;
-
-       /*
-        * after the snapshot is created, COWing tree blocks may use more
-        * space than it frees. So we should make sure there is enough
-        * reserved space.
-        */
-       index = trans->transid & 0x1;
-       if (block_rsv->reserved + block_rsv->freed[index] < block_rsv->size) {
-               num_bytes += block_rsv->size -
-                            (block_rsv->reserved + block_rsv->freed[index]);
-       }
-
-       *bytes_to_reserve += num_bytes;
-}
-
-void btrfs_orphan_post_snapshot(struct btrfs_trans_handle *trans,
-                               struct btrfs_pending_snapshot *pending)
-{
-       struct btrfs_root *root = pending->root;
-       struct btrfs_root *snap = pending->snap;
-       struct btrfs_block_rsv *block_rsv;
-       u64 num_bytes;
-       int index;
-       int ret;
-
-       if (!root->orphan_block_rsv || list_empty(&root->orphan_list))
-               return;
-
-       /* refill source subvolume's orphan block reservation */
-       block_rsv = root->orphan_block_rsv;
-       index = trans->transid & 0x1;
-       if (block_rsv->reserved + block_rsv->freed[index] < block_rsv->size) {
-               num_bytes = block_rsv->size -
-                           (block_rsv->reserved + block_rsv->freed[index]);
-               ret = btrfs_block_rsv_migrate(&pending->block_rsv,
-                                             root->orphan_block_rsv,
-                                             num_bytes);
-               BUG_ON(ret);
-       }
-
-       /* setup orphan block reservation for the snapshot */
-       block_rsv = btrfs_alloc_block_rsv(snap);
-       BUG_ON(!block_rsv);
-
-       btrfs_add_durable_block_rsv(root->fs_info, block_rsv);
-       snap->orphan_block_rsv = block_rsv;
-
-       num_bytes = root->orphan_block_rsv->size;
-       ret = btrfs_block_rsv_migrate(&pending->block_rsv,
-                                     block_rsv, num_bytes);
-       BUG_ON(ret);
-
-#if 0
-       /* insert orphan item for the snapshot */
-       WARN_ON(!root->orphan_item_inserted);
-       ret = btrfs_insert_orphan_item(trans, root->fs_info->tree_root,
-                                      snap->root_key.objectid);
-       BUG_ON(ret);
-       snap->orphan_item_inserted = 1;
-#endif
-}
-
 enum btrfs_orphan_cleanup_state {
        ORPHAN_CLEANUP_STARTED  = 1,
        ORPHAN_CLEANUP_DONE     = 2,
@@ -2247,9 +2022,6 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
        }
        spin_unlock(&root->orphan_lock);
 
-       if (block_rsv)
-               btrfs_add_durable_block_rsv(root->fs_info, block_rsv);
-
        /* grab metadata reservation from transaction handle */
        if (reserve) {
                ret = btrfs_orphan_reserve_metadata(trans, inode);
@@ -2316,6 +2088,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
        struct btrfs_key key, found_key;
        struct btrfs_trans_handle *trans;
        struct inode *inode;
+       u64 last_objectid = 0;
        int ret = 0, nr_unlink = 0, nr_truncate = 0;
 
        if (cmpxchg(&root->orphan_cleanup_state, 0, ORPHAN_CLEANUP_STARTED))
@@ -2367,41 +2140,49 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                 * crossing root thing.  we store the inode number in the
                 * offset of the orphan item.
                 */
+
+               if (found_key.offset == last_objectid) {
+                       printk(KERN_ERR "btrfs: Error removing orphan entry, "
+                              "stopping orphan cleanup\n");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               last_objectid = found_key.offset;
+
                found_key.objectid = found_key.offset;
                found_key.type = BTRFS_INODE_ITEM_KEY;
                found_key.offset = 0;
                inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
-               if (IS_ERR(inode)) {
-                       ret = PTR_ERR(inode);
+               ret = PTR_RET(inode);
+               if (ret && ret != -ESTALE)
                        goto out;
-               }
 
                /*
-                * add this inode to the orphan list so btrfs_orphan_del does
-                * the proper thing when we hit it
+                * Inode is already gone but the orphan item is still there,
+                * kill the orphan item.
                 */
-               spin_lock(&root->orphan_lock);
-               list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list);
-               spin_unlock(&root->orphan_lock);
-
-               /*
-                * if this is a bad inode, means we actually succeeded in
-                * removing the inode, but not the orphan record, which means
-                * we need to manually delete the orphan since iput will just
-                * do a destroy_inode
-                */
-               if (is_bad_inode(inode)) {
-                       trans = btrfs_start_transaction(root, 0);
+               if (ret == -ESTALE) {
+                       trans = btrfs_start_transaction(root, 1);
                        if (IS_ERR(trans)) {
                                ret = PTR_ERR(trans);
                                goto out;
                        }
-                       btrfs_orphan_del(trans, inode);
+                       ret = btrfs_del_orphan_item(trans, root,
+                                                   found_key.objectid);
+                       BUG_ON(ret);
                        btrfs_end_transaction(trans, root);
-                       iput(inode);
                        continue;
                }
 
+               /*
+                * add this inode to the orphan list so btrfs_orphan_del does
+                * the proper thing when we hit it
+                */
+               spin_lock(&root->orphan_lock);
+               list_add(&BTRFS_I(inode)->i_orphan, &root->orphan_list);
+               spin_unlock(&root->orphan_lock);
+
                /* if we have links, this was a truncate, lets do that */
                if (inode->i_nlink) {
                        if (!S_ISREG(inode->i_mode)) {
@@ -2420,6 +2201,9 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
                if (ret)
                        goto out;
        }
+       /* release the path since we're done with it */
+       btrfs_release_path(path);
+
        root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE;
 
        if (root->orphan_block_rsv)
@@ -2647,7 +2431,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
 /*
  * copy everything in the in-memory inode into the btree.
  */
-noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
+static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root, struct inode *inode)
 {
        struct btrfs_inode_item *inode_item;
@@ -2655,21 +2439,6 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
        struct extent_buffer *leaf;
        int ret;
 
-       /*
-        * If the inode is a free space inode, we can deadlock during commit
-        * if we put it into the delayed code.
-        *
-        * The data relocation inode should also be directly updated
-        * without delay
-        */
-       if (!btrfs_is_free_space_inode(root, inode)
-           && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
-               ret = btrfs_delayed_update_inode(trans, root, inode);
-               if (!ret)
-                       btrfs_set_inode_last_trans(trans, inode);
-               return ret;
-       }
-
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -2697,6 +2466,43 @@ failed:
        return ret;
 }
 
+/*
+ * copy everything in the in-memory inode into the btree.
+ */
+noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
+                               struct btrfs_root *root, struct inode *inode)
+{
+       int ret;
+
+       /*
+        * If the inode is a free space inode, we can deadlock during commit
+        * if we put it into the delayed code.
+        *
+        * The data relocation inode should also be directly updated
+        * without delay
+        */
+       if (!btrfs_is_free_space_inode(root, inode)
+           && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
+               ret = btrfs_delayed_update_inode(trans, root, inode);
+               if (!ret)
+                       btrfs_set_inode_last_trans(trans, inode);
+               return ret;
+       }
+
+       return btrfs_update_inode_item(trans, root, inode);
+}
+
+static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
+                               struct btrfs_root *root, struct inode *inode)
+{
+       int ret;
+
+       ret = btrfs_update_inode(trans, root, inode);
+       if (ret == -ENOSPC)
+               return btrfs_update_inode_item(trans, root, inode);
+       return ret;
+}
+
 /*
  * unlink helper that gets used here in inode.c and in the tree logging
  * recovery code.  It remove a link in a directory with a given name, and
@@ -2835,7 +2641,16 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
        u64 ino = btrfs_ino(inode);
        u64 dir_ino = btrfs_ino(dir);
 
-       trans = btrfs_start_transaction(root, 10);
+       /*
+        * 1 for the possible orphan item
+        * 1 for the dir item
+        * 1 for the dir index
+        * 1 for the inode ref
+        * 1 for the inode ref in the tree log
+        * 2 for the dir entries in the log
+        * 1 for the inode
+        */
+       trans = btrfs_start_transaction(root, 8);
        if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
                return trans;
 
@@ -2858,7 +2673,8 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
                return ERR_PTR(-ENOMEM);
        }
 
-       trans = btrfs_start_transaction(root, 0);
+       /* 1 for the orphan item */
+       trans = btrfs_start_transaction(root, 1);
        if (IS_ERR(trans)) {
                btrfs_free_path(path);
                root->fs_info->enospc_unlink = 0;
@@ -2963,6 +2779,12 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
        err = 0;
 out:
        btrfs_free_path(path);
+       /* Migrate the orphan reservation over */
+       if (!err)
+               err = btrfs_block_rsv_migrate(trans->block_rsv,
+                               &root->fs_info->global_block_rsv,
+                               trans->bytes_reserved);
+
        if (err) {
                btrfs_end_transaction(trans, root);
                root->fs_info->enospc_unlink = 0;
@@ -2977,6 +2799,9 @@ static void __unlink_end_trans(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root)
 {
        if (trans->block_rsv == &root->fs_info->global_block_rsv) {
+               btrfs_block_rsv_release(root, trans->block_rsv,
+                                       trans->bytes_reserved);
+               trans->block_rsv = &root->fs_info->trans_block_rsv;
                BUG_ON(!root->fs_info->enospc_unlink);
                root->fs_info->enospc_unlink = 0;
        }
@@ -3368,6 +3193,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
        pgoff_t index = from >> PAGE_CACHE_SHIFT;
        unsigned offset = from & (PAGE_CACHE_SIZE-1);
        struct page *page;
+       gfp_t mask = btrfs_alloc_write_mask(mapping);
        int ret = 0;
        u64 page_start;
        u64 page_end;
@@ -3380,7 +3206,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
 
        ret = -ENOMEM;
 again:
-       page = find_or_create_page(mapping, index, GFP_NOFS);
+       page = find_or_create_page(mapping, index, mask);
        if (!page) {
                btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
                goto out;
@@ -3613,6 +3439,8 @@ void btrfs_evict_inode(struct inode *inode)
 {
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct btrfs_block_rsv *rsv, *global_rsv;
+       u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
        unsigned long nr;
        int ret;
 
@@ -3640,22 +3468,55 @@ void btrfs_evict_inode(struct inode *inode)
                goto no_delete;
        }
 
+       rsv = btrfs_alloc_block_rsv(root);
+       if (!rsv) {
+               btrfs_orphan_del(NULL, inode);
+               goto no_delete;
+       }
+       rsv->size = min_size;
+       global_rsv = &root->fs_info->global_block_rsv;
+
        btrfs_i_size_write(inode, 0);
 
+       /*
+        * This is a bit simpler than btrfs_truncate since
+        *
+        * 1) We've already reserved our space for our orphan item in the
+        *    unlink.
+        * 2) We're going to delete the inode item, so we don't need to update
+        *    it at all.
+        *
+        * So we just need to reserve some slack space in case we add bytes when
+        * doing the truncate.
+        */
        while (1) {
-               trans = btrfs_join_transaction(root);
-               BUG_ON(IS_ERR(trans));
-               trans->block_rsv = root->orphan_block_rsv;
+               ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size);
+
+               /*
+                * Try and steal from the global reserve since we will
+                * likely not use this space anyway, we want to try as
+                * hard as possible to get this to work.
+                */
+               if (ret)
+                       ret = btrfs_block_rsv_migrate(global_rsv, rsv, min_size);
 
-               ret = btrfs_block_rsv_check(trans, root,
-                                           root->orphan_block_rsv, 0, 5);
                if (ret) {
-                       BUG_ON(ret != -EAGAIN);
-                       ret = btrfs_commit_transaction(trans, root);
-                       BUG_ON(ret);
-                       continue;
+                       printk(KERN_WARNING "Could not get space for a "
+                              "delete, will truncate on mount %d\n", ret);
+                       btrfs_orphan_del(NULL, inode);
+                       btrfs_free_block_rsv(root, rsv);
+                       goto no_delete;
+               }
+
+               trans = btrfs_start_transaction(root, 0);
+               if (IS_ERR(trans)) {
+                       btrfs_orphan_del(NULL, inode);
+                       btrfs_free_block_rsv(root, rsv);
+                       goto no_delete;
                }
 
+               trans->block_rsv = rsv;
+
                ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0);
                if (ret != -EAGAIN)
                        break;
@@ -3664,14 +3525,17 @@ void btrfs_evict_inode(struct inode *inode)
                btrfs_end_transaction(trans, root);
                trans = NULL;
                btrfs_btree_balance_dirty(root, nr);
-
        }
 
+       btrfs_free_block_rsv(root, rsv);
+
        if (ret == 0) {
+               trans->block_rsv = root->orphan_block_rsv;
                ret = btrfs_orphan_del(trans, inode);
                BUG_ON(ret);
        }
 
+       trans->block_rsv = &root->fs_info->trans_block_rsv;
        if (!(root == root->fs_info->tree_root ||
              root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID))
                btrfs_return_ino(root, btrfs_ino(inode));
@@ -5795,8 +5659,7 @@ again:
        if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
                ret = btrfs_ordered_update_i_size(inode, 0, ordered);
                if (!ret)
-                       ret = btrfs_update_inode(trans, root, inode);
-               err = ret;
+                       err = btrfs_update_inode_fallback(trans, root, inode);
                goto out;
        }
 
@@ -5834,7 +5697,7 @@ again:
        add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
        ret = btrfs_ordered_update_i_size(inode, 0, ordered);
        if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags))
-               btrfs_update_inode(trans, root, inode);
+               btrfs_update_inode_fallback(trans, root, inode);
        ret = 0;
 out_unlock:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset,
@@ -6289,7 +6152,7 @@ int btrfs_readpage(struct file *file, struct page *page)
 {
        struct extent_io_tree *tree;
        tree = &BTRFS_I(page->mapping->host)->io_tree;
-       return extent_read_full_page(tree, page, btrfs_get_extent);
+       return extent_read_full_page(tree, page, btrfs_get_extent, 0);
 }
 
 static int btrfs_writepage(struct page *page, struct writeback_control *wbc)
@@ -6541,6 +6404,7 @@ static int btrfs_truncate(struct inode *inode)
        struct btrfs_trans_handle *trans;
        unsigned long nr;
        u64 mask = root->sectorsize - 1;
+       u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
 
        ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
        if (ret)
@@ -6588,19 +6452,23 @@ static int btrfs_truncate(struct inode *inode)
        rsv = btrfs_alloc_block_rsv(root);
        if (!rsv)
                return -ENOMEM;
-       btrfs_add_durable_block_rsv(root->fs_info, rsv);
+       rsv->size = min_size;
 
+       /*
+        * 1 for the truncate slack space
+        * 1 for the orphan item we're going to add
+        * 1 for the orphan item deletion
+        * 1 for updating the inode.
+        */
        trans = btrfs_start_transaction(root, 4);
        if (IS_ERR(trans)) {
                err = PTR_ERR(trans);
                goto out;
        }
 
-       /*
-        * Reserve space for the truncate process.  Truncate should be adding
-        * space, but if there are snapshots it may end up using space.
-        */
-       ret = btrfs_truncate_reserve_metadata(trans, root, rsv);
+       /* Migrate the slack space for the truncate to our reserve */
+       ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv,
+                                     min_size);
        BUG_ON(ret);
 
        ret = btrfs_orphan_add(trans, inode);
@@ -6609,21 +6477,6 @@ static int btrfs_truncate(struct inode *inode)
                goto out;
        }
 
-       nr = trans->blocks_used;
-       btrfs_end_transaction(trans, root);
-       btrfs_btree_balance_dirty(root, nr);
-
-       /*
-        * Ok so we've already migrated our bytes over for the truncate, so here
-        * just reserve the one slot we need for updating the inode.
-        */
-       trans = btrfs_start_transaction(root, 1);
-       if (IS_ERR(trans)) {
-               err = PTR_ERR(trans);
-               goto out;
-       }
-       trans->block_rsv = rsv;
-
        /*
         * setattr is responsible for setting the ordered_data_close flag,
         * but that is only tested during the last file release.  That
@@ -6645,20 +6498,30 @@ static int btrfs_truncate(struct inode *inode)
                btrfs_add_ordered_operation(trans, root, inode);
 
        while (1) {
+               ret = btrfs_block_rsv_refill(root, rsv, min_size);
+               if (ret) {
+                       /*
+                        * This can only happen with the original transaction we
+                        * started above, every other time we shouldn't have a
+                        * transaction started yet.
+                        */
+                       if (ret == -EAGAIN)
+                               goto end_trans;
+                       err = ret;
+                       break;
+               }
+
                if (!trans) {
-                       trans = btrfs_start_transaction(root, 3);
+                       /* Just need the 1 for updating the inode */
+                       trans = btrfs_start_transaction(root, 1);
                        if (IS_ERR(trans)) {
                                err = PTR_ERR(trans);
                                goto out;
                        }
-
-                       ret = btrfs_truncate_reserve_metadata(trans, root,
-                                                             rsv);
-                       BUG_ON(ret);
-
-                       trans->block_rsv = rsv;
                }
 
+               trans->block_rsv = rsv;
+
                ret = btrfs_truncate_inode_items(trans, root, inode,
                                                 inode->i_size,
                                                 BTRFS_EXTENT_DATA_KEY);
@@ -6673,7 +6536,7 @@ static int btrfs_truncate(struct inode *inode)
                        err = ret;
                        break;
                }
-
+end_trans:
                nr = trans->blocks_used;
                btrfs_end_transaction(trans, root);
                trans = NULL;
@@ -6693,14 +6556,16 @@ static int btrfs_truncate(struct inode *inode)
                ret = btrfs_orphan_del(NULL, inode);
        }
 
-       trans->block_rsv = &root->fs_info->trans_block_rsv;
-       ret = btrfs_update_inode(trans, root, inode);
-       if (ret && !err)
-               err = ret;
+       if (trans) {
+               trans->block_rsv = &root->fs_info->trans_block_rsv;
+               ret = btrfs_update_inode(trans, root, inode);
+               if (ret && !err)
+                       err = ret;
 
-       nr = trans->blocks_used;
-       ret = btrfs_end_transaction_throttle(trans, root);
-       btrfs_btree_balance_dirty(root, nr);
+               nr = trans->blocks_used;
+               ret = btrfs_end_transaction_throttle(trans, root);
+               btrfs_btree_balance_dirty(root, nr);
+       }
 
 out:
        btrfs_free_block_rsv(root, rsv);
@@ -6755,9 +6620,9 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
        ei->last_sub_trans = 0;
        ei->logged_trans = 0;
        ei->delalloc_bytes = 0;
-       ei->reserved_bytes = 0;
        ei->disk_i_size = 0;
        ei->flags = 0;
+       ei->csum_bytes = 0;
        ei->index_cnt = (u64)-1;
        ei->last_unlink_trans = 0;
 
@@ -6769,6 +6634,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
        ei->orphan_meta_reserved = 0;
        ei->dummy_inode = 0;
        ei->in_defrag = 0;
+       ei->delalloc_meta_reserved = 0;
        ei->force_compress = BTRFS_COMPRESS_NONE;
 
        ei->delayed_node = NULL;
@@ -6803,6 +6669,8 @@ void btrfs_destroy_inode(struct inode *inode)
        WARN_ON(inode->i_data.nrpages);
        WARN_ON(BTRFS_I(inode)->outstanding_extents);
        WARN_ON(BTRFS_I(inode)->reserved_extents);
+       WARN_ON(BTRFS_I(inode)->delalloc_bytes);
+       WARN_ON(BTRFS_I(inode)->csum_bytes);
 
        /*
         * This can happen where we create an inode, but somebody else also
@@ -6926,11 +6794,13 @@ static int btrfs_getattr(struct vfsmount *mnt,
                         struct dentry *dentry, struct kstat *stat)
 {
        struct inode *inode = dentry->d_inode;
+       u32 blocksize = inode->i_sb->s_blocksize;
+
        generic_fillattr(inode, stat);
        stat->dev = BTRFS_I(inode)->root->anon_dev;
        stat->blksize = PAGE_CACHE_SIZE;
-       stat->blocks = (inode_get_bytes(inode) +
-                       BTRFS_I(inode)->delalloc_bytes) >> 9;
+       stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) +
+               ALIGN(BTRFS_I(inode)->delalloc_bytes, blocksize)) >> 9;
        return 0;
 }
 
@@ -7420,7 +7290,6 @@ static struct extent_io_ops btrfs_extent_io_ops = {
        .readpage_end_io_hook = btrfs_readpage_end_io_hook,
        .writepage_end_io_hook = btrfs_writepage_end_io_hook,
        .writepage_start_hook = btrfs_writepage_start_hook,
-       .readpage_io_failed_hook = btrfs_io_failed_hook,
        .set_bit_hook = btrfs_set_bit_hook,
        .clear_bit_hook = btrfs_clear_bit_hook,
        .merge_extent_hook = btrfs_merge_extent_hook,
index dae5dfe41ba59fdd820006b96ff4ed2803d51887..72d461656f606647292657f2367ee438a50d2a40 100644 (file)
@@ -51,6 +51,7 @@
 #include "volumes.h"
 #include "locking.h"
 #include "inode-map.h"
+#include "backref.h"
 
 /* Mask out flags that are inappropriate for the given type of inode. */
 static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags)
@@ -117,7 +118,7 @@ void btrfs_update_iflags(struct inode *inode)
 /*
  * Inherit flags from the parent inode.
  *
- * Unlike extN we don't have any flags we don't want to inherit currently.
+ * Currently only the compression flags and the cow flags are inherited.
  */
 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir)
 {
@@ -128,12 +129,17 @@ void btrfs_inherit_iflags(struct inode *inode, struct inode *dir)
 
        flags = BTRFS_I(dir)->flags;
 
-       if (S_ISREG(inode->i_mode))
-               flags &= ~BTRFS_INODE_DIRSYNC;
-       else if (!S_ISDIR(inode->i_mode))
-               flags &= (BTRFS_INODE_NODUMP | BTRFS_INODE_NOATIME);
+       if (flags & BTRFS_INODE_NOCOMPRESS) {
+               BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
+               BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+       } else if (flags & BTRFS_INODE_COMPRESS) {
+               BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
+               BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;
+       }
+
+       if (flags & BTRFS_INODE_NODATACOW)
+               BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW;
 
-       BTRFS_I(inode)->flags = flags;
        btrfs_update_iflags(inode);
 }
 
@@ -277,6 +283,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
        struct fstrim_range range;
        u64 minlen = ULLONG_MAX;
        u64 num_devices = 0;
+       u64 total_bytes = btrfs_super_total_bytes(root->fs_info->super_copy);
        int ret;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -295,12 +302,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
                }
        }
        rcu_read_unlock();
+
        if (!num_devices)
                return -EOPNOTSUPP;
-
        if (copy_from_user(&range, arg, sizeof(range)))
                return -EFAULT;
+       if (range.start > total_bytes)
+               return -EINVAL;
 
+       range.len = min(range.len, total_bytes - range.start);
        range.minlen = max(range.minlen, minlen);
        ret = btrfs_trim_fs(root, &range);
        if (ret < 0)
@@ -760,7 +770,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
        int ret = 1;
 
        /*
-        * make sure that once we start defragging and extent, we keep on
+        * make sure that once we start defragging an extent, we keep on
         * defragging it
         */
        if (start < *defrag_end)
@@ -805,7 +815,6 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
         * extent will force at least part of that big extent to be defragged.
         */
        if (ret) {
-               *last_len += len;
                *defrag_end = extent_map_end(em);
        } else {
                *last_len = 0;
@@ -843,6 +852,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
        int i_done;
        struct btrfs_ordered_extent *ordered;
        struct extent_state *cached_state = NULL;
+       gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
 
        if (isize == 0)
                return 0;
@@ -860,7 +870,7 @@ again:
        for (i = 0; i < num_pages; i++) {
                struct page *page;
                page = find_or_create_page(inode->i_mapping,
-                                           start_index + i, GFP_NOFS);
+                                           start_index + i, mask);
                if (!page)
                        break;
 
@@ -972,18 +982,20 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
        struct btrfs_super_block *disk_super;
        struct file_ra_state *ra = NULL;
        unsigned long last_index;
+       u64 isize = i_size_read(inode);
        u64 features;
        u64 last_len = 0;
        u64 skip = 0;
        u64 defrag_end = 0;
        u64 newer_off = range->start;
-       int newer_left = 0;
        unsigned long i;
+       unsigned long ra_index = 0;
        int ret;
        int defrag_count = 0;
        int compress_type = BTRFS_COMPRESS_ZLIB;
        int extent_thresh = range->extent_thresh;
-       int newer_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
+       int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
+       int cluster = max_cluster;
        u64 new_align = ~((u64)128 * 1024 - 1);
        struct page **pages = NULL;
 
@@ -997,7 +1009,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        compress_type = range->compress_type;
        }
 
-       if (inode->i_size == 0)
+       if (isize == 0)
                return 0;
 
        /*
@@ -1013,7 +1025,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                ra = &file->f_ra;
        }
 
-       pages = kmalloc(sizeof(struct page *) * newer_cluster,
+       pages = kmalloc(sizeof(struct page *) * max_cluster,
                        GFP_NOFS);
        if (!pages) {
                ret = -ENOMEM;
@@ -1022,10 +1034,10 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
        /* find the last page to defrag */
        if (range->start + range->len > range->start) {
-               last_index = min_t(u64, inode->i_size - 1,
+               last_index = min_t(u64, isize - 1,
                         range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
        } else {
-               last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT;
+               last_index = (isize - 1) >> PAGE_CACHE_SHIFT;
        }
 
        if (newer_than) {
@@ -1038,14 +1050,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                         * the extents in the file evenly spaced
                         */
                        i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
-                       newer_left = newer_cluster;
                } else
                        goto out_ra;
        } else {
                i = range->start >> PAGE_CACHE_SHIFT;
        }
        if (!max_to_defrag)
-               max_to_defrag = last_index - 1;
+               max_to_defrag = last_index;
 
        /*
         * make writeback starts from i, so the defrag range can be
@@ -1079,18 +1090,31 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        i = max(i + 1, next);
                        continue;
                }
+
+               if (!newer_than) {
+                       cluster = (PAGE_CACHE_ALIGN(defrag_end) >>
+                                  PAGE_CACHE_SHIFT) - i;
+                       cluster = min(cluster, max_cluster);
+               } else {
+                       cluster = max_cluster;
+               }
+
                if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
                        BTRFS_I(inode)->force_compress = compress_type;
 
-               btrfs_force_ra(inode->i_mapping, ra, file, i, newer_cluster);
+               if (i + cluster > ra_index) {
+                       ra_index = max(i, ra_index);
+                       btrfs_force_ra(inode->i_mapping, ra, file, ra_index,
+                                      cluster);
+                       ra_index += max_cluster;
+               }
 
-               ret = cluster_pages_for_defrag(inode, pages, i, newer_cluster);
+               ret = cluster_pages_for_defrag(inode, pages, i, cluster);
                if (ret < 0)
                        goto out_ra;
 
                defrag_count += ret;
                balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret);
-               i += ret;
 
                if (newer_than) {
                        if (newer_off == (u64)-1)
@@ -1105,12 +1129,17 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        if (!ret) {
                                range->start = newer_off;
                                i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
-                               newer_left = newer_cluster;
                        } else {
                                break;
                        }
                } else {
-                       i++;
+                       if (ret > 0) {
+                               i += ret;
+                               last_len += ret << PAGE_CACHE_SHIFT;
+                       } else {
+                               i++;
+                               last_len = 0;
+                       }
                }
        }
 
@@ -1136,16 +1165,14 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                mutex_unlock(&inode->i_mutex);
        }
 
-       disk_super = &root->fs_info->super_copy;
+       disk_super = root->fs_info->super_copy;
        features = btrfs_super_incompat_flags(disk_super);
        if (range->compress_type == BTRFS_COMPRESS_LZO) {
                features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
                btrfs_set_super_incompat_flags(disk_super, features);
        }
 
-       if (!file)
-               kfree(ra);
-       return defrag_count;
+       ret = defrag_count;
 
 out_ra:
        if (!file)
@@ -1189,12 +1216,12 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                *devstr = '\0';
                devstr = vol_args->name;
                devid = simple_strtoull(devstr, &end, 10);
-               printk(KERN_INFO "resizing devid %llu\n",
+               printk(KERN_INFO "btrfs: resizing devid %llu\n",
                       (unsigned long long)devid);
        }
        device = btrfs_find_device(root, devid, NULL, NULL);
        if (!device) {
-               printk(KERN_INFO "resizer unable to find device %llu\n",
+               printk(KERN_INFO "btrfs: resizer unable to find device %llu\n",
                       (unsigned long long)devid);
                ret = -EINVAL;
                goto out_unlock;
@@ -1240,7 +1267,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
        do_div(new_size, root->sectorsize);
        new_size *= root->sectorsize;
 
-       printk(KERN_INFO "new size for %s is %llu\n",
+       printk(KERN_INFO "btrfs: new size for %s is %llu\n",
                device->name, (unsigned long long)new_size);
 
        if (new_size > old_size) {
@@ -1251,7 +1278,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                }
                ret = btrfs_grow_device(trans, device, new_size);
                btrfs_commit_transaction(trans, root);
-       } else {
+       } else if (new_size < old_size) {
                ret = btrfs_shrink_device(device, new_size);
        }
 
@@ -2587,7 +2614,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
                return PTR_ERR(trans);
        }
 
-       dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+       dir_id = btrfs_super_root_dir(root->fs_info->super_copy);
        di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
                                   dir_id, "default", 7, 1);
        if (IS_ERR_OR_NULL(di)) {
@@ -2603,7 +2630,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
        btrfs_mark_buffer_dirty(path->nodes[0]);
        btrfs_free_path(path);
 
-       disk_super = &root->fs_info->super_copy;
+       disk_super = root->fs_info->super_copy;
        features = btrfs_super_incompat_flags(disk_super);
        if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) {
                features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL;
@@ -2864,6 +2891,147 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root,
        return ret;
 }
 
+static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
+{
+       int ret = 0;
+       int i;
+       u64 rel_ptr;
+       int size;
+       struct btrfs_ioctl_ino_path_args *ipa = NULL;
+       struct inode_fs_paths *ipath = NULL;
+       struct btrfs_path *path;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       path = btrfs_alloc_path();
+       if (!path) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ipa = memdup_user(arg, sizeof(*ipa));
+       if (IS_ERR(ipa)) {
+               ret = PTR_ERR(ipa);
+               ipa = NULL;
+               goto out;
+       }
+
+       size = min_t(u32, ipa->size, 4096);
+       ipath = init_ipath(size, root, path);
+       if (IS_ERR(ipath)) {
+               ret = PTR_ERR(ipath);
+               ipath = NULL;
+               goto out;
+       }
+
+       ret = paths_from_inode(ipa->inum, ipath);
+       if (ret < 0)
+               goto out;
+
+       for (i = 0; i < ipath->fspath->elem_cnt; ++i) {
+               rel_ptr = ipath->fspath->val[i] -
+                         (u64)(unsigned long)ipath->fspath->val;
+               ipath->fspath->val[i] = rel_ptr;
+       }
+
+       ret = copy_to_user((void *)(unsigned long)ipa->fspath,
+                          (void *)(unsigned long)ipath->fspath, size);
+       if (ret) {
+               ret = -EFAULT;
+               goto out;
+       }
+
+out:
+       btrfs_free_path(path);
+       free_ipath(ipath);
+       kfree(ipa);
+
+       return ret;
+}
+
+static int build_ino_list(u64 inum, u64 offset, u64 root, void *ctx)
+{
+       struct btrfs_data_container *inodes = ctx;
+       const size_t c = 3 * sizeof(u64);
+
+       if (inodes->bytes_left >= c) {
+               inodes->bytes_left -= c;
+               inodes->val[inodes->elem_cnt] = inum;
+               inodes->val[inodes->elem_cnt + 1] = offset;
+               inodes->val[inodes->elem_cnt + 2] = root;
+               inodes->elem_cnt += 3;
+       } else {
+               inodes->bytes_missing += c - inodes->bytes_left;
+               inodes->bytes_left = 0;
+               inodes->elem_missed += 3;
+       }
+
+       return 0;
+}
+
+static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
+                                       void __user *arg)
+{
+       int ret = 0;
+       int size;
+       u64 extent_offset;
+       struct btrfs_ioctl_logical_ino_args *loi;
+       struct btrfs_data_container *inodes = NULL;
+       struct btrfs_path *path = NULL;
+       struct btrfs_key key;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       loi = memdup_user(arg, sizeof(*loi));
+       if (IS_ERR(loi)) {
+               ret = PTR_ERR(loi);
+               loi = NULL;
+               goto out;
+       }
+
+       path = btrfs_alloc_path();
+       if (!path) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       size = min_t(u32, loi->size, 4096);
+       inodes = init_data_container(size);
+       if (IS_ERR(inodes)) {
+               ret = PTR_ERR(inodes);
+               inodes = NULL;
+               goto out;
+       }
+
+       ret = extent_from_logical(root->fs_info, loi->logical, path, &key);
+
+       if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+               ret = -ENOENT;
+       if (ret < 0)
+               goto out;
+
+       extent_offset = loi->logical - key.objectid;
+       ret = iterate_extent_inodes(root->fs_info, path, key.objectid,
+                                       extent_offset, build_ino_list, inodes);
+
+       if (ret < 0)
+               goto out;
+
+       ret = copy_to_user((void *)(unsigned long)loi->inodes,
+                          (void *)(unsigned long)inodes, size);
+       if (ret)
+               ret = -EFAULT;
+
+out:
+       btrfs_free_path(path);
+       kfree(inodes);
+       kfree(loi);
+
+       return ret;
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
                cmd, unsigned long arg)
 {
@@ -2921,6 +3089,10 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_tree_search(file, argp);
        case BTRFS_IOC_INO_LOOKUP:
                return btrfs_ioctl_ino_lookup(file, argp);
+       case BTRFS_IOC_INO_PATHS:
+               return btrfs_ioctl_ino_to_path(root, argp);
+       case BTRFS_IOC_LOGICAL_INO:
+               return btrfs_ioctl_logical_to_ino(root, argp);
        case BTRFS_IOC_SPACE_INFO:
                return btrfs_ioctl_space_info(root, argp);
        case BTRFS_IOC_SYNC:
index ad1ea789fcb4d281dcd80398bd75bbec2b1e30d9..252ae9915de8fcfa4b6b7a3a502735c28d1819f6 100644 (file)
@@ -193,6 +193,30 @@ struct btrfs_ioctl_space_args {
        struct btrfs_ioctl_space_info spaces[0];
 };
 
+struct btrfs_data_container {
+       __u32   bytes_left;     /* out -- bytes not needed to deliver output */
+       __u32   bytes_missing;  /* out -- additional bytes needed for result */
+       __u32   elem_cnt;       /* out */
+       __u32   elem_missed;    /* out */
+       __u64   val[0];         /* out */
+};
+
+struct btrfs_ioctl_ino_path_args {
+       __u64                           inum;           /* in */
+       __u32                           size;           /* in */
+       __u64                           reserved[4];
+       /* struct btrfs_data_container  *fspath;           out */
+       __u64                           fspath;         /* out */
+};
+
+struct btrfs_ioctl_logical_ino_args {
+       __u64                           logical;        /* in */
+       __u32                           size;           /* in */
+       __u64                           reserved[4];
+       /* struct btrfs_data_container  *inodes;        out   */
+       __u64                           inodes;
+};
+
 #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
                                   struct btrfs_ioctl_vol_args)
 #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -248,4 +272,9 @@ struct btrfs_ioctl_space_args {
                                 struct btrfs_ioctl_dev_info_args)
 #define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
                               struct btrfs_ioctl_fs_info_args)
+#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
+                                       struct btrfs_ioctl_ino_path_args)
+#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
+                                       struct btrfs_ioctl_ino_path_args)
+
 #endif
index fb2605d998e92e465d13cb989575dd7a01eb8a83..f38e452486b8d12ba36589248579dc158981c3be 100644 (file)
@@ -158,8 +158,7 @@ static void print_extent_ref_v0(struct extent_buffer *eb, int slot)
 void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
 {
        int i;
-       u32 type;
-       u32 nr = btrfs_header_nritems(l);
+       u32 type, nr;
        struct btrfs_item *item;
        struct btrfs_root_item *ri;
        struct btrfs_dir_item *di;
@@ -172,6 +171,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
        struct btrfs_key key;
        struct btrfs_key found_key;
 
+       if (!l)
+               return;
+
+       nr = btrfs_header_nritems(l);
+
        printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n",
                (unsigned long long)btrfs_header_bytenr(l), nr,
                btrfs_leaf_free_space(root, l));
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
new file mode 100644 (file)
index 0000000..2373b39
--- /dev/null
@@ -0,0 +1,951 @@
+/*
+ * Copyright (C) 2011 STRATO.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/blkdev.h>
+#include <linux/rbtree.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include "ctree.h"
+#include "volumes.h"
+#include "disk-io.h"
+#include "transaction.h"
+
+#undef DEBUG
+
+/*
+ * This is the implementation for the generic read ahead framework.
+ *
+ * To trigger a readahead, btrfs_reada_add must be called. It will start
+ * a read ahead for the given range [start, end) on tree root. The returned
+ * handle can either be used to wait on the readahead to finish
+ * (btrfs_reada_wait), or to send it to the background (btrfs_reada_detach).
+ *
+ * The read ahead works as follows:
+ * On btrfs_reada_add, the root of the tree is inserted into a radix_tree.
+ * reada_start_machine will then search for extents to prefetch and trigger
+ * some reads. When a read finishes for a node, all contained node/leaf
+ * pointers that lie in the given range will also be enqueued. The reads will
+ * be triggered in sequential order, thus giving a big win over a naive
+ * enumeration. It will also make use of multi-device layouts. Each disk
+ * will have its on read pointer and all disks will by utilized in parallel.
+ * Also will no two disks read both sides of a mirror simultaneously, as this
+ * would waste seeking capacity. Instead both disks will read different parts
+ * of the filesystem.
+ * Any number of readaheads can be started in parallel. The read order will be
+ * determined globally, i.e. 2 parallel readaheads will normally finish faster
+ * than the 2 started one after another.
+ */
+
+#define MAX_MIRRORS 2
+#define MAX_IN_FLIGHT 6
+
+struct reada_extctl {
+       struct list_head        list;
+       struct reada_control    *rc;
+       u64                     generation;
+};
+
+struct reada_extent {
+       u64                     logical;
+       struct btrfs_key        top;
+       u32                     blocksize;
+       int                     err;
+       struct list_head        extctl;
+       struct kref             refcnt;
+       spinlock_t              lock;
+       struct reada_zone       *zones[MAX_MIRRORS];
+       int                     nzones;
+       struct btrfs_device     *scheduled_for;
+};
+
+struct reada_zone {
+       u64                     start;
+       u64                     end;
+       u64                     elems;
+       struct list_head        list;
+       spinlock_t              lock;
+       int                     locked;
+       struct btrfs_device     *device;
+       struct btrfs_device     *devs[MAX_MIRRORS]; /* full list, incl self */
+       int                     ndevs;
+       struct kref             refcnt;
+};
+
+struct reada_machine_work {
+       struct btrfs_work       work;
+       struct btrfs_fs_info    *fs_info;
+};
+
+static void reada_extent_put(struct btrfs_fs_info *, struct reada_extent *);
+static void reada_control_release(struct kref *kref);
+static void reada_zone_release(struct kref *kref);
+static void reada_start_machine(struct btrfs_fs_info *fs_info);
+static void __reada_start_machine(struct btrfs_fs_info *fs_info);
+
+static int reada_add_block(struct reada_control *rc, u64 logical,
+                          struct btrfs_key *top, int level, u64 generation);
+
+/* recurses */
+/* in case of err, eb might be NULL */
+static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
+                           u64 start, int err)
+{
+       int level = 0;
+       int nritems;
+       int i;
+       u64 bytenr;
+       u64 generation;
+       struct reada_extent *re;
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct list_head list;
+       unsigned long index = start >> PAGE_CACHE_SHIFT;
+       struct btrfs_device *for_dev;
+
+       if (eb)
+               level = btrfs_header_level(eb);
+
+       /* find extent */
+       spin_lock(&fs_info->reada_lock);
+       re = radix_tree_lookup(&fs_info->reada_tree, index);
+       if (re)
+               kref_get(&re->refcnt);
+       spin_unlock(&fs_info->reada_lock);
+
+       if (!re)
+               return -1;
+
+       spin_lock(&re->lock);
+       /*
+        * just take the full list from the extent. afterwards we
+        * don't need the lock anymore
+        */
+       list_replace_init(&re->extctl, &list);
+       for_dev = re->scheduled_for;
+       re->scheduled_for = NULL;
+       spin_unlock(&re->lock);
+
+       if (err == 0) {
+               nritems = level ? btrfs_header_nritems(eb) : 0;
+               generation = btrfs_header_generation(eb);
+               /*
+                * FIXME: currently we just set nritems to 0 if this is a leaf,
+                * effectively ignoring the content. In a next step we could
+                * trigger more readahead depending from the content, e.g.
+                * fetch the checksums for the extents in the leaf.
+                */
+       } else {
+               /*
+                * this is the error case, the extent buffer has not been
+                * read correctly. We won't access anything from it and
+                * just cleanup our data structures. Effectively this will
+                * cut the branch below this node from read ahead.
+                */
+               nritems = 0;
+               generation = 0;
+       }
+
+       for (i = 0; i < nritems; i++) {
+               struct reada_extctl *rec;
+               u64 n_gen;
+               struct btrfs_key key;
+               struct btrfs_key next_key;
+
+               btrfs_node_key_to_cpu(eb, &key, i);
+               if (i + 1 < nritems)
+                       btrfs_node_key_to_cpu(eb, &next_key, i + 1);
+               else
+                       next_key = re->top;
+               bytenr = btrfs_node_blockptr(eb, i);
+               n_gen = btrfs_node_ptr_generation(eb, i);
+
+               list_for_each_entry(rec, &list, list) {
+                       struct reada_control *rc = rec->rc;
+
+                       /*
+                        * if the generation doesn't match, just ignore this
+                        * extctl. This will probably cut off a branch from
+                        * prefetch. Alternatively one could start a new (sub-)
+                        * prefetch for this branch, starting again from root.
+                        * FIXME: move the generation check out of this loop
+                        */
+#ifdef DEBUG
+                       if (rec->generation != generation) {
+                               printk(KERN_DEBUG "generation mismatch for "
+                                               "(%llu,%d,%llu) %llu != %llu\n",
+                                      key.objectid, key.type, key.offset,
+                                      rec->generation, generation);
+                       }
+#endif
+                       if (rec->generation == generation &&
+                           btrfs_comp_cpu_keys(&key, &rc->key_end) < 0 &&
+                           btrfs_comp_cpu_keys(&next_key, &rc->key_start) > 0)
+                               reada_add_block(rc, bytenr, &next_key,
+                                               level - 1, n_gen);
+               }
+       }
+       /*
+        * free extctl records
+        */
+       while (!list_empty(&list)) {
+               struct reada_control *rc;
+               struct reada_extctl *rec;
+
+               rec = list_first_entry(&list, struct reada_extctl, list);
+               list_del(&rec->list);
+               rc = rec->rc;
+               kfree(rec);
+
+               kref_get(&rc->refcnt);
+               if (atomic_dec_and_test(&rc->elems)) {
+                       kref_put(&rc->refcnt, reada_control_release);
+                       wake_up(&rc->wait);
+               }
+               kref_put(&rc->refcnt, reada_control_release);
+
+               reada_extent_put(fs_info, re);  /* one ref for each entry */
+       }
+       reada_extent_put(fs_info, re);  /* our ref */
+       if (for_dev)
+               atomic_dec(&for_dev->reada_in_flight);
+
+       return 0;
+}
+
+/*
+ * start is passed separately in case eb in NULL, which may be the case with
+ * failed I/O
+ */
+int btree_readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
+                        u64 start, int err)
+{
+       int ret;
+
+       ret = __readahead_hook(root, eb, start, err);
+
+       reada_start_machine(root->fs_info);
+
+       return ret;
+}
+
+static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info,
+                                         struct btrfs_device *dev, u64 logical,
+                                         struct btrfs_bio *bbio)
+{
+       int ret;
+       int looped = 0;
+       struct reada_zone *zone;
+       struct btrfs_block_group_cache *cache = NULL;
+       u64 start;
+       u64 end;
+       int i;
+
+again:
+       zone = NULL;
+       spin_lock(&fs_info->reada_lock);
+       ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone,
+                                    logical >> PAGE_CACHE_SHIFT, 1);
+       if (ret == 1)
+               kref_get(&zone->refcnt);
+       spin_unlock(&fs_info->reada_lock);
+
+       if (ret == 1) {
+               if (logical >= zone->start && logical < zone->end)
+                       return zone;
+               spin_lock(&fs_info->reada_lock);
+               kref_put(&zone->refcnt, reada_zone_release);
+               spin_unlock(&fs_info->reada_lock);
+       }
+
+       if (looped)
+               return NULL;
+
+       cache = btrfs_lookup_block_group(fs_info, logical);
+       if (!cache)
+               return NULL;
+
+       start = cache->key.objectid;
+       end = start + cache->key.offset - 1;
+       btrfs_put_block_group(cache);
+
+       zone = kzalloc(sizeof(*zone), GFP_NOFS);
+       if (!zone)
+               return NULL;
+
+       zone->start = start;
+       zone->end = end;
+       INIT_LIST_HEAD(&zone->list);
+       spin_lock_init(&zone->lock);
+       zone->locked = 0;
+       kref_init(&zone->refcnt);
+       zone->elems = 0;
+       zone->device = dev; /* our device always sits at index 0 */
+       for (i = 0; i < bbio->num_stripes; ++i) {
+               /* bounds have already been checked */
+               zone->devs[i] = bbio->stripes[i].dev;
+       }
+       zone->ndevs = bbio->num_stripes;
+
+       spin_lock(&fs_info->reada_lock);
+       ret = radix_tree_insert(&dev->reada_zones,
+                               (unsigned long)zone->end >> PAGE_CACHE_SHIFT,
+                               zone);
+       spin_unlock(&fs_info->reada_lock);
+
+       if (ret) {
+               kfree(zone);
+               looped = 1;
+               goto again;
+       }
+
+       return zone;
+}
+
+static struct reada_extent *reada_find_extent(struct btrfs_root *root,
+                                             u64 logical,
+                                             struct btrfs_key *top, int level)
+{
+       int ret;
+       int looped = 0;
+       struct reada_extent *re = NULL;
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
+       struct btrfs_bio *bbio = NULL;
+       struct btrfs_device *dev;
+       u32 blocksize;
+       u64 length;
+       int nzones = 0;
+       int i;
+       unsigned long index = logical >> PAGE_CACHE_SHIFT;
+
+again:
+       spin_lock(&fs_info->reada_lock);
+       re = radix_tree_lookup(&fs_info->reada_tree, index);
+       if (re)
+               kref_get(&re->refcnt);
+       spin_unlock(&fs_info->reada_lock);
+
+       if (re || looped)
+               return re;
+
+       re = kzalloc(sizeof(*re), GFP_NOFS);
+       if (!re)
+               return NULL;
+
+       blocksize = btrfs_level_size(root, level);
+       re->logical = logical;
+       re->blocksize = blocksize;
+       re->top = *top;
+       INIT_LIST_HEAD(&re->extctl);
+       spin_lock_init(&re->lock);
+       kref_init(&re->refcnt);
+
+       /*
+        * map block
+        */
+       length = blocksize;
+       ret = btrfs_map_block(map_tree, REQ_WRITE, logical, &length, &bbio, 0);
+       if (ret || !bbio || length < blocksize)
+               goto error;
+
+       if (bbio->num_stripes > MAX_MIRRORS) {
+               printk(KERN_ERR "btrfs readahead: more than %d copies not "
+                               "supported", MAX_MIRRORS);
+               goto error;
+       }
+
+       for (nzones = 0; nzones < bbio->num_stripes; ++nzones) {
+               struct reada_zone *zone;
+
+               dev = bbio->stripes[nzones].dev;
+               zone = reada_find_zone(fs_info, dev, logical, bbio);
+               if (!zone)
+                       break;
+
+               re->zones[nzones] = zone;
+               spin_lock(&zone->lock);
+               if (!zone->elems)
+                       kref_get(&zone->refcnt);
+               ++zone->elems;
+               spin_unlock(&zone->lock);
+               spin_lock(&fs_info->reada_lock);
+               kref_put(&zone->refcnt, reada_zone_release);
+               spin_unlock(&fs_info->reada_lock);
+       }
+       re->nzones = nzones;
+       if (nzones == 0) {
+               /* not a single zone found, error and out */
+               goto error;
+       }
+
+       /* insert extent in reada_tree + all per-device trees, all or nothing */
+       spin_lock(&fs_info->reada_lock);
+       ret = radix_tree_insert(&fs_info->reada_tree, index, re);
+       if (ret) {
+               spin_unlock(&fs_info->reada_lock);
+               if (ret != -ENOMEM) {
+                       /* someone inserted the extent in the meantime */
+                       looped = 1;
+               }
+               goto error;
+       }
+       for (i = 0; i < nzones; ++i) {
+               dev = bbio->stripes[i].dev;
+               ret = radix_tree_insert(&dev->reada_extents, index, re);
+               if (ret) {
+                       while (--i >= 0) {
+                               dev = bbio->stripes[i].dev;
+                               BUG_ON(dev == NULL);
+                               radix_tree_delete(&dev->reada_extents, index);
+                       }
+                       BUG_ON(fs_info == NULL);
+                       radix_tree_delete(&fs_info->reada_tree, index);
+                       spin_unlock(&fs_info->reada_lock);
+                       goto error;
+               }
+       }
+       spin_unlock(&fs_info->reada_lock);
+
+       kfree(bbio);
+       return re;
+
+error:
+       while (nzones) {
+               struct reada_zone *zone;
+
+               --nzones;
+               zone = re->zones[nzones];
+               kref_get(&zone->refcnt);
+               spin_lock(&zone->lock);
+               --zone->elems;
+               if (zone->elems == 0) {
+                       /*
+                        * no fs_info->reada_lock needed, as this can't be
+                        * the last ref
+                        */
+                       kref_put(&zone->refcnt, reada_zone_release);
+               }
+               spin_unlock(&zone->lock);
+
+               spin_lock(&fs_info->reada_lock);
+               kref_put(&zone->refcnt, reada_zone_release);
+               spin_unlock(&fs_info->reada_lock);
+       }
+       kfree(bbio);
+       kfree(re);
+       if (looped)
+               goto again;
+       return NULL;
+}
+
+static void reada_kref_dummy(struct kref *kr)
+{
+}
+
+static void reada_extent_put(struct btrfs_fs_info *fs_info,
+                            struct reada_extent *re)
+{
+       int i;
+       unsigned long index = re->logical >> PAGE_CACHE_SHIFT;
+
+       spin_lock(&fs_info->reada_lock);
+       if (!kref_put(&re->refcnt, reada_kref_dummy)) {
+               spin_unlock(&fs_info->reada_lock);
+               return;
+       }
+
+       radix_tree_delete(&fs_info->reada_tree, index);
+       for (i = 0; i < re->nzones; ++i) {
+               struct reada_zone *zone = re->zones[i];
+
+               radix_tree_delete(&zone->device->reada_extents, index);
+       }
+
+       spin_unlock(&fs_info->reada_lock);
+
+       for (i = 0; i < re->nzones; ++i) {
+               struct reada_zone *zone = re->zones[i];
+
+               kref_get(&zone->refcnt);
+               spin_lock(&zone->lock);
+               --zone->elems;
+               if (zone->elems == 0) {
+                       /* no fs_info->reada_lock needed, as this can't be
+                        * the last ref */
+                       kref_put(&zone->refcnt, reada_zone_release);
+               }
+               spin_unlock(&zone->lock);
+
+               spin_lock(&fs_info->reada_lock);
+               kref_put(&zone->refcnt, reada_zone_release);
+               spin_unlock(&fs_info->reada_lock);
+       }
+       if (re->scheduled_for)
+               atomic_dec(&re->scheduled_for->reada_in_flight);
+
+       kfree(re);
+}
+
+static void reada_zone_release(struct kref *kref)
+{
+       struct reada_zone *zone = container_of(kref, struct reada_zone, refcnt);
+
+       radix_tree_delete(&zone->device->reada_zones,
+                         zone->end >> PAGE_CACHE_SHIFT);
+
+       kfree(zone);
+}
+
+static void reada_control_release(struct kref *kref)
+{
+       struct reada_control *rc = container_of(kref, struct reada_control,
+                                               refcnt);
+
+       kfree(rc);
+}
+
+static int reada_add_block(struct reada_control *rc, u64 logical,
+                          struct btrfs_key *top, int level, u64 generation)
+{
+       struct btrfs_root *root = rc->root;
+       struct reada_extent *re;
+       struct reada_extctl *rec;
+
+       re = reada_find_extent(root, logical, top, level); /* takes one ref */
+       if (!re)
+               return -1;
+
+       rec = kzalloc(sizeof(*rec), GFP_NOFS);
+       if (!rec) {
+               reada_extent_put(root->fs_info, re);
+               return -1;
+       }
+
+       rec->rc = rc;
+       rec->generation = generation;
+       atomic_inc(&rc->elems);
+
+       spin_lock(&re->lock);
+       list_add_tail(&rec->list, &re->extctl);
+       spin_unlock(&re->lock);
+
+       /* leave the ref on the extent */
+
+       return 0;
+}
+
+/*
+ * called with fs_info->reada_lock held
+ */
+static void reada_peer_zones_set_lock(struct reada_zone *zone, int lock)
+{
+       int i;
+       unsigned long index = zone->end >> PAGE_CACHE_SHIFT;
+
+       for (i = 0; i < zone->ndevs; ++i) {
+               struct reada_zone *peer;
+               peer = radix_tree_lookup(&zone->devs[i]->reada_zones, index);
+               if (peer && peer->device != zone->device)
+                       peer->locked = lock;
+       }
+}
+
+/*
+ * called with fs_info->reada_lock held
+ */
+static int reada_pick_zone(struct btrfs_device *dev)
+{
+       struct reada_zone *top_zone = NULL;
+       struct reada_zone *top_locked_zone = NULL;
+       u64 top_elems = 0;
+       u64 top_locked_elems = 0;
+       unsigned long index = 0;
+       int ret;
+
+       if (dev->reada_curr_zone) {
+               reada_peer_zones_set_lock(dev->reada_curr_zone, 0);
+               kref_put(&dev->reada_curr_zone->refcnt, reada_zone_release);
+               dev->reada_curr_zone = NULL;
+       }
+       /* pick the zone with the most elements */
+       while (1) {
+               struct reada_zone *zone;
+
+               ret = radix_tree_gang_lookup(&dev->reada_zones,
+                                            (void **)&zone, index, 1);
+               if (ret == 0)
+                       break;
+               index = (zone->end >> PAGE_CACHE_SHIFT) + 1;
+               if (zone->locked) {
+                       if (zone->elems > top_locked_elems) {
+                               top_locked_elems = zone->elems;
+                               top_locked_zone = zone;
+                       }
+               } else {
+                       if (zone->elems > top_elems) {
+                               top_elems = zone->elems;
+                               top_zone = zone;
+                       }
+               }
+       }
+       if (top_zone)
+               dev->reada_curr_zone = top_zone;
+       else if (top_locked_zone)
+               dev->reada_curr_zone = top_locked_zone;
+       else
+               return 0;
+
+       dev->reada_next = dev->reada_curr_zone->start;
+       kref_get(&dev->reada_curr_zone->refcnt);
+       reada_peer_zones_set_lock(dev->reada_curr_zone, 1);
+
+       return 1;
+}
+
+static int reada_start_machine_dev(struct btrfs_fs_info *fs_info,
+                                  struct btrfs_device *dev)
+{
+       struct reada_extent *re = NULL;
+       int mirror_num = 0;
+       struct extent_buffer *eb = NULL;
+       u64 logical;
+       u32 blocksize;
+       int ret;
+       int i;
+       int need_kick = 0;
+
+       spin_lock(&fs_info->reada_lock);
+       if (dev->reada_curr_zone == NULL) {
+               ret = reada_pick_zone(dev);
+               if (!ret) {
+                       spin_unlock(&fs_info->reada_lock);
+                       return 0;
+               }
+       }
+       /*
+        * FIXME currently we issue the reads one extent at a time. If we have
+        * a contiguous block of extents, we could also coagulate them or use
+        * plugging to speed things up
+        */
+       ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re,
+                                    dev->reada_next >> PAGE_CACHE_SHIFT, 1);
+       if (ret == 0 || re->logical >= dev->reada_curr_zone->end) {
+               ret = reada_pick_zone(dev);
+               if (!ret) {
+                       spin_unlock(&fs_info->reada_lock);
+                       return 0;
+               }
+               re = NULL;
+               ret = radix_tree_gang_lookup(&dev->reada_extents, (void **)&re,
+                                       dev->reada_next >> PAGE_CACHE_SHIFT, 1);
+       }
+       if (ret == 0) {
+               spin_unlock(&fs_info->reada_lock);
+               return 0;
+       }
+       dev->reada_next = re->logical + re->blocksize;
+       kref_get(&re->refcnt);
+
+       spin_unlock(&fs_info->reada_lock);
+
+       /*
+        * find mirror num
+        */
+       for (i = 0; i < re->nzones; ++i) {
+               if (re->zones[i]->device == dev) {
+                       mirror_num = i + 1;
+                       break;
+               }
+       }
+       logical = re->logical;
+       blocksize = re->blocksize;
+
+       spin_lock(&re->lock);
+       if (re->scheduled_for == NULL) {
+               re->scheduled_for = dev;
+               need_kick = 1;
+       }
+       spin_unlock(&re->lock);
+
+       reada_extent_put(fs_info, re);
+
+       if (!need_kick)
+               return 0;
+
+       atomic_inc(&dev->reada_in_flight);
+       ret = reada_tree_block_flagged(fs_info->extent_root, logical, blocksize,
+                        mirror_num, &eb);
+       if (ret)
+               __readahead_hook(fs_info->extent_root, NULL, logical, ret);
+       else if (eb)
+               __readahead_hook(fs_info->extent_root, eb, eb->start, ret);
+
+       if (eb)
+               free_extent_buffer(eb);
+
+       return 1;
+
+}
+
+static void reada_start_machine_worker(struct btrfs_work *work)
+{
+       struct reada_machine_work *rmw;
+       struct btrfs_fs_info *fs_info;
+
+       rmw = container_of(work, struct reada_machine_work, work);
+       fs_info = rmw->fs_info;
+
+       kfree(rmw);
+
+       __reada_start_machine(fs_info);
+}
+
+static void __reada_start_machine(struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_device *device;
+       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+       u64 enqueued;
+       u64 total = 0;
+       int i;
+
+       do {
+               enqueued = 0;
+               list_for_each_entry(device, &fs_devices->devices, dev_list) {
+                       if (atomic_read(&device->reada_in_flight) <
+                           MAX_IN_FLIGHT)
+                               enqueued += reada_start_machine_dev(fs_info,
+                                                                   device);
+               }
+               total += enqueued;
+       } while (enqueued && total < 10000);
+
+       if (enqueued == 0)
+               return;
+
+       /*
+        * If everything is already in the cache, this is effectively single
+        * threaded. To a) not hold the caller for too long and b) to utilize
+        * more cores, we broke the loop above after 10000 iterations and now
+        * enqueue to workers to finish it. This will distribute the load to
+        * the cores.
+        */
+       for (i = 0; i < 2; ++i)
+               reada_start_machine(fs_info);
+}
+
+static void reada_start_machine(struct btrfs_fs_info *fs_info)
+{
+       struct reada_machine_work *rmw;
+
+       rmw = kzalloc(sizeof(*rmw), GFP_NOFS);
+       if (!rmw) {
+               /* FIXME we cannot handle this properly right now */
+               BUG();
+       }
+       rmw->work.func = reada_start_machine_worker;
+       rmw->fs_info = fs_info;
+
+       btrfs_queue_worker(&fs_info->readahead_workers, &rmw->work);
+}
+
+#ifdef DEBUG
+static void dump_devs(struct btrfs_fs_info *fs_info, int all)
+{
+       struct btrfs_device *device;
+       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+       unsigned long index;
+       int ret;
+       int i;
+       int j;
+       int cnt;
+
+       spin_lock(&fs_info->reada_lock);
+       list_for_each_entry(device, &fs_devices->devices, dev_list) {
+               printk(KERN_DEBUG "dev %lld has %d in flight\n", device->devid,
+                       atomic_read(&device->reada_in_flight));
+               index = 0;
+               while (1) {
+                       struct reada_zone *zone;
+                       ret = radix_tree_gang_lookup(&device->reada_zones,
+                                                    (void **)&zone, index, 1);
+                       if (ret == 0)
+                               break;
+                       printk(KERN_DEBUG "  zone %llu-%llu elems %llu locked "
+                               "%d devs", zone->start, zone->end, zone->elems,
+                               zone->locked);
+                       for (j = 0; j < zone->ndevs; ++j) {
+                               printk(KERN_CONT " %lld",
+                                       zone->devs[j]->devid);
+                       }
+                       if (device->reada_curr_zone == zone)
+                               printk(KERN_CONT " curr off %llu",
+                                       device->reada_next - zone->start);
+                       printk(KERN_CONT "\n");
+                       index = (zone->end >> PAGE_CACHE_SHIFT) + 1;
+               }
+               cnt = 0;
+               index = 0;
+               while (all) {
+                       struct reada_extent *re = NULL;
+
+                       ret = radix_tree_gang_lookup(&device->reada_extents,
+                                                    (void **)&re, index, 1);
+                       if (ret == 0)
+                               break;
+                       printk(KERN_DEBUG
+                               "  re: logical %llu size %u empty %d for %lld",
+                               re->logical, re->blocksize,
+                               list_empty(&re->extctl), re->scheduled_for ?
+                               re->scheduled_for->devid : -1);
+
+                       for (i = 0; i < re->nzones; ++i) {
+                               printk(KERN_CONT " zone %llu-%llu devs",
+                                       re->zones[i]->start,
+                                       re->zones[i]->end);
+                               for (j = 0; j < re->zones[i]->ndevs; ++j) {
+                                       printk(KERN_CONT " %lld",
+                                               re->zones[i]->devs[j]->devid);
+                               }
+                       }
+                       printk(KERN_CONT "\n");
+                       index = (re->logical >> PAGE_CACHE_SHIFT) + 1;
+                       if (++cnt > 15)
+                               break;
+               }
+       }
+
+       index = 0;
+       cnt = 0;
+       while (all) {
+               struct reada_extent *re = NULL;
+
+               ret = radix_tree_gang_lookup(&fs_info->reada_tree, (void **)&re,
+                                            index, 1);
+               if (ret == 0)
+                       break;
+               if (!re->scheduled_for) {
+                       index = (re->logical >> PAGE_CACHE_SHIFT) + 1;
+                       continue;
+               }
+               printk(KERN_DEBUG
+                       "re: logical %llu size %u list empty %d for %lld",
+                       re->logical, re->blocksize, list_empty(&re->extctl),
+                       re->scheduled_for ? re->scheduled_for->devid : -1);
+               for (i = 0; i < re->nzones; ++i) {
+                       printk(KERN_CONT " zone %llu-%llu devs",
+                               re->zones[i]->start,
+                               re->zones[i]->end);
+                       for (i = 0; i < re->nzones; ++i) {
+                               printk(KERN_CONT " zone %llu-%llu devs",
+                                       re->zones[i]->start,
+                                       re->zones[i]->end);
+                               for (j = 0; j < re->zones[i]->ndevs; ++j) {
+                                       printk(KERN_CONT " %lld",
+                                               re->zones[i]->devs[j]->devid);
+                               }
+                       }
+               }
+               printk(KERN_CONT "\n");
+               index = (re->logical >> PAGE_CACHE_SHIFT) + 1;
+       }
+       spin_unlock(&fs_info->reada_lock);
+}
+#endif
+
+/*
+ * interface
+ */
+struct reada_control *btrfs_reada_add(struct btrfs_root *root,
+                       struct btrfs_key *key_start, struct btrfs_key *key_end)
+{
+       struct reada_control *rc;
+       u64 start;
+       u64 generation;
+       int level;
+       struct extent_buffer *node;
+       static struct btrfs_key max_key = {
+               .objectid = (u64)-1,
+               .type = (u8)-1,
+               .offset = (u64)-1
+       };
+
+       rc = kzalloc(sizeof(*rc), GFP_NOFS);
+       if (!rc)
+               return ERR_PTR(-ENOMEM);
+
+       rc->root = root;
+       rc->key_start = *key_start;
+       rc->key_end = *key_end;
+       atomic_set(&rc->elems, 0);
+       init_waitqueue_head(&rc->wait);
+       kref_init(&rc->refcnt);
+       kref_get(&rc->refcnt); /* one ref for having elements */
+
+       node = btrfs_root_node(root);
+       start = node->start;
+       level = btrfs_header_level(node);
+       generation = btrfs_header_generation(node);
+       free_extent_buffer(node);
+
+       reada_add_block(rc, start, &max_key, level, generation);
+
+       reada_start_machine(root->fs_info);
+
+       return rc;
+}
+
+#ifdef DEBUG
+int btrfs_reada_wait(void *handle)
+{
+       struct reada_control *rc = handle;
+
+       while (atomic_read(&rc->elems)) {
+               wait_event_timeout(rc->wait, atomic_read(&rc->elems) == 0,
+                                  5 * HZ);
+               dump_devs(rc->root->fs_info, rc->elems < 10 ? 1 : 0);
+       }
+
+       dump_devs(rc->root->fs_info, rc->elems < 10 ? 1 : 0);
+
+       kref_put(&rc->refcnt, reada_control_release);
+
+       return 0;
+}
+#else
+int btrfs_reada_wait(void *handle)
+{
+       struct reada_control *rc = handle;
+
+       while (atomic_read(&rc->elems)) {
+               wait_event(rc->wait, atomic_read(&rc->elems) == 0);
+       }
+
+       kref_put(&rc->refcnt, reada_control_release);
+
+       return 0;
+}
+#endif
+
+void btrfs_reada_detach(void *handle)
+{
+       struct reada_control *rc = handle;
+
+       kref_put(&rc->refcnt, reada_control_release);
+}
index 59bb1764273d476b7efe01a8d0948f4f473de6f2..dff29d5e151a3b80d516be44cc1ebdf0d00adad6 100644 (file)
@@ -1174,6 +1174,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
                        list_add_tail(&new_edge->list[UPPER],
                                      &new_node->lower);
                }
+       } else {
+               list_add_tail(&new_node->lower, &cache->leaves);
        }
 
        rb_node = tree_insert(&cache->rb_root, new_node->bytenr,
@@ -2041,8 +2043,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
                BUG_ON(IS_ERR(trans));
                trans->block_rsv = rc->block_rsv;
 
-               ret = btrfs_block_rsv_check(trans, root, rc->block_rsv,
-                                           min_reserved, 0);
+               ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved);
                if (ret) {
                        BUG_ON(ret != -EAGAIN);
                        ret = btrfs_commit_transaction(trans, root);
@@ -2152,8 +2153,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 again:
        if (!err) {
                num_bytes = rc->merging_rsv_size;
-               ret = btrfs_block_rsv_add(NULL, root, rc->block_rsv,
-                                         num_bytes);
+               ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
                if (ret)
                        err = ret;
        }
@@ -2427,7 +2427,7 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
        num_bytes = calcu_metadata_size(rc, node, 1) * 2;
 
        trans->block_rsv = rc->block_rsv;
-       ret = btrfs_block_rsv_add(trans, root, rc->block_rsv, num_bytes);
+       ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
        if (ret) {
                if (ret == -EAGAIN)
                        rc->commit_transaction = 1;
@@ -2922,6 +2922,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
        unsigned long last_index;
        struct page *page;
        struct file_ra_state *ra;
+       gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
        int nr = 0;
        int ret = 0;
 
@@ -2956,7 +2957,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
                                                  ra, NULL, index,
                                                  last_index + 1 - index);
                        page = find_or_create_page(inode->i_mapping, index,
-                                                  GFP_NOFS);
+                                                  mask);
                        if (!page) {
                                btrfs_delalloc_release_metadata(inode,
                                                        PAGE_CACHE_SIZE);
@@ -3323,8 +3324,11 @@ static int find_data_references(struct reloc_control *rc,
        }
 
        key.objectid = ref_objectid;
-       key.offset = ref_offset;
        key.type = BTRFS_EXTENT_DATA_KEY;
+       if (ref_offset > ((u64)-1 << 32))
+               key.offset = 0;
+       else
+               key.offset = ref_offset;
 
        path->search_commit_root = 1;
        path->skip_locking = 1;
@@ -3645,14 +3649,11 @@ int prepare_to_relocate(struct reloc_control *rc)
         * btrfs_init_reloc_root will use them when there
         * is no reservation in transaction handle.
         */
-       ret = btrfs_block_rsv_add(NULL, rc->extent_root, rc->block_rsv,
+       ret = btrfs_block_rsv_add(rc->extent_root, rc->block_rsv,
                                  rc->extent_root->nodesize * 256);
        if (ret)
                return ret;
 
-       rc->block_rsv->refill_used = 1;
-       btrfs_add_durable_block_rsv(rc->extent_root->fs_info, rc->block_rsv);
-
        memset(&rc->cluster, 0, sizeof(rc->cluster));
        rc->search_start = rc->block_group->key.objectid;
        rc->extents_found = 0;
@@ -3777,8 +3778,7 @@ restart:
                        }
                }
 
-               ret = btrfs_block_rsv_check(trans, rc->extent_root,
-                                           rc->block_rsv, 0, 5);
+               ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);
                if (ret < 0) {
                        if (ret != -EAGAIN) {
                                err = ret;
index a8d03d5efb5df3b3a8d4f6fa659909e571a69a7c..c27bcb67f3304d806ab7e90cef8c3bcdef78b19c 100644 (file)
  */
 
 #include <linux/blkdev.h>
+#include <linux/ratelimit.h>
 #include "ctree.h"
 #include "volumes.h"
 #include "disk-io.h"
 #include "ordered-data.h"
+#include "transaction.h"
+#include "backref.h"
+#include "extent_io.h"
 
 /*
  * This is only the first step towards a full-features scrub. It reads all
  * any can be found.
  *
  * Future enhancements:
- *  - To enhance the performance, better read-ahead strategies for the
- *    extent-tree can be employed.
  *  - In case an unrepairable extent is encountered, track which files are
  *    affected and report them
  *  - In case of a read error on files with nodatasum, map the file and read
  *    the extent to trigger a writeback of the good copy
  *  - track and record media errors, throw out bad devices
  *  - add a mode to also read unallocated space
- *  - make the prefetch cancellable
  */
 
 struct scrub_bio;
@@ -63,7 +64,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix);
 struct scrub_page {
        u64                     flags;  /* extent flags */
        u64                     generation;
-       u64                     mirror_num;
+       int                     mirror_num;
        int                     have_csum;
        u8                      csum[BTRFS_CSUM_SIZE];
 };
@@ -87,6 +88,7 @@ struct scrub_dev {
        int                     first_free;
        int                     curr;
        atomic_t                in_flight;
+       atomic_t                fixup_cnt;
        spinlock_t              list_lock;
        wait_queue_head_t       list_wait;
        u16                     csum_size;
@@ -100,6 +102,27 @@ struct scrub_dev {
        spinlock_t              stat_lock;
 };
 
+struct scrub_fixup_nodatasum {
+       struct scrub_dev        *sdev;
+       u64                     logical;
+       struct btrfs_root       *root;
+       struct btrfs_work       work;
+       int                     mirror_num;
+};
+
+struct scrub_warning {
+       struct btrfs_path       *path;
+       u64                     extent_item_size;
+       char                    *scratch_buf;
+       char                    *msg_buf;
+       const char              *errstr;
+       sector_t                sector;
+       u64                     logical;
+       struct btrfs_device     *dev;
+       int                     msg_bufsize;
+       int                     scratch_bufsize;
+};
+
 static void scrub_free_csums(struct scrub_dev *sdev)
 {
        while (!list_empty(&sdev->csum_list)) {
@@ -175,14 +198,15 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev)
 
                if (i != SCRUB_BIOS_PER_DEV-1)
                        sdev->bios[i]->next_free = i + 1;
-                else
+               else
                        sdev->bios[i]->next_free = -1;
        }
        sdev->first_free = 0;
        sdev->curr = -1;
        atomic_set(&sdev->in_flight, 0);
+       atomic_set(&sdev->fixup_cnt, 0);
        atomic_set(&sdev->cancel_req, 0);
-       sdev->csum_size = btrfs_super_csum_size(&fs_info->super_copy);
+       sdev->csum_size = btrfs_super_csum_size(fs_info->super_copy);
        INIT_LIST_HEAD(&sdev->csum_list);
 
        spin_lock_init(&sdev->list_lock);
@@ -195,24 +219,366 @@ nomem:
        return ERR_PTR(-ENOMEM);
 }
 
+static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx)
+{
+       u64 isize;
+       u32 nlink;
+       int ret;
+       int i;
+       struct extent_buffer *eb;
+       struct btrfs_inode_item *inode_item;
+       struct scrub_warning *swarn = ctx;
+       struct btrfs_fs_info *fs_info = swarn->dev->dev_root->fs_info;
+       struct inode_fs_paths *ipath = NULL;
+       struct btrfs_root *local_root;
+       struct btrfs_key root_key;
+
+       root_key.objectid = root;
+       root_key.type = BTRFS_ROOT_ITEM_KEY;
+       root_key.offset = (u64)-1;
+       local_root = btrfs_read_fs_root_no_name(fs_info, &root_key);
+       if (IS_ERR(local_root)) {
+               ret = PTR_ERR(local_root);
+               goto err;
+       }
+
+       ret = inode_item_info(inum, 0, local_root, swarn->path);
+       if (ret) {
+               btrfs_release_path(swarn->path);
+               goto err;
+       }
+
+       eb = swarn->path->nodes[0];
+       inode_item = btrfs_item_ptr(eb, swarn->path->slots[0],
+                                       struct btrfs_inode_item);
+       isize = btrfs_inode_size(eb, inode_item);
+       nlink = btrfs_inode_nlink(eb, inode_item);
+       btrfs_release_path(swarn->path);
+
+       ipath = init_ipath(4096, local_root, swarn->path);
+       if (IS_ERR(ipath)) {
+               ret = PTR_ERR(ipath);
+               ipath = NULL;
+               goto err;
+       }
+       ret = paths_from_inode(inum, ipath);
+
+       if (ret < 0)
+               goto err;
+
+       /*
+        * we deliberately ignore the bit ipath might have been too small to
+        * hold all of the paths here
+        */
+       for (i = 0; i < ipath->fspath->elem_cnt; ++i)
+               printk(KERN_WARNING "btrfs: %s at logical %llu on dev "
+                       "%s, sector %llu, root %llu, inode %llu, offset %llu, "
+                       "length %llu, links %u (path: %s)\n", swarn->errstr,
+                       swarn->logical, swarn->dev->name,
+                       (unsigned long long)swarn->sector, root, inum, offset,
+                       min(isize - offset, (u64)PAGE_SIZE), nlink,
+                       (char *)(unsigned long)ipath->fspath->val[i]);
+
+       free_ipath(ipath);
+       return 0;
+
+err:
+       printk(KERN_WARNING "btrfs: %s at logical %llu on dev "
+               "%s, sector %llu, root %llu, inode %llu, offset %llu: path "
+               "resolving failed with ret=%d\n", swarn->errstr,
+               swarn->logical, swarn->dev->name,
+               (unsigned long long)swarn->sector, root, inum, offset, ret);
+
+       free_ipath(ipath);
+       return 0;
+}
+
+static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
+                               int ix)
+{
+       struct btrfs_device *dev = sbio->sdev->dev;
+       struct btrfs_fs_info *fs_info = dev->dev_root->fs_info;
+       struct btrfs_path *path;
+       struct btrfs_key found_key;
+       struct extent_buffer *eb;
+       struct btrfs_extent_item *ei;
+       struct scrub_warning swarn;
+       u32 item_size;
+       int ret;
+       u64 ref_root;
+       u8 ref_level;
+       unsigned long ptr = 0;
+       const int bufsize = 4096;
+       u64 extent_offset;
+
+       path = btrfs_alloc_path();
+
+       swarn.scratch_buf = kmalloc(bufsize, GFP_NOFS);
+       swarn.msg_buf = kmalloc(bufsize, GFP_NOFS);
+       swarn.sector = (sbio->physical + ix * PAGE_SIZE) >> 9;
+       swarn.logical = sbio->logical + ix * PAGE_SIZE;
+       swarn.errstr = errstr;
+       swarn.dev = dev;
+       swarn.msg_bufsize = bufsize;
+       swarn.scratch_bufsize = bufsize;
+
+       if (!path || !swarn.scratch_buf || !swarn.msg_buf)
+               goto out;
+
+       ret = extent_from_logical(fs_info, swarn.logical, path, &found_key);
+       if (ret < 0)
+               goto out;
+
+       extent_offset = swarn.logical - found_key.objectid;
+       swarn.extent_item_size = found_key.offset;
+
+       eb = path->nodes[0];
+       ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
+       item_size = btrfs_item_size_nr(eb, path->slots[0]);
+
+       if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+               do {
+                       ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
+                                                       &ref_root, &ref_level);
+                       printk(KERN_WARNING "%s at logical %llu on dev %s, "
+                               "sector %llu: metadata %s (level %d) in tree "
+                               "%llu\n", errstr, swarn.logical, dev->name,
+                               (unsigned long long)swarn.sector,
+                               ref_level ? "node" : "leaf",
+                               ret < 0 ? -1 : ref_level,
+                               ret < 0 ? -1 : ref_root);
+               } while (ret != 1);
+       } else {
+               swarn.path = path;
+               iterate_extent_inodes(fs_info, path, found_key.objectid,
+                                       extent_offset,
+                                       scrub_print_warning_inode, &swarn);
+       }
+
+out:
+       btrfs_free_path(path);
+       kfree(swarn.scratch_buf);
+       kfree(swarn.msg_buf);
+}
+
+static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *ctx)
+{
+       struct page *page = NULL;
+       unsigned long index;
+       struct scrub_fixup_nodatasum *fixup = ctx;
+       int ret;
+       int corrected = 0;
+       struct btrfs_key key;
+       struct inode *inode = NULL;
+       u64 end = offset + PAGE_SIZE - 1;
+       struct btrfs_root *local_root;
+
+       key.objectid = root;
+       key.type = BTRFS_ROOT_ITEM_KEY;
+       key.offset = (u64)-1;
+       local_root = btrfs_read_fs_root_no_name(fixup->root->fs_info, &key);
+       if (IS_ERR(local_root))
+               return PTR_ERR(local_root);
+
+       key.type = BTRFS_INODE_ITEM_KEY;
+       key.objectid = inum;
+       key.offset = 0;
+       inode = btrfs_iget(fixup->root->fs_info->sb, &key, local_root, NULL);
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
+
+       index = offset >> PAGE_CACHE_SHIFT;
+
+       page = find_or_create_page(inode->i_mapping, index, GFP_NOFS);
+       if (!page) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       if (PageUptodate(page)) {
+               struct btrfs_mapping_tree *map_tree;
+               if (PageDirty(page)) {
+                       /*
+                        * we need to write the data to the defect sector. the
+                        * data that was in that sector is not in memory,
+                        * because the page was modified. we must not write the
+                        * modified page to that sector.
+                        *
+                        * TODO: what could be done here: wait for the delalloc
+                        *       runner to write out that page (might involve
+                        *       COW) and see whether the sector is still
+                        *       referenced afterwards.
+                        *
+                        * For the meantime, we'll treat this error
+                        * incorrectable, although there is a chance that a
+                        * later scrub will find the bad sector again and that
+                        * there's no dirty page in memory, then.
+                        */
+                       ret = -EIO;
+                       goto out;
+               }
+               map_tree = &BTRFS_I(inode)->root->fs_info->mapping_tree;
+               ret = repair_io_failure(map_tree, offset, PAGE_SIZE,
+                                       fixup->logical, page,
+                                       fixup->mirror_num);
+               unlock_page(page);
+               corrected = !ret;
+       } else {
+               /*
+                * we need to get good data first. the general readpage path
+                * will call repair_io_failure for us, we just have to make
+                * sure we read the bad mirror.
+                */
+               ret = set_extent_bits(&BTRFS_I(inode)->io_tree, offset, end,
+                                       EXTENT_DAMAGED, GFP_NOFS);
+               if (ret) {
+                       /* set_extent_bits should give proper error */
+                       WARN_ON(ret > 0);
+                       if (ret > 0)
+                               ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = extent_read_full_page(&BTRFS_I(inode)->io_tree, page,
+                                               btrfs_get_extent,
+                                               fixup->mirror_num);
+               wait_on_page_locked(page);
+
+               corrected = !test_range_bit(&BTRFS_I(inode)->io_tree, offset,
+                                               end, EXTENT_DAMAGED, 0, NULL);
+               if (!corrected)
+                       clear_extent_bits(&BTRFS_I(inode)->io_tree, offset, end,
+                                               EXTENT_DAMAGED, GFP_NOFS);
+       }
+
+out:
+       if (page)
+               put_page(page);
+       if (inode)
+               iput(inode);
+
+       if (ret < 0)
+               return ret;
+
+       if (ret == 0 && corrected) {
+               /*
+                * we only need to call readpage for one of the inodes belonging
+                * to this extent. so make iterate_extent_inodes stop
+                */
+               return 1;
+       }
+
+       return -EIO;
+}
+
+static void scrub_fixup_nodatasum(struct btrfs_work *work)
+{
+       int ret;
+       struct scrub_fixup_nodatasum *fixup;
+       struct scrub_dev *sdev;
+       struct btrfs_trans_handle *trans = NULL;
+       struct btrfs_fs_info *fs_info;
+       struct btrfs_path *path;
+       int uncorrectable = 0;
+
+       fixup = container_of(work, struct scrub_fixup_nodatasum, work);
+       sdev = fixup->sdev;
+       fs_info = fixup->root->fs_info;
+
+       path = btrfs_alloc_path();
+       if (!path) {
+               spin_lock(&sdev->stat_lock);
+               ++sdev->stat.malloc_errors;
+               spin_unlock(&sdev->stat_lock);
+               uncorrectable = 1;
+               goto out;
+       }
+
+       trans = btrfs_join_transaction(fixup->root);
+       if (IS_ERR(trans)) {
+               uncorrectable = 1;
+               goto out;
+       }
+
+       /*
+        * the idea is to trigger a regular read through the standard path. we
+        * read a page from the (failed) logical address by specifying the
+        * corresponding copynum of the failed sector. thus, that readpage is
+        * expected to fail.
+        * that is the point where on-the-fly error correction will kick in
+        * (once it's finished) and rewrite the failed sector if a good copy
+        * can be found.
+        */
+       ret = iterate_inodes_from_logical(fixup->logical, fixup->root->fs_info,
+                                               path, scrub_fixup_readpage,
+                                               fixup);
+       if (ret < 0) {
+               uncorrectable = 1;
+               goto out;
+       }
+       WARN_ON(ret != 1);
+
+       spin_lock(&sdev->stat_lock);
+       ++sdev->stat.corrected_errors;
+       spin_unlock(&sdev->stat_lock);
+
+out:
+       if (trans && !IS_ERR(trans))
+               btrfs_end_transaction(trans, fixup->root);
+       if (uncorrectable) {
+               spin_lock(&sdev->stat_lock);
+               ++sdev->stat.uncorrectable_errors;
+               spin_unlock(&sdev->stat_lock);
+               printk_ratelimited(KERN_ERR "btrfs: unable to fixup "
+                                       "(nodatasum) error at logical %llu\n",
+                                       fixup->logical);
+       }
+
+       btrfs_free_path(path);
+       kfree(fixup);
+
+       /* see caller why we're pretending to be paused in the scrub counters */
+       mutex_lock(&fs_info->scrub_lock);
+       atomic_dec(&fs_info->scrubs_running);
+       atomic_dec(&fs_info->scrubs_paused);
+       mutex_unlock(&fs_info->scrub_lock);
+       atomic_dec(&sdev->fixup_cnt);
+       wake_up(&fs_info->scrub_pause_wait);
+       wake_up(&sdev->list_wait);
+}
+
 /*
  * scrub_recheck_error gets called when either verification of the page
  * failed or the bio failed to read, e.g. with EIO. In the latter case,
  * recheck_error gets called for every page in the bio, even though only
  * one may be bad
  */
-static void scrub_recheck_error(struct scrub_bio *sbio, int ix)
+static int scrub_recheck_error(struct scrub_bio *sbio, int ix)
 {
+       struct scrub_dev *sdev = sbio->sdev;
+       u64 sector = (sbio->physical + ix * PAGE_SIZE) >> 9;
+       static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
+                                       DEFAULT_RATELIMIT_BURST);
+
        if (sbio->err) {
-               if (scrub_fixup_io(READ, sbio->sdev->dev->bdev,
-                                  (sbio->physical + ix * PAGE_SIZE) >> 9,
+               if (scrub_fixup_io(READ, sbio->sdev->dev->bdev, sector,
                                   sbio->bio->bi_io_vec[ix].bv_page) == 0) {
                        if (scrub_fixup_check(sbio, ix) == 0)
-                               return;
+                               return 0;
                }
+               if (__ratelimit(&_rs))
+                       scrub_print_warning("i/o error", sbio, ix);
+       } else {
+               if (__ratelimit(&_rs))
+                       scrub_print_warning("checksum error", sbio, ix);
        }
 
+       spin_lock(&sdev->stat_lock);
+       ++sdev->stat.read_errors;
+       spin_unlock(&sdev->stat_lock);
+
        scrub_fixup(sbio, ix);
+       return 1;
 }
 
 static int scrub_fixup_check(struct scrub_bio *sbio, int ix)
@@ -250,7 +616,8 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
        struct scrub_dev *sdev = sbio->sdev;
        struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info;
        struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
-       struct btrfs_multi_bio *multi = NULL;
+       struct btrfs_bio *bbio = NULL;
+       struct scrub_fixup_nodatasum *fixup;
        u64 logical = sbio->logical + ix * PAGE_SIZE;
        u64 length;
        int i;
@@ -259,38 +626,57 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
 
        if ((sbio->spag[ix].flags & BTRFS_EXTENT_FLAG_DATA) &&
            (sbio->spag[ix].have_csum == 0)) {
+               fixup = kzalloc(sizeof(*fixup), GFP_NOFS);
+               if (!fixup)
+                       goto uncorrectable;
+               fixup->sdev = sdev;
+               fixup->logical = logical;
+               fixup->root = fs_info->extent_root;
+               fixup->mirror_num = sbio->spag[ix].mirror_num;
                /*
-                * nodatasum, don't try to fix anything
-                * FIXME: we can do better, open the inode and trigger a
-                * writeback
+                * increment scrubs_running to prevent cancel requests from
+                * completing as long as a fixup worker is running. we must also
+                * increment scrubs_paused to prevent deadlocking on pause
+                * requests used for transactions commits (as the worker uses a
+                * transaction context). it is safe to regard the fixup worker
+                * as paused for all matters practical. effectively, we only
+                * avoid cancellation requests from completing.
                 */
-               goto uncorrectable;
+               mutex_lock(&fs_info->scrub_lock);
+               atomic_inc(&fs_info->scrubs_running);
+               atomic_inc(&fs_info->scrubs_paused);
+               mutex_unlock(&fs_info->scrub_lock);
+               atomic_inc(&sdev->fixup_cnt);
+               fixup->work.func = scrub_fixup_nodatasum;
+               btrfs_queue_worker(&fs_info->scrub_workers, &fixup->work);
+               return;
        }
 
        length = PAGE_SIZE;
        ret = btrfs_map_block(map_tree, REQ_WRITE, logical, &length,
-                             &multi, 0);
-       if (ret || !multi || length < PAGE_SIZE) {
+                             &bbio, 0);
+       if (ret || !bbio || length < PAGE_SIZE) {
                printk(KERN_ERR
                       "scrub_fixup: btrfs_map_block failed us for %llu\n",
                       (unsigned long long)logical);
                WARN_ON(1);
+               kfree(bbio);
                return;
        }
 
-       if (multi->num_stripes == 1)
+       if (bbio->num_stripes == 1)
                /* there aren't any replicas */
                goto uncorrectable;
 
        /*
         * first find a good copy
         */
-       for (i = 0; i < multi->num_stripes; ++i) {
-               if (i == sbio->spag[ix].mirror_num)
+       for (i = 0; i < bbio->num_stripes; ++i) {
+               if (i + 1 == sbio->spag[ix].mirror_num)
                        continue;
 
-               if (scrub_fixup_io(READ, multi->stripes[i].dev->bdev,
-                                  multi->stripes[i].physical >> 9,
+               if (scrub_fixup_io(READ, bbio->stripes[i].dev->bdev,
+                                  bbio->stripes[i].physical >> 9,
                                   sbio->bio->bi_io_vec[ix].bv_page)) {
                        /* I/O-error, this is not a good copy */
                        continue;
@@ -299,7 +685,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
                if (scrub_fixup_check(sbio, ix) == 0)
                        break;
        }
-       if (i == multi->num_stripes)
+       if (i == bbio->num_stripes)
                goto uncorrectable;
 
        if (!sdev->readonly) {
@@ -314,25 +700,23 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
                }
        }
 
-       kfree(multi);
+       kfree(bbio);
        spin_lock(&sdev->stat_lock);
        ++sdev->stat.corrected_errors;
        spin_unlock(&sdev->stat_lock);
 
-       if (printk_ratelimit())
-               printk(KERN_ERR "btrfs: fixed up at %llu\n",
-                      (unsigned long long)logical);
+       printk_ratelimited(KERN_ERR "btrfs: fixed up error at logical %llu\n",
+                              (unsigned long long)logical);
        return;
 
 uncorrectable:
-       kfree(multi);
+       kfree(bbio);
        spin_lock(&sdev->stat_lock);
        ++sdev->stat.uncorrectable_errors;
        spin_unlock(&sdev->stat_lock);
 
-       if (printk_ratelimit())
-               printk(KERN_ERR "btrfs: unable to fixup at %llu\n",
-                        (unsigned long long)logical);
+       printk_ratelimited(KERN_ERR "btrfs: unable to fixup (regular) error at "
+                               "logical %llu\n", (unsigned long long)logical);
 }
 
 static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,
@@ -382,8 +766,14 @@ static void scrub_checksum(struct btrfs_work *work)
        int ret;
 
        if (sbio->err) {
+               ret = 0;
                for (i = 0; i < sbio->count; ++i)
-                       scrub_recheck_error(sbio, i);
+                       ret |= scrub_recheck_error(sbio, i);
+               if (!ret) {
+                       spin_lock(&sdev->stat_lock);
+                       ++sdev->stat.unverified_errors;
+                       spin_unlock(&sdev->stat_lock);
+               }
 
                sbio->bio->bi_flags &= ~(BIO_POOL_MASK - 1);
                sbio->bio->bi_flags |= 1 << BIO_UPTODATE;
@@ -396,10 +786,6 @@ static void scrub_checksum(struct btrfs_work *work)
                        bi->bv_offset = 0;
                        bi->bv_len = PAGE_SIZE;
                }
-
-               spin_lock(&sdev->stat_lock);
-               ++sdev->stat.read_errors;
-               spin_unlock(&sdev->stat_lock);
                goto out;
        }
        for (i = 0; i < sbio->count; ++i) {
@@ -420,8 +806,14 @@ static void scrub_checksum(struct btrfs_work *work)
                        WARN_ON(1);
                }
                kunmap_atomic(buffer, KM_USER0);
-               if (ret)
-                       scrub_recheck_error(sbio, i);
+               if (ret) {
+                       ret = scrub_recheck_error(sbio, i);
+                       if (!ret) {
+                               spin_lock(&sdev->stat_lock);
+                               ++sdev->stat.unverified_errors;
+                               spin_unlock(&sdev->stat_lock);
+                       }
+               }
        }
 
 out:
@@ -557,57 +949,27 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer)
 static int scrub_submit(struct scrub_dev *sdev)
 {
        struct scrub_bio *sbio;
-       struct bio *bio;
-       int i;
 
        if (sdev->curr == -1)
                return 0;
 
        sbio = sdev->bios[sdev->curr];
-
-       bio = bio_alloc(GFP_NOFS, sbio->count);
-       if (!bio)
-               goto nomem;
-
-       bio->bi_private = sbio;
-       bio->bi_end_io = scrub_bio_end_io;
-       bio->bi_bdev = sdev->dev->bdev;
-       bio->bi_sector = sbio->physical >> 9;
-
-       for (i = 0; i < sbio->count; ++i) {
-               struct page *page;
-               int ret;
-
-               page = alloc_page(GFP_NOFS);
-               if (!page)
-                       goto nomem;
-
-               ret = bio_add_page(bio, page, PAGE_SIZE, 0);
-               if (!ret) {
-                       __free_page(page);
-                       goto nomem;
-               }
-       }
-
        sbio->err = 0;
        sdev->curr = -1;
        atomic_inc(&sdev->in_flight);
 
-       submit_bio(READ, bio);
+       submit_bio(READ, sbio->bio);
 
        return 0;
-
-nomem:
-       scrub_free_bio(bio);
-
-       return -ENOMEM;
 }
 
 static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len,
-                     u64 physical, u64 flags, u64 gen, u64 mirror_num,
+                     u64 physical, u64 flags, u64 gen, int mirror_num,
                      u8 *csum, int force)
 {
        struct scrub_bio *sbio;
+       struct page *page;
+       int ret;
 
 again:
        /*
@@ -628,12 +990,22 @@ again:
        }
        sbio = sdev->bios[sdev->curr];
        if (sbio->count == 0) {
+               struct bio *bio;
+
                sbio->physical = physical;
                sbio->logical = logical;
+               bio = bio_alloc(GFP_NOFS, SCRUB_PAGES_PER_BIO);
+               if (!bio)
+                       return -ENOMEM;
+
+               bio->bi_private = sbio;
+               bio->bi_end_io = scrub_bio_end_io;
+               bio->bi_bdev = sdev->dev->bdev;
+               bio->bi_sector = sbio->physical >> 9;
+               sbio->err = 0;
+               sbio->bio = bio;
        } else if (sbio->physical + sbio->count * PAGE_SIZE != physical ||
                   sbio->logical + sbio->count * PAGE_SIZE != logical) {
-               int ret;
-
                ret = scrub_submit(sdev);
                if (ret)
                        return ret;
@@ -643,6 +1015,20 @@ again:
        sbio->spag[sbio->count].generation = gen;
        sbio->spag[sbio->count].have_csum = 0;
        sbio->spag[sbio->count].mirror_num = mirror_num;
+
+       page = alloc_page(GFP_NOFS);
+       if (!page)
+               return -ENOMEM;
+
+       ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0);
+       if (!ret) {
+               __free_page(page);
+               ret = scrub_submit(sdev);
+               if (ret)
+                       return ret;
+               goto again;
+       }
+
        if (csum) {
                sbio->spag[sbio->count].have_csum = 1;
                memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size);
@@ -701,7 +1087,7 @@ static int scrub_find_csum(struct scrub_dev *sdev, u64 logical, u64 len,
 
 /* scrub extent tries to collect up to 64 kB for each bio */
 static int scrub_extent(struct scrub_dev *sdev, u64 logical, u64 len,
-                       u64 physical, u64 flags, u64 gen, u64 mirror_num)
+                       u64 physical, u64 flags, u64 gen, int mirror_num)
 {
        int ret;
        u8 csum[BTRFS_CSUM_SIZE];
@@ -741,13 +1127,16 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev,
        int slot;
        int i;
        u64 nstripes;
-       int start_stripe;
        struct extent_buffer *l;
        struct btrfs_key key;
        u64 physical;
        u64 logical;
        u64 generation;
-       u64 mirror_num;
+       int mirror_num;
+       struct reada_control *reada1;
+       struct reada_control *reada2;
+       struct btrfs_key key_start;
+       struct btrfs_key key_end;
 
        u64 increment = map->stripe_len;
        u64 offset;
@@ -758,102 +1147,88 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev,
        if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
                offset = map->stripe_len * num;
                increment = map->stripe_len * map->num_stripes;
-               mirror_num = 0;
+               mirror_num = 1;
        } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
                int factor = map->num_stripes / map->sub_stripes;
                offset = map->stripe_len * (num / map->sub_stripes);
                increment = map->stripe_len * factor;
-               mirror_num = num % map->sub_stripes;
+               mirror_num = num % map->sub_stripes + 1;
        } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
                increment = map->stripe_len;
-               mirror_num = num % map->num_stripes;
+               mirror_num = num % map->num_stripes + 1;
        } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
                increment = map->stripe_len;
-               mirror_num = num % map->num_stripes;
+               mirror_num = num % map->num_stripes + 1;
        } else {
                increment = map->stripe_len;
-               mirror_num = 0;
+               mirror_num = 1;
        }
 
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
 
-       path->reada = 2;
        path->search_commit_root = 1;
        path->skip_locking = 1;
 
        /*
-        * find all extents for each stripe and just read them to get
-        * them into the page cache
-        * FIXME: we can do better. build a more intelligent prefetching
+        * trigger the readahead for extent tree csum tree and wait for
+        * completion. During readahead, the scrub is officially paused
+        * to not hold off transaction commits
         */
        logical = base + offset;
-       physical = map->stripes[num].physical;
-       ret = 0;
-       for (i = 0; i < nstripes; ++i) {
-               key.objectid = logical;
-               key.type = BTRFS_EXTENT_ITEM_KEY;
-               key.offset = (u64)0;
-
-               ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
-               if (ret < 0)
-                       goto out_noplug;
-
-               /*
-                * we might miss half an extent here, but that doesn't matter,
-                * as it's only the prefetch
-                */
-               while (1) {
-                       l = path->nodes[0];
-                       slot = path->slots[0];
-                       if (slot >= btrfs_header_nritems(l)) {
-                               ret = btrfs_next_leaf(root, path);
-                               if (ret == 0)
-                                       continue;
-                               if (ret < 0)
-                                       goto out_noplug;
 
-                               break;
-                       }
-                       btrfs_item_key_to_cpu(l, &key, slot);
+       wait_event(sdev->list_wait,
+                  atomic_read(&sdev->in_flight) == 0);
+       atomic_inc(&fs_info->scrubs_paused);
+       wake_up(&fs_info->scrub_pause_wait);
 
-                       if (key.objectid >= logical + map->stripe_len)
-                               break;
+       /* FIXME it might be better to start readahead at commit root */
+       key_start.objectid = logical;
+       key_start.type = BTRFS_EXTENT_ITEM_KEY;
+       key_start.offset = (u64)0;
+       key_end.objectid = base + offset + nstripes * increment;
+       key_end.type = BTRFS_EXTENT_ITEM_KEY;
+       key_end.offset = (u64)0;
+       reada1 = btrfs_reada_add(root, &key_start, &key_end);
+
+       key_start.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
+       key_start.type = BTRFS_EXTENT_CSUM_KEY;
+       key_start.offset = logical;
+       key_end.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
+       key_end.type = BTRFS_EXTENT_CSUM_KEY;
+       key_end.offset = base + offset + nstripes * increment;
+       reada2 = btrfs_reada_add(csum_root, &key_start, &key_end);
+
+       if (!IS_ERR(reada1))
+               btrfs_reada_wait(reada1);
+       if (!IS_ERR(reada2))
+               btrfs_reada_wait(reada2);
 
-                       path->slots[0]++;
-               }
-               btrfs_release_path(path);
-               logical += increment;
-               physical += map->stripe_len;
-               cond_resched();
+       mutex_lock(&fs_info->scrub_lock);
+       while (atomic_read(&fs_info->scrub_pause_req)) {
+               mutex_unlock(&fs_info->scrub_lock);
+               wait_event(fs_info->scrub_pause_wait,
+                  atomic_read(&fs_info->scrub_pause_req) == 0);
+               mutex_lock(&fs_info->scrub_lock);
        }
+       atomic_dec(&fs_info->scrubs_paused);
+       mutex_unlock(&fs_info->scrub_lock);
+       wake_up(&fs_info->scrub_pause_wait);
 
        /*
         * collect all data csums for the stripe to avoid seeking during
         * the scrub. This might currently (crc32) end up to be about 1MB
         */
-       start_stripe = 0;
        blk_start_plug(&plug);
-again:
-       logical = base + offset + start_stripe * increment;
-       for (i = start_stripe; i < nstripes; ++i) {
-               ret = btrfs_lookup_csums_range(csum_root, logical,
-                                              logical + map->stripe_len - 1,
-                                              &sdev->csum_list, 1);
-               if (ret)
-                       goto out;
 
-               logical += increment;
-               cond_resched();
-       }
        /*
         * now find all extents for each stripe and scrub them
         */
-       logical = base + offset + start_stripe * increment;
-       physical = map->stripes[num].physical + start_stripe * map->stripe_len;
+       logical = base + offset;
+       physical = map->stripes[num].physical;
        ret = 0;
-       for (i = start_stripe; i < nstripes; ++i) {
+       for (i = 0; i < nstripes; ++i) {
                /*
                 * canceled?
                 */
@@ -882,11 +1257,14 @@ again:
                        atomic_dec(&fs_info->scrubs_paused);
                        mutex_unlock(&fs_info->scrub_lock);
                        wake_up(&fs_info->scrub_pause_wait);
-                       scrub_free_csums(sdev);
-                       start_stripe = i;
-                       goto again;
                }
 
+               ret = btrfs_lookup_csums_range(csum_root, logical,
+                                              logical + map->stripe_len - 1,
+                                              &sdev->csum_list, 1);
+               if (ret)
+                       goto out;
+
                key.objectid = logical;
                key.type = BTRFS_EXTENT_ITEM_KEY;
                key.offset = (u64)0;
@@ -982,7 +1360,6 @@ next:
 
 out:
        blk_finish_plug(&plug);
-out_noplug:
        btrfs_free_path(path);
        return ret < 0 ? ret : 0;
 }
@@ -1253,10 +1630,11 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end,
                ret = scrub_enumerate_chunks(sdev, start, end);
 
        wait_event(sdev->list_wait, atomic_read(&sdev->in_flight) == 0);
-
        atomic_dec(&fs_info->scrubs_running);
        wake_up(&fs_info->scrub_pause_wait);
 
+       wait_event(sdev->list_wait, atomic_read(&sdev->fixup_cnt) == 0);
+
        if (progress)
                memcpy(progress, &sdev->stat, sizeof(*progress));
 
index 15634d4648d719922bc36313657c31b60066973c..e28ad4baf483af6b4c7e5d8450dc4a73909d0247 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/magic.h>
 #include <linux/slab.h>
 #include <linux/cleancache.h>
+#include <linux/mnt_namespace.h>
 #include "compat.h"
 #include "delayed-inode.h"
 #include "ctree.h"
@@ -58,6 +59,7 @@
 #include <trace/events/btrfs.h>
 
 static const struct super_operations btrfs_super_ops;
+static struct file_system_type btrfs_fs_type;
 
 static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno,
                                      char nbuf[16])
@@ -162,7 +164,7 @@ enum {
        Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
        Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
        Opt_enospc_debug, Opt_subvolrootid, Opt_defrag,
-       Opt_inode_cache, Opt_err,
+       Opt_inode_cache, Opt_no_space_cache, Opt_recovery, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -195,6 +197,8 @@ static match_table_t tokens = {
        {Opt_subvolrootid, "subvolrootid=%d"},
        {Opt_defrag, "autodefrag"},
        {Opt_inode_cache, "inode_cache"},
+       {Opt_no_space_cache, "nospace_cache"},
+       {Opt_recovery, "recovery"},
        {Opt_err, NULL},
 };
 
@@ -206,14 +210,19 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
 {
        struct btrfs_fs_info *info = root->fs_info;
        substring_t args[MAX_OPT_ARGS];
-       char *p, *num, *orig;
+       char *p, *num, *orig = NULL;
+       u64 cache_gen;
        int intarg;
        int ret = 0;
        char *compress_type;
        bool compress_force = false;
 
+       cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
+       if (cache_gen)
+               btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+
        if (!options)
-               return 0;
+               goto out;
 
        /*
         * strsep changes the string, duplicate it because parse_options
@@ -360,9 +369,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        btrfs_set_opt(info->mount_opt, DISCARD);
                        break;
                case Opt_space_cache:
-                       printk(KERN_INFO "btrfs: enabling disk space caching\n");
                        btrfs_set_opt(info->mount_opt, SPACE_CACHE);
                        break;
+               case Opt_no_space_cache:
+                       printk(KERN_INFO "btrfs: disabling disk space caching\n");
+                       btrfs_clear_opt(info->mount_opt, SPACE_CACHE);
+                       break;
                case Opt_inode_cache:
                        printk(KERN_INFO "btrfs: enabling inode map caching\n");
                        btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE);
@@ -381,6 +393,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        printk(KERN_INFO "btrfs: enabling auto defrag");
                        btrfs_set_opt(info->mount_opt, AUTO_DEFRAG);
                        break;
+               case Opt_recovery:
+                       printk(KERN_INFO "btrfs: enabling auto recovery");
+                       btrfs_set_opt(info->mount_opt, RECOVERY);
+                       break;
                case Opt_err:
                        printk(KERN_INFO "btrfs: unrecognized mount option "
                               "'%s'\n", p);
@@ -391,6 +407,8 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                }
        }
 out:
+       if (!ret && btrfs_test_opt(root, SPACE_CACHE))
+               printk(KERN_INFO "btrfs: disk space caching is enabled\n");
        kfree(orig);
        return ret;
 }
@@ -406,12 +424,12 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
                u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices)
 {
        substring_t args[MAX_OPT_ARGS];
-       char *opts, *orig, *p;
+       char *device_name, *opts, *orig, *p;
        int error = 0;
        int intarg;
 
        if (!options)
-               goto out;
+               return 0;
 
        /*
         * strsep changes the string, duplicate it because parse_options
@@ -430,6 +448,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
                token = match_token(p, tokens, args);
                switch (token) {
                case Opt_subvol:
+                       kfree(*subvol_name);
                        *subvol_name = match_strdup(&args[0]);
                        break;
                case Opt_subvolid:
@@ -457,29 +476,24 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
                        }
                        break;
                case Opt_device:
-                       error = btrfs_scan_one_device(match_strdup(&args[0]),
+                       device_name = match_strdup(&args[0]);
+                       if (!device_name) {
+                               error = -ENOMEM;
+                               goto out;
+                       }
+                       error = btrfs_scan_one_device(device_name,
                                        flags, holder, fs_devices);
+                       kfree(device_name);
                        if (error)
-                               goto out_free_opts;
+                               goto out;
                        break;
                default:
                        break;
                }
        }
 
- out_free_opts:
+out:
        kfree(orig);
- out:
-       /*
-        * If no subvolume name is specified we use the default one.  Allocate
-        * a copy of the string "." here so that code later in the
-        * mount path doesn't care if it's the default volume or another one.
-        */
-       if (!*subvol_name) {
-               *subvol_name = kstrdup(".", GFP_KERNEL);
-               if (!*subvol_name)
-                       return -ENOMEM;
-       }
        return error;
 }
 
@@ -492,7 +506,6 @@ static struct dentry *get_default_root(struct super_block *sb,
        struct btrfs_path *path;
        struct btrfs_key location;
        struct inode *inode;
-       struct dentry *dentry;
        u64 dir_id;
        int new = 0;
 
@@ -517,7 +530,7 @@ static struct dentry *get_default_root(struct super_block *sb,
         * will mount by default if we haven't been given a specific subvolume
         * to mount.
         */
-       dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
+       dir_id = btrfs_super_root_dir(root->fs_info->super_copy);
        di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
        if (IS_ERR(di)) {
                btrfs_free_path(path);
@@ -566,29 +579,7 @@ setup_root:
                return dget(sb->s_root);
        }
 
-       if (new) {
-               const struct qstr name = { .name = "/", .len = 1 };
-
-               /*
-                * New inode, we need to make the dentry a sibling of s_root so
-                * everything gets cleaned up properly on unmount.
-                */
-               dentry = d_alloc(sb->s_root, &name);
-               if (!dentry) {
-                       iput(inode);
-                       return ERR_PTR(-ENOMEM);
-               }
-               d_splice_alias(inode, dentry);
-       } else {
-               /*
-                * We found the inode in cache, just find a dentry for it and
-                * put the reference to the inode we just got.
-                */
-               dentry = d_find_alias(inode);
-               iput(inode);
-       }
-
-       return dentry;
+       return d_obtain_alias(inode);
 }
 
 static int btrfs_fill_super(struct super_block *sb,
@@ -719,6 +710,8 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
                seq_puts(seq, ",noacl");
        if (btrfs_test_opt(root, SPACE_CACHE))
                seq_puts(seq, ",space_cache");
+       else
+               seq_puts(seq, ",nospace_cache");
        if (btrfs_test_opt(root, CLEAR_CACHE))
                seq_puts(seq, ",clear_cache");
        if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
@@ -753,6 +746,111 @@ static int btrfs_set_super(struct super_block *s, void *data)
        return set_anon_super(s, data);
 }
 
+/*
+ * subvolumes are identified by ino 256
+ */
+static inline int is_subvolume_inode(struct inode *inode)
+{
+       if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
+               return 1;
+       return 0;
+}
+
+/*
+ * This will strip out the subvol=%s argument for an argument string and add
+ * subvolid=0 to make sure we get the actual tree root for path walking to the
+ * subvol we want.
+ */
+static char *setup_root_args(char *args)
+{
+       unsigned copied = 0;
+       unsigned len = strlen(args) + 2;
+       char *pos;
+       char *ret;
+
+       /*
+        * We need the same args as before, but minus
+        *
+        * subvol=a
+        *
+        * and add
+        *
+        * subvolid=0
+        *
+        * which is a difference of 2 characters, so we allocate strlen(args) +
+        * 2 characters.
+        */
+       ret = kzalloc(len * sizeof(char), GFP_NOFS);
+       if (!ret)
+               return NULL;
+       pos = strstr(args, "subvol=");
+
+       /* This shouldn't happen, but just in case.. */
+       if (!pos) {
+               kfree(ret);
+               return NULL;
+       }
+
+       /*
+        * The subvol=<> arg is not at the front of the string, copy everybody
+        * up to that into ret.
+        */
+       if (pos != args) {
+               *pos = '\0';
+               strcpy(ret, args);
+               copied += strlen(args);
+               pos++;
+       }
+
+       strncpy(ret + copied, "subvolid=0", len - copied);
+
+       /* Length of subvolid=0 */
+       copied += 10;
+
+       /*
+        * If there is no , after the subvol= option then we know there's no
+        * other options and we can just return.
+        */
+       pos = strchr(pos, ',');
+       if (!pos)
+               return ret;
+
+       /* Copy the rest of the arguments into our buffer */
+       strncpy(ret + copied, pos, len - copied);
+       copied += strlen(pos);
+
+       return ret;
+}
+
+static struct dentry *mount_subvol(const char *subvol_name, int flags,
+                                  const char *device_name, char *data)
+{
+       struct dentry *root;
+       struct vfsmount *mnt;
+       char *newargs;
+
+       newargs = setup_root_args(data);
+       if (!newargs)
+               return ERR_PTR(-ENOMEM);
+       mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name,
+                            newargs);
+       kfree(newargs);
+       if (IS_ERR(mnt))
+               return ERR_CAST(mnt);
+
+       root = mount_subtree(mnt, subvol_name);
+
+       if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) {
+               struct super_block *s = root->d_sb;
+               dput(root);
+               root = ERR_PTR(-EINVAL);
+               deactivate_locked_super(s);
+               printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n",
+                               subvol_name);
+       }
+
+       return root;
+}
 
 /*
  * Find a superblock for the given device / mount point.
@@ -767,7 +865,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
        struct super_block *s;
        struct dentry *root;
        struct btrfs_fs_devices *fs_devices = NULL;
-       struct btrfs_root *tree_root = NULL;
        struct btrfs_fs_info *fs_info = NULL;
        fmode_t mode = FMODE_READ;
        char *subvol_name = NULL;
@@ -781,21 +878,20 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
        error = btrfs_parse_early_options(data, mode, fs_type,
                                          &subvol_name, &subvol_objectid,
                                          &subvol_rootid, &fs_devices);
-       if (error)
+       if (error) {
+               kfree(subvol_name);
                return ERR_PTR(error);
+       }
 
-       error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices);
-       if (error)
-               goto error_free_subvol_name;
+       if (subvol_name) {
+               root = mount_subvol(subvol_name, flags, device_name, data);
+               kfree(subvol_name);
+               return root;
+       }
 
-       error = btrfs_open_devices(fs_devices, mode, fs_type);
+       error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices);
        if (error)
-               goto error_free_subvol_name;
-
-       if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
-               error = -EACCES;
-               goto error_close_devices;
-       }
+               return ERR_PTR(error);
 
        /*
         * Setup a dummy root and fs_info for test/set super.  This is because
@@ -804,19 +900,40 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
         * then open_ctree will properly initialize everything later.
         */
        fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
-       tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
-       if (!fs_info || !tree_root) {
+       if (!fs_info)
+               return ERR_PTR(-ENOMEM);
+
+       fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
+       if (!fs_info->tree_root) {
                error = -ENOMEM;
-               goto error_close_devices;
+               goto error_fs_info;
        }
-       fs_info->tree_root = tree_root;
+       fs_info->tree_root->fs_info = fs_info;
        fs_info->fs_devices = fs_devices;
-       tree_root->fs_info = fs_info;
+
+       fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
+       fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS);
+       if (!fs_info->super_copy || !fs_info->super_for_commit) {
+               error = -ENOMEM;
+               goto error_fs_info;
+       }
+
+       error = btrfs_open_devices(fs_devices, mode, fs_type);
+       if (error)
+               goto error_fs_info;
+
+       if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
+               error = -EACCES;
+               goto error_close_devices;
+       }
 
        bdev = fs_devices->latest_bdev;
-       s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
-       if (IS_ERR(s))
-               goto error_s;
+       s = sget(fs_type, btrfs_test_super, btrfs_set_super,
+                fs_info->tree_root);
+       if (IS_ERR(s)) {
+               error = PTR_ERR(s);
+               goto error_close_devices;
+       }
 
        if (s->s_root) {
                if ((flags ^ s->s_flags) & MS_RDONLY) {
@@ -826,75 +943,35 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                }
 
                btrfs_close_devices(fs_devices);
-               kfree(fs_info);
-               kfree(tree_root);
+               free_fs_info(fs_info);
        } else {
                char b[BDEVNAME_SIZE];
 
                s->s_flags = flags | MS_NOSEC;
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               btrfs_sb(s)->fs_info->bdev_holder = fs_type;
                error = btrfs_fill_super(s, fs_devices, data,
                                         flags & MS_SILENT ? 1 : 0);
                if (error) {
                        deactivate_locked_super(s);
-                       goto error_free_subvol_name;
+                       return ERR_PTR(error);
                }
 
-               btrfs_sb(s)->fs_info->bdev_holder = fs_type;
                s->s_flags |= MS_ACTIVE;
        }
 
-       /* if they gave us a subvolume name bind mount into that */
-       if (strcmp(subvol_name, ".")) {
-               struct dentry *new_root;
-
-               root = get_default_root(s, subvol_rootid);
-               if (IS_ERR(root)) {
-                       error = PTR_ERR(root);
-                       deactivate_locked_super(s);
-                       goto error_free_subvol_name;
-               }
-
-               mutex_lock(&root->d_inode->i_mutex);
-               new_root = lookup_one_len(subvol_name, root,
-                                     strlen(subvol_name));
-               mutex_unlock(&root->d_inode->i_mutex);
-
-               if (IS_ERR(new_root)) {
-                       dput(root);
-                       deactivate_locked_super(s);
-                       error = PTR_ERR(new_root);
-                       goto error_free_subvol_name;
-               }
-               if (!new_root->d_inode) {
-                       dput(root);
-                       dput(new_root);
-                       deactivate_locked_super(s);
-                       error = -ENXIO;
-                       goto error_free_subvol_name;
-               }
-               dput(root);
-               root = new_root;
-       } else {
-               root = get_default_root(s, subvol_objectid);
-               if (IS_ERR(root)) {
-                       error = PTR_ERR(root);
-                       deactivate_locked_super(s);
-                       goto error_free_subvol_name;
-               }
+       root = get_default_root(s, subvol_objectid);
+       if (IS_ERR(root)) {
+               deactivate_locked_super(s);
+               return root;
        }
 
-       kfree(subvol_name);
        return root;
 
-error_s:
-       error = PTR_ERR(s);
 error_close_devices:
        btrfs_close_devices(fs_devices);
-       kfree(fs_info);
-       kfree(tree_root);
-error_free_subvol_name:
-       kfree(subvol_name);
+error_fs_info:
+       free_fs_info(fs_info);
        return ERR_PTR(error);
 }
 
@@ -919,7 +996,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                if (root->fs_info->fs_devices->rw_devices == 0)
                        return -EACCES;
 
-               if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
+               if (btrfs_super_log_root(root->fs_info->super_copy) != 0)
                        return -EINVAL;
 
                ret = btrfs_cleanup_fs_roots(root->fs_info);
@@ -980,7 +1057,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
        int i = 0, nr_devices;
        int ret;
 
-       nr_devices = fs_info->fs_devices->rw_devices;
+       nr_devices = fs_info->fs_devices->open_devices;
        BUG_ON(!nr_devices);
 
        devices_info = kmalloc(sizeof(*devices_info) * nr_devices,
@@ -1002,8 +1079,8 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
        else
                min_stripe_size = BTRFS_STRIPE_LEN;
 
-       list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
-               if (!device->in_fs_metadata)
+       list_for_each_entry(device, &fs_devices->devices, dev_list) {
+               if (!device->in_fs_metadata || !device->bdev)
                        continue;
 
                avail_space = device->total_bytes - device->bytes_used;
@@ -1085,7 +1162,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
 static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct btrfs_root *root = btrfs_sb(dentry->d_sb);
-       struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+       struct btrfs_super_block *disk_super = root->fs_info->super_copy;
        struct list_head *head = &root->fs_info->space_info;
        struct btrfs_space_info *found;
        u64 total_used = 0;
index e24b7964a15502b2ff0f6325f4a2b98c226b6688..81376d94cd3c6a4639ebef35df501dbefbfb2435 100644 (file)
@@ -55,6 +55,7 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail)
        struct btrfs_transaction *cur_trans;
 
        spin_lock(&root->fs_info->trans_lock);
+loop:
        if (root->fs_info->trans_no_join) {
                if (!nofail) {
                        spin_unlock(&root->fs_info->trans_lock);
@@ -75,16 +76,18 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail)
        cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
        if (!cur_trans)
                return -ENOMEM;
+
        spin_lock(&root->fs_info->trans_lock);
        if (root->fs_info->running_transaction) {
+               /*
+                * someone started a transaction after we unlocked.  Make sure
+                * to redo the trans_no_join checks above
+                */
                kmem_cache_free(btrfs_transaction_cachep, cur_trans);
                cur_trans = root->fs_info->running_transaction;
-               atomic_inc(&cur_trans->use_count);
-               atomic_inc(&cur_trans->num_writers);
-               cur_trans->num_joined++;
-               spin_unlock(&root->fs_info->trans_lock);
-               return 0;
+               goto loop;
        }
+
        atomic_set(&cur_trans->num_writers, 1);
        cur_trans->num_joined = 0;
        init_waitqueue_head(&cur_trans->writer_wait);
@@ -275,7 +278,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
         */
        if (num_items > 0 && root != root->fs_info->chunk_root) {
                num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
-               ret = btrfs_block_rsv_add(NULL, root,
+               ret = btrfs_block_rsv_add(root,
                                          &root->fs_info->trans_block_rsv,
                                          num_bytes);
                if (ret)
@@ -418,8 +421,8 @@ static int should_end_transaction(struct btrfs_trans_handle *trans,
                                  struct btrfs_root *root)
 {
        int ret;
-       ret = btrfs_block_rsv_check(trans, root,
-                                   &root->fs_info->global_block_rsv, 0, 5);
+
+       ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5);
        return ret ? 1 : 0;
 }
 
@@ -427,17 +430,26 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *root)
 {
        struct btrfs_transaction *cur_trans = trans->transaction;
+       struct btrfs_block_rsv *rsv = trans->block_rsv;
        int updates;
 
        smp_mb();
        if (cur_trans->blocked || cur_trans->delayed_refs.flushing)
                return 1;
 
+       /*
+        * We need to do this in case we're deleting csums so the global block
+        * rsv get's used instead of the csum block rsv.
+        */
+       trans->block_rsv = NULL;
+
        updates = trans->delayed_ref_updates;
        trans->delayed_ref_updates = 0;
        if (updates)
                btrfs_run_delayed_refs(trans, root, updates);
 
+       trans->block_rsv = rsv;
+
        return should_end_transaction(trans, root);
 }
 
@@ -453,6 +465,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
                return 0;
        }
 
+       btrfs_trans_release_metadata(trans, root);
+       trans->block_rsv = NULL;
        while (count < 4) {
                unsigned long cur = trans->delayed_ref_updates;
                trans->delayed_ref_updates = 0;
@@ -473,8 +487,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
                count++;
        }
 
-       btrfs_trans_release_metadata(trans, root);
-
        if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
            should_end_transaction(trans, root)) {
                trans->transaction->blocked = 1;
@@ -562,50 +574,21 @@ int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans,
 int btrfs_write_marked_extents(struct btrfs_root *root,
                               struct extent_io_tree *dirty_pages, int mark)
 {
-       int ret;
        int err = 0;
        int werr = 0;
-       struct page *page;
-       struct inode *btree_inode = root->fs_info->btree_inode;
+       struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
        u64 start = 0;
        u64 end;
-       unsigned long index;
-
-       while (1) {
-               ret = find_first_extent_bit(dirty_pages, start, &start, &end,
-                                           mark);
-               if (ret)
-                       break;
-               while (start <= end) {
-                       cond_resched();
-
-                       index = start >> PAGE_CACHE_SHIFT;
-                       start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
-                       page = find_get_page(btree_inode->i_mapping, index);
-                       if (!page)
-                               continue;
-
-                       btree_lock_page_hook(page);
-                       if (!page->mapping) {
-                               unlock_page(page);
-                               page_cache_release(page);
-                               continue;
-                       }
 
-                       if (PageWriteback(page)) {
-                               if (PageDirty(page))
-                                       wait_on_page_writeback(page);
-                               else {
-                                       unlock_page(page);
-                                       page_cache_release(page);
-                                       continue;
-                               }
-                       }
-                       err = write_one_page(page, 0);
-                       if (err)
-                               werr = err;
-                       page_cache_release(page);
-               }
+       while (!find_first_extent_bit(dirty_pages, start, &start, &end,
+                                     mark)) {
+               convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, mark,
+                                  GFP_NOFS);
+               err = filemap_fdatawrite_range(mapping, start, end);
+               if (err)
+                       werr = err;
+               cond_resched();
+               start = end + 1;
        }
        if (err)
                werr = err;
@@ -621,39 +604,20 @@ int btrfs_write_marked_extents(struct btrfs_root *root,
 int btrfs_wait_marked_extents(struct btrfs_root *root,
                              struct extent_io_tree *dirty_pages, int mark)
 {
-       int ret;
        int err = 0;
        int werr = 0;
-       struct page *page;
-       struct inode *btree_inode = root->fs_info->btree_inode;
+       struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
        u64 start = 0;
        u64 end;
-       unsigned long index;
 
-       while (1) {
-               ret = find_first_extent_bit(dirty_pages, start, &start, &end,
-                                           mark);
-               if (ret)
-                       break;
-
-               clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS);
-               while (start <= end) {
-                       index = start >> PAGE_CACHE_SHIFT;
-                       start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
-                       page = find_get_page(btree_inode->i_mapping, index);
-                       if (!page)
-                               continue;
-                       if (PageDirty(page)) {
-                               btree_lock_page_hook(page);
-                               wait_on_page_writeback(page);
-                               err = write_one_page(page, 0);
-                               if (err)
-                                       werr = err;
-                       }
-                       wait_on_page_writeback(page);
-                       page_cache_release(page);
-                       cond_resched();
-               }
+       while (!find_first_extent_bit(dirty_pages, start, &start, &end,
+                                     EXTENT_NEED_WAIT)) {
+               clear_extent_bits(dirty_pages, start, end, EXTENT_NEED_WAIT, GFP_NOFS);
+               err = filemap_fdatawait_range(mapping, start, end);
+               if (err)
+                       werr = err;
+               cond_resched();
+               start = end + 1;
        }
        if (err)
                werr = err;
@@ -673,7 +637,12 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
 
        ret = btrfs_write_marked_extents(root, dirty_pages, mark);
        ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
-       return ret || ret2;
+
+       if (ret)
+               return ret;
+       if (ret2)
+               return ret2;
+       return 0;
 }
 
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
@@ -816,6 +785,10 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
 
                        btrfs_save_ino_cache(root, trans);
 
+                       /* see comments in should_cow_block() */
+                       root->force_cow = 0;
+                       smp_wmb();
+
                        if (root->commit_root != root->node) {
                                mutex_lock(&root->fs_commit_mutex);
                                switch_commit_root(root);
@@ -911,11 +884,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        }
 
        btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
-       btrfs_orphan_pre_snapshot(trans, pending, &to_reserve);
 
        if (to_reserve > 0) {
-               ret = btrfs_block_rsv_add(trans, root, &pending->block_rsv,
-                                         to_reserve);
+               ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv,
+                                                 to_reserve);
                if (ret) {
                        pending->error = ret;
                        goto fail;
@@ -979,6 +951,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        btrfs_tree_unlock(old);
        free_extent_buffer(old);
 
+       /* see comments in should_cow_block() */
+       root->force_cow = 1;
+       smp_wmb();
+
        btrfs_set_root_node(new_root_item, tmp);
        /* record when the snapshot was created in key.offset */
        key.offset = trans->transid;
@@ -1002,7 +978,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        BUG_ON(IS_ERR(pending->snap));
 
        btrfs_reloc_post_snapshot(trans, pending);
-       btrfs_orphan_post_snapshot(trans, pending);
 fail:
        kfree(new_root_item);
        trans->block_rsv = rsv;
@@ -1032,7 +1007,7 @@ static void update_super_roots(struct btrfs_root *root)
        struct btrfs_root_item *root_item;
        struct btrfs_super_block *super;
 
-       super = &root->fs_info->super_copy;
+       super = root->fs_info->super_copy;
 
        root_item = &root->fs_info->chunk_root->root_item;
        super->chunk_root = root_item->bytenr;
@@ -1043,7 +1018,7 @@ static void update_super_roots(struct btrfs_root *root)
        super->root = root_item->bytenr;
        super->generation = root_item->generation;
        super->root_level = root_item->level;
-       if (super->cache_generation != 0 || btrfs_test_opt(root, SPACE_CACHE))
+       if (btrfs_test_opt(root, SPACE_CACHE))
                super->cache_generation = root_item->generation;
 }
 
@@ -1168,14 +1143,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_run_ordered_operations(root, 0);
 
+       btrfs_trans_release_metadata(trans, root);
+       trans->block_rsv = NULL;
+
        /* make a pass through all the delayed refs we have so far
         * any runnings procs may add more while we are here
         */
        ret = btrfs_run_delayed_refs(trans, root, 0);
        BUG_ON(ret);
 
-       btrfs_trans_release_metadata(trans, root);
-
        cur_trans = trans->transaction;
        /*
         * set the flushing flag so procs in this transaction have to
@@ -1341,12 +1317,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        update_super_roots(root);
 
        if (!root->fs_info->log_root_recovering) {
-               btrfs_set_super_log_root(&root->fs_info->super_copy, 0);
-               btrfs_set_super_log_root_level(&root->fs_info->super_copy, 0);
+               btrfs_set_super_log_root(root->fs_info->super_copy, 0);
+               btrfs_set_super_log_root_level(root->fs_info->super_copy, 0);
        }
 
-       memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy,
-              sizeof(root->fs_info->super_copy));
+       memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy,
+              sizeof(*root->fs_info->super_copy));
 
        trans->transaction->blocked = 0;
        spin_lock(&root->fs_info->trans_lock);
index 0618aa39740b35cc7cb1620e5c1cf034c18a5400..3568374d419da8ee50eb17f4af5319964750614d 100644 (file)
@@ -276,8 +276,9 @@ static int process_one_buffer(struct btrfs_root *log,
                              struct walk_control *wc, u64 gen)
 {
        if (wc->pin)
-               btrfs_pin_extent(log->fs_info->extent_root,
-                                eb->start, eb->len, 0);
+               btrfs_pin_extent_for_log_replay(wc->trans,
+                                               log->fs_info->extent_root,
+                                               eb->start, eb->len);
 
        if (btrfs_buffer_uptodate(eb, gen)) {
                if (wc->write)
@@ -1760,7 +1761,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 
                                WARN_ON(root_owner !=
                                        BTRFS_TREE_LOG_OBJECTID);
-                               ret = btrfs_free_reserved_extent(root,
+                               ret = btrfs_free_and_pin_reserved_extent(root,
                                                         bytenr, blocksize);
                                BUG_ON(ret);
                        }
@@ -1828,7 +1829,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                                btrfs_tree_unlock(next);
 
                                WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
-                               ret = btrfs_free_reserved_extent(root,
+                               ret = btrfs_free_and_pin_reserved_extent(root,
                                                path->nodes[*level]->start,
                                                path->nodes[*level]->len);
                                BUG_ON(ret);
@@ -1897,7 +1898,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
 
                        WARN_ON(log->root_key.objectid !=
                                BTRFS_TREE_LOG_OBJECTID);
-                       ret = btrfs_free_reserved_extent(log, next->start,
+                       ret = btrfs_free_and_pin_reserved_extent(log, next->start,
                                                         next->len);
                        BUG_ON(ret);
                }
@@ -2013,10 +2014,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        /* wait for previous tree log sync to complete */
        if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
                wait_log_commit(trans, root, root->log_transid - 1);
-
        while (1) {
                unsigned long batch = root->log_batch;
-               if (root->log_multiple_pids) {
+               /* when we're on an ssd, just kick the log commit out */
+               if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) {
                        mutex_unlock(&root->log_mutex);
                        schedule_timeout_uninterruptible(1);
                        mutex_lock(&root->log_mutex);
@@ -2117,9 +2118,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
        BUG_ON(ret);
        btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
 
-       btrfs_set_super_log_root(&root->fs_info->super_for_commit,
+       btrfs_set_super_log_root(root->fs_info->super_for_commit,
                                log_root_tree->node->start);
-       btrfs_set_super_log_root_level(&root->fs_info->super_for_commit,
+       btrfs_set_super_log_root_level(root->fs_info->super_for_commit,
                                btrfs_header_level(log_root_tree->node));
 
        log_root_tree->log_batch = 0;
index f2a4cc79da61da62740d1de33552037f27b072a2..0a8c8f8304b14c3d9190926eeee3dfa5e3d59d33 100644 (file)
@@ -366,6 +366,14 @@ static noinline int device_list_add(const char *path,
                }
                INIT_LIST_HEAD(&device->dev_alloc_list);
 
+               /* init readahead state */
+               spin_lock_init(&device->reada_lock);
+               device->reada_curr_zone = NULL;
+               atomic_set(&device->reada_in_flight, 0);
+               device->reada_next = 0;
+               INIT_RADIX_TREE(&device->reada_zones, GFP_NOFS & ~__GFP_WAIT);
+               INIT_RADIX_TREE(&device->reada_extents, GFP_NOFS & ~__GFP_WAIT);
+
                mutex_lock(&fs_devices->device_list_mutex);
                list_add_rcu(&device->dev_list, &fs_devices->devices);
                mutex_unlock(&fs_devices->device_list_mutex);
@@ -597,10 +605,8 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                set_blocksize(bdev, 4096);
 
                bh = btrfs_read_dev_super(bdev);
-               if (!bh) {
-                       ret = -EINVAL;
+               if (!bh)
                        goto error_close;
-               }
 
                disk_super = (struct btrfs_super_block *)bh->b_data;
                devid = btrfs_stack_device_id(&disk_super->dev_item);
@@ -655,7 +661,7 @@ error:
                continue;
        }
        if (fs_devices->open_devices == 0) {
-               ret = -EIO;
+               ret = -EINVAL;
                goto out;
        }
        fs_devices->seeding = seeding;
@@ -993,7 +999,7 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
        key.objectid = device->devid;
        key.offset = start;
        key.type = BTRFS_DEV_EXTENT_KEY;
-
+again:
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
        if (ret > 0) {
                ret = btrfs_previous_item(root, path, key.objectid,
@@ -1006,6 +1012,9 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
                                        struct btrfs_dev_extent);
                BUG_ON(found_key.offset > start || found_key.offset +
                       btrfs_dev_extent_length(leaf, extent) < start);
+               key = found_key;
+               btrfs_release_path(path);
+               goto again;
        } else if (ret == 0) {
                leaf = path->nodes[0];
                extent = btrfs_item_ptr(leaf, path->slots[0],
@@ -1013,8 +1022,13 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
        }
        BUG_ON(ret);
 
-       if (device->bytes_used > 0)
-               device->bytes_used -= btrfs_dev_extent_length(leaf, extent);
+       if (device->bytes_used > 0) {
+               u64 len = btrfs_dev_extent_length(leaf, extent);
+               device->bytes_used -= len;
+               spin_lock(&root->fs_info->free_chunk_lock);
+               root->fs_info->free_chunk_space += len;
+               spin_unlock(&root->fs_info->free_chunk_lock);
+       }
        ret = btrfs_del_item(trans, root, path);
 
 out:
@@ -1356,6 +1370,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
        if (ret)
                goto error_undo;
 
+       spin_lock(&root->fs_info->free_chunk_lock);
+       root->fs_info->free_chunk_space = device->total_bytes -
+               device->bytes_used;
+       spin_unlock(&root->fs_info->free_chunk_lock);
+
        device->in_fs_metadata = 0;
        btrfs_scrub_cancel_dev(root, device);
 
@@ -1387,8 +1406,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
        call_rcu(&device->rcu, free_device);
        mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
 
-       num_devices = btrfs_super_num_devices(&root->fs_info->super_copy) - 1;
-       btrfs_set_super_num_devices(&root->fs_info->super_copy, num_devices);
+       num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
+       btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices);
 
        if (cur_devices->open_devices == 0) {
                struct btrfs_fs_devices *fs_devices;
@@ -1450,7 +1469,7 @@ static int btrfs_prepare_sprout(struct btrfs_trans_handle *trans,
        struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
        struct btrfs_fs_devices *old_devices;
        struct btrfs_fs_devices *seed_devices;
-       struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+       struct btrfs_super_block *disk_super = root->fs_info->super_copy;
        struct btrfs_device *device;
        u64 super_flags;
 
@@ -1592,7 +1611,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
        if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding)
                return -EINVAL;
 
-       bdev = blkdev_get_by_path(device_path, FMODE_EXCL,
+       bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL,
                                  root->fs_info->bdev_holder);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
@@ -1691,15 +1710,19 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
                root->fs_info->fs_devices->num_can_discard++;
        root->fs_info->fs_devices->total_rw_bytes += device->total_bytes;
 
+       spin_lock(&root->fs_info->free_chunk_lock);
+       root->fs_info->free_chunk_space += device->total_bytes;
+       spin_unlock(&root->fs_info->free_chunk_lock);
+
        if (!blk_queue_nonrot(bdev_get_queue(bdev)))
                root->fs_info->fs_devices->rotating = 1;
 
-       total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
-       btrfs_set_super_total_bytes(&root->fs_info->super_copy,
+       total_bytes = btrfs_super_total_bytes(root->fs_info->super_copy);
+       btrfs_set_super_total_bytes(root->fs_info->super_copy,
                                    total_bytes + device->total_bytes);
 
-       total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy);
-       btrfs_set_super_num_devices(&root->fs_info->super_copy,
+       total_bytes = btrfs_super_num_devices(root->fs_info->super_copy);
+       btrfs_set_super_num_devices(root->fs_info->super_copy,
                                    total_bytes + 1);
        mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
 
@@ -1790,7 +1813,7 @@ static int __btrfs_grow_device(struct btrfs_trans_handle *trans,
                      struct btrfs_device *device, u64 new_size)
 {
        struct btrfs_super_block *super_copy =
-               &device->dev_root->fs_info->super_copy;
+               device->dev_root->fs_info->super_copy;
        u64 old_total = btrfs_super_total_bytes(super_copy);
        u64 diff = new_size - device->total_bytes;
 
@@ -1849,7 +1872,7 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
 static int btrfs_del_sys_chunk(struct btrfs_root *root, u64 chunk_objectid, u64
                        chunk_offset)
 {
-       struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
+       struct btrfs_super_block *super_copy = root->fs_info->super_copy;
        struct btrfs_disk_key *disk_key;
        struct btrfs_chunk *chunk;
        u8 *ptr;
@@ -2175,7 +2198,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
        bool retried = false;
        struct extent_buffer *l;
        struct btrfs_key key;
-       struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
+       struct btrfs_super_block *super_copy = root->fs_info->super_copy;
        u64 old_total = btrfs_super_total_bytes(super_copy);
        u64 old_size = device->total_bytes;
        u64 diff = device->total_bytes - new_size;
@@ -2192,8 +2215,12 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
        lock_chunks(root);
 
        device->total_bytes = new_size;
-       if (device->writeable)
+       if (device->writeable) {
                device->fs_devices->total_rw_bytes -= diff;
+               spin_lock(&root->fs_info->free_chunk_lock);
+               root->fs_info->free_chunk_space -= diff;
+               spin_unlock(&root->fs_info->free_chunk_lock);
+       }
        unlock_chunks(root);
 
 again:
@@ -2257,6 +2284,9 @@ again:
                device->total_bytes = old_size;
                if (device->writeable)
                        device->fs_devices->total_rw_bytes += diff;
+               spin_lock(&root->fs_info->free_chunk_lock);
+               root->fs_info->free_chunk_space += diff;
+               spin_unlock(&root->fs_info->free_chunk_lock);
                unlock_chunks(root);
                goto done;
        }
@@ -2292,7 +2322,7 @@ static int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
                           struct btrfs_key *key,
                           struct btrfs_chunk *chunk, int item_size)
 {
-       struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
+       struct btrfs_super_block *super_copy = root->fs_info->super_copy;
        struct btrfs_disk_key disk_key;
        u32 array_size;
        u8 *ptr;
@@ -2615,6 +2645,11 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans,
                index++;
        }
 
+       spin_lock(&extent_root->fs_info->free_chunk_lock);
+       extent_root->fs_info->free_chunk_space -= (stripe_size *
+                                                  map->num_stripes);
+       spin_unlock(&extent_root->fs_info->free_chunk_lock);
+
        index = 0;
        stripe = &chunk->stripe;
        while (index < map->num_stripes) {
@@ -2848,7 +2883,7 @@ static int find_live_mirror(struct map_lookup *map, int first, int num,
 
 static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                             u64 logical, u64 *length,
-                            struct btrfs_multi_bio **multi_ret,
+                            struct btrfs_bio **bbio_ret,
                             int mirror_num)
 {
        struct extent_map *em;
@@ -2866,18 +2901,18 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
        int i;
        int num_stripes;
        int max_errors = 0;
-       struct btrfs_multi_bio *multi = NULL;
+       struct btrfs_bio *bbio = NULL;
 
-       if (multi_ret && !(rw & (REQ_WRITE | REQ_DISCARD)))
+       if (bbio_ret && !(rw & (REQ_WRITE | REQ_DISCARD)))
                stripes_allocated = 1;
 again:
-       if (multi_ret) {
-               multi = kzalloc(btrfs_multi_bio_size(stripes_allocated),
+       if (bbio_ret) {
+               bbio = kzalloc(btrfs_bio_size(stripes_allocated),
                                GFP_NOFS);
-               if (!multi)
+               if (!bbio)
                        return -ENOMEM;
 
-               atomic_set(&multi->error, 0);
+               atomic_set(&bbio->error, 0);
        }
 
        read_lock(&em_tree->lock);
@@ -2898,7 +2933,7 @@ again:
        if (mirror_num > map->num_stripes)
                mirror_num = 0;
 
-       /* if our multi bio struct is too small, back off and try again */
+       /* if our btrfs_bio struct is too small, back off and try again */
        if (rw & REQ_WRITE) {
                if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
                                 BTRFS_BLOCK_GROUP_DUP)) {
@@ -2917,11 +2952,11 @@ again:
                        stripes_required = map->num_stripes;
                }
        }
-       if (multi_ret && (rw & (REQ_WRITE | REQ_DISCARD)) &&
+       if (bbio_ret && (rw & (REQ_WRITE | REQ_DISCARD)) &&
            stripes_allocated < stripes_required) {
                stripes_allocated = map->num_stripes;
                free_extent_map(em);
-               kfree(multi);
+               kfree(bbio);
                goto again;
        }
        stripe_nr = offset;
@@ -2950,7 +2985,7 @@ again:
                *length = em->len - offset;
        }
 
-       if (!multi_ret)
+       if (!bbio_ret)
                goto out;
 
        num_stripes = 1;
@@ -2975,13 +3010,17 @@ again:
                        stripe_index = find_live_mirror(map, 0,
                                            map->num_stripes,
                                            current->pid % map->num_stripes);
+                       mirror_num = stripe_index + 1;
                }
 
        } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
-               if (rw & (REQ_WRITE | REQ_DISCARD))
+               if (rw & (REQ_WRITE | REQ_DISCARD)) {
                        num_stripes = map->num_stripes;
-               else if (mirror_num)
+               } else if (mirror_num) {
                        stripe_index = mirror_num - 1;
+               } else {
+                       mirror_num = 1;
+               }
 
        } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
                int factor = map->num_stripes / map->sub_stripes;
@@ -3001,6 +3040,7 @@ again:
                        stripe_index = find_live_mirror(map, stripe_index,
                                              map->sub_stripes, stripe_index +
                                              current->pid % map->sub_stripes);
+                       mirror_num = stripe_index + 1;
                }
        } else {
                /*
@@ -3009,15 +3049,16 @@ again:
                 * stripe_index is the number of our device in the stripe array
                 */
                stripe_index = do_div(stripe_nr, map->num_stripes);
+               mirror_num = stripe_index + 1;
        }
        BUG_ON(stripe_index >= map->num_stripes);
 
        if (rw & REQ_DISCARD) {
                for (i = 0; i < num_stripes; i++) {
-                       multi->stripes[i].physical =
+                       bbio->stripes[i].physical =
                                map->stripes[stripe_index].physical +
                                stripe_offset + stripe_nr * map->stripe_len;
-                       multi->stripes[i].dev = map->stripes[stripe_index].dev;
+                       bbio->stripes[i].dev = map->stripes[stripe_index].dev;
 
                        if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
                                u64 stripes;
@@ -3038,16 +3079,16 @@ again:
                                }
                                stripes = stripe_nr_end - 1 - j;
                                do_div(stripes, map->num_stripes);
-                               multi->stripes[i].length = map->stripe_len *
+                               bbio->stripes[i].length = map->stripe_len *
                                        (stripes - stripe_nr + 1);
 
                                if (i == 0) {
-                                       multi->stripes[i].length -=
+                                       bbio->stripes[i].length -=
                                                stripe_offset;
                                        stripe_offset = 0;
                                }
                                if (stripe_index == last_stripe)
-                                       multi->stripes[i].length -=
+                                       bbio->stripes[i].length -=
                                                stripe_end_offset;
                        } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
                                u64 stripes;
@@ -3072,11 +3113,11 @@ again:
                                }
                                stripes = stripe_nr_end - 1 - j;
                                do_div(stripes, factor);
-                               multi->stripes[i].length = map->stripe_len *
+                               bbio->stripes[i].length = map->stripe_len *
                                        (stripes - stripe_nr + 1);
 
                                if (i < map->sub_stripes) {
-                                       multi->stripes[i].length -=
+                                       bbio->stripes[i].length -=
                                                stripe_offset;
                                        if (i == map->sub_stripes - 1)
                                                stripe_offset = 0;
@@ -3084,11 +3125,11 @@ again:
                                if (stripe_index >= last_stripe &&
                                    stripe_index <= (last_stripe +
                                                     map->sub_stripes - 1)) {
-                                       multi->stripes[i].length -=
+                                       bbio->stripes[i].length -=
                                                stripe_end_offset;
                                }
                        } else
-                               multi->stripes[i].length = *length;
+                               bbio->stripes[i].length = *length;
 
                        stripe_index++;
                        if (stripe_index == map->num_stripes) {
@@ -3099,19 +3140,20 @@ again:
                }
        } else {
                for (i = 0; i < num_stripes; i++) {
-                       multi->stripes[i].physical =
+                       bbio->stripes[i].physical =
                                map->stripes[stripe_index].physical +
                                stripe_offset +
                                stripe_nr * map->stripe_len;
-                       multi->stripes[i].dev =
+                       bbio->stripes[i].dev =
                                map->stripes[stripe_index].dev;
                        stripe_index++;
                }
        }
-       if (multi_ret) {
-               *multi_ret = multi;
-               multi->num_stripes = num_stripes;
-               multi->max_errors = max_errors;
+       if (bbio_ret) {
+               *bbio_ret = bbio;
+               bbio->num_stripes = num_stripes;
+               bbio->max_errors = max_errors;
+               bbio->mirror_num = mirror_num;
        }
 out:
        free_extent_map(em);
@@ -3120,9 +3162,9 @@ out:
 
 int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                      u64 logical, u64 *length,
-                     struct btrfs_multi_bio **multi_ret, int mirror_num)
+                     struct btrfs_bio **bbio_ret, int mirror_num)
 {
-       return __btrfs_map_block(map_tree, rw, logical, length, multi_ret,
+       return __btrfs_map_block(map_tree, rw, logical, length, bbio_ret,
                                 mirror_num);
 }
 
@@ -3191,28 +3233,30 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
        return 0;
 }
 
-static void end_bio_multi_stripe(struct bio *bio, int err)
+static void btrfs_end_bio(struct bio *bio, int err)
 {
-       struct btrfs_multi_bio *multi = bio->bi_private;
+       struct btrfs_bio *bbio = bio->bi_private;
        int is_orig_bio = 0;
 
        if (err)
-               atomic_inc(&multi->error);
+               atomic_inc(&bbio->error);
 
-       if (bio == multi->orig_bio)
+       if (bio == bbio->orig_bio)
                is_orig_bio = 1;
 
-       if (atomic_dec_and_test(&multi->stripes_pending)) {
+       if (atomic_dec_and_test(&bbio->stripes_pending)) {
                if (!is_orig_bio) {
                        bio_put(bio);
-                       bio = multi->orig_bio;
+                       bio = bbio->orig_bio;
                }
-               bio->bi_private = multi->private;
-               bio->bi_end_io = multi->end_io;
+               bio->bi_private = bbio->private;
+               bio->bi_end_io = bbio->end_io;
+               bio->bi_bdev = (struct block_device *)
+                                       (unsigned long)bbio->mirror_num;
                /* only send an error to the higher layers if it is
                 * beyond the tolerance of the multi-bio
                 */
-               if (atomic_read(&multi->error) > multi->max_errors) {
+               if (atomic_read(&bbio->error) > bbio->max_errors) {
                        err = -EIO;
                } else if (err) {
                        /*
@@ -3222,7 +3266,7 @@ static void end_bio_multi_stripe(struct bio *bio, int err)
                        set_bit(BIO_UPTODATE, &bio->bi_flags);
                        err = 0;
                }
-               kfree(multi);
+               kfree(bbio);
 
                bio_endio(bio, err);
        } else if (!is_orig_bio) {
@@ -3302,20 +3346,20 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
        u64 logical = (u64)bio->bi_sector << 9;
        u64 length = 0;
        u64 map_length;
-       struct btrfs_multi_bio *multi = NULL;
        int ret;
        int dev_nr = 0;
        int total_devs = 1;
+       struct btrfs_bio *bbio = NULL;
 
        length = bio->bi_size;
        map_tree = &root->fs_info->mapping_tree;
        map_length = length;
 
-       ret = btrfs_map_block(map_tree, rw, logical, &map_length, &multi,
+       ret = btrfs_map_block(map_tree, rw, logical, &map_length, &bbio,
                              mirror_num);
        BUG_ON(ret);
 
-       total_devs = multi->num_stripes;
+       total_devs = bbio->num_stripes;
        if (map_length < length) {
                printk(KERN_CRIT "mapping failed logical %llu bio len %llu "
                       "len %llu\n", (unsigned long long)logical,
@@ -3323,25 +3367,28 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                       (unsigned long long)map_length);
                BUG();
        }
-       multi->end_io = first_bio->bi_end_io;
-       multi->private = first_bio->bi_private;
-       multi->orig_bio = first_bio;
-       atomic_set(&multi->stripes_pending, multi->num_stripes);
+
+       bbio->orig_bio = first_bio;
+       bbio->private = first_bio->bi_private;
+       bbio->end_io = first_bio->bi_end_io;
+       atomic_set(&bbio->stripes_pending, bbio->num_stripes);
 
        while (dev_nr < total_devs) {
-               if (total_devs > 1) {
-                       if (dev_nr < total_devs - 1) {
-                               bio = bio_clone(first_bio, GFP_NOFS);
-                               BUG_ON(!bio);
-                       } else {
-                               bio = first_bio;
-                       }
-                       bio->bi_private = multi;
-                       bio->bi_end_io = end_bio_multi_stripe;
+               if (dev_nr < total_devs - 1) {
+                       bio = bio_clone(first_bio, GFP_NOFS);
+                       BUG_ON(!bio);
+               } else {
+                       bio = first_bio;
                }
-               bio->bi_sector = multi->stripes[dev_nr].physical >> 9;
-               dev = multi->stripes[dev_nr].dev;
+               bio->bi_private = bbio;
+               bio->bi_end_io = btrfs_end_bio;
+               bio->bi_sector = bbio->stripes[dev_nr].physical >> 9;
+               dev = bbio->stripes[dev_nr].dev;
                if (dev && dev->bdev && (rw != WRITE || dev->writeable)) {
+                       pr_debug("btrfs_map_bio: rw %d, secor=%llu, dev=%lu "
+                                "(%s id %llu), size=%u\n", rw,
+                                (u64)bio->bi_sector, (u_long)dev->bdev->bd_dev,
+                                dev->name, dev->devid, bio->bi_size);
                        bio->bi_bdev = dev->bdev;
                        if (async_submit)
                                schedule_bio(root, dev, rw, bio);
@@ -3354,8 +3401,6 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                }
                dev_nr++;
        }
-       if (total_devs == 1)
-               kfree(multi);
        return 0;
 }
 
@@ -3616,15 +3661,20 @@ static int read_one_dev(struct btrfs_root *root,
        fill_device_from_item(leaf, dev_item, device);
        device->dev_root = root->fs_info->dev_root;
        device->in_fs_metadata = 1;
-       if (device->writeable)
+       if (device->writeable) {
                device->fs_devices->total_rw_bytes += device->total_bytes;
+               spin_lock(&root->fs_info->free_chunk_lock);
+               root->fs_info->free_chunk_space += device->total_bytes -
+                       device->bytes_used;
+               spin_unlock(&root->fs_info->free_chunk_lock);
+       }
        ret = 0;
        return ret;
 }
 
 int btrfs_read_sys_array(struct btrfs_root *root)
 {
-       struct btrfs_super_block *super_copy = &root->fs_info->super_copy;
+       struct btrfs_super_block *super_copy = root->fs_info->super_copy;
        struct extent_buffer *sb;
        struct btrfs_disk_key *disk_key;
        struct btrfs_chunk *chunk;
index 6d866db4e1774ab08e73b8f6c5ad6d8aaa08861b..78f2d4d4f37fe81317395688a8b090b71e53a612 100644 (file)
@@ -92,6 +92,20 @@ struct btrfs_device {
        struct btrfs_work work;
        struct rcu_head rcu;
        struct work_struct rcu_work;
+
+       /* readahead state */
+       spinlock_t reada_lock;
+       atomic_t reada_in_flight;
+       u64 reada_next;
+       struct reada_zone *reada_curr_zone;
+       struct radix_tree_root reada_zones;
+       struct radix_tree_root reada_extents;
+
+       /* for sending down flush barriers */
+       struct bio *flush_bio;
+       struct completion flush_wait;
+       int nobarriers;
+
 };
 
 struct btrfs_fs_devices {
@@ -136,7 +150,10 @@ struct btrfs_bio_stripe {
        u64 length; /* only used for discard mappings */
 };
 
-struct btrfs_multi_bio {
+struct btrfs_bio;
+typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
+
+struct btrfs_bio {
        atomic_t stripes_pending;
        bio_end_io_t *end_io;
        struct bio *orig_bio;
@@ -144,6 +161,7 @@ struct btrfs_multi_bio {
        atomic_t error;
        int max_errors;
        int num_stripes;
+       int mirror_num;
        struct btrfs_bio_stripe stripes[];
 };
 
@@ -171,7 +189,7 @@ struct map_lookup {
 int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
                                   u64 end, u64 *length);
 
-#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
+#define btrfs_bio_size(n) (sizeof(struct btrfs_bio) + \
                            (sizeof(struct btrfs_bio_stripe) * (n)))
 
 int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
@@ -180,7 +198,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
                           u64 chunk_offset, u64 start, u64 num_bytes);
 int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
                    u64 logical, u64 *length,
-                   struct btrfs_multi_bio **multi_ret, int mirror_num);
+                   struct btrfs_bio **bbio_ret, int mirror_num);
 int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
                     u64 chunk_start, u64 physical, u64 devid,
                     u64 **logical, int *naddrs, int *stripe_len);
index 426aa464f1afc45aa5501e35af6ebb4f8ab37aa7..3848b04e310e4800f6768160c6ef5111734ad1d5 100644 (file)
@@ -127,6 +127,17 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
 again:
        ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode),
                                      name, name_len, value, size);
+       /*
+        * If we're setting an xattr to a new value but the new value is say
+        * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting
+        * back from split_leaf.  This is because it thinks we'll be extending
+        * the existing item size, but we're asking for enough space to add the
+        * item itself.  So if we get EOVERFLOW just set ret to EEXIST and let
+        * the rest of the function figure it out.
+        */
+       if (ret == -EOVERFLOW)
+               ret = -EEXIST;
+
        if (ret == -EEXIST) {
                if (flags & XATTR_CREATE)
                        goto out;
index 70a19745cb61d1e1b1c92c26370668d298c15e13..19d8eb7fdc81a1ed4be1fd4bd248d1037598fb1a 100644 (file)
@@ -288,7 +288,7 @@ static void free_more_memory(void)
        struct zone *zone;
        int nid;
 
-       wakeup_flusher_threads(1024);
+       wakeup_flusher_threads(1024, WB_REASON_FREE_MORE_MEM);
        yield();
 
        for_each_online_node(nid) {
index 15b21e35078a2f5cb204ccc00d1959d47366c89b..0f327c6c967954ec329f25bb44f45a1e4219cd71 100644 (file)
@@ -487,17 +487,15 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
                ci->i_rdcache_gen++;
 
        /*
-        * if we are newly issued FILE_SHARED, clear I_COMPLETE; we
+        * if we are newly issued FILE_SHARED, clear D_COMPLETE; we
         * don't know what happened to this directory while we didn't
         * have the cap.
         */
        if ((issued & CEPH_CAP_FILE_SHARED) &&
            (had & CEPH_CAP_FILE_SHARED) == 0) {
                ci->i_shared_gen++;
-               if (S_ISDIR(ci->vfs_inode.i_mode)) {
-                       dout(" marking %p NOT complete\n", &ci->vfs_inode);
-                       ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
-               }
+               if (S_ISDIR(ci->vfs_inode.i_mode))
+                       ceph_dir_clear_complete(&ci->vfs_inode);
        }
 }
 
index 382abc9a6a5409ffc052556f58bcb612c5680c5f..bca3948e9dbf6758746c896359471f4730407e24 100644 (file)
@@ -108,7 +108,7 @@ static unsigned fpos_off(loff_t p)
  * falling back to a "normal" sync readdir if any dentries in the dir
  * are dropped.
  *
- * I_COMPLETE tells indicates we have all dentries in the dir.  It is
+ * D_COMPLETE tells indicates we have all dentries in the dir.  It is
  * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by
  * the MDS if/when the directory is modified).
  */
@@ -199,8 +199,8 @@ more:
        filp->f_pos++;
 
        /* make sure a dentry wasn't dropped while we didn't have parent lock */
-       if (!ceph_i_test(dir, CEPH_I_COMPLETE)) {
-               dout(" lost I_COMPLETE on %p; falling back to mds\n", dir);
+       if (!ceph_dir_test_complete(dir)) {
+               dout(" lost D_COMPLETE on %p; falling back to mds\n", dir);
                err = -EAGAIN;
                goto out;
        }
@@ -285,7 +285,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if ((filp->f_pos == 2 || fi->dentry) &&
            !ceph_test_mount_opt(fsc, NOASYNCREADDIR) &&
            ceph_snap(inode) != CEPH_SNAPDIR &&
-           (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+           ceph_dir_test_complete(inode) &&
            __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
                spin_unlock(&inode->i_lock);
                err = __dcache_readdir(filp, dirent, filldir);
@@ -351,7 +351,7 @@ more:
 
                if (!req->r_did_prepopulate) {
                        dout("readdir !did_prepopulate");
-                       fi->dir_release_count--;    /* preclude I_COMPLETE */
+                       fi->dir_release_count--;    /* preclude D_COMPLETE */
                }
 
                /* note next offset and last dentry name */
@@ -430,8 +430,7 @@ more:
         */
        spin_lock(&inode->i_lock);
        if (ci->i_release_count == fi->dir_release_count) {
-               dout(" marking %p complete\n", inode);
-               /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
+               ceph_dir_set_complete(inode);
                ci->i_max_offset = filp->f_pos;
        }
        spin_unlock(&inode->i_lock);
@@ -614,7 +613,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
                            fsc->mount_options->snapdir_name,
                            dentry->d_name.len) &&
                    !is_root_ceph_dentry(dir, dentry) &&
-                   (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
+                   ceph_dir_test_complete(dir) &&
                    (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) {
                        spin_unlock(&dir->i_lock);
                        dout(" dir %p complete, -ENOENT\n", dir);
@@ -934,7 +933,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
                 */
 
                /* d_move screws up d_subdirs order */
-               ceph_i_clear(new_dir, CEPH_I_COMPLETE);
+               ceph_dir_clear_complete(new_dir);
 
                d_move(old_dentry, new_dentry);
 
@@ -1092,7 +1091,75 @@ static int ceph_snapdir_d_revalidate(struct dentry *dentry,
        return 1;
 }
 
+/*
+ * Set/clear/test dir complete flag on the dir's dentry.
+ */
+static struct dentry * __d_find_any_alias(struct inode *inode)
+{
+       struct dentry *alias;
+
+       if (list_empty(&inode->i_dentry))
+               return NULL;
+       alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias);
+       return alias;
+}
+
+void ceph_dir_set_complete(struct inode *inode)
+{
+       struct dentry *dentry = __d_find_any_alias(inode);
+       
+       if (dentry && ceph_dentry(dentry)) {
+               dout(" marking %p (%p) complete\n", inode, dentry);
+               set_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
+       }
+}
+
+void ceph_dir_clear_complete(struct inode *inode)
+{
+       struct dentry *dentry = __d_find_any_alias(inode);
 
+       if (dentry && ceph_dentry(dentry)) {
+               dout(" marking %p (%p) NOT complete\n", inode, dentry);
+               clear_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
+       }
+}
+
+bool ceph_dir_test_complete(struct inode *inode)
+{
+       struct dentry *dentry = __d_find_any_alias(inode);
+
+       if (dentry && ceph_dentry(dentry))
+               return test_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags);
+       return false;
+}
+
+/*
+ * When the VFS prunes a dentry from the cache, we need to clear the
+ * complete flag on the parent directory.
+ *
+ * Called under dentry->d_lock.
+ */
+static void ceph_d_prune(struct dentry *dentry)
+{
+       struct ceph_dentry_info *di;
+
+       dout("ceph_d_prune %p\n", dentry);
+
+       /* do we have a valid parent? */
+       if (!dentry->d_parent || IS_ROOT(dentry))
+               return;
+
+       /* if we are not hashed, we don't affect D_COMPLETE */
+       if (d_unhashed(dentry))
+               return;
+
+       /*
+        * we hold d_lock, so d_parent is stable, and d_fsdata is never
+        * cleared until d_release
+        */
+       di = ceph_dentry(dentry->d_parent);
+       clear_bit(CEPH_D_COMPLETE, &di->flags);
+}
 
 /*
  * read() on a dir.  This weird interface hack only works if mounted
@@ -1306,6 +1373,7 @@ const struct inode_operations ceph_dir_iops = {
 const struct dentry_operations ceph_dentry_ops = {
        .d_revalidate = ceph_d_revalidate,
        .d_release = ceph_d_release,
+       .d_prune = ceph_d_prune,
 };
 
 const struct dentry_operations ceph_snapdir_dentry_ops = {
@@ -1315,4 +1383,5 @@ const struct dentry_operations ceph_snapdir_dentry_ops = {
 
 const struct dentry_operations ceph_snap_dentry_ops = {
        .d_release = ceph_d_release,
+       .d_prune = ceph_d_prune,
 };
index 1616a0d37cbd785d9ade8579ba108e8e4174ff15..116f36502f178f5ce0475bdfdd77073e9452e614 100644 (file)
@@ -771,9 +771,9 @@ no_change:
            ceph_snap(inode) == CEPH_NOSNAP &&
            (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
            (issued & CEPH_CAP_FILE_EXCL) == 0 &&
-           (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
+           !ceph_dir_test_complete(inode)) {
                dout(" marking %p complete (empty)\n", inode);
-               /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
+               ceph_dir_set_complete(inode);
                ci->i_max_offset = 2;
        }
 
@@ -856,7 +856,7 @@ static void ceph_set_dentry_offset(struct dentry *dn)
        di = ceph_dentry(dn);
 
        spin_lock(&inode->i_lock);
-       if ((ceph_inode(inode)->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
+       if (!ceph_dir_test_complete(inode)) {
                spin_unlock(&inode->i_lock);
                return;
        }
@@ -1056,7 +1056,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                         * d_move() puts the renamed dentry at the end of
                         * d_subdirs.  We need to assign it an appropriate
                         * directory offset so we can behave when holding
-                        * I_COMPLETE.
+                        * D_COMPLETE.
                         */
                        ceph_set_dentry_offset(req->r_old_dentry);
                        dout("dn %p gets new offset %lld\n", req->r_old_dentry, 
@@ -1328,12 +1328,13 @@ int ceph_inode_set_size(struct inode *inode, loff_t size)
  */
 void ceph_queue_writeback(struct inode *inode)
 {
+       ihold(inode);
        if (queue_work(ceph_inode_to_client(inode)->wb_wq,
                       &ceph_inode(inode)->i_wb_work)) {
                dout("ceph_queue_writeback %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_writeback %p failed\n", inode);
+               iput(inode);
        }
 }
 
@@ -1353,12 +1354,13 @@ static void ceph_writeback_work(struct work_struct *work)
  */
 void ceph_queue_invalidate(struct inode *inode)
 {
+       ihold(inode);
        if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
                       &ceph_inode(inode)->i_pg_inv_work)) {
                dout("ceph_queue_invalidate %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_invalidate %p failed\n", inode);
+               iput(inode);
        }
 }
 
@@ -1434,13 +1436,14 @@ void ceph_queue_vmtruncate(struct inode *inode)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
 
+       ihold(inode);
        if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq,
                       &ci->i_vmtruncate_work)) {
                dout("ceph_queue_vmtruncate %p\n", inode);
-               ihold(inode);
        } else {
                dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
                     inode, ci->i_truncate_pending);
+               iput(inode);
        }
 }
 
index 1d72f15fe9f4570aee8a033e120478ff1fc66a97..264ab701154fead54aec35e0f45152e4709f201a 100644 (file)
@@ -619,7 +619,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
  *
  * Called under mdsc->mutex.
  */
-struct dentry *get_nonsnap_parent(struct dentry *dentry)
+static struct dentry *get_nonsnap_parent(struct dentry *dentry)
 {
        /*
         * we don't need to worry about protecting the d_parent access
@@ -2002,7 +2002,7 @@ out:
 }
 
 /*
- * Invalidate dir I_COMPLETE, dentry lease state on an aborted MDS
+ * Invalidate dir D_COMPLETE, dentry lease state on an aborted MDS
  * namespace request.
  */
 void ceph_invalidate_dir_request(struct ceph_mds_request *req)
@@ -2010,9 +2010,9 @@ void ceph_invalidate_dir_request(struct ceph_mds_request *req)
        struct inode *inode = req->r_locked_dir;
        struct ceph_inode_info *ci = ceph_inode(inode);
 
-       dout("invalidate_dir_request %p (I_COMPLETE, lease(s))\n", inode);
+       dout("invalidate_dir_request %p (D_COMPLETE, lease(s))\n", inode);
        spin_lock(&inode->i_lock);
-       ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+       ceph_dir_clear_complete(inode);
        ci->i_release_count++;
        spin_unlock(&inode->i_lock);
 
@@ -3154,7 +3154,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
 /*
  * true if all sessions are closed, or we force unmount
  */
-bool done_closing_sessions(struct ceph_mds_client *mdsc)
+static bool done_closing_sessions(struct ceph_mds_client *mdsc)
 {
        int i, n = 0;
 
index 788f5ad8e66de6e3be4c7a3530584024b9e98883..8dc73a594a90c11e31f20ef925104ea10e5b0b15 100644 (file)
@@ -426,7 +426,7 @@ static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg)
 /*
  * create a new fs client
  */
-struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
+static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
                                        struct ceph_options *opt)
 {
        struct ceph_fs_client *fsc;
@@ -502,7 +502,7 @@ fail:
        return ERR_PTR(err);
 }
 
-void destroy_fs_client(struct ceph_fs_client *fsc)
+static void destroy_fs_client(struct ceph_fs_client *fsc)
 {
        dout("destroy_fs_client %p\n", fsc);
 
@@ -638,10 +638,12 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
        if (err == 0) {
                dout("open_root_inode success\n");
                if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT &&
-                   fsc->sb->s_root == NULL)
+                   fsc->sb->s_root == NULL) {
                        root = d_alloc_root(req->r_target_inode);
-               else
+                       ceph_init_dentry(root);
+               } else {
                        root = d_obtain_alias(req->r_target_inode);
+               }
                req->r_target_inode = NULL;
                dout("open_root_inode success, root dentry is %p\n", root);
        } else {
index b01442aaf278eff165f10596ba291c8953dee99e..01bf189e08a91387b6f4686b9999fe03ccf8aa32 100644 (file)
@@ -203,6 +203,7 @@ struct ceph_inode_xattr {
  * Ceph dentry state
  */
 struct ceph_dentry_info {
+       unsigned long flags;
        struct ceph_mds_session *lease_session;
        u32 lease_gen, lease_shared_gen;
        u32 lease_seq;
@@ -213,6 +214,18 @@ struct ceph_dentry_info {
        u64 offset;
 };
 
+/*
+ * dentry flags
+ *
+ * The locking for D_COMPLETE is a bit odd:
+ *  - we can clear it at almost any time (see ceph_d_prune)
+ *  - it is only meaningful if:
+ *    - we hold dir inode i_lock
+ *    - we hold dir FILE_SHARED caps
+ *    - the dentry D_COMPLETE is set
+ */
+#define CEPH_D_COMPLETE 1  /* if set, d_u.d_subdirs is complete directory */
+
 struct ceph_inode_xattrs_info {
        /*
         * (still encoded) xattr blob. we avoid the overhead of parsing
@@ -251,7 +264,7 @@ struct ceph_inode_info {
        struct timespec i_rctime;
        u64 i_rbytes, i_rfiles, i_rsubdirs;
        u64 i_files, i_subdirs;
-       u64 i_max_offset;  /* largest readdir offset, set with I_COMPLETE */
+       u64 i_max_offset;  /* largest readdir offset, set with D_COMPLETE */
 
        struct rb_root i_fragtree;
        struct mutex i_fragtree_mutex;
@@ -416,7 +429,6 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
 /*
  * Ceph inode.
  */
-#define CEPH_I_COMPLETE  1  /* we have complete directory cached */
 #define CEPH_I_NODELAY   4  /* do not delay cap release */
 #define CEPH_I_FLUSH     8  /* do not delay flush of dirty metadata */
 #define CEPH_I_NOFLUSH  16  /* do not flush dirty caps */
@@ -473,6 +485,13 @@ static inline loff_t ceph_make_fpos(unsigned frag, unsigned off)
        return ((loff_t)frag << 32) | (loff_t)off;
 }
 
+/*
+ * set/clear directory D_COMPLETE flag
+ */
+void ceph_dir_set_complete(struct inode *inode);
+void ceph_dir_clear_complete(struct inode *inode);
+bool ceph_dir_test_complete(struct inode *inode);
+
 /*
  * caps helpers
  */
index c0458c543f170f1ebca913f17c1116f0fd77620d..8cd4b52d42174ee0a4d524d3176b59102751c61e 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <linux/inet.h>
+#include <linux/module.h>
 #include <net/ipv6.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
@@ -440,6 +441,8 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
        smb_msg.msg_controllen = 0;
 
        for (total_read = 0; to_read; total_read += length, to_read -= length) {
+               try_to_freeze();
+
                if (server_unresponsive(server)) {
                        total_read = -EAGAIN;
                        break;
index c1f063cd1b0cf2cd5d8d957a4a65f75b61a4c42a..4dd9283885e745bafdd7dce81e5456f98c5635c9 100644 (file)
@@ -645,20 +645,20 @@ int cifs_closedir(struct inode *inode, struct file *file)
 }
 
 static struct cifsLockInfo *
-cifs_lock_init(__u64 len, __u64 offset, __u8 type, __u16 netfid)
+cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 netfid)
 {
-       struct cifsLockInfo *li =
+       struct cifsLockInfo *lock =
                kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
-       if (!li)
-               return li;
-       li->netfid = netfid;
-       li->offset = offset;
-       li->length = len;
-       li->type = type;
-       li->pid = current->tgid;
-       INIT_LIST_HEAD(&li->blist);
-       init_waitqueue_head(&li->block_q);
-       return li;
+       if (!lock)
+               return lock;
+       lock->offset = offset;
+       lock->length = length;
+       lock->type = type;
+       lock->netfid = netfid;
+       lock->pid = current->tgid;
+       INIT_LIST_HEAD(&lock->blist);
+       init_waitqueue_head(&lock->block_q);
+       return lock;
 }
 
 static void
@@ -672,7 +672,7 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock)
 }
 
 static bool
-cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
+__cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
                        __u64 length, __u8 type, __u16 netfid,
                        struct cifsLockInfo **conf_lock)
 {
@@ -694,6 +694,21 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
        return false;
 }
 
+static bool
+cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
+                       struct cifsLockInfo **conf_lock)
+{
+       return __cifs_find_lock_conflict(cinode, lock->offset, lock->length,
+                                        lock->type, lock->netfid, conf_lock);
+}
+
+/*
+ * Check if there is another lock that prevents us to set the lock (mandatory
+ * style). If such a lock exists, update the flock structure with its
+ * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks
+ * or leave it the same if we can't. Returns 0 if we don't need to request to
+ * the server or 1 otherwise.
+ */
 static int
 cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
               __u8 type, __u16 netfid, struct file_lock *flock)
@@ -704,8 +719,8 @@ cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
 
        mutex_lock(&cinode->lock_mutex);
 
-       exist = cifs_find_lock_conflict(cinode, offset, length, type, netfid,
-                                       &conf_lock);
+       exist = __cifs_find_lock_conflict(cinode, offset, length, type, netfid,
+                                         &conf_lock);
        if (exist) {
                flock->fl_start = conf_lock->offset;
                flock->fl_end = conf_lock->offset + conf_lock->length - 1;
@@ -723,40 +738,33 @@ cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
        return rc;
 }
 
-static int
-cifs_lock_add(struct cifsInodeInfo *cinode, __u64 len, __u64 offset,
-             __u8 type, __u16 netfid)
+static void
+cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock)
 {
-       struct cifsLockInfo *li;
-
-       li = cifs_lock_init(len, offset, type, netfid);
-       if (!li)
-               return -ENOMEM;
-
        mutex_lock(&cinode->lock_mutex);
-       list_add_tail(&li->llist, &cinode->llist);
+       list_add_tail(&lock->llist, &cinode->llist);
        mutex_unlock(&cinode->lock_mutex);
-       return 0;
 }
 
+/*
+ * Set the byte-range lock (mandatory style). Returns:
+ * 1) 0, if we set the lock and don't need to request to the server;
+ * 2) 1, if no locks prevent us but we need to request to the server;
+ * 3) -EACCESS, if there is a lock that prevents us and wait is false.
+ */
 static int
-cifs_lock_add_if(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
-                __u8 type, __u16 netfid, bool wait)
+cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
+                bool wait)
 {
-       struct cifsLockInfo *lock, *conf_lock;
+       struct cifsLockInfo *conf_lock;
        bool exist;
        int rc = 0;
 
-       lock = cifs_lock_init(length, offset, type, netfid);
-       if (!lock)
-               return -ENOMEM;
-
 try_again:
        exist = false;
        mutex_lock(&cinode->lock_mutex);
 
-       exist = cifs_find_lock_conflict(cinode, offset, length, type, netfid,
-                                       &conf_lock);
+       exist = cifs_find_lock_conflict(cinode, lock, &conf_lock);
        if (!exist && cinode->can_cache_brlcks) {
                list_add_tail(&lock->llist, &cinode->llist);
                mutex_unlock(&cinode->lock_mutex);
@@ -775,17 +783,21 @@ try_again:
                                        (lock->blist.next == &lock->blist));
                if (!rc)
                        goto try_again;
-               else {
-                       mutex_lock(&cinode->lock_mutex);
-                       list_del_init(&lock->blist);
-               }
+               mutex_lock(&cinode->lock_mutex);
+               list_del_init(&lock->blist);
        }
 
-       kfree(lock);
        mutex_unlock(&cinode->lock_mutex);
        return rc;
 }
 
+/*
+ * Check if there is another lock that prevents us to set the lock (posix
+ * style). If such a lock exists, update the flock structure with its
+ * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks
+ * or leave it the same if we can't. Returns 0 if we don't need to request to
+ * the server or 1 otherwise.
+ */
 static int
 cifs_posix_lock_test(struct file *file, struct file_lock *flock)
 {
@@ -808,6 +820,12 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock)
        return rc;
 }
 
+/*
+ * Set the byte-range lock (posix style). Returns:
+ * 1) 0, if we set the lock and don't need to request to the server;
+ * 2) 1, if we need to request to the server;
+ * 3) <0, if the error occurs while setting the lock.
+ */
 static int
 cifs_posix_lock_set(struct file *file, struct file_lock *flock)
 {
@@ -933,7 +951,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile)
                else
                        type = CIFS_WRLCK;
 
-               lck = cifs_lock_init(length, flock->fl_start, type,
+               lck = cifs_lock_init(flock->fl_start, length, type,
                                     cfile->netfid);
                if (!lck) {
                        rc = -ENOMEM;
@@ -1070,14 +1088,12 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u8 type,
                if (rc != 0)
                        cERROR(1, "Error unlocking previously locked "
                                   "range %d during test of lock", rc);
-               rc = 0;
-               return rc;
+               return 0;
        }
 
        if (type & LOCKING_ANDX_SHARED_LOCK) {
                flock->fl_type = F_WRLCK;
-               rc = 0;
-               return rc;
+               return 0;
        }
 
        rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
@@ -1095,8 +1111,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u8 type,
        } else
                flock->fl_type = F_WRLCK;
 
-       rc = 0;
-       return rc;
+       return 0;
 }
 
 static void
@@ -1254,20 +1269,26 @@ cifs_setlk(struct file *file,  struct file_lock *flock, __u8 type,
        }
 
        if (lock) {
-               rc = cifs_lock_add_if(cinode, flock->fl_start, length,
-                                     type, netfid, wait_flag);
+               struct cifsLockInfo *lock;
+
+               lock = cifs_lock_init(flock->fl_start, length, type, netfid);
+               if (!lock)
+                       return -ENOMEM;
+
+               rc = cifs_lock_add_if(cinode, lock, wait_flag);
                if (rc < 0)
-                       return rc;
-               else if (!rc)
+                       kfree(lock);
+               if (rc <= 0)
                        goto out;
 
                rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
                                 flock->fl_start, 0, 1, type, wait_flag, 0);
-               if (rc == 0) {
-                       /* For Windows locks we must store them. */
-                       rc = cifs_lock_add(cinode, length, flock->fl_start,
-                                          type, netfid);
+               if (rc) {
+                       kfree(lock);
+                       goto out;
                }
+
+               cifs_lock_add(cinode, lock);
        } else if (unlock)
                rc = cifs_unlock_range(cfile, flock, xid);
 
index 5de03ec20144449c2dea66441b1e66cc577f4a48..a090bbe6ee29e196018867c9f5e4da3efe9d82b9 100644 (file)
@@ -554,7 +554,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
                                 rc);
                        return rc;
                }
-               cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+               /* FindFirst/Next set last_entry to NULL on malformed reply */
+               if (cifsFile->srch_inf.last_entry)
+                       cifs_save_resume_key(cifsFile->srch_inf.last_entry,
+                                               cifsFile);
        }
 
        while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
@@ -562,7 +565,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
                cFYI(1, "calling findnext2");
                rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
                                  &cifsFile->srch_inf);
-               cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+               /* FindFirst/Next set last_entry to NULL on malformed reply */
+               if (cifsFile->srch_inf.last_entry)
+                       cifs_save_resume_key(cifsFile->srch_inf.last_entry,
+                                               cifsFile);
                if (rc)
                        return -ENOENT;
        }
index 7cacba12b8f114468ef56dab7d58fc5678d0c878..80d850881938d0c0950addc4d97ae4855dadfa4a 100644 (file)
@@ -209,7 +209,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
 {
        int rc;
        int len;
-       __u16 wpwd[129];
+       __le16 wpwd[129];
 
        /* Password cannot be longer than 128 characters */
        if (passwd) /* Password must be converted to NT unicode */
@@ -219,8 +219,8 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16,
                *wpwd = 0; /* Ensure string is null terminated */
        }
 
-       rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16));
-       memset(wpwd, 0, 129 * sizeof(__u16));
+       rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
+       memset(wpwd, 0, 129 * sizeof(__le16));
 
        return rc;
 }
index 274f13e2f0946ed66ac186833efa1898b84db3fa..89509b5a090e27320e45b9c0c2f5480e082b1a37 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/bit_spinlock.h>
 #include <linux/rculist_bl.h>
 #include <linux/prefetch.h>
+#include <linux/ratelimit.h>
 #include "internal.h"
 
 /*
@@ -546,9 +547,11 @@ int d_invalidate(struct dentry * dentry)
         * would make it unreachable from the root,
         * we might still populate it if it was a
         * working directory or similar).
+        * We also need to leave mountpoints alone,
+        * directory or not.
         */
-       if (dentry->d_count > 1) {
-               if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
+       if (dentry->d_count > 1 && dentry->d_inode) {
+               if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) {
                        spin_unlock(&dentry->d_lock);
                        return -EBUSY;
                }
@@ -2381,8 +2384,16 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                                actual = __d_unalias(inode, dentry, alias);
                        }
                        write_sequnlock(&rename_lock);
-                       if (IS_ERR(actual))
+                       if (IS_ERR(actual)) {
+                               if (PTR_ERR(actual) == -ELOOP)
+                                       pr_warn_ratelimited(
+                                               "VFS: Lookup of '%s' in %s %s"
+                                               " would have caused loop\n",
+                                               dentry->d_name.name,
+                                               inode->i_sb->s_type->name,
+                                               inode->i_sb->s_id);
                                dput(alias);
+                       }
                        goto out_nolock;
                }
        }
@@ -2428,16 +2439,14 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name)
 /**
  * prepend_path - Prepend path string to a buffer
  * @path: the dentry/vfsmount to report
- * @root: root vfsmnt/dentry (may be modified by this function)
+ * @root: root vfsmnt/dentry
  * @buffer: pointer to the end of the buffer
  * @buflen: pointer to buffer length
  *
  * Caller holds the rename_lock.
- *
- * If path is not reachable from the supplied root, then the value of
- * root is changed (without modifying refcounts).
  */
-static int prepend_path(const struct path *path, struct path *root,
+static int prepend_path(const struct path *path,
+                       const struct path *root,
                        char **buffer, int *buflen)
 {
        struct dentry *dentry = path->dentry;
@@ -2472,10 +2481,10 @@ static int prepend_path(const struct path *path, struct path *root,
                dentry = parent;
        }
 
-out:
        if (!error && !slash)
                error = prepend(buffer, buflen, "/", 1);
 
+out:
        br_read_unlock(vfsmount_lock);
        return error;
 
@@ -2489,15 +2498,17 @@ global_root:
                WARN(1, "Root dentry has weird name <%.*s>\n",
                     (int) dentry->d_name.len, dentry->d_name.name);
        }
-       root->mnt = vfsmnt;
-       root->dentry = dentry;
+       if (!slash)
+               error = prepend(buffer, buflen, "/", 1);
+       if (!error)
+               error = vfsmnt->mnt_ns ? 1 : 2;
        goto out;
 }
 
 /**
  * __d_path - return the path of a dentry
  * @path: the dentry/vfsmount to report
- * @root: root vfsmnt/dentry (may be modified by this function)
+ * @root: root vfsmnt/dentry
  * @buf: buffer to return value in
  * @buflen: buffer length
  *
@@ -2508,10 +2519,10 @@ global_root:
  *
  * "buflen" should be positive.
  *
- * If path is not reachable from the supplied root, then the value of
- * root is changed (without modifying refcounts).
+ * If the path is not reachable from the supplied root, return %NULL.
  */
-char *__d_path(const struct path *path, struct path *root,
+char *__d_path(const struct path *path,
+              const struct path *root,
               char *buf, int buflen)
 {
        char *res = buf + buflen;
@@ -2522,7 +2533,28 @@ char *__d_path(const struct path *path, struct path *root,
        error = prepend_path(path, root, &res, &buflen);
        write_sequnlock(&rename_lock);
 
-       if (error)
+       if (error < 0)
+               return ERR_PTR(error);
+       if (error > 0)
+               return NULL;
+       return res;
+}
+
+char *d_absolute_path(const struct path *path,
+              char *buf, int buflen)
+{
+       struct path root = {};
+       char *res = buf + buflen;
+       int error;
+
+       prepend(&res, &buflen, "\0", 1);
+       write_seqlock(&rename_lock);
+       error = prepend_path(path, &root, &res, &buflen);
+       write_sequnlock(&rename_lock);
+
+       if (error > 1)
+               error = -EINVAL;
+       if (error < 0)
                return ERR_PTR(error);
        return res;
 }
@@ -2530,8 +2562,9 @@ char *__d_path(const struct path *path, struct path *root,
 /*
  * same as __d_path but appends "(deleted)" for unlinked files.
  */
-static int path_with_deleted(const struct path *path, struct path *root,
-                                char **buf, int *buflen)
+static int path_with_deleted(const struct path *path,
+                            const struct path *root,
+                            char **buf, int *buflen)
 {
        prepend(buf, buflen, "\0", 1);
        if (d_unlinked(path->dentry)) {
@@ -2568,7 +2601,6 @@ char *d_path(const struct path *path, char *buf, int buflen)
 {
        char *res = buf + buflen;
        struct path root;
-       struct path tmp;
        int error;
 
        /*
@@ -2583,9 +2615,8 @@ char *d_path(const struct path *path, char *buf, int buflen)
 
        get_fs_root(current->fs, &root);
        write_seqlock(&rename_lock);
-       tmp = root;
-       error = path_with_deleted(path, &tmp, &res, &buflen);
-       if (error)
+       error = path_with_deleted(path, &root, &res, &buflen);
+       if (error < 0)
                res = ERR_PTR(error);
        write_sequnlock(&rename_lock);
        path_put(&root);
@@ -2606,7 +2637,6 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
 {
        char *res = buf + buflen;
        struct path root;
-       struct path tmp;
        int error;
 
        if (path->dentry->d_op && path->dentry->d_op->d_dname)
@@ -2614,9 +2644,8 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
 
        get_fs_root(current->fs, &root);
        write_seqlock(&rename_lock);
-       tmp = root;
-       error = path_with_deleted(path, &tmp, &res, &buflen);
-       if (!error && !path_equal(&tmp, &root))
+       error = path_with_deleted(path, &root, &res, &buflen);
+       if (error > 0)
                error = prepend_unreachable(&res, &buflen);
        write_sequnlock(&rename_lock);
        path_put(&root);
@@ -2747,19 +2776,18 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
        write_seqlock(&rename_lock);
        if (!d_unlinked(pwd.dentry)) {
                unsigned long len;
-               struct path tmp = root;
                char *cwd = page + PAGE_SIZE;
                int buflen = PAGE_SIZE;
 
                prepend(&cwd, &buflen, "\0", 1);
-               error = prepend_path(&pwd, &tmp, &cwd, &buflen);
+               error = prepend_path(&pwd, &root, &cwd, &buflen);
                write_sequnlock(&rename_lock);
 
-               if (error)
+               if (error < 0)
                        goto out;
 
                /* Unreachable from current root */
-               if (!path_equal(&tmp, &root)) {
+               if (error > 0) {
                        error = prepend_unreachable(&cwd, &buflen);
                        if (error)
                                goto out;
index 58609bde3b9fc076187afa3317582788f2f6bc7f..2a834255c75de911b7e1f8eb10026972913e14b4 100644 (file)
@@ -967,7 +967,7 @@ static void ecryptfs_set_default_crypt_stat_vals(
 
 /**
  * ecryptfs_new_file_context
- * @ecryptfs_dentry: The eCryptfs dentry
+ * @ecryptfs_inode: The eCryptfs inode
  *
  * If the crypto context for the file has not yet been established,
  * this is where we do that.  Establishing a new crypto context
@@ -984,13 +984,13 @@ static void ecryptfs_set_default_crypt_stat_vals(
  *
  * Returns zero on success; non-zero otherwise
  */
-int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
+int ecryptfs_new_file_context(struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-           &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+           &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
            &ecryptfs_superblock_to_private(
-                   ecryptfs_dentry->d_sb)->mount_crypt_stat;
+                   ecryptfs_inode->i_sb)->mount_crypt_stat;
        int cipher_name_len;
        int rc = 0;
 
@@ -1299,12 +1299,12 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
 }
 
 static int
-ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
+ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode,
                                    char *virt, size_t virt_len)
 {
        int rc;
 
-       rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
+       rc = ecryptfs_write_lower(ecryptfs_inode, virt,
                                  0, virt_len);
        if (rc < 0)
                printk(KERN_ERR "%s: Error attempting to write header "
@@ -1338,7 +1338,8 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
 
 /**
  * ecryptfs_write_metadata
- * @ecryptfs_dentry: The eCryptfs dentry
+ * @ecryptfs_dentry: The eCryptfs dentry, which should be negative
+ * @ecryptfs_inode: The newly created eCryptfs inode
  *
  * Write the file headers out.  This will likely involve a userspace
  * callout, in which the session key is encrypted with one or more
@@ -1348,10 +1349,11 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
  *
  * Returns zero on success; non-zero on error
  */
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
+                           struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-               &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        unsigned int order;
        char *virt;
        size_t virt_len;
@@ -1391,7 +1393,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
                                                      size);
        else
-               rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt,
+               rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
                                                         virt_len);
        if (rc) {
                printk(KERN_ERR "%s: Error writing metadata out to lower file; "
@@ -1943,7 +1945,7 @@ static unsigned char *portable_filename_chars = ("-.0123456789ABCD"
 
 /* We could either offset on every reverse map or just pad some 0x00's
  * at the front here */
-static const unsigned char filename_rev_map[] = {
+static const unsigned char filename_rev_map[256] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */
@@ -1959,7 +1961,7 @@ static const unsigned char filename_rev_map[] = {
        0x00, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, /* 103 */
        0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, /* 111 */
        0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, /* 119 */
-       0x3D, 0x3E, 0x3F
+       0x3D, 0x3E, 0x3F /* 123 - 255 initialized to 0x00 */
 };
 
 /**
index 54481a3b2c7960e6ba205696c9d69ec44b331194..a9f29b12fbf290ba4987f778e582357d38ae1258 100644 (file)
@@ -584,9 +584,10 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
 int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
 int ecryptfs_encrypt_page(struct page *page);
 int ecryptfs_decrypt_page(struct page *page);
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
+                           struct inode *ecryptfs_inode);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
-int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+int ecryptfs_new_file_context(struct inode *ecryptfs_inode);
 void ecryptfs_write_crypt_stat_flags(char *page_virt,
                                     struct ecryptfs_crypt_stat *crypt_stat,
                                     size_t *written);
index c6ac98cf9baaeca5d898cce216aa0dc08df2716c..d3f95f941c47e68a1d0a2cbe60371f148d64e124 100644 (file)
@@ -139,6 +139,27 @@ out:
        return rc;
 }
 
+static void ecryptfs_vma_close(struct vm_area_struct *vma)
+{
+       filemap_write_and_wait(vma->vm_file->f_mapping);
+}
+
+static const struct vm_operations_struct ecryptfs_file_vm_ops = {
+       .close          = ecryptfs_vma_close,
+       .fault          = filemap_fault,
+};
+
+static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       int rc;
+
+       rc = generic_file_mmap(file, vma);
+       if (!rc)
+               vma->vm_ops = &ecryptfs_file_vm_ops;
+
+       return rc;
+}
+
 struct kmem_cache *ecryptfs_file_info_cache;
 
 /**
@@ -349,7 +370,7 @@ const struct file_operations ecryptfs_main_fops = {
 #ifdef CONFIG_COMPAT
        .compat_ioctl = ecryptfs_compat_ioctl,
 #endif
-       .mmap = generic_file_mmap,
+       .mmap = ecryptfs_file_mmap,
        .open = ecryptfs_open,
        .flush = ecryptfs_flush,
        .release = ecryptfs_release,
index a36d327f15215e471628e2fda253e84ccd6100e9..32f90a3ae63eb85bc6d162aa16f28d48b3cdac7f 100644 (file)
@@ -172,22 +172,23 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
  * it. It will also update the eCryptfs directory inode to mimic the
  * stat of the lower directory inode.
  *
- * Returns zero on success; non-zero on error condition
+ * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
  */
-static int
+static struct inode *
 ecryptfs_do_create(struct inode *directory_inode,
                   struct dentry *ecryptfs_dentry, int mode)
 {
        int rc;
        struct dentry *lower_dentry;
        struct dentry *lower_dir_dentry;
+       struct inode *inode;
 
        lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
        lower_dir_dentry = lock_parent(lower_dentry);
        if (IS_ERR(lower_dir_dentry)) {
                ecryptfs_printk(KERN_ERR, "Error locking directory of "
                                "dentry\n");
-               rc = PTR_ERR(lower_dir_dentry);
+               inode = ERR_CAST(lower_dir_dentry);
                goto out;
        }
        rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
@@ -195,20 +196,19 @@ ecryptfs_do_create(struct inode *directory_inode,
        if (rc) {
                printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
                       "rc = [%d]\n", __func__, rc);
+               inode = ERR_PTR(rc);
                goto out_lock;
        }
-       rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
-                               directory_inode->i_sb);
-       if (rc) {
-               ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n");
+       inode = __ecryptfs_get_inode(lower_dentry->d_inode,
+                                    directory_inode->i_sb);
+       if (IS_ERR(inode))
                goto out_lock;
-       }
        fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode);
        fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode);
 out_lock:
        unlock_dir(lower_dir_dentry);
 out:
-       return rc;
+       return inode;
 }
 
 /**
@@ -219,26 +219,26 @@ out:
  *
  * Returns zero on success
  */
-static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
+static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
+                                   struct inode *ecryptfs_inode)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
-               &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+               &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
        int rc = 0;
 
-       if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
+       if (S_ISDIR(ecryptfs_inode->i_mode)) {
                ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
                crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
                goto out;
        }
        ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
-       rc = ecryptfs_new_file_context(ecryptfs_dentry);
+       rc = ecryptfs_new_file_context(ecryptfs_inode);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error creating new file "
                                "context; rc = [%d]\n", rc);
                goto out;
        }
-       rc = ecryptfs_get_lower_file(ecryptfs_dentry,
-                                    ecryptfs_dentry->d_inode);
+       rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to initialize "
                        "the lower file for the dentry with name "
@@ -246,10 +246,10 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
                        ecryptfs_dentry->d_name.name, rc);
                goto out;
        }
-       rc = ecryptfs_write_metadata(ecryptfs_dentry);
+       rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
        if (rc)
                printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
-       ecryptfs_put_lower_file(ecryptfs_dentry->d_inode);
+       ecryptfs_put_lower_file(ecryptfs_inode);
 out:
        return rc;
 }
@@ -269,18 +269,28 @@ static int
 ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
                int mode, struct nameidata *nd)
 {
+       struct inode *ecryptfs_inode;
        int rc;
 
-       /* ecryptfs_do_create() calls ecryptfs_interpose() */
-       rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode);
-       if (unlikely(rc)) {
+       ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
+                                           mode);
+       if (unlikely(IS_ERR(ecryptfs_inode))) {
                ecryptfs_printk(KERN_WARNING, "Failed to create file in"
                                "lower filesystem\n");
+               rc = PTR_ERR(ecryptfs_inode);
                goto out;
        }
        /* At this point, a file exists on "disk"; we need to make sure
         * that this on disk file is prepared to be an ecryptfs file */
-       rc = ecryptfs_initialize_file(ecryptfs_dentry);
+       rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
+       if (rc) {
+               drop_nlink(ecryptfs_inode);
+               unlock_new_inode(ecryptfs_inode);
+               iput(ecryptfs_inode);
+               goto out;
+       }
+       d_instantiate(ecryptfs_dentry, ecryptfs_inode);
+       unlock_new_inode(ecryptfs_inode);
 out:
        return rc;
 }
index fcfa86ae6faf0227a37ab4e6b6305b62c90ef2fc..d271ad837202f819d73e4de97880336ec4ecbfcd 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/div64.h>
 #include <linux/lcm.h>
 
index 057b237b8b698a5cc5d16f7cf53ef7e63aff9435..e6085ec192d665ef2182625b1b4e0b1ccdb3e3d5 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/parser.h>
 #include <linux/vfs.h>
 #include <linux/random.h>
+#include <linux/module.h>
 #include <linux/exportfs.h>
 #include <linux/slab.h>
 
index f6dba4505f1cc7e4f251f28a18bbeea5b3dcb2a7..12ccacda44e0288e13247e3e79ebd414287eb548 100644 (file)
@@ -565,7 +565,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
        brelse(bitmap_bh);
        printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu"
               ", computed = %llu, %llu\n",
-              EXT4_B2C(sbi, ext4_free_blocks_count(es)),
+              EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
               desc_count, bitmap_count);
        return bitmap_count;
 #else
index cc5a6da030a149f31ea61cd35b9803782a4a57a7..848f436df29f6ffec6e8487549764d98c63d5b6b 100644 (file)
@@ -2270,6 +2270,7 @@ retry:
                        ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: "
                               "%ld pages, ino %lu; err %d", __func__,
                                wbc->nr_to_write, inode->i_ino, ret);
+                       blk_finish_plug(&plug);
                        goto out_writepages;
                }
 
@@ -2372,7 +2373,7 @@ static int ext4_nonda_switch(struct super_block *sb)
         * start pushing delalloc when 1/2 of free blocks are dirty.
         */
        if (free_blocks < 2 * dirty_blocks)
-               writeback_inodes_sb_if_idle(sb);
+               writeback_inodes_sb_if_idle(sb, WB_REASON_FS_FREE_SPACE);
 
        return 0;
 }
@@ -2806,8 +2807,8 @@ out:
        spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
 
        /* queue the work to convert unwritten extents to written */
-       queue_work(wq, &io_end->work);
        iocb->private = NULL;
+       queue_work(wq, &io_end->work);
 
        /* XXX: probably should move into the real I/O completion handler */
        inode_dio_done(inode);
index 9953d80145ad0f6331086053a7d80301c418f3a7..3858767ec672ef214ad5f288f30932ee0b5d933a 100644 (file)
@@ -1683,7 +1683,9 @@ static int parse_options(char *options, struct super_block *sb,
                        data_opt = EXT4_MOUNT_WRITEBACK_DATA;
                datacheck:
                        if (is_remount) {
-                               if (test_opt(sb, DATA_FLAGS) != data_opt) {
+                               if (!sbi->s_journal)
+                                       ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option");
+                               else if (test_opt(sb, DATA_FLAGS) != data_opt) {
                                        ext4_msg(sb, KERN_ERR,
                                                "Cannot change data mode on remount");
                                        return 0;
@@ -3099,8 +3101,6 @@ static void ext4_destroy_lazyinit_thread(void)
 }
 
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
-                               __releases(kernel_lock)
-                               __acquires(kernel_lock)
 {
        char *orig_data = kstrdup(data, GFP_KERNEL);
        struct buffer_head *bh;
index 04cf3b91e5016a1f7e3ceef734c7d85574ec296d..73c3992b2bb4aa765d3dc2418e907ca0a7ba78f2 100644 (file)
@@ -41,11 +41,23 @@ struct wb_writeback_work {
        unsigned int for_kupdate:1;
        unsigned int range_cyclic:1;
        unsigned int for_background:1;
+       enum wb_reason reason;          /* why was writeback initiated? */
 
        struct list_head list;          /* pending work list */
        struct completion *done;        /* set if the caller waits */
 };
 
+const char *wb_reason_name[] = {
+       [WB_REASON_BACKGROUND]          = "background",
+       [WB_REASON_TRY_TO_FREE_PAGES]   = "try_to_free_pages",
+       [WB_REASON_SYNC]                = "sync",
+       [WB_REASON_PERIODIC]            = "periodic",
+       [WB_REASON_LAPTOP_TIMER]        = "laptop_timer",
+       [WB_REASON_FREE_MORE_MEM]       = "free_more_memory",
+       [WB_REASON_FS_FREE_SPACE]       = "fs_free_space",
+       [WB_REASON_FORKER_THREAD]       = "forker_thread"
+};
+
 /*
  * Include the creation of the trace points after defining the
  * wb_writeback_work structure so that the definition remains local to this
@@ -115,7 +127,7 @@ static void bdi_queue_work(struct backing_dev_info *bdi,
 
 static void
 __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
-                     bool range_cyclic)
+                     bool range_cyclic, enum wb_reason reason)
 {
        struct wb_writeback_work *work;
 
@@ -135,6 +147,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
        work->sync_mode = WB_SYNC_NONE;
        work->nr_pages  = nr_pages;
        work->range_cyclic = range_cyclic;
+       work->reason    = reason;
 
        bdi_queue_work(bdi, work);
 }
@@ -150,9 +163,10 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
  *   completion. Caller need not hold sb s_umount semaphore.
  *
  */
-void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages)
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
+                       enum wb_reason reason)
 {
-       __bdi_start_writeback(bdi, nr_pages, true);
+       __bdi_start_writeback(bdi, nr_pages, true, reason);
 }
 
 /**
@@ -251,7 +265,7 @@ static bool inode_dirtied_after(struct inode *inode, unsigned long t)
  */
 static int move_expired_inodes(struct list_head *delaying_queue,
                               struct list_head *dispatch_queue,
-                              unsigned long *older_than_this)
+                              struct wb_writeback_work *work)
 {
        LIST_HEAD(tmp);
        struct list_head *pos, *node;
@@ -262,8 +276,8 @@ static int move_expired_inodes(struct list_head *delaying_queue,
 
        while (!list_empty(delaying_queue)) {
                inode = wb_inode(delaying_queue->prev);
-               if (older_than_this &&
-                   inode_dirtied_after(inode, *older_than_this))
+               if (work->older_than_this &&
+                   inode_dirtied_after(inode, *work->older_than_this))
                        break;
                if (sb && sb != inode->i_sb)
                        do_sb_sort = 1;
@@ -302,13 +316,13 @@ out:
  *                                           |
  *                                           +--> dequeue for IO
  */
-static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this)
+static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work)
 {
        int moved;
        assert_spin_locked(&wb->list_lock);
        list_splice_init(&wb->b_more_io, &wb->b_io);
-       moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
-       trace_writeback_queue_io(wb, older_than_this, moved);
+       moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, work);
+       trace_writeback_queue_io(wb, work, moved);
 }
 
 static int write_inode(struct inode *inode, struct writeback_control *wbc)
@@ -641,31 +655,40 @@ static long __writeback_inodes_wb(struct bdi_writeback *wb,
        return wrote;
 }
 
-long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages)
+long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
+                               enum wb_reason reason)
 {
        struct wb_writeback_work work = {
                .nr_pages       = nr_pages,
                .sync_mode      = WB_SYNC_NONE,
                .range_cyclic   = 1,
+               .reason         = reason,
        };
 
        spin_lock(&wb->list_lock);
        if (list_empty(&wb->b_io))
-               queue_io(wb, NULL);
+               queue_io(wb, &work);
        __writeback_inodes_wb(wb, &work);
        spin_unlock(&wb->list_lock);
 
        return nr_pages - work.nr_pages;
 }
 
-static inline bool over_bground_thresh(void)
+static bool over_bground_thresh(struct backing_dev_info *bdi)
 {
        unsigned long background_thresh, dirty_thresh;
 
        global_dirty_limits(&background_thresh, &dirty_thresh);
 
-       return (global_page_state(NR_FILE_DIRTY) +
-               global_page_state(NR_UNSTABLE_NFS) > background_thresh);
+       if (global_page_state(NR_FILE_DIRTY) +
+           global_page_state(NR_UNSTABLE_NFS) > background_thresh)
+               return true;
+
+       if (bdi_stat(bdi, BDI_RECLAIMABLE) >
+                               bdi_dirty_limit(bdi, background_thresh))
+               return true;
+
+       return false;
 }
 
 /*
@@ -675,7 +698,7 @@ static inline bool over_bground_thresh(void)
 static void wb_update_bandwidth(struct bdi_writeback *wb,
                                unsigned long start_time)
 {
-       __bdi_update_bandwidth(wb->bdi, 0, 0, 0, 0, start_time);
+       __bdi_update_bandwidth(wb->bdi, 0, 0, 0, 0, 0, start_time);
 }
 
 /*
@@ -727,7 +750,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                 * For background writeout, stop when we are below the
                 * background dirty threshold
                 */
-               if (work->for_background && !over_bground_thresh())
+               if (work->for_background && !over_bground_thresh(wb->bdi))
                        break;
 
                if (work->for_kupdate) {
@@ -738,7 +761,7 @@ static long wb_writeback(struct bdi_writeback *wb,
 
                trace_writeback_start(wb->bdi, work);
                if (list_empty(&wb->b_io))
-                       queue_io(wb, work->older_than_this);
+                       queue_io(wb, work);
                if (work->sb)
                        progress = writeback_sb_inodes(work->sb, wb, work);
                else
@@ -811,13 +834,14 @@ static unsigned long get_nr_dirty_pages(void)
 
 static long wb_check_background_flush(struct bdi_writeback *wb)
 {
-       if (over_bground_thresh()) {
+       if (over_bground_thresh(wb->bdi)) {
 
                struct wb_writeback_work work = {
                        .nr_pages       = LONG_MAX,
                        .sync_mode      = WB_SYNC_NONE,
                        .for_background = 1,
                        .range_cyclic   = 1,
+                       .reason         = WB_REASON_BACKGROUND,
                };
 
                return wb_writeback(wb, &work);
@@ -851,6 +875,7 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb)
                        .sync_mode      = WB_SYNC_NONE,
                        .for_kupdate    = 1,
                        .range_cyclic   = 1,
+                       .reason         = WB_REASON_PERIODIC,
                };
 
                return wb_writeback(wb, &work);
@@ -969,7 +994,7 @@ int bdi_writeback_thread(void *data)
  * Start writeback of `nr_pages' pages.  If `nr_pages' is zero, write back
  * the whole world.
  */
-void wakeup_flusher_threads(long nr_pages)
+void wakeup_flusher_threads(long nr_pages, enum wb_reason reason)
 {
        struct backing_dev_info *bdi;
 
@@ -982,7 +1007,7 @@ void wakeup_flusher_threads(long nr_pages)
        list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
                if (!bdi_has_dirty_io(bdi))
                        continue;
-               __bdi_start_writeback(bdi, nr_pages, false);
+               __bdi_start_writeback(bdi, nr_pages, false, reason);
        }
        rcu_read_unlock();
 }
@@ -1203,7 +1228,9 @@ static void wait_sb_inodes(struct super_block *sb)
  * on how many (if any) will be written, and this function does not wait
  * for IO completion of submitted IO.
  */
-void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr)
+void writeback_inodes_sb_nr(struct super_block *sb,
+                           unsigned long nr,
+                           enum wb_reason reason)
 {
        DECLARE_COMPLETION_ONSTACK(done);
        struct wb_writeback_work work = {
@@ -1212,6 +1239,7 @@ void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr)
                .tagged_writepages      = 1,
                .done                   = &done,
                .nr_pages               = nr,
+               .reason                 = reason,
        };
 
        WARN_ON(!rwsem_is_locked(&sb->s_umount));
@@ -1228,9 +1256,9 @@ EXPORT_SYMBOL(writeback_inodes_sb_nr);
  * on how many (if any) will be written, and this function does not wait
  * for IO completion of submitted IO.
  */
-void writeback_inodes_sb(struct super_block *sb)
+void writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)
 {
-       return writeback_inodes_sb_nr(sb, get_nr_dirty_pages());
+       return writeback_inodes_sb_nr(sb, get_nr_dirty_pages(), reason);
 }
 EXPORT_SYMBOL(writeback_inodes_sb);
 
@@ -1241,11 +1269,11 @@ EXPORT_SYMBOL(writeback_inodes_sb);
  * Invoke writeback_inodes_sb if no writeback is currently underway.
  * Returns 1 if writeback was started, 0 if not.
  */
-int writeback_inodes_sb_if_idle(struct super_block *sb)
+int writeback_inodes_sb_if_idle(struct super_block *sb, enum wb_reason reason)
 {
        if (!writeback_in_progress(sb->s_bdi)) {
                down_read(&sb->s_umount);
-               writeback_inodes_sb(sb);
+               writeback_inodes_sb(sb, reason);
                up_read(&sb->s_umount);
                return 1;
        } else
@@ -1262,11 +1290,12 @@ EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
  * Returns 1 if writeback was started, 0 if not.
  */
 int writeback_inodes_sb_nr_if_idle(struct super_block *sb,
-                                  unsigned long nr)
+                                  unsigned long nr,
+                                  enum wb_reason reason)
 {
        if (!writeback_in_progress(sb->s_bdi)) {
                down_read(&sb->s_umount);
-               writeback_inodes_sb_nr(sb, nr);
+               writeback_inodes_sb_nr(sb, nr, reason);
                up_read(&sb->s_umount);
                return 1;
        } else
@@ -1290,6 +1319,7 @@ void sync_inodes_sb(struct super_block *sb)
                .nr_pages       = LONG_MAX,
                .range_cyclic   = 0,
                .done           = &done,
+               .reason         = WB_REASON_SYNC,
        };
 
        WARN_ON(!rwsem_is_locked(&sb->s_umount));
index b6cca47f7b07781c8c71a4ab2ea2facac67d37e5..3426521f3205cce09a98b8a1bd01ffe9e44f84c0 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/stat.h>
+#include <linux/module.h>
 
 #include "fuse_i.h"
 
index 7e823bbd24536d9acfc27037c5d0f2268e47d322..cb23c2be731aed23c5524a301aed6bfc65ea7336 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/kthread.h>
+#include <linux/export.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/gfs2_ondisk.h>
index e673a88b8ae7560b14796b611aa57b267193411f..b1ce4c7ad3fb4f33e12ff4c8e320368b851e52c8 100644 (file)
@@ -40,6 +40,8 @@ int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
 
        src = in->name;
        srclen = in->len;
+       if (srclen > HFS_NAMELEN)
+               srclen = HFS_NAMELEN;
        dst = out;
        dstlen = HFS_MAX_NAMELEN;
        if (nls_io) {
index 7da2a06508e5448c59aebcee03518d78f2b0599b..f84b380d65e5d1a1898248bdb7a77dd3bc8b5aa4 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/ioprio.h>
 #include <linux/blkdev.h>
 #include <linux/capability.h>
@@ -47,28 +48,12 @@ int set_task_ioprio(struct task_struct *task, int ioprio)
        if (err)
                return err;
 
-       task_lock(task);
-       do {
-               ioc = task->io_context;
-               /* see wmb() in current_io_context() */
-               smp_read_barrier_depends();
-               if (ioc)
-                       break;
-
-               ioc = alloc_io_context(GFP_ATOMIC, -1);
-               if (!ioc) {
-                       err = -ENOMEM;
-                       break;
-               }
-               task->io_context = ioc;
-       } while (1);
-
-       if (!err) {
-               ioc->ioprio = ioprio;
-               ioc->ioprio_changed = 1;
+       ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
+       if (ioc) {
+               ioc_ioprio_changed(ioc, ioprio);
+               put_io_context(ioc, NULL);
        }
 
-       task_unlock(task);
        return err;
 }
 EXPORT_SYMBOL_GPL(set_task_ioprio);
index de4247021d25a0dae391d4c2e93f16f8b882d41e..5b6c9d1a2fb9bb3c99bf84d2ef0f6f67296491fa 100644 (file)
@@ -53,6 +53,78 @@ static int jffs2_is_best_compression(struct jffs2_compressor *this,
        return 0;
 }
 
+/*
+ * jffs2_selected_compress:
+ * @compr: Explicit compression type to use (ie, JFFS2_COMPR_ZLIB).
+ *     If 0, just take the first available compression mode.
+ * @data_in: Pointer to uncompressed data
+ * @cpage_out: Pointer to returned pointer to buffer for compressed data
+ * @datalen: On entry, holds the amount of data available for compression.
+ *     On exit, expected to hold the amount of data actually compressed.
+ * @cdatalen: On entry, holds the amount of space available for compressed
+ *     data. On exit, expected to hold the actual size of the compressed
+ *     data.
+ *
+ * Returns: the compression type used.  Zero is used to show that the data
+ * could not be compressed; probably because we couldn't find the requested
+ * compression mode.
+ */
+static int jffs2_selected_compress(u8 compr, unsigned char *data_in,
+               unsigned char **cpage_out, u32 *datalen, u32 *cdatalen)
+{
+       struct jffs2_compressor *this;
+       int err, ret = JFFS2_COMPR_NONE;
+       uint32_t orig_slen, orig_dlen;
+       char *output_buf;
+
+       output_buf = kmalloc(*cdatalen, GFP_KERNEL);
+       if (!output_buf) {
+               printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
+               return ret;
+       }
+       orig_slen = *datalen;
+       orig_dlen = *cdatalen;
+       spin_lock(&jffs2_compressor_list_lock);
+       list_for_each_entry(this, &jffs2_compressor_list, list) {
+               /* Skip decompress-only and disabled modules */
+               if (!this->compress || this->disabled)
+                       continue;
+
+               /* Skip if not the desired compression type */
+               if (compr && (compr != this->compr))
+                       continue;
+
+               /*
+                * Either compression type was unspecified, or we found our
+                * compressor; either way, we're good to go.
+                */
+               this->usecount++;
+               spin_unlock(&jffs2_compressor_list_lock);
+
+               *datalen  = orig_slen;
+               *cdatalen = orig_dlen;
+               err = this->compress(data_in, output_buf, datalen, cdatalen);
+
+               spin_lock(&jffs2_compressor_list_lock);
+               this->usecount--;
+               if (!err) {
+                       /* Success */
+                       ret = this->compr;
+                       this->stat_compr_blocks++;
+                       this->stat_compr_orig_size += *datalen;
+                       this->stat_compr_new_size += *cdatalen;
+                       break;
+               }
+       }
+       spin_unlock(&jffs2_compressor_list_lock);
+       if (ret == JFFS2_COMPR_NONE)
+               kfree(output_buf);
+       else
+               *cpage_out = output_buf;
+
+       return ret;
+}
+
 /* jffs2_compress:
  * @data_in: Pointer to uncompressed data
  * @cpage_out: Pointer to returned pointer to buffer for compressed data
@@ -76,47 +148,23 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                        uint32_t *datalen, uint32_t *cdatalen)
 {
        int ret = JFFS2_COMPR_NONE;
-       int compr_ret;
+       int mode, compr_ret;
        struct jffs2_compressor *this, *best=NULL;
        unsigned char *output_buf = NULL, *tmp_buf;
        uint32_t orig_slen, orig_dlen;
        uint32_t best_slen=0, best_dlen=0;
 
-       switch (jffs2_compression_mode) {
+       if (c->mount_opts.override_compr)
+               mode = c->mount_opts.compr;
+       else
+               mode = jffs2_compression_mode;
+
+       switch (mode) {
        case JFFS2_COMPR_MODE_NONE:
                break;
        case JFFS2_COMPR_MODE_PRIORITY:
-               output_buf = kmalloc(*cdatalen,GFP_KERNEL);
-               if (!output_buf) {
-                       printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n");
-                       goto out;
-               }
-               orig_slen = *datalen;
-               orig_dlen = *cdatalen;
-               spin_lock(&jffs2_compressor_list_lock);
-               list_for_each_entry(this, &jffs2_compressor_list, list) {
-                       /* Skip decompress-only backwards-compatibility and disabled modules */
-                       if ((!this->compress)||(this->disabled))
-                               continue;
-
-                       this->usecount++;
-                       spin_unlock(&jffs2_compressor_list_lock);
-                       *datalen  = orig_slen;
-                       *cdatalen = orig_dlen;
-                       compr_ret = this->compress(data_in, output_buf, datalen, cdatalen);
-                       spin_lock(&jffs2_compressor_list_lock);
-                       this->usecount--;
-                       if (!compr_ret) {
-                               ret = this->compr;
-                               this->stat_compr_blocks++;
-                               this->stat_compr_orig_size += *datalen;
-                               this->stat_compr_new_size  += *cdatalen;
-                               break;
-                       }
-               }
-               spin_unlock(&jffs2_compressor_list_lock);
-               if (ret == JFFS2_COMPR_NONE)
-                       kfree(output_buf);
+               ret = jffs2_selected_compress(0, data_in, cpage_out, datalen,
+                               cdatalen);
                break;
        case JFFS2_COMPR_MODE_SIZE:
        case JFFS2_COMPR_MODE_FAVOURLZO:
@@ -174,22 +222,28 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                        best->stat_compr_orig_size += best_slen;
                        best->stat_compr_new_size  += best_dlen;
                        ret = best->compr;
+                       *cpage_out = output_buf;
                }
                spin_unlock(&jffs2_compressor_list_lock);
                break;
+       case JFFS2_COMPR_MODE_FORCELZO:
+               ret = jffs2_selected_compress(JFFS2_COMPR_LZO, data_in,
+                               cpage_out, datalen, cdatalen);
+               break;
+       case JFFS2_COMPR_MODE_FORCEZLIB:
+               ret = jffs2_selected_compress(JFFS2_COMPR_ZLIB, data_in,
+                               cpage_out, datalen, cdatalen);
+               break;
        default:
                printk(KERN_ERR "JFFS2: unknown compression mode.\n");
        }
- out:
+
        if (ret == JFFS2_COMPR_NONE) {
                *cpage_out = data_in;
                *datalen = *cdatalen;
                none_stat_compr_blocks++;
                none_stat_compr_size += *datalen;
        }
-       else {
-               *cpage_out = output_buf;
-       }
        return ret;
 }
 
index 13bb7597ab3987b5da405d5bd857e50b64dce4ab..5e91d578f4ed858c2ac575f375619000c5c6814c 100644 (file)
@@ -40,6 +40,8 @@
 #define JFFS2_COMPR_MODE_PRIORITY   1
 #define JFFS2_COMPR_MODE_SIZE       2
 #define JFFS2_COMPR_MODE_FAVOURLZO  3
+#define JFFS2_COMPR_MODE_FORCELZO   4
+#define JFFS2_COMPR_MODE_FORCEZLIB  5
 
 #define FAVOUR_LZO_PERCENT 80
 
index 7286e44ac66540822f65cd72bc4974435d8a9633..4b8afe39a87f2807859b9eda971b08ddc27dae7e 100644 (file)
@@ -379,7 +379,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags)
        jffs2_do_setattr(inode, &iattr);
 }
 
-int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
+int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
 {
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
 
index 0bc6a6c80a56d569054c14bed1865ea2979a0407..55a0c1dceadfddcf990b8fdbcfec015fc75fab32 100644 (file)
 
 struct jffs2_inodirty;
 
+struct jffs2_mount_opts {
+       bool override_compr;
+       unsigned int compr;
+};
+
 /* A struct for the overall file system control.  Pointers to
    jffs2_sb_info structs are named `c' in the source code.
    Nee jffs_control
@@ -126,6 +131,7 @@ struct jffs2_sb_info {
 #endif
 
        struct jffs2_summary *summary;          /* Summary information */
+       struct jffs2_mount_opts mount_opts;
 
 #ifdef CONFIG_JFFS2_FS_XATTR
 #define XATTRINDEX_HASHSIZE    (57)
index 6c1755c59c0ff9975a331d3217f751e274b221a0..ab65ee3ec858e9ad7a810a5174242c6e4222dcae 100644 (file)
@@ -176,7 +176,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags);
 struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode,
                               struct jffs2_raw_inode *ri);
 int jffs2_statfs (struct dentry *, struct kstatfs *);
-int jffs2_remount_fs (struct super_block *, int *, char *);
+int jffs2_do_remount_fs(struct super_block *, int *, char *);
 int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
 void jffs2_gc_release_inode(struct jffs2_sb_info *c,
                            struct jffs2_inode_info *f);
index 8d8cd3419d02a75a7b0a7336da995a430324448b..28107ca136e481a556f686376292bf2244a78a91 100644 (file)
@@ -275,9 +275,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
        else
                c->mtd->unpoint(c->mtd, 0, c->mtd->size);
 #endif
-       if (s)
-               kfree(s);
-
+       kfree(s);
        return ret;
 }
 
index 853b8e300084cf2bb3c9941055ebc5aa433203e3..e7e97445411569d506ad5ac845e9cff3fc511971 100644 (file)
 #include <linux/fs.h>
 #include <linux/err.h>
 #include <linux/mount.h>
+#include <linux/parser.h>
 #include <linux/jffs2.h>
 #include <linux/pagemap.h>
 #include <linux/mtd/super.h>
 #include <linux/ctype.h>
 #include <linux/namei.h>
+#include <linux/seq_file.h>
 #include <linux/exportfs.h>
 #include "compr.h"
 #include "nodelist.h"
@@ -75,6 +77,37 @@ static void jffs2_write_super(struct super_block *sb)
        unlock_super(sb);
 }
 
+static const char *jffs2_compr_name(unsigned int compr)
+{
+       switch (compr) {
+       case JFFS2_COMPR_MODE_NONE:
+               return "none";
+#ifdef CONFIG_JFFS2_LZO
+       case JFFS2_COMPR_MODE_FORCELZO:
+               return "lzo";
+#endif
+#ifdef CONFIG_JFFS2_ZLIB
+       case JFFS2_COMPR_MODE_FORCEZLIB:
+               return "zlib";
+#endif
+       default:
+               /* should never happen; programmer error */
+               WARN_ON(1);
+               return "";
+       }
+}
+
+static int jffs2_show_options(struct seq_file *s, struct vfsmount *mnt)
+{
+       struct jffs2_sb_info *c = JFFS2_SB_INFO(mnt->mnt_sb);
+       struct jffs2_mount_opts *opts = &c->mount_opts;
+
+       if (opts->override_compr)
+               seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
+
+       return 0;
+}
+
 static int jffs2_sync_fs(struct super_block *sb, int wait)
 {
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
@@ -133,6 +166,85 @@ static const struct export_operations jffs2_export_ops = {
        .fh_to_parent = jffs2_fh_to_parent,
 };
 
+/*
+ * JFFS2 mount options.
+ *
+ * Opt_override_compr: override default compressor
+ * Opt_err: just end of array marker
+ */
+enum {
+       Opt_override_compr,
+       Opt_err,
+};
+
+static const match_table_t tokens = {
+       {Opt_override_compr, "compr=%s"},
+       {Opt_err, NULL},
+};
+
+static int jffs2_parse_options(struct jffs2_sb_info *c, char *data)
+{
+       substring_t args[MAX_OPT_ARGS];
+       char *p, *name;
+
+       if (!data)
+               return 0;
+
+       while ((p = strsep(&data, ","))) {
+               int token;
+
+               if (!*p)
+                       continue;
+
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_override_compr:
+                       name = match_strdup(&args[0]);
+
+                       if (!name)
+                               return -ENOMEM;
+                       if (!strcmp(name, "none"))
+                               c->mount_opts.compr = JFFS2_COMPR_MODE_NONE;
+#ifdef CONFIG_JFFS2_LZO
+                       else if (!strcmp(name, "lzo"))
+                               c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO;
+#endif
+#ifdef CONFIG_JFFS2_ZLIB
+                       else if (!strcmp(name, "zlib"))
+                               c->mount_opts.compr =
+                                               JFFS2_COMPR_MODE_FORCEZLIB;
+#endif
+                       else {
+                               printk(KERN_ERR "JFFS2 Error: unknown compressor \"%s\"",
+                                               name);
+                               kfree(name);
+                               return -EINVAL;
+                       }
+                       kfree(name);
+                       c->mount_opts.override_compr = true;
+                       break;
+               default:
+                       printk(KERN_ERR "JFFS2 Error: unrecognized mount option '%s' or missing value\n",
+                                       p);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
+{
+       struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+       int err;
+
+       err = jffs2_parse_options(c, data);
+       if (err)
+               return -EINVAL;
+
+       return jffs2_do_remount_fs(sb, flags, data);
+}
+
 static const struct super_operations jffs2_super_operations =
 {
        .alloc_inode =  jffs2_alloc_inode,
@@ -143,6 +255,7 @@ static const struct super_operations jffs2_super_operations =
        .remount_fs =   jffs2_remount_fs,
        .evict_inode =  jffs2_evict_inode,
        .dirty_inode =  jffs2_dirty_inode,
+       .show_options = jffs2_show_options,
        .sync_fs =      jffs2_sync_fs,
 };
 
@@ -166,6 +279,12 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
        c->os_priv = sb;
        sb->s_fs_info = c;
 
+       ret = jffs2_parse_options(c, data);
+       if (ret) {
+               kfree(c);
+               return -EINVAL;
+       }
+
        /* Initialize JFFS2 superblock locks, the further initialization will
         * be done later */
        mutex_init(&c->alloc_sem);
index 4515bea0268fa6ac17f8b2d61bd818bea42b6674..b09e51d2f81f98a1a985cdc410802b909bd361f2 100644 (file)
@@ -578,8 +578,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
        if (!jffs2_is_writebuffered(c))
                return 0;
 
-       if (mutex_trylock(&c->alloc_sem)) {
-               mutex_unlock(&c->alloc_sem);
+       if (!mutex_is_locked(&c->alloc_sem)) {
                printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");
                BUG();
        }
@@ -1026,7 +1025,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
        int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
        struct mtd_oob_ops ops;
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
        ops.oobbuf = c->oobbuf;
        ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
@@ -1069,7 +1068,7 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
        struct mtd_oob_ops ops;
        int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = cmlen;
        ops.oobbuf = c->oobbuf;
        ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
@@ -1095,7 +1094,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
        struct mtd_oob_ops ops;
        int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
 
-       ops.mode = MTD_OOB_AUTO;
+       ops.mode = MTD_OPS_AUTO_OOB;
        ops.ooblen = cmlen;
        ops.oobbuf = (uint8_t *)&oob_cleanmarker;
        ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
index 583636f745e59dbe7e66e1b3871496ac3b29a63d..cc5f811ed383ce9ad239e659e0056c59a81a5f73 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/buffer_head.h>         /* for sync_blockdev() */
 #include <linux/bio.h>
 #include <linux/freezer.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/seq_file.h>
index f2697e4df10919f1d87d7ae39346fe96e128d32e..e795c234ea33592e12cb264c0c8c84d2146f29c3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/bio.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/module.h>
 #include <linux/mtd/mtd.h>
 #include <linux/statfs.h>
 #include <linux/buffer_head.h>
index 3f32bcb0d9bd5beb882b67480ff3593d202f5837..ef175cb8cfd8e20be4be8496660521a371297a50 100644 (file)
 #include <linux/bitops.h>
 #include <linux/sched.h>
 
-static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
-
 static DEFINE_SPINLOCK(bitmap_lock);
 
-static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits)
+/*
+ * bitmap consists of blocks filled with 16bit words
+ * bit set == busy, bit clear == free
+ * endianness is a mess, but for counting zero bits it really doesn't matter...
+ */
+static __u32 count_free(struct buffer_head *map[], unsigned blocksize, __u32 numbits)
 {
-       unsigned i, j, sum = 0;
-       struct buffer_head *bh;
-  
-       for (i=0; i<numblocks-1; i++) {
-               if (!(bh=map[i])) 
-                       return(0);
-               for (j=0; j<bh->b_size; j++)
-                       sum += nibblemap[bh->b_data[j] & 0xf]
-                               + nibblemap[(bh->b_data[j]>>4) & 0xf];
-       }
+       __u32 sum = 0;
+       unsigned blocks = DIV_ROUND_UP(numbits, blocksize * 8);
 
-       if (numblocks==0 || !(bh=map[numblocks-1]))
-               return(0);
-       i = ((numbits - (numblocks-1) * bh->b_size * 8) / 16) * 2;
-       for (j=0; j<i; j++) {
-               sum += nibblemap[bh->b_data[j] & 0xf]
-                       + nibblemap[(bh->b_data[j]>>4) & 0xf];
+       while (blocks--) {
+               unsigned words = blocksize / 2;
+               __u16 *p = (__u16 *)(*map++)->b_data;
+               while (words--)
+                       sum += 16 - hweight16(*p++);
        }
 
-       i = numbits%16;
-       if (i!=0) {
-               i = *(__u16 *)(&bh->b_data[j]) | ~((1<<i) - 1);
-               sum += nibblemap[i & 0xf] + nibblemap[(i>>4) & 0xf];
-               sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf];
-       }
-       return(sum);
+       return sum;
 }
 
 void minix_free_block(struct inode *inode, unsigned long block)
@@ -105,10 +93,12 @@ int minix_new_block(struct inode * inode)
        return 0;
 }
 
-unsigned long minix_count_free_blocks(struct minix_sb_info *sbi)
+unsigned long minix_count_free_blocks(struct super_block *sb)
 {
-       return (count_free(sbi->s_zmap, sbi->s_zmap_blocks,
-               sbi->s_nzones - sbi->s_firstdatazone + 1)
+       struct minix_sb_info *sbi = minix_sb(sb);
+       u32 bits = sbi->s_nzones - (sbi->s_firstdatazone + 1);
+
+       return (count_free(sbi->s_zmap, sb->s_blocksize, bits)
                << sbi->s_log_zone_size);
 }
 
@@ -273,7 +263,10 @@ struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
        return inode;
 }
 
-unsigned long minix_count_free_inodes(struct minix_sb_info *sbi)
+unsigned long minix_count_free_inodes(struct super_block *sb)
 {
-       return count_free(sbi->s_imap, sbi->s_imap_blocks, sbi->s_ninodes + 1);
+       struct minix_sb_info *sbi = minix_sb(sb);
+       u32 bits = sbi->s_ninodes + 1;
+
+       return count_free(sbi->s_imap, sb->s_blocksize, bits);
 }
index 64cdcd662ffccca98fecad85103f10a2348a76bc..1d9e33966db089eb2ba5ed3f7aab9967bd2c0b4e 100644 (file)
@@ -279,6 +279,27 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
        else if (sbi->s_mount_state & MINIX_ERROR_FS)
                printk("MINIX-fs: mounting file system with errors, "
                        "running fsck is recommended\n");
+
+       /* Apparently minix can create filesystems that allocate more blocks for
+        * the bitmaps than needed.  We simply ignore that, but verify it didn't
+        * create one with not enough blocks and bail out if so.
+        */
+       block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize);
+       if (sbi->s_imap_blocks < block) {
+               printk("MINIX-fs: file system does not have enough "
+                               "imap blocks allocated.  Refusing to mount\n");
+               goto out_iput;
+       }
+
+       block = minix_blocks_needed(
+                       (sbi->s_nzones - (sbi->s_firstdatazone + 1)),
+                       s->s_blocksize);
+       if (sbi->s_zmap_blocks < block) {
+               printk("MINIX-fs: file system does not have enough "
+                               "zmap blocks allocated.  Refusing to mount.\n");
+               goto out_iput;
+       }
+
        return 0;
 
 out_iput:
@@ -339,10 +360,10 @@ static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_type = sb->s_magic;
        buf->f_bsize = sb->s_blocksize;
        buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size;
-       buf->f_bfree = minix_count_free_blocks(sbi);
+       buf->f_bfree = minix_count_free_blocks(sb);
        buf->f_bavail = buf->f_bfree;
        buf->f_files = sbi->s_ninodes;
-       buf->f_ffree = minix_count_free_inodes(sbi);
+       buf->f_ffree = minix_count_free_inodes(sb);
        buf->f_namelen = sbi->s_namelen;
        buf->f_fsid.val[0] = (u32)id;
        buf->f_fsid.val[1] = (u32)(id >> 32);
index 341e2122879a7604611426d4f702f211ee3ed59a..26bbd55e82ea2ab42f61fa2898fd45fee17f7074 100644 (file)
@@ -48,10 +48,10 @@ extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, stru
 extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
 extern struct inode * minix_new_inode(const struct inode *, int, int *);
 extern void minix_free_inode(struct inode * inode);
-extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi);
+extern unsigned long minix_count_free_inodes(struct super_block *sb);
 extern int minix_new_block(struct inode * inode);
 extern void minix_free_block(struct inode *inode, unsigned long block);
-extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
+extern unsigned long minix_count_free_blocks(struct super_block *sb);
 extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len);
 
@@ -88,6 +88,11 @@ static inline struct minix_inode_info *minix_i(struct inode *inode)
        return list_entry(inode, struct minix_inode_info, vfs_inode);
 }
 
+static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize)
+{
+       return DIV_ROUND_UP(bits, blocksize * 8);
+}
+
 #if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \
        defined(CONFIG_MINIX_FS_BIG_ENDIAN_16BIT_INDEXED)
 
@@ -125,7 +130,7 @@ static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size)
        if (!size)
                return 0;
 
-       size = (size >> 4) + ((size & 15) > 0);
+       size >>= 4;
        while (*p++ == 0xffff) {
                if (--size == 0)
                        return (p - addr) << 4;
index ac6d214da82790a8f16671e59dfffaf49e4c75bd..5008f01787f5681730a9273693a1a863e7e6cc7e 100644 (file)
@@ -852,7 +852,7 @@ static int follow_managed(struct path *path, unsigned flags)
                mntput(path->mnt);
        if (ret == -EISDIR)
                ret = 0;
-       return ret;
+       return ret < 0 ? ret : need_mntput;
 }
 
 int follow_down_one(struct path *path)
@@ -900,6 +900,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
                        break;
                path->mnt = mounted;
                path->dentry = mounted->mnt_root;
+               nd->flags |= LOOKUP_JUMPED;
                nd->seq = read_seqcount_begin(&path->dentry->d_seq);
                /*
                 * Update the inode too. We don't need to re-check the
@@ -1213,6 +1214,8 @@ retry:
                path_put_conditional(path, nd);
                return err;
        }
+       if (err)
+               nd->flags |= LOOKUP_JUMPED;
        *inode = path->dentry->d_inode;
        return 0;
 }
@@ -2146,6 +2149,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        }
 
        /* create side of things */
+       /*
+        * This will *only* deal with leaving RCU mode - LOOKUP_JUMPED has been
+        * cleared when we got to the last component we are about to look up
+        */
        error = complete_walk(nd);
        if (error)
                return ERR_PTR(error);
@@ -2214,6 +2221,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        if (error < 0)
                goto exit_dput;
 
+       if (error)
+               nd->flags |= LOOKUP_JUMPED;
+
        error = -ENOENT;
        if (!path->dentry->d_inode)
                goto exit_dput;
@@ -2223,6 +2233,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 
        path_to_nameidata(path, nd);
        nd->inode = path->dentry->d_inode;
+       /* Why this, you ask?  _Now_ we might have grown LOOKUP_JUMPED... */
+       error = complete_walk(nd);
+       if (error)
+               goto exit;
        error = -EISDIR;
        if (S_ISDIR(nd->inode->i_mode))
                goto exit;
index e5e1c7d1839b791f0c52428a9ffe058bd7ded092..cfc6d4448aa54bdc538131b1e53285a92bb20073 100644 (file)
@@ -1048,15 +1048,12 @@ static int show_mountinfo(struct seq_file *m, void *v)
        if (err)
                goto out;
        seq_putc(m, ' ');
-       seq_path_root(m, &mnt_path, &root, " \t\n\\");
-       if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) {
-               /*
-                * Mountpoint is outside root, discard that one.  Ugly,
-                * but less so than trying to do that in iterator in a
-                * race-free way (due to renames).
-                */
-               return SEQ_SKIP;
-       }
+
+       /* mountpoints outside of chroot jail will give SEQ_SKIP on this */
+       err = seq_path_root(m, &mnt_path, &root, " \t\n\\");
+       if (err)
+               goto out;
+
        seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
        show_mnt_opts(m, mnt);
 
@@ -2483,11 +2480,43 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
                __mnt_make_longterm(mnt);
                new_ns->root = mnt;
                list_add(&new_ns->list, &new_ns->root->mnt_list);
+       } else {
+               mntput(mnt);
        }
        return new_ns;
 }
 EXPORT_SYMBOL(create_mnt_ns);
 
+struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
+{
+       struct mnt_namespace *ns;
+       struct super_block *s;
+       struct path path;
+       int err;
+
+       ns = create_mnt_ns(mnt);
+       if (IS_ERR(ns))
+               return ERR_CAST(ns);
+
+       err = vfs_path_lookup(mnt->mnt_root, mnt,
+                       name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
+
+       put_mnt_ns(ns);
+
+       if (err)
+               return ERR_PTR(err);
+
+       /* trade a vfsmount reference for active sb one */
+       s = path.mnt->mnt_sb;
+       atomic_inc(&s->s_active);
+       mntput(path.mnt);
+       /* lock the sucker */
+       down_write(&s->s_umount);
+       /* ... and return the root of (sub)tree on it */
+       return path.dentry;
+}
+EXPORT_SYMBOL(mount_subtree);
+
 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
                char __user *, type, unsigned long, flags, void __user *, data)
 {
@@ -2744,3 +2773,8 @@ void kern_unmount(struct vfsmount *mnt)
        }
 }
 EXPORT_SYMBOL(kern_unmount);
+
+bool our_mnt(struct vfsmount *mnt)
+{
+       return check_mnt(mnt);
+}
index b238d95ac48c7b926ff1e02eae157ea09fa58a68..ac289909814768a626ad817dbf40627805e7899e 100644 (file)
@@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                res = ERR_CAST(inode);
index 0a1f8312b4dcf0fe9272310f1ab6d00178cdd2a8..eca56d4b39c0ae82caf3abb117bb9ad5163ec1b3 100644 (file)
 
 #define NFSDBG_FACILITY                NFSDBG_FILE
 
-static int nfs_file_open(struct inode *, struct file *);
-static int nfs_file_release(struct inode *, struct file *);
-static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
-static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
-static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
-                                       struct pipe_inode_info *pipe,
-                                       size_t count, unsigned int flags);
-static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
-                               unsigned long nr_segs, loff_t pos);
-static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
-                                       struct file *filp, loff_t *ppos,
-                                       size_t count, unsigned int flags);
-static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
-                               unsigned long nr_segs, loff_t pos);
-static int  nfs_file_flush(struct file *, fl_owner_t id);
-static int  nfs_file_fsync(struct file *, loff_t, loff_t, int datasync);
-static int nfs_check_flags(int flags);
-static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
-static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
-
 static const struct vm_operations_struct nfs_file_vm_ops;
 
-const struct file_operations nfs_file_operations = {
-       .llseek         = nfs_file_llseek,
-       .read           = do_sync_read,
-       .write          = do_sync_write,
-       .aio_read       = nfs_file_read,
-       .aio_write      = nfs_file_write,
-       .mmap           = nfs_file_mmap,
-       .open           = nfs_file_open,
-       .flush          = nfs_file_flush,
-       .release        = nfs_file_release,
-       .fsync          = nfs_file_fsync,
-       .lock           = nfs_lock,
-       .flock          = nfs_flock,
-       .splice_read    = nfs_file_splice_read,
-       .splice_write   = nfs_file_splice_write,
-       .check_flags    = nfs_check_flags,
-       .setlease       = nfs_setlease,
-};
-
 const struct inode_operations nfs_file_inode_operations = {
        .permission     = nfs_permission,
        .getattr        = nfs_getattr,
@@ -886,3 +846,54 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
                        file->f_path.dentry->d_name.name, arg);
        return -EINVAL;
 }
+
+const struct file_operations nfs_file_operations = {
+       .llseek         = nfs_file_llseek,
+       .read           = do_sync_read,
+       .write          = do_sync_write,
+       .aio_read       = nfs_file_read,
+       .aio_write      = nfs_file_write,
+       .mmap           = nfs_file_mmap,
+       .open           = nfs_file_open,
+       .flush          = nfs_file_flush,
+       .release        = nfs_file_release,
+       .fsync          = nfs_file_fsync,
+       .lock           = nfs_lock,
+       .flock          = nfs_flock,
+       .splice_read    = nfs_file_splice_read,
+       .splice_write   = nfs_file_splice_write,
+       .check_flags    = nfs_check_flags,
+       .setlease       = nfs_setlease,
+};
+
+#ifdef CONFIG_NFS_V4
+static int
+nfs4_file_open(struct inode *inode, struct file *filp)
+{
+       /*
+        * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to
+        * this point, then something is very wrong
+        */
+       dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp);
+       return -ENOTDIR;
+}
+
+const struct file_operations nfs4_file_operations = {
+       .llseek         = nfs_file_llseek,
+       .read           = do_sync_read,
+       .write          = do_sync_write,
+       .aio_read       = nfs_file_read,
+       .aio_write      = nfs_file_write,
+       .mmap           = nfs_file_mmap,
+       .open           = nfs4_file_open,
+       .flush          = nfs_file_flush,
+       .release        = nfs_file_release,
+       .fsync          = nfs_file_fsync,
+       .lock           = nfs_lock,
+       .flock          = nfs_flock,
+       .splice_read    = nfs_file_splice_read,
+       .splice_write   = nfs_file_splice_write,
+       .check_flags    = nfs_check_flags,
+       .setlease       = nfs_setlease,
+};
+#endif /* CONFIG_NFS_V4 */
index c07a55aec83867ee1489ff29134862bc891dfa82..50a15fa8cf985e41e21b786f4f6d9d9ed96cf37e 100644 (file)
@@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                 */
                inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
                if (S_ISREG(inode->i_mode)) {
-                       inode->i_fop = &nfs_file_operations;
+                       inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
                        inode->i_data.a_ops = &nfs_file_aops;
                        inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
                } else if (S_ISDIR(inode->i_mode)) {
index c1a1bd8ddf1cbecfbba4f375fec6c78d5d36ae60..3f4d95751d52f3e152fc7f2dcb5d1a6d8fc2184b 100644 (file)
@@ -299,6 +299,8 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
 extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
                struct list_head *head);
 
+extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
+               struct inode *inode);
 extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
 extern void nfs_readdata_release(struct nfs_read_data *rdata);
 
index 85f1690ca08c110bcd1c1754e564f23619295a1a..d4bc9ed917484106dbed777942e0db096be08236 100644 (file)
@@ -853,6 +853,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
        .dentry_ops     = &nfs_dentry_operations,
        .dir_inode_ops  = &nfs3_dir_inode_operations,
        .file_inode_ops = &nfs3_file_inode_operations,
+       .file_ops       = &nfs_file_operations,
        .getroot        = nfs3_proc_get_root,
        .getattr        = nfs3_proc_getattr,
        .setattr        = nfs3_proc_setattr,
index 12185aadb349cbf236573ccd0028b37ba384d964..a62d36b9a99ebb912286a8fcf87f425e6b06f203 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
+#include <linux/module.h>
 
 #include "internal.h"
 #include "nfs4filelayout.h"
index b60fddf606f7d23e6f01305420446d74102001a7..be2bbac13817c7ec624363afb4caf8bdd65a72b4 100644 (file)
@@ -2464,8 +2464,7 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst
                case -NFS4ERR_BADNAME:
                        return -ENOENT;
                case -NFS4ERR_MOVED:
-                       err = nfs4_get_referral(dir, name, fattr, fhandle);
-                       break;
+                       return nfs4_get_referral(dir, name, fattr, fhandle);
                case -NFS4ERR_WRONGSEC:
                        nfs_fixup_secinfo_attributes(fattr, fhandle);
                }
@@ -6253,6 +6252,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .dentry_ops     = &nfs4_dentry_operations,
        .dir_inode_ops  = &nfs4_dir_inode_operations,
        .file_inode_ops = &nfs4_file_inode_operations,
+       .file_ops       = &nfs4_file_operations,
        .getroot        = nfs4_proc_get_root,
        .getattr        = nfs4_proc_getattr,
        .setattr        = nfs4_proc_setattr,
index 0a5ff5c195114ba5cdcd703b07891fd5e60ef7e3..5668f7c54c41e2d35ff1afd2c24a2bf786406c71 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/nfs_page.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
+#include <linux/export.h>
 
 #include "internal.h"
 #include "pnfs.h"
index a2478bc74442ae67f8bbc0d5fab936823dcde43e..8e672a2b2d693193e8ca7252d70c73578d739e0f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
+#include <linux/module.h>
 #include "internal.h"
 #include "pnfs.h"
 #include "iostat.h"
@@ -1259,6 +1260,25 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
 
+static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
+{
+       struct nfs_pageio_descriptor pgio;
+
+       put_lseg(data->lseg);
+       data->lseg = NULL;
+       dprintk("pnfs write error = %d\n", data->pnfs_error);
+
+       nfs_pageio_init_read_mds(&pgio, data->inode);
+
+       while (!list_empty(&data->pages)) {
+               struct nfs_page *req = nfs_list_entry(data->pages.next);
+
+               nfs_list_remove_request(req);
+               nfs_pageio_add_request(&pgio, req);
+       }
+       nfs_pageio_complete(&pgio);
+}
+
 /*
  * Called by non rpc-based layout drivers
  */
@@ -1267,11 +1287,8 @@ void pnfs_ld_read_done(struct nfs_read_data *data)
        if (likely(!data->pnfs_error)) {
                __nfs4_read_done_cb(data);
                data->mds_ops->rpc_call_done(&data->task, data);
-       } else {
-               put_lseg(data->lseg);
-               data->lseg = NULL;
-               dprintk("pnfs write error = %d\n", data->pnfs_error);
-       }
+       } else
+               pnfs_ld_handle_read_error(data);
        data->mds_ops->rpc_release(data);
 }
 EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
index 6fda5228ef5627d45da3cdf4933e6a098b018820..4f359d2a26ebe3ce4a2160758c2a5e6c69163ba6 100644 (file)
@@ -28,6 +28,7 @@
  *  such damages.
  */
 
+#include <linux/export.h>
 #include "pnfs.h"
 
 #define NFSDBG_FACILITY                NFSDBG_PNFS
index ac40b8535d7e0e7493f13063afdbe57169837c9e..f48125da198a2d5a50bc0861805212a129427920 100644 (file)
@@ -710,6 +710,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
        .dentry_ops     = &nfs_dentry_operations,
        .dir_inode_ops  = &nfs_dir_inode_operations,
        .file_inode_ops = &nfs_file_inode_operations,
+       .file_ops       = &nfs_file_operations,
        .getroot        = nfs_proc_get_root,
        .getattr        = nfs_proc_getattr,
        .setattr        = nfs_proc_setattr,
index 8b48ec63f7229de8cb9435cfe82cc9d9876e6268..cfa175c223dcfa5b79ebf17b3d609649fbd7188d 100644 (file)
@@ -109,7 +109,7 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data)
        }
 }
 
-static void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
+void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio,
                struct inode *inode)
 {
        nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops,
@@ -534,23 +534,13 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
 static void nfs_readpage_release_full(void *calldata)
 {
        struct nfs_read_data *data = calldata;
-       struct nfs_pageio_descriptor pgio;
 
-       if (data->pnfs_error) {
-               nfs_pageio_init_read_mds(&pgio, data->inode);
-               pgio.pg_recoalesce = 1;
-       }
        while (!list_empty(&data->pages)) {
                struct nfs_page *req = nfs_list_entry(data->pages.next);
 
                nfs_list_remove_request(req);
-               if (!data->pnfs_error)
-                       nfs_readpage_release(req);
-               else
-                       nfs_pageio_add_request(&pgio, req);
+               nfs_readpage_release(req);
        }
-       if (data->pnfs_error)
-               nfs_pageio_complete(&pgio);
        nfs_readdata_release(calldata);
 }
 
index 480b3b6bf71ef82f122a433cbf3ec62d789c033a..134777406ee31938271db7ad0af8c8cb444e6fc9 100644 (file)
@@ -2787,43 +2787,18 @@ static void nfs_referral_loop_unprotect(void)
 static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
                const char *export_path)
 {
-       struct mnt_namespace *ns_private;
-       struct super_block *s;
        struct dentry *dentry;
-       struct path path;
-       int ret;
-
-       ns_private = create_mnt_ns(root_mnt);
-       ret = PTR_ERR(ns_private);
-       if (IS_ERR(ns_private))
-               goto out_mntput;
-
-       ret = nfs_referral_loop_protect();
-       if (ret != 0)
-               goto out_put_mnt_ns;
+       int ret = nfs_referral_loop_protect();
 
-       ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
-                       export_path, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
+       if (ret) {
+               mntput(root_mnt);
+               return ERR_PTR(ret);
+       }
 
+       dentry = mount_subtree(root_mnt, export_path);
        nfs_referral_loop_unprotect();
-       put_mnt_ns(ns_private);
-
-       if (ret != 0)
-               goto out_err;
-
-       s = path.mnt->mnt_sb;
-       atomic_inc(&s->s_active);
-       dentry = dget(path.dentry);
 
-       path_put(&path);
-       down_write(&s->s_umount);
        return dentry;
-out_put_mnt_ns:
-       put_mnt_ns(ns_private);
-out_mntput:
-       mntput(root_mnt);
-out_err:
-       return ERR_PTR(ret);
 }
 
 static struct dentry *nfs4_try_mount(int flags, const char *dev_name,
index b016b8a36399d9f491866547ea3f7ea8ca4b8552..1dda78db6a73256e8aeee11254e968f0547e4075 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/nfs_mount.h>
 #include <linux/nfs_page.h>
 #include <linux/backing-dev.h>
+#include <linux/export.h>
 
 #include <asm/uaccess.h>
 
index ad88f1c0a4c3f5d5f05173aafba65f143e6ec0f2..9c51aff02ae28f7b77d2da214a9057da8dc06518 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/nfs_fs.h>
+#include <linux/export.h>
 #include "acl.h"
 
 
index db34a585e1129926b672ccc9f5a2f4b42c0a6f2e..c45a2ea4a09097acba065bbd7cdfaf1718cb7d23 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/gss_api.h>
 #include <linux/sunrpc/gss_krb5_enctypes.h>
+#include <linux/module.h>
 
 #include "idmap.h"
 #include "nfsd.h"
index 52cd976b6099fafbb4950ed25fef81d93ee255e4..eda7d7e55e05c45aa309f1465f60368bf3f00242 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/sched.h>
 #include <linux/freezer.h>
+#include <linux/module.h>
 #include <linux/fs_struct.h>
 #include <linux/swap.h>
 
index ed553c60de827e0ebad24e3501e0e00d21c82cfc..3165aebb43c87934b743ecf08e5f02cef586d771 100644 (file)
@@ -5699,7 +5699,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
                                           OCFS2_JOURNAL_ACCESS_WRITE);
        if (ret) {
                mlog_errno(ret);
-               goto out;
+               goto out_commit;
        }
 
        dquot_free_space_nodirty(inode,
index c1efe939c774e2c9b909892f6c95434d6da760ee..78b68af3b0e32627b1874277d8ae58003501acb5 100644 (file)
@@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
        }
 
        if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
+               /*
+                * Unlock the page and cycle ip_alloc_sem so that we don't
+                * busyloop waiting for ip_alloc_sem to unlock
+                */
                ret = AOP_TRUNCATED_PAGE;
+               unlock_page(page);
+               unlock = 0;
+               down_read(&oi->ip_alloc_sem);
+               up_read(&oi->ip_alloc_sem);
                goto out_inode_unlock;
        }
 
@@ -563,6 +571,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
        int level;
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
@@ -570,6 +579,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        if (ocfs2_iocb_is_sem_locked(iocb))
                ocfs2_iocb_clear_sem_locked(iocb);
 
+       if (ocfs2_iocb_is_unaligned_aio(iocb)) {
+               ocfs2_iocb_clear_unaligned_aio(iocb);
+
+               if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
+       }
+
        ocfs2_iocb_clear_rw_locked(iocb);
 
        level = ocfs2_iocb_rw_locked_level(iocb);
@@ -862,6 +880,12 @@ struct ocfs2_write_ctxt {
        struct page                     *w_pages[OCFS2_MAX_CTXT_PAGES];
        struct page                     *w_target_page;
 
+       /*
+        * w_target_locked is used for page_mkwrite path indicating no unlocking
+        * against w_target_page in ocfs2_write_end_nolock.
+        */
+       unsigned int                    w_target_locked:1;
+
        /*
         * ocfs2_write_end() uses this to know what the real range to
         * write in the target should be.
@@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
 
 static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
 {
+       int i;
+
+       /*
+        * w_target_locked is only set to true in the page_mkwrite() case.
+        * The intent is to allow us to lock the target page from write_begin()
+        * to write_end(). The caller must hold a ref on w_target_page.
+        */
+       if (wc->w_target_locked) {
+               BUG_ON(!wc->w_target_page);
+               for (i = 0; i < wc->w_num_pages; i++) {
+                       if (wc->w_target_page == wc->w_pages[i]) {
+                               wc->w_pages[i] = NULL;
+                               break;
+                       }
+               }
+               mark_page_accessed(wc->w_target_page);
+               page_cache_release(wc->w_target_page);
+       }
        ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
 
        brelse(wc->w_di_bh);
@@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                         */
                        lock_page(mmap_page);
 
+                       /* Exit and let the caller retry */
                        if (mmap_page->mapping != mapping) {
+                               WARN_ON(mmap_page->mapping);
                                unlock_page(mmap_page);
-                               /*
-                                * Sanity check - the locking in
-                                * ocfs2_pagemkwrite() should ensure
-                                * that this code doesn't trigger.
-                                */
-                               ret = -EINVAL;
-                               mlog_errno(ret);
+                               ret = -EAGAIN;
                                goto out;
                        }
 
                        page_cache_get(mmap_page);
                        wc->w_pages[i] = mmap_page;
+                       wc->w_target_locked = true;
                } else {
                        wc->w_pages[i] = find_or_create_page(mapping, index,
                                                             GFP_NOFS);
@@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                        wc->w_target_page = wc->w_pages[i];
        }
 out:
+       if (ret)
+               wc->w_target_locked = false;
        return ret;
 }
 
@@ -1817,11 +1858,23 @@ try_again:
         */
        ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
                                         cluster_of_pages, mmap_page);
-       if (ret) {
+       if (ret && ret != -EAGAIN) {
                mlog_errno(ret);
                goto out_quota;
        }
 
+       /*
+        * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
+        * the target page. In this case, we exit with no error and no target
+        * page. This will trigger the caller, page_mkwrite(), to re-try
+        * the operation.
+        */
+       if (ret == -EAGAIN) {
+               BUG_ON(wc->w_target_page);
+               ret = 0;
+               goto out_quota;
+       }
+
        ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
                                          len);
        if (ret) {
index 75cf3ad987a66d911c15234a803243185ccc5a94..ffb2da370a99d05dd4b919fc64a5483dbc2df7a3 100644 (file)
@@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits {
        OCFS2_IOCB_RW_LOCK = 0,
        OCFS2_IOCB_RW_LOCK_LEVEL,
        OCFS2_IOCB_SEM,
+       OCFS2_IOCB_UNALIGNED_IO,
        OCFS2_IOCB_NUM_LOCKS
 };
 
@@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits {
        clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
 #define ocfs2_iocb_is_sem_locked(iocb) \
        test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+
+#define ocfs2_iocb_set_unaligned_aio(iocb) \
+       set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_unaligned_aio(iocb) \
+       clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_unaligned_aio(iocb) \
+       test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+
+#define OCFS2_IOEND_WQ_HASH_SZ 37
+#define ocfs2_ioend_wq(v)   (&ocfs2__ioend_wq[((unsigned long)(v)) %\
+                                           OCFS2_IOEND_WQ_HASH_SZ])
+extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 #endif /* OCFS2_FILE_H */
index 9a3e6bbff27bd4839b487c2c14282fd9ef1a4675..a4e855e3690e6ab844d37788b71649975321cb19 100644 (file)
@@ -216,6 +216,7 @@ struct o2hb_region {
 
        struct list_head        hr_all_item;
        unsigned                hr_unclean_stop:1,
+                               hr_aborted_start:1,
                                hr_item_pinned:1,
                                hr_item_dropped:1;
 
@@ -254,6 +255,10 @@ struct o2hb_region {
         * a more complete api that doesn't lead to this sort of fragility. */
        atomic_t                hr_steady_iterations;
 
+       /* terminate o2hb thread if it does not reach steady state
+        * (hr_steady_iterations == 0) within hr_unsteady_iterations */
+       atomic_t                hr_unsteady_iterations;
+
        char                    hr_dev_name[BDEVNAME_SIZE];
 
        unsigned int            hr_timeout_ms;
@@ -324,6 +329,10 @@ static void o2hb_write_timeout(struct work_struct *work)
 
 static void o2hb_arm_write_timeout(struct o2hb_region *reg)
 {
+       /* Arm writeout only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
+               return;
+
        mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
             O2HB_MAX_WRITE_TIMEOUT_MS);
 
@@ -537,9 +546,14 @@ static int o2hb_verify_crc(struct o2hb_region *reg,
        return read == computed;
 }
 
-/* We want to make sure that nobody is heartbeating on top of us --
- * this will help detect an invalid configuration. */
-static void o2hb_check_last_timestamp(struct o2hb_region *reg)
+/*
+ * Compare the slot data with what we wrote in the last iteration.
+ * If the match fails, print an appropriate error message. This is to
+ * detect errors like... another node hearting on the same slot,
+ * flaky device that is losing writes, etc.
+ * Returns 1 if check succeeds, 0 otherwise.
+ */
+static int o2hb_check_own_slot(struct o2hb_region *reg)
 {
        struct o2hb_disk_slot *slot;
        struct o2hb_disk_heartbeat_block *hb_block;
@@ -548,13 +562,13 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
        slot = &reg->hr_slots[o2nm_this_node()];
        /* Don't check on our 1st timestamp */
        if (!slot->ds_last_time)
-               return;
+               return 0;
 
        hb_block = slot->ds_raw_block;
        if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time &&
            le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation &&
            hb_block->hb_node == slot->ds_node_num)
-               return;
+               return 1;
 
 #define ERRSTR1                "Another node is heartbeating on device"
 #define ERRSTR2                "Heartbeat generation mismatch on device"
@@ -574,6 +588,8 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
             (unsigned long long)slot->ds_last_time, hb_block->hb_node,
             (unsigned long long)le64_to_cpu(hb_block->hb_generation),
             (unsigned long long)le64_to_cpu(hb_block->hb_seq));
+
+       return 0;
 }
 
 static inline void o2hb_prepare_block(struct o2hb_region *reg,
@@ -719,17 +735,24 @@ static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot)
        o2nm_node_put(node);
 }
 
-static void o2hb_set_quorum_device(struct o2hb_region *reg,
-                                  struct o2hb_disk_slot *slot)
+static void o2hb_set_quorum_device(struct o2hb_region *reg)
 {
-       assert_spin_locked(&o2hb_live_lock);
-
        if (!o2hb_global_heartbeat_active())
                return;
 
-       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+       /* Prevent race with o2hb_heartbeat_group_drop_item() */
+       if (kthread_should_stop())
+               return;
+
+       /* Tag region as quorum only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
                return;
 
+       spin_lock(&o2hb_live_lock);
+
+       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+               goto unlock;
+
        /*
         * A region can be added to the quorum only when it sees all
         * live nodes heartbeat on it. In other words, the region has been
@@ -737,13 +760,10 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
         */
        if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap,
                   sizeof(o2hb_live_node_bitmap)))
-               return;
-
-       if (slot->ds_changed_samples < O2HB_LIVE_THRESHOLD)
-               return;
+               goto unlock;
 
-       printk(KERN_NOTICE "o2hb: Region %s is now a quorum device\n",
-              config_item_name(&reg->hr_item));
+       printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n",
+              config_item_name(&reg->hr_item), reg->hr_dev_name);
 
        set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
 
@@ -754,6 +774,8 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
        if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
                           O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
                o2hb_region_unpin(NULL);
+unlock:
+       spin_unlock(&o2hb_live_lock);
 }
 
 static int o2hb_check_slot(struct o2hb_region *reg,
@@ -925,8 +947,6 @@ fire_callbacks:
                slot->ds_equal_samples = 0;
        }
 out:
-       o2hb_set_quorum_device(reg, slot);
-
        spin_unlock(&o2hb_live_lock);
 
        o2hb_run_event_list(&event);
@@ -957,7 +977,8 @@ static int o2hb_highest_node(unsigned long *nodes,
 
 static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 {
-       int i, ret, highest_node, change = 0;
+       int i, ret, highest_node;
+       int membership_change = 0, own_slot_ok = 0;
        unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
        unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
        struct o2hb_bio_wait_ctxt write_wc;
@@ -966,7 +987,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                                       sizeof(configured_nodes));
        if (ret) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /*
@@ -982,8 +1003,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 
        highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES);
        if (highest_node >= O2NM_MAX_NODES) {
-               mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n");
-               return -EINVAL;
+               mlog(ML_NOTICE, "o2hb: No configured nodes found!\n");
+               ret = -EINVAL;
+               goto bail;
        }
 
        /* No sense in reading the slots of nodes that don't exist
@@ -993,29 +1015,27 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
        ret = o2hb_read_slots(reg, highest_node + 1);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /* With an up to date view of the slots, we can check that no
         * other node has been improperly configured to heartbeat in
         * our slot. */
-       o2hb_check_last_timestamp(reg);
+       own_slot_ok = o2hb_check_own_slot(reg);
 
        /* fill in the proper info for our next heartbeat */
        o2hb_prepare_block(reg, reg->hr_generation);
 
-       /* And fire off the write. Note that we don't wait on this I/O
-        * until later. */
        ret = o2hb_issue_node_write(reg, &write_wc);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        i = -1;
        while((i = find_next_bit(configured_nodes,
                                 O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
-               change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
+               membership_change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
        }
 
        /*
@@ -1030,18 +1050,39 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                 * disk */
                mlog(ML_ERROR, "Write error %d on device \"%s\"\n",
                     write_wc.wc_error, reg->hr_dev_name);
-               return write_wc.wc_error;
+               ret = write_wc.wc_error;
+               goto bail;
        }
 
-       o2hb_arm_write_timeout(reg);
+       /* Skip disarming the timeout if own slot has stale/bad data */
+       if (own_slot_ok) {
+               o2hb_set_quorum_device(reg);
+               o2hb_arm_write_timeout(reg);
+       }
 
+bail:
        /* let the person who launched us know when things are steady */
-       if (!change && (atomic_read(&reg->hr_steady_iterations) != 0)) {
-               if (atomic_dec_and_test(&reg->hr_steady_iterations))
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (!ret && own_slot_ok && !membership_change) {
+                       if (atomic_dec_and_test(&reg->hr_steady_iterations))
+                               wake_up(&o2hb_steady_queue);
+               }
+       }
+
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (atomic_dec_and_test(&reg->hr_unsteady_iterations)) {
+                       printk(KERN_NOTICE "o2hb: Unable to stabilize "
+                              "heartbeart on region %s (%s)\n",
+                              config_item_name(&reg->hr_item),
+                              reg->hr_dev_name);
+                       atomic_set(&reg->hr_steady_iterations, 0);
+                       reg->hr_aborted_start = 1;
                        wake_up(&o2hb_steady_queue);
+                       ret = -EIO;
+               }
        }
 
-       return 0;
+       return ret;
 }
 
 /* Subtract b from a, storing the result in a. a *must* have a larger
@@ -1095,7 +1136,8 @@ static int o2hb_thread(void *data)
        /* Pin node */
        o2nm_depend_this_node();
 
-       while (!kthread_should_stop() && !reg->hr_unclean_stop) {
+       while (!kthread_should_stop() &&
+              !reg->hr_unclean_stop && !reg->hr_aborted_start) {
                /* We track the time spent inside
                 * o2hb_do_disk_heartbeat so that we avoid more than
                 * hr_timeout_ms between disk writes. On busy systems
@@ -1103,10 +1145,7 @@ static int o2hb_thread(void *data)
                 * likely to time itself out. */
                do_gettimeofday(&before_hb);
 
-               i = 0;
-               do {
-                       ret = o2hb_do_disk_heartbeat(reg);
-               } while (ret && ++i < 2);
+               ret = o2hb_do_disk_heartbeat(reg);
 
                do_gettimeofday(&after_hb);
                elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
@@ -1117,7 +1156,8 @@ static int o2hb_thread(void *data)
                     after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
                     elapsed_msec);
 
-               if (elapsed_msec < reg->hr_timeout_ms) {
+               if (!kthread_should_stop() &&
+                   elapsed_msec < reg->hr_timeout_ms) {
                        /* the kthread api has blocked signals for us so no
                         * need to record the return value. */
                        msleep_interruptible(reg->hr_timeout_ms - elapsed_msec);
@@ -1134,20 +1174,20 @@ static int o2hb_thread(void *data)
         * to timeout on this region when we could just as easily
         * write a clear generation - thus indicating to them that
         * this node has left this region.
-        *
-        * XXX: Should we skip this on unclean_stop? */
-       o2hb_prepare_block(reg, 0);
-       ret = o2hb_issue_node_write(reg, &write_wc);
-       if (ret == 0) {
-               o2hb_wait_on_io(reg, &write_wc);
-       } else {
-               mlog_errno(ret);
+        */
+       if (!reg->hr_unclean_stop && !reg->hr_aborted_start) {
+               o2hb_prepare_block(reg, 0);
+               ret = o2hb_issue_node_write(reg, &write_wc);
+               if (ret == 0)
+                       o2hb_wait_on_io(reg, &write_wc);
+               else
+                       mlog_errno(ret);
        }
 
        /* Unpin node */
        o2nm_undepend_this_node();
 
-       mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
+       mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n");
 
        return 0;
 }
@@ -1158,6 +1198,7 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
        struct o2hb_debug_buf *db = inode->i_private;
        struct o2hb_region *reg;
        unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long lts;
        char *buf = NULL;
        int i = -1;
        int out = 0;
@@ -1194,9 +1235,11 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
 
        case O2HB_DB_TYPE_REGION_ELAPSED_TIME:
                reg = (struct o2hb_region *)db->db_data;
-               out += snprintf(buf + out, PAGE_SIZE - out, "%u\n",
-                               jiffies_to_msecs(jiffies -
-                                                reg->hr_last_timeout_start));
+               lts = reg->hr_last_timeout_start;
+               /* If 0, it has never been set before */
+               if (lts)
+                       lts = jiffies_to_msecs(jiffies - lts);
+               out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts);
                goto done;
 
        case O2HB_DB_TYPE_REGION_PINNED:
@@ -1426,6 +1469,8 @@ static void o2hb_region_release(struct config_item *item)
        struct page *page;
        struct o2hb_region *reg = to_o2hb_region(item);
 
+       mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name);
+
        if (reg->hr_tmp_block)
                kfree(reg->hr_tmp_block);
 
@@ -1792,7 +1837,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                        live_threshold <<= 1;
                spin_unlock(&o2hb_live_lock);
        }
-       atomic_set(&reg->hr_steady_iterations, live_threshold + 1);
+       ++live_threshold;
+       atomic_set(&reg->hr_steady_iterations, live_threshold);
+       /* unsteady_iterations is double the steady_iterations */
+       atomic_set(&reg->hr_unsteady_iterations, (live_threshold << 1));
 
        hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
                              reg->hr_item.ci_name);
@@ -1809,14 +1857,12 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
        ret = wait_event_interruptible(o2hb_steady_queue,
                                atomic_read(&reg->hr_steady_iterations) == 0);
        if (ret) {
-               /* We got interrupted (hello ptrace!).  Clean up */
-               spin_lock(&o2hb_live_lock);
-               hb_task = reg->hr_task;
-               reg->hr_task = NULL;
-               spin_unlock(&o2hb_live_lock);
+               atomic_set(&reg->hr_steady_iterations, 0);
+               reg->hr_aborted_start = 1;
+       }
 
-               if (hb_task)
-                       kthread_stop(hb_task);
+       if (reg->hr_aborted_start) {
+               ret = -EIO;
                goto out;
        }
 
@@ -1833,8 +1879,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                ret = -EIO;
 
        if (hb_task && o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s\n",
-                      config_item_name(&reg->hr_item));
+               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n",
+                      config_item_name(&reg->hr_item), reg->hr_dev_name);
 
 out:
        if (filp)
@@ -2092,13 +2138,6 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 
        /* stop the thread when the user removes the region dir */
        spin_lock(&o2hb_live_lock);
-       if (o2hb_global_heartbeat_active()) {
-               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
-               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
-               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
-                       quorum_region = 1;
-               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
-       }
        hb_task = reg->hr_task;
        reg->hr_task = NULL;
        reg->hr_item_dropped = 1;
@@ -2107,19 +2146,30 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
        if (hb_task)
                kthread_stop(hb_task);
 
+       if (o2hb_global_heartbeat_active()) {
+               spin_lock(&o2hb_live_lock);
+               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
+               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
+               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+                       quorum_region = 1;
+               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
+               spin_unlock(&o2hb_live_lock);
+               printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n",
+                      ((atomic_read(&reg->hr_steady_iterations) == 0) ?
+                       "stopped" : "start aborted"), config_item_name(item),
+                      reg->hr_dev_name);
+       }
+
        /*
         * If we're racing a dev_write(), we need to wake them.  They will
         * check reg->hr_task
         */
        if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               reg->hr_aborted_start = 1;
                atomic_set(&reg->hr_steady_iterations, 0);
                wake_up(&o2hb_steady_queue);
        }
 
-       if (o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n",
-                      config_item_name(&reg->hr_item));
-
        config_item_put(item);
 
        if (!o2hb_global_heartbeat_active() || !quorum_region)
index 3a5835904b3db4d522c561908171f528bb74f6bd..dc45deb19e6885e56a1f5be46cbd39444c46f810 100644 (file)
@@ -47,6 +47,7 @@
 #define SC_DEBUG_NAME          "sock_containers"
 #define NST_DEBUG_NAME         "send_tracking"
 #define STATS_DEBUG_NAME       "stats"
+#define NODES_DEBUG_NAME       "connected_nodes"
 
 #define SHOW_SOCK_CONTAINERS   0
 #define SHOW_SOCK_STATS                1
@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
 static struct dentry *sc_dentry;
 static struct dentry *nst_dentry;
 static struct dentry *stats_dentry;
+static struct dentry *nodes_dentry;
 
 static DEFINE_SPINLOCK(o2net_debug_lock);
 
@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
        .release = sc_fop_release,
 };
 
-int o2net_debugfs_init(void)
+static int o2net_fill_bitmap(char *buf, int len)
 {
-       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
-       if (!o2net_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       int i = -1, out = 0;
 
-       nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                        o2net_dentry, NULL,
-                                        &nst_seq_fops);
-       if (!nst_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       o2net_fill_node_map(map, sizeof(map));
 
-       sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                       o2net_dentry, NULL,
-                                       &sc_seq_fops);
-       if (!sc_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+               out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+       out += snprintf(buf + out, PAGE_SIZE - out, "\n");
 
-       stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                          o2net_dentry, NULL,
-                                          &stats_seq_fops);
-       if (!stats_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       return out;
+}
+
+static int nodes_fop_open(struct inode *inode, struct file *file)
+{
+       char *buf;
+
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));
+
+       file->private_data = buf;
 
        return 0;
-bail:
-       debugfs_remove(stats_dentry);
-       debugfs_remove(sc_dentry);
-       debugfs_remove(nst_dentry);
-       debugfs_remove(o2net_dentry);
-       return -ENOMEM;
 }
 
+static int o2net_debug_release(struct inode *inode, struct file *file)
+{
+       kfree(file->private_data);
+       return 0;
+}
+
+static ssize_t o2net_debug_read(struct file *file, char __user *buf,
+                               size_t nbytes, loff_t *ppos)
+{
+       return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+                                      i_size_read(file->f_mapping->host));
+}
+
+static const struct file_operations nodes_fops = {
+       .open           = nodes_fop_open,
+       .release        = o2net_debug_release,
+       .read           = o2net_debug_read,
+       .llseek         = generic_file_llseek,
+};
+
 void o2net_debugfs_exit(void)
 {
+       debugfs_remove(nodes_dentry);
        debugfs_remove(stats_dentry);
        debugfs_remove(sc_dentry);
        debugfs_remove(nst_dentry);
        debugfs_remove(o2net_dentry);
 }
 
+int o2net_debugfs_init(void)
+{
+       mode_t mode = S_IFREG|S_IRUSR;
+
+       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
+       if (o2net_dentry)
+               nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nst_seq_fops);
+       if (nst_dentry)
+               sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &sc_seq_fops);
+       if (sc_dentry)
+               stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &stats_seq_fops);
+       if (stats_dentry)
+               nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nodes_fops);
+       if (nodes_dentry)
+               return 0;
+
+       o2net_debugfs_exit();
+       mlog_errno(-ENOMEM);
+       return -ENOMEM;
+}
+
 #endif /* CONFIG_DEBUG_FS */
index db5ee4b4f47aaf36f698a004fbc99b0f3e722380..044e7b58d31c7662a75e29f636cfb86bf2846b67 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/idr.h>
 #include <linux/kref.h>
 #include <linux/net.h>
+#include <linux/export.h>
 #include <net/tcp.h>
 
 #include <asm/uaccess.h>
@@ -545,7 +546,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
        }
 
        if (was_valid && !valid) {
-               printk(KERN_NOTICE "o2net: no longer connected to "
+               printk(KERN_NOTICE "o2net: No longer connected to "
                       SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc));
                o2net_complete_nodes_nsw(nn);
        }
@@ -555,7 +556,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                cancel_delayed_work(&nn->nn_connect_expired);
                printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n",
                       o2nm_this_node() > sc->sc_node->nd_num ?
-                               "connected to" : "accepted connection from",
+                      "Connected to" : "Accepted connection from",
                       SC_NODEF_ARGS(sc));
        }
 
@@ -643,7 +644,7 @@ static void o2net_state_change(struct sock *sk)
                        o2net_sc_queue_work(sc, &sc->sc_connect_work);
                        break;
                default:
-                       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT
+                       printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT
                              " shutdown, state %d\n",
                              SC_NODEF_ARGS(sc), sk->sk_state);
                        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
@@ -1034,6 +1035,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
        return ret;
 }
 
+/* Get a map of all nodes to which this node is currently connected to */
+void o2net_fill_node_map(unsigned long *map, unsigned bytes)
+{
+       struct o2net_sock_container *sc;
+       int node, ret;
+
+       BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
+
+       memset(map, 0, bytes);
+       for (node = 0; node < O2NM_MAX_NODES; ++node) {
+               o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
+               if (!ret) {
+                       set_bit(node, map);
+                       sc_put(sc);
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(o2net_fill_node_map);
+
 int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                           size_t caller_veclen, u8 target_node, int *status)
 {
@@ -1284,11 +1304,11 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
 
        if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol "
-                    "version %llu but %llu is required, disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    (unsigned long long)be64_to_cpu(hand->protocol_version),
-                    O2NET_PROTOCOL_VERSION);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net "
+                      "protocol version %llu but %llu is required. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      (unsigned long long)be64_to_cpu(hand->protocol_version),
+                      O2NET_PROTOCOL_VERSION);
 
                /* don't bother reconnecting if its the wrong version. */
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
@@ -1302,33 +1322,33 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
         */
        if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
                                o2net_idle_timeout()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_idle_timeout_ms),
-                    o2net_idle_timeout());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network "
+                      "idle timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_idle_timeout_ms),
+                      o2net_idle_timeout());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
                        o2net_keepalive_delay()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_keepalive_delay_ms),
-                    o2net_keepalive_delay());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive "
+                      "delay of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_keepalive_delay_ms),
+                      o2net_keepalive_delay());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) !=
                        O2HB_MAX_WRITE_TIMEOUT_MS) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
-                    O2HB_MAX_WRITE_TIMEOUT_MS);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat "
+                      "timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
+                      O2HB_MAX_WRITE_TIMEOUT_MS);
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
@@ -1539,28 +1559,16 @@ static void o2net_idle_timer(unsigned long data)
 {
        struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
-
 #ifdef CONFIG_DEBUG_FS
-       ktime_t now = ktime_get();
+       unsigned long msecs = ktime_to_ms(ktime_get()) -
+               ktime_to_ms(sc->sc_tv_timer);
+#else
+       unsigned long msecs = o2net_idle_timeout();
 #endif
 
-       printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
-            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
-                    o2net_idle_timeout() / 1000,
-                    o2net_idle_timeout() % 1000);
-
-#ifdef CONFIG_DEBUG_FS
-       mlog(ML_NOTICE, "Here are some times that might help debug the "
-            "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, "
-            "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n",
-            (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now),
-            (long long)ktime_to_us(sc->sc_tv_data_ready),
-            (long long)ktime_to_us(sc->sc_tv_advance_start),
-            (long long)ktime_to_us(sc->sc_tv_advance_stop),
-            sc->sc_msg_key, sc->sc_msg_type,
-            (long long)ktime_to_us(sc->sc_tv_func_start),
-            (long long)ktime_to_us(sc->sc_tv_func_stop));
-#endif
+       printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been "
+              "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc),
+              msecs / 1000, msecs % 1000);
 
        /*
         * Initialize the nn_timeout so that the next connection attempt
@@ -1693,8 +1701,8 @@ static void o2net_start_connect(struct work_struct *work)
 
 out:
        if (ret) {
-               mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed "
-                    "with errno %d\n", SC_NODEF_ARGS(sc), ret);
+               printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT
+                      " failed with errno %d\n", SC_NODEF_ARGS(sc), ret);
                /* 0 err so that another will be queued and attempted
                 * from set_nn_state */
                if (sc)
@@ -1717,8 +1725,8 @@ static void o2net_connect_expired(struct work_struct *work)
 
        spin_lock(&nn->nn_lock);
        if (!nn->nn_sc_valid) {
-               mlog(ML_ERROR, "no connection established with node %u after "
-                    "%u.%u seconds, giving up and returning errors.\n",
+               printk(KERN_NOTICE "o2net: No connection established with "
+                      "node %u after %u.%u seconds, giving up.\n",
                     o2net_num_from_nn(nn),
                     o2net_idle_timeout() / 1000,
                     o2net_idle_timeout() % 1000);
@@ -1861,21 +1869,21 @@ static int o2net_accept_one(struct socket *sock)
 
        node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
        if (node == NULL) {
-               mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n",
-                    &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+                      "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
 
        if (o2nm_this_node() >= node->nd_num) {
                local_node = o2nm_get_node_by_num(o2nm_this_node());
-               mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' ("
-                    "%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n",
-                    local_node->nd_name, local_node->nd_num,
-                    &(local_node->nd_ipv4_address),
-                    ntohs(local_node->nd_ipv4_port),
-                    node->nd_name, node->nd_num, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Unexpected connect attempt seen "
+                      "at node '%s' (%u, %pI4:%d) from node '%s' (%u, "
+                      "%pI4:%d)\n", local_node->nd_name, local_node->nd_num,
+                      &(local_node->nd_ipv4_address),
+                      ntohs(local_node->nd_ipv4_port), node->nd_name,
+                      node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
@@ -1900,10 +1908,10 @@ static int o2net_accept_one(struct socket *sock)
                ret = 0;
        spin_unlock(&nn->nn_lock);
        if (ret) {
-               mlog(ML_NOTICE, "attempt to connect from node '%s' at "
-                    "%pI4:%d but it already has an open connection\n",
-                    node->nd_name, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+                      "at %pI4:%d but it already has an open connection\n",
+                      node->nd_name, &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                goto out;
        }
 
@@ -1983,7 +1991,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
 
        ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret);
+               printk(KERN_ERR "o2net: Error %d while creating socket\n", ret);
                goto out;
        }
 
@@ -2000,16 +2008,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
        sock->sk->sk_reuse = 1;
        ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to bind socket at %pI4:%u, "
-                    "ret=%d\n", &addr, ntohs(port), ret);
+               printk(KERN_ERR "o2net: Error %d while binding socket at "
+                      "%pI4:%u\n", ret, &addr, ntohs(port)); 
                goto out;
        }
 
        ret = sock->ops->listen(sock, 64);
-       if (ret < 0) {
-               mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n",
-                    &addr, ntohs(port), ret);
-       }
+       if (ret < 0)
+               printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
+                      ret, &addr, ntohs(port));
 
 out:
        if (ret) {
index fd6179eb26d4cd2cfb43f4ff053237837712113e..5bada2a69b503cd365d626a25e4ae6d08ad50b7a 100644 (file)
@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
                           struct list_head *unreg_list);
 void o2net_unregister_handler_list(struct list_head *list);
 
+void o2net_fill_node_map(unsigned long *map, unsigned bytes);
+
 struct o2nm_node;
 int o2net_register_hb_callbacks(void);
 void o2net_unregister_hb_callbacks(void);
index e2878b5895fb543a86c11f0128b025dbb0335c38..8fe4e2892ab9ccd983304a825c338df57a5376b8 100644 (file)
@@ -1184,8 +1184,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
                        if (pde)
                                le16_add_cpu(&pde->rec_len,
                                                le16_to_cpu(de->rec_len));
-                       else
-                               de->inode = 0;
+                       de->inode = 0;
                        dir->i_version++;
                        ocfs2_journal_dirty(handle, bh);
                        goto bail;
index d602abb51b610d525cc437daa05c25d2105fe0c3..a5952ceecba5a83147389ad4a1cd24972ee0bfbe 100644 (file)
@@ -859,8 +859,8 @@ void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
 void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
 int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
 
 void dlm_put(struct dlm_ctxt *dlm);
 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
@@ -877,9 +877,8 @@ static inline void dlm_lockres_get(struct dlm_lock_resource *res)
        kref_get(&res->refs);
 }
 void dlm_lockres_put(struct dlm_lock_resource *res);
-void __dlm_unhash_lockres(struct dlm_lock_resource *res);
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                         struct dlm_lock_resource *res);
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
                                                     const char *name,
                                                     unsigned int len,
@@ -902,46 +901,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
                                          const char *name,
                                          unsigned int namelen);
 
-#define dlm_lockres_set_refmap_bit(bit,res)  \
-       __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
-#define dlm_lockres_clear_refmap_bit(bit,res)  \
-       __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit);
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit);
 
-static inline void __dlm_lockres_set_refmap_bit(int bit,
-                                               struct dlm_lock_resource *res,
-                                               const char *file,
-                                               int line)
-{
-       //printk("%s:%d:%.*s: setting bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       set_bit(bit, res->refmap);
-}
-
-static inline void __dlm_lockres_clear_refmap_bit(int bit,
-                                                 struct dlm_lock_resource *res,
-                                                 const char *file,
-                                                 int line)
-{
-       //printk("%s:%d:%.*s: clearing bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       clear_bit(bit, res->refmap);
-}
-
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line);
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line);
-#define dlm_lockres_drop_inflight_ref(d,r)  \
-       __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref_new(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
 
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
index 56f82cb912e379e4149ab5454261a9bb6bdadf67..0e28e242226d8f69dfc638b8426c7700b8b1ba18 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/sysctl.h>
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 
 #include "cluster/heartbeat.h"
 #include "cluster/nodemanager.h"
index 6ed6b95dcf935a6516e935b85a3ca9ffc0b8a9d8..92f2ead0fab6de22fa138cc4410dee6e1544216c 100644 (file)
@@ -157,16 +157,18 @@ static int dlm_protocol_compare(struct dlm_protocol_version *existing,
 
 static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
 
-void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
-       if (!hlist_unhashed(&lockres->hash_node)) {
-               hlist_del_init(&lockres->hash_node);
-               dlm_lockres_put(lockres);
-       }
+       if (hlist_unhashed(&res->hash_node))
+               return;
+
+       mlog(0, "%s: Unhash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
+       hlist_del_init(&res->hash_node);
+       dlm_lockres_put(res);
 }
 
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                      struct dlm_lock_resource *res)
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
        struct hlist_head *bucket;
        struct qstr *q;
@@ -180,6 +182,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
        dlm_lockres_get(res);
 
        hlist_add_head(&res->hash_node, bucket);
+
+       mlog(0, "%s: Hash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
 }
 
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
@@ -539,17 +544,17 @@ again:
 
 static void __dlm_print_nodes(struct dlm_ctxt *dlm)
 {
-       int node = -1;
+       int node = -1, num = 0;
 
        assert_spin_locked(&dlm->spinlock);
 
-       printk(KERN_NOTICE "o2dlm: Nodes in domain %s: ", dlm->name);
-
+       printk("( ");
        while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
                                     node + 1)) < O2NM_MAX_NODES) {
                printk("%d ", node);
+               ++num;
        }
-       printk("\n");
+       printk(") %u nodes\n", num);
 }
 
 static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
@@ -566,11 +571,10 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
 
        node = exit_msg->node_idx;
 
-       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s\n", node, dlm->name);
-
        spin_lock(&dlm->spinlock);
        clear_bit(node, dlm->domain_map);
        clear_bit(node, dlm->exit_domain_map);
+       printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s ", node, dlm->name);
        __dlm_print_nodes(dlm);
 
        /* notify anything attached to the heartbeat events */
@@ -755,6 +759,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
 
                dlm_mark_domain_leaving(dlm);
                dlm_leave_domain(dlm);
+               printk(KERN_NOTICE "o2dlm: Leaving domain %s\n", dlm->name);
                dlm_force_free_mles(dlm);
                dlm_complete_dlm_shutdown(dlm);
        }
@@ -970,7 +975,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
                clear_bit(assert->node_idx, dlm->exit_domain_map);
                __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
 
-               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n",
+               printk(KERN_NOTICE "o2dlm: Node %u joins domain %s ",
                       assert->node_idx, dlm->name);
                __dlm_print_nodes(dlm);
 
@@ -1701,8 +1706,10 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
 bail:
        spin_lock(&dlm->spinlock);
        __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
-       if (!status)
+       if (!status) {
+               printk(KERN_NOTICE "o2dlm: Joining domain %s ", dlm->name);
                __dlm_print_nodes(dlm);
+       }
        spin_unlock(&dlm->spinlock);
 
        if (ctxt) {
@@ -2131,13 +2138,6 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
                goto leave;
        }
 
-       if (!o2hb_check_local_node_heartbeating()) {
-               mlog(ML_ERROR, "the local node has not been configured, or is "
-                    "not heartbeating\n");
-               ret = -EPROTO;
-               goto leave;
-       }
-
        mlog(0, "register called for domain \"%s\"\n", domain);
 
 retry:
index 8d39e0fd66f7379b8fb08ac40502efa0d4a51cc6..975810b98492a34f4576b9d3d3ac3e4421fb18c1 100644 (file)
@@ -183,10 +183,6 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
                        kick_thread = 1;
                }
        }
-       /* reduce the inflight count, this may result in the lockres
-        * being purged below during calc_usage */
-       if (lock->ml.node == dlm->node_num)
-               dlm_lockres_drop_inflight_ref(dlm, res);
 
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -231,10 +227,16 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
             lock->ml.type, res->lockname.len,
             res->lockname.name, flags);
 
+       /*
+        * Wait if resource is getting recovered, remastered, etc.
+        * If the resource was remastered and new owner is self, then exit.
+        */
        spin_lock(&res->spinlock);
-
-       /* will exit this call with spinlock held */
        __dlm_wait_on_lockres(res);
+       if (res->owner == dlm->node_num) {
+               spin_unlock(&res->spinlock);
+               return DLM_RECOVERING;
+       }
        res->state |= DLM_LOCK_RES_IN_PROGRESS;
 
        /* add lock to local (secondary) queue */
@@ -319,27 +321,23 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
        tmpret = o2net_send_message(DLM_CREATE_LOCK_MSG, dlm->key, &create,
                                    sizeof(create), res->owner, &status);
        if (tmpret >= 0) {
-               // successfully sent and received
-               ret = status;  // this is already a dlm_status
+               ret = status;
                if (ret == DLM_REJECTED) {
-                       mlog(ML_ERROR, "%s:%.*s: BUG.  this is a stale lockres "
-                            "no longer owned by %u.  that node is coming back "
-                            "up currently.\n", dlm->name, create.namelen,
+                       mlog(ML_ERROR, "%s: res %.*s, Stale lockres no longer "
+                            "owned by node %u. That node is coming back up "
+                            "currently.\n", dlm->name, create.namelen,
                             create.name, res->owner);
                        dlm_print_one_lock_resource(res);
                        BUG();
                }
        } else {
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", tmpret, DLM_CREATE_LOCK_MSG, dlm->key,
-                    res->owner);
-               if (dlm_is_host_down(tmpret)) {
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send CREATE LOCK to "
+                    "node %u\n", dlm->name, create.namelen, create.name,
+                    tmpret, res->owner);
+               if (dlm_is_host_down(tmpret))
                        ret = DLM_RECOVERING;
-                       mlog(0, "node %u died so returning DLM_RECOVERING "
-                            "from lock message!\n", res->owner);
-               } else {
+               else
                        ret = dlm_err_to_dlm_status(tmpret);
-               }
        }
 
        return ret;
@@ -440,7 +438,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
                /* zero memory only if kernel-allocated */
                lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
                if (!lksb) {
-                       kfree(lock);
+                       kmem_cache_free(dlm_lock_cache, lock);
                        return NULL;
                }
                kernel_allocated = 1;
@@ -718,18 +716,10 @@ retry_lock:
 
                if (status == DLM_RECOVERING || status == DLM_MIGRATING ||
                    status == DLM_FORWARD) {
-                       mlog(0, "retrying lock with migration/"
-                            "recovery/in progress\n");
                        msleep(100);
-                       /* no waiting for dlm_reco_thread */
                        if (recovery) {
                                if (status != DLM_RECOVERING)
                                        goto retry_lock;
-
-                               mlog(0, "%s: got RECOVERING "
-                                    "for $RECOVERY lock, master "
-                                    "was %u\n", dlm->name,
-                                    res->owner);
                                /* wait to see the node go down, then
                                 * drop down and allow the lockres to
                                 * get cleaned up.  need to remaster. */
@@ -741,6 +731,14 @@ retry_lock:
                        }
                }
 
+               /* Inflight taken in dlm_get_lock_resource() is dropped here */
+               spin_lock(&res->spinlock);
+               dlm_lockres_drop_inflight_ref(dlm, res);
+               spin_unlock(&res->spinlock);
+
+               dlm_lockres_calc_usage(dlm, res);
+               dlm_kick_thread(dlm, res);
+
                if (status != DLM_NORMAL) {
                        lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
                        if (status != DLM_NOTQUEUED)
index 11eefb8c12e98fb418f41c31a3b0a32201be3ca1..005261c333b090f5f53f376bd5bbed55b8e16ba7 100644 (file)
@@ -631,39 +631,54 @@ error:
        return NULL;
 }
 
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit)
 {
-       if (!new_lockres)
-               assert_spin_locked(&res->spinlock);
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, set node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       set_bit(bit, res->refmap);
+}
+
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit)
+{
+       assert_spin_locked(&res->spinlock);
+
+       mlog(0, "res %.*s, clr node %u, %ps()\n", res->lockname.len,
+            res->lockname.name, bit, __builtin_return_address(0));
+
+       clear_bit(bit, res->refmap);
+}
+
+
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
+{
+       assert_spin_locked(&res->spinlock);
 
-       if (!test_bit(dlm->node_num, res->refmap)) {
-               BUG_ON(res->inflight_locks != 0);
-               dlm_lockres_set_refmap_bit(dlm->node_num, res);
-       }
        res->inflight_locks++;
-       mlog(0, "%s:%.*s: inflight++: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
+
+       mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
 }
 
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res)
 {
        assert_spin_locked(&res->spinlock);
 
        BUG_ON(res->inflight_locks == 0);
+
        res->inflight_locks--;
-       mlog(0, "%s:%.*s: inflight--: now %u\n",
-            dlm->name, res->lockname.len, res->lockname.name,
-            res->inflight_locks);
-       if (res->inflight_locks == 0)
-               dlm_lockres_clear_refmap_bit(dlm->node_num, res);
+
+       mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name,
+            res->lockname.len, res->lockname.name, res->inflight_locks,
+            __builtin_return_address(0));
+
        wake_up(&res->wq);
 }
 
@@ -697,7 +712,6 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
        unsigned int hash;
        int tries = 0;
        int bit, wait_on_recovery = 0;
-       int drop_inflight_if_nonlocal = 0;
 
        BUG_ON(!lockid);
 
@@ -709,36 +723,33 @@ lookup:
        spin_lock(&dlm->spinlock);
        tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash);
        if (tmpres) {
-               int dropping_ref = 0;
-
                spin_unlock(&dlm->spinlock);
-
                spin_lock(&tmpres->spinlock);
-               /* We wait for the other thread that is mastering the resource */
+               /* Wait on the thread that is mastering the resource */
                if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
                        __dlm_wait_on_lockres(tmpres);
                        BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN);
+                       spin_unlock(&tmpres->spinlock);
+                       dlm_lockres_put(tmpres);
+                       tmpres = NULL;
+                       goto lookup;
                }
 
-               if (tmpres->owner == dlm->node_num) {
-                       BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF);
-                       dlm_lockres_grab_inflight_ref(dlm, tmpres);
-               } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF)
-                       dropping_ref = 1;
-               spin_unlock(&tmpres->spinlock);
-
-               /* wait until done messaging the master, drop our ref to allow
-                * the lockres to be purged, start over. */
-               if (dropping_ref) {
-                       spin_lock(&tmpres->spinlock);
-                       __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF);
+               /* Wait on the resource purge to complete before continuing */
+               if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) {
+                       BUG_ON(tmpres->owner == dlm->node_num);
+                       __dlm_wait_on_lockres_flags(tmpres,
+                                                   DLM_LOCK_RES_DROPPING_REF);
                        spin_unlock(&tmpres->spinlock);
                        dlm_lockres_put(tmpres);
                        tmpres = NULL;
                        goto lookup;
                }
 
-               mlog(0, "found in hash!\n");
+               /* Grab inflight ref to pin the resource */
+               dlm_lockres_grab_inflight_ref(dlm, tmpres);
+
+               spin_unlock(&tmpres->spinlock);
                if (res)
                        dlm_lockres_put(res);
                res = tmpres;
@@ -829,8 +840,8 @@ lookup:
                 * but they might own this lockres.  wait on them. */
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                }
@@ -843,12 +854,11 @@ lookup:
 
        /* finally add the lockres to its hash bucket */
        __dlm_insert_lockres(dlm, res);
-       /* since this lockres is new it doesn't not require the spinlock */
-       dlm_lockres_grab_inflight_ref_new(dlm, res);
 
-       /* if this node does not become the master make sure to drop
-        * this inflight reference below */
-       drop_inflight_if_nonlocal = 1;
+       /* Grab inflight ref to pin the resource */
+       spin_lock(&res->spinlock);
+       dlm_lockres_grab_inflight_ref(dlm, res);
+       spin_unlock(&res->spinlock);
 
        /* get an extra ref on the mle in case this is a BLOCK
         * if so, the creator of the BLOCK may try to put the last
@@ -864,8 +874,8 @@ redo_request:
                 * dlm spinlock would be detectable be a change on the mle,
                 * so we only need to clear out the recovery map once. */
                if (dlm_is_recovery_lock(lockid, namelen)) {
-                       mlog(ML_NOTICE, "%s: recovery map is not empty, but "
-                            "must master $RECOVERY lock now\n", dlm->name);
+                       mlog(0, "%s: Recovery map is not empty, but must "
+                            "master $RECOVERY lock now\n", dlm->name);
                        if (!dlm_pre_master_reco_lockres(dlm, res))
                                wait_on_recovery = 0;
                        else {
@@ -883,8 +893,8 @@ redo_request:
                spin_lock(&dlm->spinlock);
                bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0);
                if (bit < O2NM_MAX_NODES) {
-                       mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to "
-                            "recover before lock mastery can begin\n",
+                       mlog(0, "%s: res %.*s, At least one node (%d) "
+                            "to recover before lock mastery can begin\n",
                             dlm->name, namelen, (char *)lockid, bit);
                        wait_on_recovery = 1;
                } else
@@ -913,8 +923,8 @@ redo_request:
                         * yet, keep going until it does.  this is how the
                         * master will know that asserts are needed back to
                         * the lower nodes. */
-                       mlog(0, "%s:%.*s: requests only up to %u but master "
-                            "is %u, keep going\n", dlm->name, namelen,
+                       mlog(0, "%s: res %.*s, Requests only up to %u but "
+                            "master is %u, keep going\n", dlm->name, namelen,
                             lockid, nodenum, mle->master);
                }
        }
@@ -924,13 +934,12 @@ wait:
        ret = dlm_wait_for_lock_mastery(dlm, res, mle, &blocked);
        if (ret < 0) {
                wait_on_recovery = 1;
-               mlog(0, "%s:%.*s: node map changed, redo the "
-                    "master request now, blocked=%d\n",
-                    dlm->name, res->lockname.len,
+               mlog(0, "%s: res %.*s, Node map changed, redo the master "
+                    "request now, blocked=%d\n", dlm->name, res->lockname.len,
                     res->lockname.name, blocked);
                if (++tries > 20) {
-                       mlog(ML_ERROR, "%s:%.*s: spinning on "
-                            "dlm_wait_for_lock_mastery, blocked=%d\n",
+                       mlog(ML_ERROR, "%s: res %.*s, Spinning on "
+                            "dlm_wait_for_lock_mastery, blocked = %d\n",
                             dlm->name, res->lockname.len,
                             res->lockname.name, blocked);
                        dlm_print_one_lock_resource(res);
@@ -940,7 +949,8 @@ wait:
                goto redo_request;
        }
 
-       mlog(0, "lockres mastered by %u\n", res->owner);
+       mlog(0, "%s: res %.*s, Mastered by %u\n", dlm->name, res->lockname.len,
+            res->lockname.name, res->owner);
        /* make sure we never continue without this */
        BUG_ON(res->owner == O2NM_MAX_NODES);
 
@@ -952,8 +962,6 @@ wait:
 
 wake_waiters:
        spin_lock(&res->spinlock);
-       if (res->owner != dlm->node_num && drop_inflight_if_nonlocal)
-               dlm_lockres_drop_inflight_ref(dlm, res);
        res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
        spin_unlock(&res->spinlock);
        wake_up(&res->wq);
@@ -1426,9 +1434,7 @@ way_up_top:
                }
 
                if (res->owner == dlm->node_num) {
-                       mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                            dlm->name, namelen, name, request->node_idx);
-                       dlm_lockres_set_refmap_bit(request->node_idx, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, request->node_idx);
                        spin_unlock(&res->spinlock);
                        response = DLM_MASTER_RESP_YES;
                        if (mle)
@@ -1493,10 +1499,8 @@ way_up_top:
                                 * go back and clean the mles on any
                                 * other nodes */
                                dispatch_assert = 1;
-                               dlm_lockres_set_refmap_bit(request->node_idx, res);
-                               mlog(0, "%s:%.*s: setting bit %u in refmap\n",
-                                    dlm->name, namelen, name,
-                                    request->node_idx);
+                               dlm_lockres_set_refmap_bit(dlm, res,
+                                                          request->node_idx);
                        } else
                                response = DLM_MASTER_RESP_NO;
                } else {
@@ -1702,7 +1706,7 @@ again:
                             "lockres, set the bit in the refmap\n",
                             namelen, lockname, to);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(to, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, to);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -2187,8 +2191,6 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        namelen = res->lockname.len;
        BUG_ON(namelen > O2NM_MAX_NAME_LEN);
 
-       mlog(0, "%s:%.*s: sending deref to %d\n",
-            dlm->name, namelen, lockname, res->owner);
        memset(&deref, 0, sizeof(deref));
        deref.node_idx = dlm->node_num;
        deref.namelen = namelen;
@@ -2197,14 +2199,12 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        ret = o2net_send_message(DLM_DEREF_LOCKRES_MSG, dlm->key,
                                 &deref, sizeof(deref), res->owner, &r);
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to "
-                    "node %u\n", ret, DLM_DEREF_LOCKRES_MSG, dlm->key,
-                    res->owner);
+               mlog(ML_ERROR, "%s: res %.*s, error %d send DEREF to node %u\n",
+                    dlm->name, namelen, lockname, ret, res->owner);
        else if (r < 0) {
                /* BAD.  other node says I did not have a ref. */
-               mlog(ML_ERROR,"while dropping ref on %s:%.*s "
-                   "(master=%u) got %d.\n", dlm->name, namelen,
-                   lockname, res->owner, r);
+               mlog(ML_ERROR, "%s: res %.*s, DEREF to node %u got %d\n",
+                    dlm->name, namelen, lockname, res->owner, r);
                dlm_print_one_lock_resource(res);
                BUG();
        }
@@ -2260,7 +2260,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
        else {
                BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
                if (test_bit(node, res->refmap)) {
-                       dlm_lockres_clear_refmap_bit(node, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, node);
                        cleared = 1;
                }
        }
@@ -2320,7 +2320,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
        BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF);
        if (test_bit(node, res->refmap)) {
                __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
-               dlm_lockres_clear_refmap_bit(node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, node);
                cleared = 1;
        }
        spin_unlock(&res->spinlock);
@@ -2802,7 +2802,8 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                                BUG_ON(!list_empty(&lock->bast_list));
                                BUG_ON(lock->ast_pending);
                                BUG_ON(lock->bast_pending);
-                               dlm_lockres_clear_refmap_bit(lock->ml.node, res);
+                               dlm_lockres_clear_refmap_bit(dlm, res,
+                                                            lock->ml.node);
                                list_del_init(&lock->list);
                                dlm_lock_put(lock);
                                /* In a normal unlock, we would have added a
@@ -2823,7 +2824,7 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
                        mlog(0, "%s:%.*s: node %u had a ref to this "
                             "migrating lockres, clearing\n", dlm->name,
                             res->lockname.len, res->lockname.name, bit);
-                       dlm_lockres_clear_refmap_bit(bit, res);
+                       dlm_lockres_clear_refmap_bit(dlm, res, bit);
                }
                bit++;
        }
@@ -2916,9 +2917,9 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                                         &migrate, sizeof(migrate), nodenum,
                                         &status);
                if (ret < 0) {
-                       mlog(ML_ERROR, "Error %d when sending message %u (key "
-                            "0x%x) to node %u\n", ret, DLM_MIGRATE_REQUEST_MSG,
-                            dlm->key, nodenum);
+                       mlog(ML_ERROR, "%s: res %.*s, Error %d send "
+                            "MIGRATE_REQUEST to node %u\n", dlm->name,
+                            migrate.namelen, migrate.name, ret, nodenum);
                        if (!dlm_is_host_down(ret)) {
                                mlog(ML_ERROR, "unhandled error=%d!\n", ret);
                                BUG();
@@ -2937,7 +2938,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
                             dlm->name, res->lockname.len, res->lockname.name,
                             nodenum);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(nodenum, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, nodenum);
                        spin_unlock(&res->spinlock);
                }
        }
@@ -3271,7 +3272,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
         * mastery reference here since old_master will briefly have
         * a reference after the migration completes */
        spin_lock(&res->spinlock);
-       dlm_lockres_set_refmap_bit(old_master, res);
+       dlm_lockres_set_refmap_bit(dlm, res, old_master);
        spin_unlock(&res->spinlock);
 
        mlog(0, "now time to do a migrate request to other nodes\n");
index 7efab6d28a21b4ee6a8376559d70f739a4e1da90..01ebfd0bdad72264b99345378f0c6febe246503d 100644 (file)
@@ -362,40 +362,38 @@ static int dlm_is_node_recovered(struct dlm_ctxt *dlm, u8 node)
 }
 
 
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(ML_NOTICE, "%s: waiting %dms for notification of "
-                    "death of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_dead(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the death of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_dead(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(ML_NOTICE, "%s: waiting indefinitely for notification "
-                    "of death of node %u\n", dlm->name, node);
+                                  dlm_is_node_dead(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_dead(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout)
 {
-       if (timeout) {
-               mlog(0, "%s: waiting %dms for notification of "
-                    "recovery of node %u\n", dlm->name, timeout, node);
+       if (dlm_is_node_recovered(dlm, node))
+               return;
+
+       printk(KERN_NOTICE "o2dlm: Waiting on the recovery of node %u in "
+              "domain %s\n", node, dlm->name);
+
+       if (timeout)
                wait_event_timeout(dlm->dlm_reco_thread_wq,
-                          dlm_is_node_recovered(dlm, node),
-                          msecs_to_jiffies(timeout));
-       } else {
-               mlog(0, "%s: waiting indefinitely for notification "
-                    "of recovery of node %u\n", dlm->name, node);
+                                  dlm_is_node_recovered(dlm, node),
+                                  msecs_to_jiffies(timeout));
+       else
                wait_event(dlm->dlm_reco_thread_wq,
                           dlm_is_node_recovered(dlm, node));
-       }
-       /* for now, return 0 */
-       return 0;
 }
 
 /* callers of the top-level api calls (dlmlock/dlmunlock) should
@@ -430,6 +428,8 @@ static void dlm_begin_recovery(struct dlm_ctxt *dlm)
 {
        spin_lock(&dlm->spinlock);
        BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
+       printk(KERN_NOTICE "o2dlm: Begin recovery on domain %s for node %u\n",
+              dlm->name, dlm->reco.dead_node);
        dlm->reco.state |= DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
 }
@@ -440,9 +440,18 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm)
        BUG_ON(!(dlm->reco.state & DLM_RECO_STATE_ACTIVE));
        dlm->reco.state &= ~DLM_RECO_STATE_ACTIVE;
        spin_unlock(&dlm->spinlock);
+       printk(KERN_NOTICE "o2dlm: End recovery on domain %s\n", dlm->name);
        wake_up(&dlm->reco.event);
 }
 
+static void dlm_print_recovery_master(struct dlm_ctxt *dlm)
+{
+       printk(KERN_NOTICE "o2dlm: Node %u (%s) is the Recovery Master for the "
+              "dead node %u in domain %s\n", dlm->reco.new_master,
+              (dlm->node_num == dlm->reco.new_master ? "me" : "he"),
+              dlm->reco.dead_node, dlm->name);
+}
+
 static int dlm_do_recovery(struct dlm_ctxt *dlm)
 {
        int status = 0;
@@ -505,9 +514,8 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
                }
                mlog(0, "another node will master this recovery session.\n");
        }
-       mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
-            dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
-            dlm->node_num, dlm->reco.dead_node);
+
+       dlm_print_recovery_master(dlm);
 
        /* it is safe to start everything back up here
         * because all of the dead node's lock resources
@@ -518,15 +526,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
        return 0;
 
 master_here:
-       mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node "
-            "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task),
-            dlm->node_num, dlm->reco.dead_node, dlm->name);
+       dlm_print_recovery_master(dlm);
 
        status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
        if (status < 0) {
                /* we should never hit this anymore */
-               mlog(ML_ERROR, "error %d remastering locks for node %u, "
-                    "retrying.\n", status, dlm->reco.dead_node);
+               mlog(ML_ERROR, "%s: Error %d remastering locks for node %u, "
+                    "retrying.\n", dlm->name, status, dlm->reco.dead_node);
                /* yield a bit to allow any final network messages
                 * to get handled on remaining nodes */
                msleep(100);
@@ -567,7 +573,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                BUG_ON(ndata->state != DLM_RECO_NODE_DATA_INIT);
                ndata->state = DLM_RECO_NODE_DATA_REQUESTING;
 
-               mlog(0, "requesting lock info from node %u\n",
+               mlog(0, "%s: Requesting lock info from node %u\n", dlm->name,
                     ndata->node_num);
 
                if (ndata->node_num == dlm->node_num) {
@@ -640,7 +646,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
                spin_unlock(&dlm_reco_state_lock);
        }
 
-       mlog(0, "done requesting all lock info\n");
+       mlog(0, "%s: Done requesting all lock info\n", dlm->name);
 
        /* nodes should be sending reco data now
         * just need to wait */
@@ -802,10 +808,9 @@ static int dlm_request_all_locks(struct dlm_ctxt *dlm, u8 request_from,
 
        /* negative status is handled by caller */
        if (ret < 0)
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_LOCK_REQUEST_MSG,
-                    dlm->key, request_from);
-
+               mlog(ML_ERROR, "%s: Error %d send LOCK_REQUEST to node %u "
+                    "to recover dead node %u\n", dlm->name, ret,
+                    request_from, dead_node);
        // return from here, then
        // sleep until all received or error
        return ret;
@@ -956,9 +961,9 @@ static int dlm_send_all_done_msg(struct dlm_ctxt *dlm, u8 dead_node, u8 send_to)
        ret = o2net_send_message(DLM_RECO_DATA_DONE_MSG, dlm->key, &done_msg,
                                 sizeof(done_msg), send_to, &tmpret);
        if (ret < 0) {
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_RECO_DATA_DONE_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: Error %d send RECO_DATA_DONE to node %u "
+                    "to recover dead node %u\n", dlm->name, ret, send_to,
+                    dead_node);
                if (!dlm_is_host_down(ret)) {
                        BUG();
                }
@@ -1127,9 +1132,11 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
        if (ret < 0) {
                /* XXX: negative status is not handled.
                 * this will end up killing this node. */
-               mlog(ML_ERROR, "Error %d when sending message %u (key "
-                    "0x%x) to node %u\n", ret, DLM_MIG_LOCKRES_MSG,
-                    dlm->key, send_to);
+               mlog(ML_ERROR, "%s: res %.*s, Error %d send MIG_LOCKRES to "
+                    "node %u (%s)\n", dlm->name, mres->lockname_len,
+                    mres->lockname, ret, send_to,
+                    (orig_flags & DLM_MRES_MIGRATION ?
+                     "migration" : "recovery"));
        } else {
                /* might get an -ENOMEM back here */
                ret = status;
@@ -1767,7 +1774,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
                             dlm->name, mres->lockname_len, mres->lockname,
                             from);
                        spin_lock(&res->spinlock);
-                       dlm_lockres_set_refmap_bit(from, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, from);
                        spin_unlock(&res->spinlock);
                        added++;
                        break;
@@ -1965,7 +1972,7 @@ skip_lvb:
                        mlog(0, "%s:%.*s: added lock for node %u, "
                             "setting refmap bit\n", dlm->name,
                             res->lockname.len, res->lockname.name, ml->node);
-                       dlm_lockres_set_refmap_bit(ml->node, res);
+                       dlm_lockres_set_refmap_bit(dlm, res, ml->node);
                        added++;
                }
                spin_unlock(&res->spinlock);
@@ -2084,6 +2091,9 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
 
        list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) {
                if (res->owner == dead_node) {
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
                        list_del_init(&res->recovering);
                        spin_lock(&res->spinlock);
                        /* new_master has our reference from
@@ -2105,40 +2115,30 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
        for (i = 0; i < DLM_HASH_BUCKETS; i++) {
                bucket = dlm_lockres_hash(dlm, i);
                hlist_for_each_entry(res, hash_iter, bucket, hash_node) {
-                       if (res->state & DLM_LOCK_RES_RECOVERING) {
-                               if (res->owner == dead_node) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, but "
-                                            "clearing state anyway\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else if (res->owner == dlm->node_num) {
-                                       mlog(0, "(this=%u) res %.*s owner=%u "
-                                            "was not on recovering list, "
-                                            "owner is THIS node, clearing\n",
-                                            dlm->node_num, res->lockname.len,
-                                            res->lockname.name, new_master);
-                               } else
-                                       continue;
+                       if (!(res->state & DLM_LOCK_RES_RECOVERING))
+                               continue;
 
-                               if (!list_empty(&res->recovering)) {
-                                       mlog(0, "%s:%.*s: lockres was "
-                                            "marked RECOVERING, owner=%u\n",
-                                            dlm->name, res->lockname.len,
-                                            res->lockname.name, res->owner);
-                                       list_del_init(&res->recovering);
-                                       dlm_lockres_put(res);
-                               }
-                               spin_lock(&res->spinlock);
-                               /* new_master has our reference from
-                                * the lock state sent during recovery */
-                               dlm_change_lockres_owner(dlm, res, new_master);
-                               res->state &= ~DLM_LOCK_RES_RECOVERING;
-                               if (__dlm_lockres_has_locks(res))
-                                       __dlm_dirty_lockres(dlm, res);
-                               spin_unlock(&res->spinlock);
-                               wake_up(&res->wq);
+                       if (res->owner != dead_node &&
+                           res->owner != dlm->node_num)
+                               continue;
+
+                       if (!list_empty(&res->recovering)) {
+                               list_del_init(&res->recovering);
+                               dlm_lockres_put(res);
                        }
+
+                       /* new_master has our reference from
+                        * the lock state sent during recovery */
+                       mlog(0, "%s: res %.*s, Changing owner from %u to %u\n",
+                            dlm->name, res->lockname.len, res->lockname.name,
+                            res->owner, new_master);
+                       spin_lock(&res->spinlock);
+                       dlm_change_lockres_owner(dlm, res, new_master);
+                       res->state &= ~DLM_LOCK_RES_RECOVERING;
+                       if (__dlm_lockres_has_locks(res))
+                               __dlm_dirty_lockres(dlm, res);
+                       spin_unlock(&res->spinlock);
+                       wake_up(&res->wq);
                }
        }
 }
@@ -2252,12 +2252,12 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm,
                             res->lockname.len, res->lockname.name, freed, dead_node);
                        __dlm_print_one_lock_resource(res);
                }
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        } else if (test_bit(dead_node, res->refmap)) {
                mlog(0, "%s:%.*s: dead node %u had a ref, but had "
                     "no locks and had not purged before dying\n", dlm->name,
                     res->lockname.len, res->lockname.name, dead_node);
-               dlm_lockres_clear_refmap_bit(dead_node, res);
+               dlm_lockres_clear_refmap_bit(dlm, res, dead_node);
        }
 
        /* do not kick thread yet */
@@ -2324,9 +2324,9 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
                        dlm_revalidate_lvb(dlm, res, dead_node);
                        if (res->owner == dead_node) {
                                if (res->state & DLM_LOCK_RES_DROPPING_REF) {
-                                       mlog(ML_NOTICE, "Ignore %.*s for "
+                                       mlog(ML_NOTICE, "%s: res %.*s, Skip "
                                             "recovery as it is being freed\n",
-                                            res->lockname.len,
+                                            dlm->name, res->lockname.len,
                                             res->lockname.name);
                                } else
                                        dlm_move_lockres_to_recovery_list(dlm,
index 1d6d1d22c4715e3c89bef69570916cc5bf44c259..e73c833fc2a1a97cac35903f0439115cef813c69 100644 (file)
@@ -94,24 +94,26 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res)
 {
        int bit;
 
+       assert_spin_locked(&res->spinlock);
+
        if (__dlm_lockres_has_locks(res))
                return 0;
 
+       /* Locks are in the process of being created */
+       if (res->inflight_locks)
+               return 0;
+
        if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY)
                return 0;
 
        if (res->state & DLM_LOCK_RES_RECOVERING)
                return 0;
 
+       /* Another node has this resource with this node as the master */
        bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
        if (bit < O2NM_MAX_NODES)
                return 0;
 
-       /*
-        * since the bit for dlm->node_num is not set, inflight_locks better
-        * be zero
-        */
-       BUG_ON(res->inflight_locks != 0);
        return 1;
 }
 
@@ -185,8 +187,6 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                /* clear our bit from the master's refmap, ignore errors */
                ret = dlm_drop_lockres_ref(dlm, res);
                if (ret < 0) {
-                       mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name,
-                            res->lockname.len, res->lockname.name, ret);
                        if (!dlm_is_host_down(ret))
                                BUG();
                }
@@ -209,7 +209,7 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm,
                BUG();
        }
 
-       __dlm_unhash_lockres(res);
+       __dlm_unhash_lockres(dlm, res);
 
        /* lockres is not in the hash now.  drop the flag and wake up
         * any processes waiting in dlm_get_lock_resource. */
index e1ed5e502ff25dc8afe39de464949ba13c2f9892..81a4cd22f80be84a06eac2b0fbf4348385d76262 100644 (file)
@@ -1692,7 +1692,7 @@ int ocfs2_open_lock(struct inode *inode)
        mlog(0, "inode %llu take PRMODE open lock\n",
             (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
-       if (ocfs2_mount_local(osb))
+       if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
                goto out;
 
        lockres = &OCFS2_I(inode)->ip_open_lockres;
@@ -1718,6 +1718,12 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
             (unsigned long long)OCFS2_I(inode)->ip_blkno,
             write ? "EXMODE" : "PRMODE");
 
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (write)
+                       status = -EROFS;
+               goto out;
+       }
+
        if (ocfs2_mount_local(osb))
                goto out;
 
@@ -2298,7 +2304,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
        if (ocfs2_is_hard_readonly(osb)) {
                if (ex)
                        status = -EROFS;
-               goto bail;
+               goto getbh;
        }
 
        if (ocfs2_mount_local(osb))
@@ -2356,7 +2362,7 @@ local:
                        mlog_errno(status);
                goto bail;
        }
-
+getbh:
        if (ret_bh) {
                status = ocfs2_assign_bh(inode, ret_bh, local_bh);
                if (status < 0) {
@@ -2628,8 +2634,11 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex)
 
        BUG_ON(!dl);
 
-       if (ocfs2_is_hard_readonly(osb))
-               return -EROFS;
+       if (ocfs2_is_hard_readonly(osb)) {
+               if (ex)
+                       return -EROFS;
+               return 0;
+       }
 
        if (ocfs2_mount_local(osb))
                return 0;
@@ -2647,7 +2656,7 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex)
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
        struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
 
-       if (!ocfs2_mount_local(osb))
+       if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb))
                ocfs2_cluster_unlock(osb, &dl->dl_lockres, level);
 }
 
index 23457b491e8ce53ac5b71d9cd5fc2a5e1400a07f..2f5b92ef0e533146007b49d21dd705a242125dc5 100644 (file)
@@ -832,6 +832,102 @@ out:
        return ret;
 }
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret;
+       unsigned int is_last = 0, is_data = 0;
+       u16 cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+       u32 cpos, cend, clen, hole_size;
+       u64 extoff, extlen;
+       struct buffer_head *di_bh = NULL;
+       struct ocfs2_extent_rec rec;
+
+       BUG_ON(origin != SEEK_DATA && origin != SEEK_HOLE);
+
+       ret = ocfs2_inode_lock(inode, &di_bh, 0);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       if (*offset >= inode->i_size) {
+               ret = -ENXIO;
+               goto out_unlock;
+       }
+
+       if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+               if (origin == SEEK_HOLE)
+                       *offset = inode->i_size;
+               goto out_unlock;
+       }
+
+       clen = 0;
+       cpos = *offset >> cs_bits;
+       cend = ocfs2_clusters_for_bytes(inode->i_sb, inode->i_size);
+
+       while (cpos < cend && !is_last) {
+               ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, &hole_size,
+                                                &rec, &is_last);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out_unlock;
+               }
+
+               extoff = cpos;
+               extoff <<= cs_bits;
+
+               if (rec.e_blkno == 0ULL) {
+                       clen = hole_size;
+                       is_data = 0;
+               } else {
+                       clen = le16_to_cpu(rec.e_leaf_clusters) -
+                               (cpos - le32_to_cpu(rec.e_cpos));
+                       is_data = (rec.e_flags & OCFS2_EXT_UNWRITTEN) ?  0 : 1;
+               }
+
+               if ((!is_data && origin == SEEK_HOLE) ||
+                   (is_data && origin == SEEK_DATA)) {
+                       if (extoff > *offset)
+                               *offset = extoff;
+                       goto out_unlock;
+               }
+
+               if (!is_last)
+                       cpos += clen;
+       }
+
+       if (origin == SEEK_HOLE) {
+               extoff = cpos;
+               extoff <<= cs_bits;
+               extlen = clen;
+               extlen <<=  cs_bits;
+
+               if ((extoff + extlen) > inode->i_size)
+                       extlen = inode->i_size - extoff;
+               extoff += extlen;
+               if (extoff > *offset)
+                       *offset = extoff;
+               goto out_unlock;
+       }
+
+       ret = -ENXIO;
+
+out_unlock:
+
+       brelse(di_bh);
+
+       up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+       ocfs2_inode_unlock(inode, 0);
+out:
+       if (ret && ret != -ENXIO)
+               ret = -ENXIO;
+       return ret;
+}
+
 int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
                           struct buffer_head *bhs[], int flags,
                           int (*validate)(struct super_block *sb,
index e79d41c2c90972fe801a99ec040b229a92debe98..67ea57d2fd594da7e456c1103bb1652fa68b5f69 100644 (file)
@@ -53,6 +53,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
 int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                 u64 map_start, u64 map_len);
 
+int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin);
+
 int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster,
                             u32 *p_cluster, u32 *num_clusters,
                             struct ocfs2_extent_list *el,
index de4ea1af041b654f8f1b4f1a000f6492226f701f..6e396683c3d48af7321f77b8658754982586cb35 100644 (file)
@@ -1950,6 +1950,9 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
        if (ret < 0)
                mlog_errno(ret);
 
+       if (file->f_flags & O_SYNC)
+               handle->h_sync = 1;
+
        ocfs2_commit_trans(osb, handle);
 
 out_inode_unlock:
@@ -2052,6 +2055,23 @@ out:
        return ret;
 }
 
+static void ocfs2_aiodio_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0));
+}
+
+static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
+{
+       int blockmask = inode->i_sb->s_blocksize - 1;
+       loff_t final_size = pos + count;
+
+       if ((pos & blockmask) || (final_size & blockmask))
+               return 1;
+       return 0;
+}
+
 static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
                                            struct file *file,
                                            loff_t pos, size_t count,
@@ -2230,6 +2250,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        int full_coherency = !(osb->s_mount_opt &
                               OCFS2_MOUNT_COHERENCY_BUFFERED);
+       int unaligned_dio = 0;
 
        trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
                (unsigned long long)OCFS2_I(inode)->ip_blkno,
@@ -2297,6 +2318,10 @@ relock:
                goto out;
        }
 
+       if (direct_io && !is_sync_kiocb(iocb))
+               unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left,
+                                                     *ppos);
+
        /*
         * We can't complete the direct I/O as requested, fall back to
         * buffered I/O.
@@ -2311,6 +2336,18 @@ relock:
                goto relock;
        }
 
+       if (unaligned_dio) {
+               /*
+                * Wait on previous unaligned aio to complete before
+                * proceeding.
+                */
+               ocfs2_aiodio_wait(inode);
+
+               /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */
+               atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio);
+               ocfs2_iocb_set_unaligned_aio(iocb);
+       }
+
        /*
         * To later detect whether a journal commit for sync writes is
         * necessary, we sample i_size, and cluster count here.
@@ -2382,8 +2419,12 @@ out_dio:
        if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) {
                rw_level = -1;
                have_alloc_sem = 0;
+               unaligned_dio = 0;
        }
 
+       if (unaligned_dio)
+               atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio);
+
 out:
        if (rw_level != -1)
                ocfs2_rw_unlock(inode, rw_level);
@@ -2591,6 +2632,57 @@ bail:
        return ret;
 }
 
+/* Refer generic_file_llseek_unlocked() */
+static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct inode *inode = file->f_mapping->host;
+       int ret = 0;
+
+       mutex_lock(&inode->i_mutex);
+
+       switch (origin) {
+       case SEEK_SET:
+               break;
+       case SEEK_END:
+               offset += inode->i_size;
+               break;
+       case SEEK_CUR:
+               if (offset == 0) {
+                       offset = file->f_pos;
+                       goto out;
+               }
+               offset += file->f_pos;
+               break;
+       case SEEK_DATA:
+       case SEEK_HOLE:
+               ret = ocfs2_seek_data_hole_offset(file, &offset, origin);
+               if (ret)
+                       goto out;
+               break;
+       default:
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
+               ret = -EINVAL;
+       if (!ret && offset > inode->i_sb->s_maxbytes)
+               ret = -EINVAL;
+       if (ret)
+               goto out;
+
+       if (offset != file->f_pos) {
+               file->f_pos = offset;
+               file->f_version = 0;
+       }
+
+out:
+       mutex_unlock(&inode->i_mutex);
+       if (ret)
+               return ret;
+       return offset;
+}
+
 const struct inode_operations ocfs2_file_iops = {
        .setattr        = ocfs2_setattr,
        .getattr        = ocfs2_getattr,
@@ -2615,7 +2707,7 @@ const struct inode_operations ocfs2_special_file_iops = {
  * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks!
  */
 const struct file_operations ocfs2_fops = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
@@ -2663,7 +2755,7 @@ const struct file_operations ocfs2_dops = {
  * the cluster.
  */
 const struct file_operations ocfs2_fops_no_plocks = {
-       .llseek         = generic_file_llseek,
+       .llseek         = ocfs2_file_llseek,
        .read           = do_sync_read,
        .write          = do_sync_write,
        .mmap           = ocfs2_mmap,
index a22d2c098890a9ca67e2056976bfc9869d74a325..17454a904d7bf488093de9f3db61dc529e0f8e3c 100644 (file)
@@ -951,7 +951,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode,
        trace_ocfs2_cleanup_delete_inode(
                (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
        if (sync_data)
-               write_inode_now(inode, 1);
+               filemap_write_and_wait(inode->i_mapping);
        truncate_inode_pages(&inode->i_data, 0);
 }
 
index 1c508b149b3ac1bd4325fd33a9aae6bdb70e024a..88924a3133fae7c15ca3f5a5259b64eecd97022e 100644 (file)
@@ -43,6 +43,9 @@ struct ocfs2_inode_info
        /* protects extended attribute changes on this inode */
        struct rw_semaphore             ip_xattr_sem;
 
+       /* Number of outstanding AIO's which are not page aligned */
+       atomic_t                        ip_unaligned_aio;
+
        /* These fields are protected by ip_lock */
        spinlock_t                      ip_lock;
        u32                             ip_open_count;
index bc91072b72196fd335c4b7cbc02ba08cb67254e6..726ff265b296bc3365cfe46e94588c1ee4f6ed6a 100644 (file)
@@ -122,7 +122,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
        if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
                (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
                if (!capable(CAP_LINUX_IMMUTABLE))
-                       goto bail_unlock;
+                       goto bail_commit;
        }
 
        ocfs2_inode->ip_attr = flags;
@@ -132,6 +132,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
        if (status < 0)
                mlog_errno(status);
 
+bail_commit:
        ocfs2_commit_trans(osb, handle);
 bail_unlock:
        ocfs2_inode_unlock(inode, 1);
@@ -381,7 +382,7 @@ int ocfs2_info_handle_freeinode(struct inode *inode,
        if (!oifi) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oifi, req))
@@ -431,7 +432,7 @@ bail:
                o2info_set_request_error(&oifi->ifi_req, req);
 
        kfree(oifi);
-
+out_err:
        return status;
 }
 
@@ -666,7 +667,7 @@ int ocfs2_info_handle_freefrag(struct inode *inode,
        if (!oiff) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto bail;
+               goto out_err;
        }
 
        if (o2info_from_user(*oiff, req))
@@ -716,7 +717,7 @@ bail:
                o2info_set_request_error(&oiff->iff_req, req);
 
        kfree(oiff);
-
+out_err:
        return status;
 }
 
index 295d56454e8b23b6e9d97a6bd258e6170311c8f5..0a42ae96dca7d4a0f662505e0e51206895ce4156 100644 (file)
@@ -1544,9 +1544,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
        /* we need to run complete recovery for offline orphan slots */
        ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
 
-       mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
-            node_num, slot_num,
-            MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+       printk(KERN_NOTICE "ocfs2: Begin replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 
        OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
 
@@ -1601,6 +1601,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
 
        jbd2_journal_destroy(journal);
 
+       printk(KERN_NOTICE "ocfs2: End replay journal (node %d, slot %d) on "\
+              "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev),
+              MINOR(osb->sb->s_dev));
 done:
        /* drop the lock on this nodes journal */
        if (got_lock)
@@ -1808,6 +1811,20 @@ static inline unsigned long ocfs2_orphan_scan_timeout(void)
  * every slot, queuing a recovery of the slot on the ocfs2_wq thread. This
  * is done to catch any orphans that are left over in orphan directories.
  *
+ * It scans all slots, even ones that are in use. It does so to handle the
+ * case described below:
+ *
+ *   Node 1 has an inode it was using. The dentry went away due to memory
+ *   pressure.  Node 1 closes the inode, but it's on the free list. The node
+ *   has the open lock.
+ *   Node 2 unlinks the inode. It grabs the dentry lock to notify others,
+ *   but node 1 has no dentry and doesn't get the message. It trylocks the
+ *   open lock, sees that another node has a PR, and does nothing.
+ *   Later node 2 runs its orphan dir. It igets the inode, trylocks the
+ *   open lock, sees the PR still, and does nothing.
+ *   Basically, we have to trigger an orphan iput on node 1. The only way
+ *   for this to happen is if node 1 runs node 2's orphan dir.
+ *
  * ocfs2_queue_orphan_scan gets called every ORPHAN_SCAN_SCHEDULE_TIMEOUT
  * seconds.  It gets an EX lock on os_lockres and checks sequence number
  * stored in LVB. If the sequence number has changed, it means some other
index 68cf2f6d3c6a40b22dda3e2d4f7e2d44349167fa..a3385b63ff5e542bcfaabe59744fa3af38b537e4 100644 (file)
@@ -441,10 +441,11 @@ static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
 #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
 
 /* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
- * update on dir + index leaf + dx root update for free list */
+ * update on dir + index leaf + dx root update for free list +
+ * previous dirblock update in the free list */
 static inline int ocfs2_link_credits(struct super_block *sb)
 {
-       return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
+       return 2*OCFS2_INODE_UPDATE_CREDITS + 4 +
               ocfs2_quota_trans_credits(sb);
 }
 
index 3e9393ca39ebd823772ae910cda1b4516d46fa62..9cd41083e99123eca1c48085fb39809e6b906b40 100644 (file)
@@ -61,7 +61,7 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
 static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
                                struct page *page)
 {
-       int ret;
+       int ret = VM_FAULT_NOPAGE;
        struct inode *inode = file->f_path.dentry->d_inode;
        struct address_space *mapping = inode->i_mapping;
        loff_t pos = page_offset(page);
@@ -71,32 +71,25 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        void *fsdata;
        loff_t size = i_size_read(inode);
 
-       /*
-        * Another node might have truncated while we were waiting on
-        * cluster locks.
-        * We don't check size == 0 before the shift. This is borrowed
-        * from do_generic_file_read.
-        */
        last_index = (size - 1) >> PAGE_CACHE_SHIFT;
-       if (unlikely(!size || page->index > last_index)) {
-               ret = -EINVAL;
-               goto out;
-       }
 
        /*
-        * The i_size check above doesn't catch the case where nodes
-        * truncated and then re-extended the file. We'll re-check the
-        * page mapping after taking the page lock inside of
-        * ocfs2_write_begin_nolock().
+        * There are cases that lead to the page no longer bebongs to the
+        * mapping.
+        * 1) pagecache truncates locally due to memory pressure.
+        * 2) pagecache truncates when another is taking EX lock against 
+        * inode lock. see ocfs2_data_convert_worker.
+        * 
+        * The i_size check doesn't catch the case where nodes truncated and
+        * then re-extended the file. We'll re-check the page mapping after
+        * taking the page lock inside of ocfs2_write_begin_nolock().
+        *
+        * Let VM retry with these cases.
         */
-       if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
-               /*
-                * the page has been umapped in ocfs2_data_downconvert_worker.
-                * So return 0 here and let VFS retry.
-                */
-               ret = 0;
+       if ((page->mapping != inode->i_mapping) ||
+           (!PageUptodate(page)) ||
+           (page_offset(page) >= size))
                goto out;
-       }
 
        /*
         * Call ocfs2_write_begin() and ocfs2_write_end() to take
@@ -116,17 +109,21 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
        if (ret) {
                if (ret != -ENOSPC)
                        mlog_errno(ret);
+               if (ret == -ENOMEM)
+                       ret = VM_FAULT_OOM;
+               else
+                       ret = VM_FAULT_SIGBUS;
                goto out;
        }
 
-       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
-                                    fsdata);
-       if (ret < 0) {
-               mlog_errno(ret);
+       if (!locked_page) {
+               ret = VM_FAULT_NOPAGE;
                goto out;
        }
+       ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page,
+                                    fsdata);
        BUG_ON(ret != len);
-       ret = 0;
+       ret = VM_FAULT_LOCKED;
 out:
        return ret;
 }
@@ -168,8 +165,6 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 out:
        ocfs2_unblock_signals(&oldset);
-       if (ret)
-               ret = VM_FAULT_SIGBUS;
        return ret;
 }
 
index d53cb706f14c27dfc5ec754dc6d0f846e424421c..184c76b8c293907368f325316da04f57801d87eb 100644 (file)
@@ -745,7 +745,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
         */
        ocfs2_probe_alloc_group(inode, gd_bh, &goal_bit, len, move_max_hop,
                                new_phys_cpos);
-       if (!new_phys_cpos) {
+       if (!*new_phys_cpos) {
                ret = -ENOSPC;
                goto out_commit;
        }
index 409285854f647e2357223bc7a8d24c36b376a6bb..d355e6e36b366bfe7dc8cc91cbabdad05976ba2c 100644 (file)
@@ -836,18 +836,65 @@ static inline unsigned int ocfs2_clusters_to_megabytes(struct super_block *sb,
 
 static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_set_bit_le(bit, bitmap);
+       __set_bit_le(bit, bitmap);
 }
 #define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
 
 static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
 {
-       __test_and_clear_bit_le(bit, bitmap);
+       __clear_bit_le(bit, bitmap);
 }
 #define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
 
 #define ocfs2_test_bit test_bit_le
 #define ocfs2_find_next_zero_bit find_next_zero_bit_le
 #define ocfs2_find_next_bit find_next_bit_le
+
+static inline void *correct_addr_and_bit_unaligned(int *bit, void *addr)
+{
+#if BITS_PER_LONG == 64
+       *bit += ((unsigned long) addr & 7UL) << 3;
+       addr = (void *) ((unsigned long) addr & ~7UL);
+#elif BITS_PER_LONG == 32
+       *bit += ((unsigned long) addr & 3UL) << 3;
+       addr = (void *) ((unsigned long) addr & ~3UL);
+#else
+#error "how many bits you are?!"
+#endif
+       return addr;
+}
+
+static inline void ocfs2_set_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       ocfs2_set_bit(bit, bitmap);
+}
+
+static inline void ocfs2_clear_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       ocfs2_clear_bit(bit, bitmap);
+}
+
+static inline int ocfs2_test_bit_unaligned(int bit, void *bitmap)
+{
+       bitmap = correct_addr_and_bit_unaligned(&bit, bitmap);
+       return ocfs2_test_bit(bit, bitmap);
+}
+
+static inline int ocfs2_find_next_zero_bit_unaligned(void *bitmap, int max,
+                                                       int start)
+{
+       int fix = 0, ret, tmpmax;
+       bitmap = correct_addr_and_bit_unaligned(&fix, bitmap);
+       tmpmax = max + fix;
+       start += fix;
+
+       ret = ocfs2_find_next_zero_bit(bitmap, tmpmax, start) - fix;
+       if (ret > max)
+               return max;
+       return ret;
+}
+
 #endif  /* OCFS2_H */
 
index dc8007fc924718c6d461b22cee52e4a8fbd6ae7d..f100bf70a9066ed1b917b8ec0451c27231840f92 100644 (file)
@@ -404,7 +404,9 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
        int status = 0;
        struct ocfs2_quota_recovery *rec;
 
-       mlog(ML_NOTICE, "Beginning quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        rec = ocfs2_alloc_quota_recovery();
        if (!rec)
                return ERR_PTR(-ENOMEM);
@@ -549,8 +551,8 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
                                goto out_commit;
                        }
                        lock_buffer(qbh);
-                       WARN_ON(!ocfs2_test_bit(bit, dchunk->dqc_bitmap));
-                       ocfs2_clear_bit(bit, dchunk->dqc_bitmap);
+                       WARN_ON(!ocfs2_test_bit_unaligned(bit, dchunk->dqc_bitmap));
+                       ocfs2_clear_bit_unaligned(bit, dchunk->dqc_bitmap);
                        le32_add_cpu(&dchunk->dqc_free, 1);
                        unlock_buffer(qbh);
                        ocfs2_journal_dirty(handle, qbh);
@@ -596,7 +598,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
        struct inode *lqinode;
        unsigned int flags;
 
-       mlog(ML_NOTICE, "Finishing quota recovery in slot %u\n", slot_num);
+       printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
+              "slot %u\n", osb->dev_str, slot_num);
+
        mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
        for (type = 0; type < MAXQUOTAS; type++) {
                if (list_empty(&(rec->r_list[type])))
@@ -612,8 +616,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
                /* Someone else is holding the lock? Then he must be
                 * doing the recovery. Just skip the file... */
                if (status == -EAGAIN) {
-                       mlog(ML_NOTICE, "skipping quota recovery for slot %d "
-                            "because quota file is locked.\n", slot_num);
+                       printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
+                              "device (%s) for slot %d because quota file is "
+                              "locked.\n", osb->dev_str, slot_num);
                        status = 0;
                        goto out_put;
                } else if (status < 0) {
@@ -944,7 +949,7 @@ static struct ocfs2_quota_chunk *ocfs2_find_free_entry(struct super_block *sb,
                      * ol_quota_entries_per_block(sb);
        }
 
-       found = ocfs2_find_next_zero_bit(dchunk->dqc_bitmap, len, 0);
+       found = ocfs2_find_next_zero_bit_unaligned(dchunk->dqc_bitmap, len, 0);
        /* We failed? */
        if (found == len) {
                mlog(ML_ERROR, "Did not find empty entry in chunk %d with %u"
@@ -1208,7 +1213,7 @@ static void olq_alloc_dquot(struct buffer_head *bh, void *private)
        struct ocfs2_local_disk_chunk *dchunk;
 
        dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
-       ocfs2_set_bit(*offset, dchunk->dqc_bitmap);
+       ocfs2_set_bit_unaligned(*offset, dchunk->dqc_bitmap);
        le32_add_cpu(&dchunk->dqc_free, -1);
 }
 
@@ -1289,7 +1294,7 @@ int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
                        (od->dq_chunk->qc_headerbh->b_data);
        /* Mark structure as freed */
        lock_buffer(od->dq_chunk->qc_headerbh);
-       ocfs2_clear_bit(offset, dchunk->dqc_bitmap);
+       ocfs2_clear_bit_unaligned(offset, dchunk->dqc_bitmap);
        le32_add_cpu(&dchunk->dqc_free, 1);
        unlock_buffer(od->dq_chunk->qc_headerbh);
        ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh);
index 26fc0014d50936137d0afb898b7c9541e8026087..1424c151cccce0170819ce4e0f36dad7d97461b8 100644 (file)
@@ -493,8 +493,8 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
                        goto bail;
                }
        } else
-               mlog(ML_NOTICE, "slot %d is already allocated to this node!\n",
-                    slot);
+               printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
+                      "allocated to this node!\n", slot, osb->dev_str);
 
        ocfs2_set_slot(si, slot, osb->node_num);
        osb->slot_num = slot;
index 19965b00c43caee7df4e09428775a55150ba9f8c..94368017edb378ce1e3961d1976408c954677c9a 100644 (file)
@@ -28,6 +28,7 @@
 #include "cluster/masklog.h"
 #include "cluster/nodemanager.h"
 #include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
 
 #include "stackglue.h"
 
@@ -255,6 +256,61 @@ static void o2cb_dump_lksb(struct ocfs2_dlm_lksb *lksb)
        dlm_print_one_lock(lksb->lksb_o2dlm.lockid);
 }
 
+/*
+ * Check if this node is heartbeating and is connected to all other
+ * heartbeating nodes.
+ */
+static int o2cb_cluster_check(void)
+{
+       u8 node_num;
+       int i;
+       unsigned long hbmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long netmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+
+       node_num = o2nm_this_node();
+       if (node_num == O2NM_MAX_NODES) {
+               printk(KERN_ERR "o2cb: This node has not been configured.\n");
+               return -EINVAL;
+       }
+
+       /*
+        * o2dlm expects o2net sockets to be created. If not, then
+        * dlm_join_domain() fails with a stack of errors which are both cryptic
+        * and incomplete. The idea here is to detect upfront whether we have
+        * managed to connect to all nodes or not. If not, then list the nodes
+        * to allow the user to check the configuration (incorrect IP, firewall,
+        * etc.) Yes, this is racy. But its not the end of the world.
+        */
+#define        O2CB_MAP_STABILIZE_COUNT        60
+       for (i = 0; i < O2CB_MAP_STABILIZE_COUNT; ++i) {
+               o2hb_fill_node_map(hbmap, sizeof(hbmap));
+               if (!test_bit(node_num, hbmap)) {
+                       printk(KERN_ERR "o2cb: %s heartbeat has not been "
+                              "started.\n", (o2hb_global_heartbeat_active() ?
+                                             "Global" : "Local"));
+                       return -EINVAL;
+               }
+               o2net_fill_node_map(netmap, sizeof(netmap));
+               /* Force set the current node to allow easy compare */
+               set_bit(node_num, netmap);
+               if (!memcmp(hbmap, netmap, sizeof(hbmap)))
+                       return 0;
+               if (i < O2CB_MAP_STABILIZE_COUNT)
+                       msleep(1000);
+       }
+
+       printk(KERN_ERR "o2cb: This node could not connect to nodes:");
+       i = -1;
+       while ((i = find_next_bit(hbmap, O2NM_MAX_NODES,
+                                 i + 1)) < O2NM_MAX_NODES) {
+               if (!test_bit(i, netmap))
+                       printk(" %u", i);
+       }
+       printk(".\n");
+
+       return -ENOTCONN;
+}
+
 /*
  * Called from the dlm when it's about to evict a node. This is how the
  * classic stack signals node death.
@@ -263,8 +319,8 @@ static void o2dlm_eviction_cb(int node_num, void *data)
 {
        struct ocfs2_cluster_connection *conn = data;
 
-       mlog(ML_NOTICE, "o2dlm has evicted node %d from group %.*s\n",
-            node_num, conn->cc_namelen, conn->cc_name);
+       printk(KERN_NOTICE "o2cb: o2dlm has evicted node %d from domain %.*s\n",
+              node_num, conn->cc_namelen, conn->cc_name);
 
        conn->cc_recovery_handler(node_num, conn->cc_recovery_data);
 }
@@ -280,12 +336,11 @@ static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn)
        BUG_ON(conn == NULL);
        BUG_ON(conn->cc_proto == NULL);
 
-       /* for now we only have one cluster/node, make sure we see it
-        * in the heartbeat universe */
-       if (!o2hb_check_local_node_heartbeating()) {
-               if (o2hb_global_heartbeat_active())
-                       mlog(ML_ERROR, "Global heartbeat not started\n");
-               rc = -EINVAL;
+       /* Ensure cluster stack is up and all nodes are connected */
+       rc = o2cb_cluster_check();
+       if (rc) {
+               printk(KERN_ERR "o2cb: Cluster check failed. Fix errors "
+                      "before retrying.\n");
                goto out;
        }
 
index 56f61027236b696fce1ccde3e1edaf86acee59a0..4994f8b0e60410ff576fa63299e29e430192080a 100644 (file)
@@ -54,6 +54,7 @@
 #include "ocfs1_fs_compat.h"
 
 #include "alloc.h"
+#include "aops.h"
 #include "blockcheck.h"
 #include "dlmglue.h"
 #include "export.h"
@@ -1107,9 +1108,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 
                ocfs2_set_ro_flag(osb, 1);
 
-               printk(KERN_NOTICE "Readonly device detected. No cluster "
-                      "services will be utilized for this mount. Recovery "
-                      "will be skipped.\n");
+               printk(KERN_NOTICE "ocfs2: Readonly device (%s) detected. "
+                      "Cluster services will not be used for this mount. "
+                      "Recovery will be skipped.\n", osb->dev_str);
        }
 
        if (!ocfs2_is_hard_readonly(osb)) {
@@ -1616,12 +1617,17 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
        return 0;
 }
 
+wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 static int __init ocfs2_init(void)
 {
-       int status;
+       int status, i;
 
        ocfs2_print_version();
 
+       for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++)
+               init_waitqueue_head(&ocfs2__ioend_wq[i]);
+
        status = init_ocfs2_uptodate_cache();
        if (status < 0) {
                mlog_errno(status);
@@ -1760,7 +1766,7 @@ static void ocfs2_inode_init_once(void *data)
        ocfs2_extent_map_init(&oi->vfs_inode);
        INIT_LIST_HEAD(&oi->ip_io_markers);
        oi->ip_dir_start_lookup = 0;
-
+       atomic_set(&oi->ip_unaligned_aio, 0);
        init_rwsem(&oi->ip_alloc_sem);
        init_rwsem(&oi->ip_xattr_sem);
        mutex_init(&oi->ip_io_mutex);
@@ -1974,7 +1980,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
         * If we failed before we got a uuid_str yet, we can't stop
         * heartbeat.  Otherwise, do it.
         */
-       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str)
+       if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str &&
+           !ocfs2_is_hard_readonly(osb))
                hangup_needed = 1;
 
        if (osb->cconn)
@@ -2353,7 +2360,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
                mlog_errno(status);
                goto bail;
        }
-       cleancache_init_shared_fs((char *)&uuid_net_key, sb);
+       cleancache_init_shared_fs((char *)&di->id2.i_super.s_uuid, sb);
 
 bail:
        return status;
@@ -2462,8 +2469,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
                        goto finally;
                }
        } else {
-               mlog(ML_NOTICE, "File system was not unmounted cleanly, "
-                    "recovering volume.\n");
+               printk(KERN_NOTICE "ocfs2: File system on device (%s) was not "
+                      "unmounted cleanly, recovering it.\n", osb->dev_str);
        }
 
        local = ocfs2_mount_local(osb);
index 194fb22ef79d590580f3245b522d0b095ef3794c..aa9e8777b09a5e345b081b0e495db378485a30e7 100644 (file)
@@ -2376,16 +2376,18 @@ static int ocfs2_remove_value_outside(struct inode*inode,
                }
 
                ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt);
-               if (ret < 0) {
-                       mlog_errno(ret);
-                       break;
-               }
 
                ocfs2_commit_trans(osb, ctxt.handle);
                if (ctxt.meta_ac) {
                        ocfs2_free_alloc_context(ctxt.meta_ac);
                        ctxt.meta_ac = NULL;
                }
+
+               if (ret < 0) {
+                       mlog_errno(ret);
+                       break;
+               }
+
        }
 
        if (ctxt.meta_ac)
index 2db1bd3173b2d77bb902273173a8ede14bf27f2e..851ba3dcdc290ab6b750793c2840bdffac755de7 100644 (file)
@@ -1652,46 +1652,12 @@ out:
        return error;
 }
 
-static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry,
-               struct kstat *stat)
-{
-       struct inode *inode = dentry->d_inode;
-       struct task_struct *task = get_proc_task(inode);
-       int rc;
-
-       if (task == NULL)
-               return -ESRCH;
-
-       rc = -EACCES;
-       if (lock_trace(task))
-               goto out_task;
-
-       generic_fillattr(inode, stat);
-       unlock_trace(task);
-       rc = 0;
-out_task:
-       put_task_struct(task);
-       return rc;
-}
-
 static const struct inode_operations proc_pid_link_inode_operations = {
        .readlink       = proc_pid_readlink,
        .follow_link    = proc_pid_follow_link,
        .setattr        = proc_setattr,
 };
 
-static const struct inode_operations proc_fdinfo_link_inode_operations = {
-       .setattr        = proc_setattr,
-       .getattr        = proc_pid_fd_link_getattr,
-};
-
-static const struct inode_operations proc_fd_link_inode_operations = {
-       .readlink       = proc_pid_readlink,
-       .follow_link    = proc_pid_follow_link,
-       .setattr        = proc_setattr,
-       .getattr        = proc_pid_fd_link_getattr,
-};
-
 
 /* building an inode */
 
@@ -1923,61 +1889,49 @@ out:
 
 static int proc_fd_info(struct inode *inode, struct path *path, char *info)
 {
-       struct task_struct *task;
-       struct files_struct *files;
+       struct task_struct *task = get_proc_task(inode);
+       struct files_struct *files = NULL;
        struct file *file;
        int fd = proc_fd(inode);
-       int rc;
-
-       task = get_proc_task(inode);
-       if (!task)
-               return -ENOENT;
-
-       rc = -EACCES;
-       if (lock_trace(task))
-               goto out_task;
-
-       rc = -ENOENT;
-       files = get_files_struct(task);
-       if (files == NULL)
-               goto out_unlock;
 
-       /*
-        * We are not taking a ref to the file structure, so we must
-        * hold ->file_lock.
-        */
-       spin_lock(&files->file_lock);
-       file = fcheck_files(files, fd);
-       if (file) {
-               unsigned int f_flags;
-               struct fdtable *fdt;
-
-               fdt = files_fdtable(files);
-               f_flags = file->f_flags & ~O_CLOEXEC;
-               if (FD_ISSET(fd, fdt->close_on_exec))
-                       f_flags |= O_CLOEXEC;
-
-               if (path) {
-                       *path = file->f_path;
-                       path_get(&file->f_path);
+       if (task) {
+               files = get_files_struct(task);
+               put_task_struct(task);
+       }
+       if (files) {
+               /*
+                * We are not taking a ref to the file structure, so we must
+                * hold ->file_lock.
+                */
+               spin_lock(&files->file_lock);
+               file = fcheck_files(files, fd);
+               if (file) {
+                       unsigned int f_flags;
+                       struct fdtable *fdt;
+
+                       fdt = files_fdtable(files);
+                       f_flags = file->f_flags & ~O_CLOEXEC;
+                       if (FD_ISSET(fd, fdt->close_on_exec))
+                               f_flags |= O_CLOEXEC;
+
+                       if (path) {
+                               *path = file->f_path;
+                               path_get(&file->f_path);
+                       }
+                       if (info)
+                               snprintf(info, PROC_FDINFO_MAX,
+                                        "pos:\t%lli\n"
+                                        "flags:\t0%o\n",
+                                        (long long) file->f_pos,
+                                        f_flags);
+                       spin_unlock(&files->file_lock);
+                       put_files_struct(files);
+                       return 0;
                }
-               if (info)
-                       snprintf(info, PROC_FDINFO_MAX,
-                                "pos:\t%lli\n"
-                                "flags:\t0%o\n",
-                                (long long) file->f_pos,
-                                f_flags);
-               rc = 0;
-       } else
-               rc = -ENOENT;
-       spin_unlock(&files->file_lock);
-       put_files_struct(files);
-
-out_unlock:
-       unlock_trace(task);
-out_task:
-       put_task_struct(task);
-       return rc;
+               spin_unlock(&files->file_lock);
+               put_files_struct(files);
+       }
+       return -ENOENT;
 }
 
 static int proc_fd_link(struct inode *inode, struct path *path)
@@ -2072,7 +2026,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
        spin_unlock(&files->file_lock);
        put_files_struct(files);
 
-       inode->i_op = &proc_fd_link_inode_operations;
+       inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
        ei->op.proc_get_link = proc_fd_link;
        d_set_d_op(dentry, &tid_fd_dentry_operations);
@@ -2104,12 +2058,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
        if (fd == ~0U)
                goto out;
 
-       result = ERR_PTR(-EACCES);
-       if (lock_trace(task))
-               goto out;
-
        result = instantiate(dir, dentry, task, &fd);
-       unlock_trace(task);
 out:
        put_task_struct(task);
 out_no_task:
@@ -2129,28 +2078,23 @@ static int proc_readfd_common(struct file * filp, void * dirent,
        retval = -ENOENT;
        if (!p)
                goto out_no_task;
-
-       retval = -EACCES;
-       if (lock_trace(p))
-               goto out;
-
        retval = 0;
 
        fd = filp->f_pos;
        switch (fd) {
                case 0:
                        if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
-                               goto out_unlock;
+                               goto out;
                        filp->f_pos++;
                case 1:
                        ino = parent_ino(dentry);
                        if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
-                               goto out_unlock;
+                               goto out;
                        filp->f_pos++;
                default:
                        files = get_files_struct(p);
                        if (!files)
-                               goto out_unlock;
+                               goto out;
                        rcu_read_lock();
                        for (fd = filp->f_pos-2;
                             fd < files_fdtable(files)->max_fds;
@@ -2174,9 +2118,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
                        rcu_read_unlock();
                        put_files_struct(files);
        }
-
-out_unlock:
-       unlock_trace(p);
 out:
        put_task_struct(p);
 out_no_task:
@@ -2254,7 +2195,6 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
        ei->fd = fd;
        inode->i_mode = S_IFREG | S_IRUSR;
        inode->i_fop = &proc_fdinfo_file_operations;
-       inode->i_op = &proc_fdinfo_link_inode_operations;
        d_set_d_op(dentry, &tid_fd_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
index 586174168e2ac8818fc51397223fe683b4afa189..80e4645f7990cf4cc0e636a7c19f9840503cdd42 100644 (file)
@@ -131,12 +131,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                K(i.freeswap),
                K(global_page_state(NR_FILE_DIRTY)),
                K(global_page_state(NR_WRITEBACK)),
-               K(global_page_state(NR_ANON_PAGES)
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+               K(global_page_state(NR_ANON_PAGES)
                  + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) *
-                 HPAGE_PMD_NR
+                 HPAGE_PMD_NR),
+#else
+               K(global_page_state(NR_ANON_PAGES)),
 #endif
-                 ),
                K(global_page_state(NR_FILE_MAPPED)),
                K(global_page_state(NR_SHMEM)),
                K(global_page_state(NR_SLAB_RECLAIMABLE) +
index 42b274da92c39d539c7c2f0f82a2f825c1a20383..2a30d67dd6b81ea03c71b3bdea4fa50913a09ae4 100644 (file)
@@ -32,7 +32,7 @@ static cputime64_t get_idle_time(int cpu)
                idle = kstat_cpu(cpu).cpustat.idle;
                idle = cputime64_add(idle, arch_idle_time(cpu));
        } else
-               idle = usecs_to_cputime(idle_time);
+               idle = nsecs_to_jiffies64(1000 * idle_time);
 
        return idle;
 }
@@ -46,7 +46,7 @@ static cputime64_t get_iowait_time(int cpu)
                /* !NO_HZ so we can rely on cpustat.iowait */
                iowait = kstat_cpu(cpu).cpustat.iowait;
        else
-               iowait = usecs_to_cputime(iowait_time);
+               iowait = nsecs_to_jiffies64(1000 * iowait_time);
 
        return iowait;
 }
index cd99bf557650c4c727cdd9ac060ec28800a0ffe5..b0f450a2bb7cc4bef696ab23591da2a75c0c1ffb 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
index 2bd620f0d796cf5dee01590c65b7ac8802e33bf9..57bbf9078ac8f327be28e88b38e10eeff1f9bfc0 100644 (file)
@@ -167,6 +167,7 @@ int pstore_register(struct pstore_info *psi)
        }
 
        psinfo = psi;
+       mutex_init(&psinfo->read_mutex);
        spin_unlock(&pstore_lock);
 
        if (owner && !try_module_get(owner)) {
@@ -195,30 +196,32 @@ EXPORT_SYMBOL_GPL(pstore_register);
 void pstore_get_records(int quiet)
 {
        struct pstore_info *psi = psinfo;
+       char                    *buf = NULL;
        ssize_t                 size;
        u64                     id;
        enum pstore_type_id     type;
        struct timespec         time;
        int                     failed = 0, rc;
-       unsigned long           flags;
 
        if (!psi)
                return;
 
-       spin_lock_irqsave(&psinfo->buf_lock, flags);
+       mutex_lock(&psi->read_mutex);
        rc = psi->open(psi);
        if (rc)
                goto out;
 
-       while ((size = psi->read(&id, &type, &time, psi)) > 0) {
-               rc = pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
+       while ((size = psi->read(&id, &type, &time, &buf, psi)) > 0) {
+               rc = pstore_mkfile(type, psi->name, id, buf, (size_t)size,
                                  time, psi);
+               kfree(buf);
+               buf = NULL;
                if (rc && (rc != -EEXIST || !quiet))
                        failed++;
        }
        psi->close(psi);
 out:
-       spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+       mutex_unlock(&psi->read_mutex);
 
        if (failed)
                printk(KERN_WARNING "pstore: failed to load %d record(s) from '%s'\n",
index aae0edb95c6c321dac9268ab5df670607eb7e7e9..35f4b0ecdeb3de1ba41756c3985436c6f67b5148 100644 (file)
@@ -286,7 +286,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
                /* caller already holds s_umount */
                if (sb->s_flags & MS_RDONLY)
                        return -EROFS;
-               writeback_inodes_sb(sb);
+               writeback_inodes_sb(sb, WB_REASON_SYNC);
                return 0;
        default:
                return -EINVAL;
index 05d6b0e78c959a341137c97fbb2ea2fa89b25197..dba43c3ea3afb6605972d3a0e3eca3ac5248876e 100644 (file)
@@ -449,8 +449,6 @@ EXPORT_SYMBOL(seq_path);
 
 /*
  * Same as seq_path, but relative to supplied root.
- *
- * root may be changed, see __d_path().
  */
 int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
                  char *esc)
@@ -463,6 +461,8 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
                char *p;
 
                p = __d_path(path, root, buf, size);
+               if (!p)
+                       return SEQ_SKIP;
                res = PTR_ERR(p);
                if (!IS_ERR(p)) {
                        char *end = mangle_path(buf, p, esc);
@@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
        }
        seq_commit(m, res);
 
-       return res < 0 ? res : 0;
+       return res < 0 && res != -ENAMETOOLONG ? res : 0;
 }
 
 /*
index c98a7477edfdc91eec85602fe1a68d6dade4c9c6..101b8ef901d78625d00c337d0df1c4e2e25c5133 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -43,7 +43,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
        if (wait)
                sync_inodes_sb(sb);
        else
-               writeback_inodes_sb(sb);
+               writeback_inodes_sb(sb, WB_REASON_SYNC);
 
        if (sb->s_op->sync_fs)
                sb->s_op->sync_fs(sb, wait);
@@ -98,7 +98,7 @@ static void sync_filesystems(int wait)
  */
 SYSCALL_DEFINE0(sync)
 {
-       wakeup_flusher_threads(0);
+       wakeup_flusher_threads(0, WB_REASON_SYNC);
        sync_filesystems(0);
        sync_filesystems(1);
        if (unlikely(laptop_mode))
index 315de66e52b21fc8016f96b5a62b4e94fa41ecd7..bc4f94b28706517e8216585b46847ea5a1ce9cc1 100644 (file)
@@ -63,7 +63,7 @@
 static void shrink_liability(struct ubifs_info *c, int nr_to_write)
 {
        down_read(&c->vfs_sb->s_umount);
-       writeback_inodes_sb(c->vfs_sb);
+       writeback_inodes_sb(c->vfs_sb, WB_REASON_FS_FREE_SPACE);
        up_read(&c->vfs_sb->s_umount);
 }
 
index eef109a1a92772d67cfe7a5693e113c8c801dbec..b09ba2dd8b625efc12130e7a20572560072d8b3b 100644 (file)
@@ -870,6 +870,22 @@ void dbg_dump_lpt_info(struct ubifs_info *c)
        spin_unlock(&dbg_lock);
 }
 
+void dbg_dump_sleb(const struct ubifs_info *c,
+                  const struct ubifs_scan_leb *sleb, int offs)
+{
+       struct ubifs_scan_node *snod;
+
+       printk(KERN_DEBUG "(pid %d) start dumping scanned data from LEB %d:%d\n",
+              current->pid, sleb->lnum, offs);
+
+       list_for_each_entry(snod, &sleb->nodes, list) {
+               cond_resched();
+               printk(KERN_DEBUG "Dumping node at LEB %d:%d len %d\n", sleb->lnum,
+                      snod->offs, snod->len);
+               dbg_dump_node(c, snod->node);
+       }
+}
+
 void dbg_dump_leb(const struct ubifs_info *c, int lnum)
 {
        struct ubifs_scan_leb *sleb;
index feb361e252acfe801d186849430c553e39a4268e..8d9c46810189a1db050d047a11b521c8fe145dba 100644 (file)
@@ -269,6 +269,8 @@ void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp);
 void dbg_dump_lprops(struct ubifs_info *c);
 void dbg_dump_lpt_info(struct ubifs_info *c);
 void dbg_dump_leb(const struct ubifs_info *c, int lnum);
+void dbg_dump_sleb(const struct ubifs_info *c,
+                  const struct ubifs_scan_leb *sleb, int offs);
 void dbg_dump_znode(const struct ubifs_info *c,
                    const struct ubifs_znode *znode);
 void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat);
@@ -387,6 +389,9 @@ static inline void dbg_dump_lpt_info(struct ubifs_info *c)        { return; }
 static inline void dbg_dump_leb(const struct ubifs_info *c,
                                int lnum)                         { return; }
 static inline void
+dbg_dump_sleb(const struct ubifs_info *c,
+             const struct ubifs_scan_leb *sleb, int offs)        { return; }
+static inline void
 dbg_dump_znode(const struct ubifs_info *c,
               const struct ubifs_znode *znode)                   { return; }
 static inline void dbg_dump_heap(struct ubifs_info *c,
index af02790d93282ec55c3ba48c3efca155b5ddea89..ee4f43f4bb998d2bc20ac1f96437e926e2f2e490 100644 (file)
@@ -983,7 +983,7 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
 }
 
 /**
- *  clean_an_unclean_leb - read and write a LEB to remove corruption.
+ * clean_an_unclean_leb - read and write a LEB to remove corruption.
  * @c: UBIFS file-system description object
  * @ucleb: unclean LEB information
  * @sbuf: LEB-sized buffer to use
index 93d938ad3d2a74ec74d56a5d64aba6860a44eb10..6094c5a5d7a8de597e3905b9c4941f458cc999f3 100644 (file)
@@ -247,7 +247,7 @@ static int create_default_filesystem(struct ubifs_info *c)
        mst->total_dirty = cpu_to_le64(tmp64);
 
        /*  The indexing LEB does not contribute to dark space */
-       tmp64 = (c->main_lebs - 1) * c->dark_wm;
+       tmp64 = ((long long)(c->main_lebs - 1) * c->dark_wm);
        mst->total_dark = cpu_to_le64(tmp64);
 
        mst->total_used = cpu_to_le64(UBIFS_INO_NODE_SZ);
index b6c4b3795c4a000ce27ac3799b5c39ae6c8044e9..76e4266d2e7e4a8fc3bfc609016e4de467b7e5cf 100644 (file)
@@ -42,6 +42,8 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
        int count, i;
 
        count = be32_to_cpu(aclp->acl_cnt);
+       if (count > XFS_ACL_MAX_ENTRIES)
+               return ERR_PTR(-EFSCORRUPTED);
 
        acl = posix_acl_alloc(count, GFP_KERNEL);
        if (!acl)
index 33b13310ee0c2f2ddf0c68abaa57e95c7f47d963..574d4ee9b6253ea3d589f23288aa7385907642bb 100644 (file)
@@ -189,7 +189,7 @@ xfs_end_io(
        int             error = 0;
 
        if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-               error = -EIO;
+               ioend->io_error = -EIO;
                goto done;
        }
        if (ioend->io_error)
index d4906e7c97873b302201cddf442bdc5eeb54a29d..c1b55e5965517a9407f678610b62f29fdabf33b3 100644 (file)
@@ -110,6 +110,7 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
 /*
  * Query whether the requested number of additional bytes of extended
  * attribute space will be able to fit inline.
+ *
  * Returns zero if not, else the di_forkoff fork offset to be used in the
  * literal area for attribute data once the new bytes have been added.
  *
@@ -122,7 +123,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
        int offset;
        int minforkoff; /* lower limit on valid forkoff locations */
        int maxforkoff; /* upper limit on valid forkoff locations */
-       int dsize;      
+       int dsize;
        xfs_mount_t *mp = dp->i_mount;
 
        offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
@@ -136,47 +137,60 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
                return (offset >= minforkoff) ? minforkoff : 0;
        }
 
-       if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
-               if (bytes <= XFS_IFORK_ASIZE(dp))
-                       return dp->i_d.di_forkoff;
+       /*
+        * If the requested numbers of bytes is smaller or equal to the
+        * current attribute fork size we can always proceed.
+        *
+        * Note that if_bytes in the data fork might actually be larger than
+        * the current data fork size is due to delalloc extents. In that
+        * case either the extent count will go down when they are converted
+        * to real extents, or the delalloc conversion will take care of the
+        * literal area rebalancing.
+        */
+       if (bytes <= XFS_IFORK_ASIZE(dp))
+               return dp->i_d.di_forkoff;
+
+       /*
+        * For attr2 we can try to move the forkoff if there is space in the
+        * literal area, but for the old format we are done if there is no
+        * space in the fixed attribute fork.
+        */
+       if (!(mp->m_flags & XFS_MOUNT_ATTR2))
                return 0;
-       }
 
        dsize = dp->i_df.if_bytes;
-       
+
        switch (dp->i_d.di_format) {
        case XFS_DINODE_FMT_EXTENTS:
-               /* 
+               /*
                 * If there is no attr fork and the data fork is extents, 
-                * determine if creating the default attr fork will result 
-                * in the extents form migrating to btree. If so, the 
-                * minimum offset only needs to be the space required for 
+                * determine if creating the default attr fork will result
+                * in the extents form migrating to btree. If so, the
+                * minimum offset only needs to be the space required for
                 * the btree root.
-                */ 
+                */
                if (!dp->i_d.di_forkoff && dp->i_df.if_bytes >
                    xfs_default_attroffset(dp))
                        dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
                break;
-               
        case XFS_DINODE_FMT_BTREE:
                /*
-                * If have data btree then keep forkoff if we have one,
-                * otherwise we are adding a new attr, so then we set 
-                * minforkoff to where the btree root can finish so we have 
+                * If we have a data btree then keep forkoff if we have one,
+                * otherwise we are adding a new attr, so then we set
+                * minforkoff to where the btree root can finish so we have
                 * plenty of room for attrs
                 */
                if (dp->i_d.di_forkoff) {
-                       if (offset < dp->i_d.di_forkoff) 
+                       if (offset < dp->i_d.di_forkoff)
                                return 0;
-                       else 
-                               return dp->i_d.di_forkoff;
-               } else
-                       dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot);
+                       return dp->i_d.di_forkoff;
+               }
+               dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot);
                break;
        }
-       
-       /* 
-        * A data fork btree root must have space for at least 
+
+       /*
+        * A data fork btree root must have space for at least
         * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
         */
        minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
@@ -186,10 +200,10 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
        maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
        maxforkoff = maxforkoff >> 3;   /* rounded down */
 
-       if (offset >= minforkoff && offset < maxforkoff)
-               return offset;
        if (offset >= maxforkoff)
                return maxforkoff;
+       if (offset >= minforkoff)
+               return offset;
        return 0;
 }
 
index c68baeb0974adb2e57f690496fa8957c94c92e0d..d0ab78837057815f17605150d31a633c2eeb2739 100644 (file)
@@ -2383,6 +2383,8 @@ xfs_bmap_btalloc(
        int             tryagain;
        int             error;
 
+       ASSERT(ap->length);
+
        mp = ap->ip->i_mount;
        align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
        if (unlikely(align)) {
@@ -4629,6 +4631,8 @@ xfs_bmapi_allocate(
        int                     error;
        int                     rt;
 
+       ASSERT(bma->length > 0);
+
        rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip);
 
        /*
@@ -4849,6 +4853,7 @@ xfs_bmapi_write(
        ASSERT(*nmap <= XFS_BMAP_MAX_NMAP);
        ASSERT(!(flags & XFS_BMAPI_IGSTATE));
        ASSERT(tp != NULL);
+       ASSERT(len > 0);
 
        whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
                XFS_ATTR_FORK : XFS_DATA_FORK;
@@ -4918,9 +4923,22 @@ xfs_bmapi_write(
                        bma.eof = eof;
                        bma.conv = !!(flags & XFS_BMAPI_CONVERT);
                        bma.wasdel = wasdelay;
-                       bma.length = len;
                        bma.offset = bno;
 
+                       /*
+                        * There's a 32/64 bit type mismatch between the
+                        * allocation length request (which can be 64 bits in
+                        * length) and the bma length request, which is
+                        * xfs_extlen_t and therefore 32 bits. Hence we have to
+                        * check for 32-bit overflows and handle them here.
+                        */
+                       if (len > (xfs_filblks_t)MAXEXTLEN)
+                               bma.length = MAXEXTLEN;
+                       else
+                               bma.length = len;
+
+                       ASSERT(len > 0);
+                       ASSERT(bma.length > 0);
                        error = xfs_bmapi_allocate(&bma, flags);
                        if (error)
                                goto error0;
index 1a3513881bce749d7d4510c2ed21f47bda02a926..eac97ef81e2a156a58d9b74b54607c6a0d2e76c3 100644 (file)
@@ -656,7 +656,7 @@ xfs_buf_item_committing(
 /*
  * This is the ops vector shared by all buf log items.
  */
-static struct xfs_item_ops xfs_buf_item_ops = {
+static const struct xfs_item_ops xfs_buf_item_ops = {
        .iop_size       = xfs_buf_item_size,
        .iop_format     = xfs_buf_item_format,
        .iop_pin        = xfs_buf_item_pin,
index bb3f71d236d28fe8e5733e8264e693a0b00692d6..0dee0b71029d8406add271b9f20350e6b8a97859 100644 (file)
@@ -295,7 +295,7 @@ xfs_qm_dquot_logitem_committing(
 /*
  * This is the ops vector for dquots
  */
-static struct xfs_item_ops xfs_dquot_item_ops = {
+static const struct xfs_item_ops xfs_dquot_item_ops = {
        .iop_size       = xfs_qm_dquot_logitem_size,
        .iop_format     = xfs_qm_dquot_logitem_format,
        .iop_pin        = xfs_qm_dquot_logitem_pin,
@@ -483,7 +483,7 @@ xfs_qm_qoff_logitem_committing(
 {
 }
 
-static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
+static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
        .iop_size       = xfs_qm_qoff_logitem_size,
        .iop_format     = xfs_qm_qoff_logitem_format,
        .iop_pin        = xfs_qm_qoff_logitem_pin,
@@ -498,7 +498,7 @@ static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
 /*
  * This is the ops vector shared by all quotaoff-start log items.
  */
-static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
+static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
        .iop_size       = xfs_qm_qoff_logitem_size,
        .iop_format     = xfs_qm_qoff_logitem_format,
        .iop_pin        = xfs_qm_qoff_logitem_pin,
index da108977b21f8582c7af92e2d4edcdbca8ba07b7..558910f5e3c06a3451558a486a7b982b0f8ee19d 100644 (file)
@@ -98,22 +98,22 @@ xfs_fs_encode_fh(
        switch (fileid_type) {
        case FILEID_INO32_GEN_PARENT:
                spin_lock(&dentry->d_lock);
-               fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino;
+               fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino;
                fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
                spin_unlock(&dentry->d_lock);
                /*FALLTHRU*/
        case FILEID_INO32_GEN:
-               fid->i32.ino = inode->i_ino;
+               fid->i32.ino = XFS_I(inode)->i_ino;
                fid->i32.gen = inode->i_generation;
                break;
        case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
                spin_lock(&dentry->d_lock);
-               fid64->parent_ino = dentry->d_parent->d_inode->i_ino;
+               fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino;
                fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
                spin_unlock(&dentry->d_lock);
                /*FALLTHRU*/
        case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
-               fid64->ino = inode->i_ino;
+               fid64->ino = XFS_I(inode)->i_ino;
                fid64->gen = inode->i_generation;
                break;
        }
index d22e62623437aafb79d62f5492252e140f3a6cb7..35c2aff38b209bd0afa1ff5b36e20230a1d3b5c5 100644 (file)
@@ -217,7 +217,7 @@ xfs_efi_item_committing(
 /*
  * This is the ops vector shared by all efi log items.
  */
-static struct xfs_item_ops xfs_efi_item_ops = {
+static const struct xfs_item_ops xfs_efi_item_ops = {
        .iop_size       = xfs_efi_item_size,
        .iop_format     = xfs_efi_item_format,
        .iop_pin        = xfs_efi_item_pin,
@@ -477,7 +477,7 @@ xfs_efd_item_committing(
 /*
  * This is the ops vector shared by all efd log items.
  */
-static struct xfs_item_ops xfs_efd_item_ops = {
+static const struct xfs_item_ops xfs_efd_item_ops = {
        .iop_size       = xfs_efd_item_size,
        .iop_format     = xfs_efd_item_format,
        .iop_pin        = xfs_efd_item_pin,
index c0237c602f11deb92fa5f533f74a647005fbf1b8..755ee8164880fe4122bac9de94119f1c7086a9b7 100644 (file)
@@ -2835,6 +2835,27 @@ corrupt_out:
        return XFS_ERROR(EFSCORRUPTED);
 }
 
+void
+xfs_promote_inode(
+       struct xfs_inode        *ip)
+{
+       struct xfs_buf          *bp;
+
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
+
+       bp = xfs_incore(ip->i_mount->m_ddev_targp, ip->i_imap.im_blkno,
+                       ip->i_imap.im_len, XBF_TRYLOCK);
+       if (!bp)
+               return;
+
+       if (XFS_BUF_ISDELAYWRITE(bp)) {
+               xfs_buf_delwri_promote(bp);
+               wake_up_process(ip->i_mount->m_ddev_targp->bt_task);
+       }
+
+       xfs_buf_relse(bp);
+}
+
 /*
  * Return a pointer to the extent record at file index idx.
  */
index 760140d1dd661f42e653576a7c947b11eb8b6fbd..b4cd4739f98e74b2e256295b48fe64e285b320b0 100644 (file)
@@ -498,6 +498,7 @@ int         xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
 void           xfs_iext_realloc(xfs_inode_t *, int, int);
 void           xfs_iunpin_wait(xfs_inode_t *);
 int            xfs_iflush(xfs_inode_t *, uint);
+void           xfs_promote_inode(struct xfs_inode *);
 void           xfs_lock_inodes(xfs_inode_t **, int, uint);
 void           xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
 
index b7cf21ba240f802ea56c26a45be341d55641a7dd..abaafdbb3e658e9c484fb82dcfd5b63afade43e9 100644 (file)
@@ -795,7 +795,7 @@ xfs_inode_item_committing(
 /*
  * This is the ops vector shared by all buf log items.
  */
-static struct xfs_item_ops xfs_inode_item_ops = {
+static const struct xfs_item_ops xfs_inode_item_ops = {
        .iop_size       = xfs_inode_item_size,
        .iop_format     = xfs_inode_item_format,
        .iop_pin        = xfs_inode_item_pin,
index 2758a6277c525998f47a6a4d59e8bbc1e9e7ee3a..34817adf4b9ed837da47d6f9ccfa977829fdd33c 100644 (file)
@@ -150,6 +150,117 @@ xlog_grant_add_space(
        } while (head_val != old);
 }
 
+STATIC bool
+xlog_reserveq_wake(
+       struct log              *log,
+       int                     *free_bytes)
+{
+       struct xlog_ticket      *tic;
+       int                     need_bytes;
+
+       list_for_each_entry(tic, &log->l_reserveq, t_queue) {
+               if (tic->t_flags & XLOG_TIC_PERM_RESERV)
+                       need_bytes = tic->t_unit_res * tic->t_cnt;
+               else
+                       need_bytes = tic->t_unit_res;
+
+               if (*free_bytes < need_bytes)
+                       return false;
+               *free_bytes -= need_bytes;
+
+               trace_xfs_log_grant_wake_up(log, tic);
+               wake_up(&tic->t_wait);
+       }
+
+       return true;
+}
+
+STATIC bool
+xlog_writeq_wake(
+       struct log              *log,
+       int                     *free_bytes)
+{
+       struct xlog_ticket      *tic;
+       int                     need_bytes;
+
+       list_for_each_entry(tic, &log->l_writeq, t_queue) {
+               ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV);
+
+               need_bytes = tic->t_unit_res;
+
+               if (*free_bytes < need_bytes)
+                       return false;
+               *free_bytes -= need_bytes;
+
+               trace_xfs_log_regrant_write_wake_up(log, tic);
+               wake_up(&tic->t_wait);
+       }
+
+       return true;
+}
+
+STATIC int
+xlog_reserveq_wait(
+       struct log              *log,
+       struct xlog_ticket      *tic,
+       int                     need_bytes)
+{
+       list_add_tail(&tic->t_queue, &log->l_reserveq);
+
+       do {
+               if (XLOG_FORCED_SHUTDOWN(log))
+                       goto shutdown;
+               xlog_grant_push_ail(log, need_bytes);
+
+               XFS_STATS_INC(xs_sleep_logspace);
+               trace_xfs_log_grant_sleep(log, tic);
+
+               xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock);
+               trace_xfs_log_grant_wake(log, tic);
+
+               spin_lock(&log->l_grant_reserve_lock);
+               if (XLOG_FORCED_SHUTDOWN(log))
+                       goto shutdown;
+       } while (xlog_space_left(log, &log->l_grant_reserve_head) < need_bytes);
+
+       list_del_init(&tic->t_queue);
+       return 0;
+shutdown:
+       list_del_init(&tic->t_queue);
+       return XFS_ERROR(EIO);
+}
+
+STATIC int
+xlog_writeq_wait(
+       struct log              *log,
+       struct xlog_ticket      *tic,
+       int                     need_bytes)
+{
+       list_add_tail(&tic->t_queue, &log->l_writeq);
+
+       do {
+               if (XLOG_FORCED_SHUTDOWN(log))
+                       goto shutdown;
+               xlog_grant_push_ail(log, need_bytes);
+
+               XFS_STATS_INC(xs_sleep_logspace);
+               trace_xfs_log_regrant_write_sleep(log, tic);
+
+               xlog_wait(&tic->t_wait, &log->l_grant_write_lock);
+               trace_xfs_log_regrant_write_wake(log, tic);
+
+               spin_lock(&log->l_grant_write_lock);
+               if (XLOG_FORCED_SHUTDOWN(log))
+                       goto shutdown;
+       } while (xlog_space_left(log, &log->l_grant_write_head) < need_bytes);
+
+       list_del_init(&tic->t_queue);
+       return 0;
+shutdown:
+       list_del_init(&tic->t_queue);
+       return XFS_ERROR(EIO);
+}
+
 static void
 xlog_tic_reset_res(xlog_ticket_t *tic)
 {
@@ -350,8 +461,19 @@ xfs_log_reserve(
                retval = xlog_grant_log_space(log, internal_ticket);
        }
 
+       if (unlikely(retval)) {
+               /*
+                * If we are failing, make sure the ticket doesn't have any
+                * current reservations.  We don't want to add this back
+                * when the ticket/ transaction gets cancelled.
+                */
+               internal_ticket->t_curr_res = 0;
+               /* ungrant will give back unit_res * t_cnt. */
+               internal_ticket->t_cnt = 0;
+       }
+
        return retval;
-}      /* xfs_log_reserve */
+}
 
 
 /*
@@ -626,7 +748,7 @@ xfs_log_item_init(
        struct xfs_mount        *mp,
        struct xfs_log_item     *item,
        int                     type,
-       struct xfs_item_ops     *ops)
+       const struct xfs_item_ops *ops)
 {
        item->li_mountp = mp;
        item->li_ailp = mp->m_ail;
@@ -2481,8 +2603,8 @@ restart:
 /*
  * Atomically get the log space required for a log ticket.
  *
- * Once a ticket gets put onto the reserveq, it will only return after
- * the needed reservation is satisfied.
+ * Once a ticket gets put onto the reserveq, it will only return after the
+ * needed reservation is satisfied.
  *
  * This function is structured so that it has a lock free fast path. This is
  * necessary because every new transaction reservation will come through this
@@ -2490,113 +2612,53 @@ restart:
  * every pass.
  *
  * As tickets are only ever moved on and off the reserveq under the
- * l_grant_reserve_lock, we only need to take that lock if we are going
- * to add the ticket to the queue and sleep. We can avoid taking the lock if the
- * ticket was never added to the reserveq because the t_queue list head will be
- * empty and we hold the only reference to it so it can safely be checked
- * unlocked.
+ * l_grant_reserve_lock, we only need to take that lock if we are going to add
+ * the ticket to the queue and sleep. We can avoid taking the lock if the ticket
+ * was never added to the reserveq because the t_queue list head will be empty
+ * and we hold the only reference to it so it can safely be checked unlocked.
  */
 STATIC int
-xlog_grant_log_space(xlog_t       *log,
-                    xlog_ticket_t *tic)
+xlog_grant_log_space(
+       struct log              *log,
+       struct xlog_ticket      *tic)
 {
-       int              free_bytes;
-       int              need_bytes;
+       int                     free_bytes, need_bytes;
+       int                     error = 0;
 
-#ifdef DEBUG
-       if (log->l_flags & XLOG_ACTIVE_RECOVERY)
-               panic("grant Recovery problem");
-#endif
+       ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY));
 
        trace_xfs_log_grant_enter(log, tic);
 
+       /*
+        * If there are other waiters on the queue then give them a chance at
+        * logspace before us.  Wake up the first waiters, if we do not wake
+        * up all the waiters then go to sleep waiting for more free space,
+        * otherwise try to get some space for this transaction.
+        */
        need_bytes = tic->t_unit_res;
        if (tic->t_flags & XFS_LOG_PERM_RESERV)
                need_bytes *= tic->t_ocnt;
-
-       /* something is already sleeping; insert new transaction at end */
-       if (!list_empty_careful(&log->l_reserveq)) {
-               spin_lock(&log->l_grant_reserve_lock);
-               /* recheck the queue now we are locked */
-               if (list_empty(&log->l_reserveq)) {
-                       spin_unlock(&log->l_grant_reserve_lock);
-                       goto redo;
-               }
-               list_add_tail(&tic->t_queue, &log->l_reserveq);
-
-               trace_xfs_log_grant_sleep1(log, tic);
-
-               /*
-                * Gotta check this before going to sleep, while we're
-                * holding the grant lock.
-                */
-               if (XLOG_FORCED_SHUTDOWN(log))
-                       goto error_return;
-
-               XFS_STATS_INC(xs_sleep_logspace);
-               xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock);
-
-               /*
-                * If we got an error, and the filesystem is shutting down,
-                * we'll catch it down below. So just continue...
-                */
-               trace_xfs_log_grant_wake1(log, tic);
-       }
-
-redo:
-       if (XLOG_FORCED_SHUTDOWN(log))
-               goto error_return_unlocked;
-
        free_bytes = xlog_space_left(log, &log->l_grant_reserve_head);
-       if (free_bytes < need_bytes) {
+       if (!list_empty_careful(&log->l_reserveq)) {
                spin_lock(&log->l_grant_reserve_lock);
-               if (list_empty(&tic->t_queue))
-                       list_add_tail(&tic->t_queue, &log->l_reserveq);
-
-               trace_xfs_log_grant_sleep2(log, tic);
-
-               if (XLOG_FORCED_SHUTDOWN(log))
-                       goto error_return;
-
-               xlog_grant_push_ail(log, need_bytes);
-
-               XFS_STATS_INC(xs_sleep_logspace);
-               xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock);
-
-               trace_xfs_log_grant_wake2(log, tic);
-               goto redo;
-       }
-
-       if (!list_empty(&tic->t_queue)) {
+               if (!xlog_reserveq_wake(log, &free_bytes) ||
+                   free_bytes < need_bytes)
+                       error = xlog_reserveq_wait(log, tic, need_bytes);
+               spin_unlock(&log->l_grant_reserve_lock);
+       } else if (free_bytes < need_bytes) {
                spin_lock(&log->l_grant_reserve_lock);
-               list_del_init(&tic->t_queue);
+               error = xlog_reserveq_wait(log, tic, need_bytes);
                spin_unlock(&log->l_grant_reserve_lock);
        }
+       if (error)
+               return error;
 
-       /* we've got enough space */
        xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes);
        xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes);
        trace_xfs_log_grant_exit(log, tic);
        xlog_verify_grant_tail(log);
        return 0;
-
-error_return_unlocked:
-       spin_lock(&log->l_grant_reserve_lock);
-error_return:
-       list_del_init(&tic->t_queue);
-       spin_unlock(&log->l_grant_reserve_lock);
-       trace_xfs_log_grant_error(log, tic);
-
-       /*
-        * If we are failing, make sure the ticket doesn't have any
-        * current reservations. We don't want to add this back when
-        * the ticket/transaction gets cancelled.
-        */
-       tic->t_curr_res = 0;
-       tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
-       return XFS_ERROR(EIO);
-}      /* xlog_grant_log_space */
-
+}
 
 /*
  * Replenish the byte reservation required by moving the grant write head.
@@ -2605,10 +2667,12 @@ error_return:
  * free fast path.
  */
 STATIC int
-xlog_regrant_write_log_space(xlog_t       *log,
-                            xlog_ticket_t *tic)
+xlog_regrant_write_log_space(
+       struct log              *log,
+       struct xlog_ticket      *tic)
 {
-       int             free_bytes, need_bytes;
+       int                     free_bytes, need_bytes;
+       int                     error = 0;
 
        tic->t_curr_res = tic->t_unit_res;
        xlog_tic_reset_res(tic);
@@ -2616,104 +2680,38 @@ xlog_regrant_write_log_space(xlog_t       *log,
        if (tic->t_cnt > 0)
                return 0;
 
-#ifdef DEBUG
-       if (log->l_flags & XLOG_ACTIVE_RECOVERY)
-               panic("regrant Recovery problem");
-#endif
+       ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY));
 
        trace_xfs_log_regrant_write_enter(log, tic);
-       if (XLOG_FORCED_SHUTDOWN(log))
-               goto error_return_unlocked;
 
-       /* If there are other waiters on the queue then give them a
-        * chance at logspace before us. Wake up the first waiters,
-        * if we do not wake up all the waiters then go to sleep waiting
-        * for more free space, otherwise try to get some space for
-        * this transaction.
+       /*
+        * If there are other waiters on the queue then give them a chance at
+        * logspace before us.  Wake up the first waiters, if we do not wake
+        * up all the waiters then go to sleep waiting for more free space,
+        * otherwise try to get some space for this transaction.
         */
        need_bytes = tic->t_unit_res;
-       if (!list_empty_careful(&log->l_writeq)) {
-               struct xlog_ticket *ntic;
-
-               spin_lock(&log->l_grant_write_lock);
-               free_bytes = xlog_space_left(log, &log->l_grant_write_head);
-               list_for_each_entry(ntic, &log->l_writeq, t_queue) {
-                       ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV);
-
-                       if (free_bytes < ntic->t_unit_res)
-                               break;
-                       free_bytes -= ntic->t_unit_res;
-                       wake_up(&ntic->t_wait);
-               }
-
-               if (ntic != list_first_entry(&log->l_writeq,
-                                               struct xlog_ticket, t_queue)) {
-                       if (list_empty(&tic->t_queue))
-                               list_add_tail(&tic->t_queue, &log->l_writeq);
-                       trace_xfs_log_regrant_write_sleep1(log, tic);
-
-                       xlog_grant_push_ail(log, need_bytes);
-
-                       XFS_STATS_INC(xs_sleep_logspace);
-                       xlog_wait(&tic->t_wait, &log->l_grant_write_lock);
-                       trace_xfs_log_regrant_write_wake1(log, tic);
-               } else
-                       spin_unlock(&log->l_grant_write_lock);
-       }
-
-redo:
-       if (XLOG_FORCED_SHUTDOWN(log))
-               goto error_return_unlocked;
-
        free_bytes = xlog_space_left(log, &log->l_grant_write_head);
-       if (free_bytes < need_bytes) {
+       if (!list_empty_careful(&log->l_writeq)) {
                spin_lock(&log->l_grant_write_lock);
-               if (list_empty(&tic->t_queue))
-                       list_add_tail(&tic->t_queue, &log->l_writeq);
-
-               if (XLOG_FORCED_SHUTDOWN(log))
-                       goto error_return;
-
-               xlog_grant_push_ail(log, need_bytes);
-
-               XFS_STATS_INC(xs_sleep_logspace);
-               trace_xfs_log_regrant_write_sleep2(log, tic);
-               xlog_wait(&tic->t_wait, &log->l_grant_write_lock);
-
-               trace_xfs_log_regrant_write_wake2(log, tic);
-               goto redo;
-       }
-
-       if (!list_empty(&tic->t_queue)) {
+               if (!xlog_writeq_wake(log, &free_bytes) ||
+                   free_bytes < need_bytes)
+                       error = xlog_writeq_wait(log, tic, need_bytes);
+               spin_unlock(&log->l_grant_write_lock);
+       } else if (free_bytes < need_bytes) {
                spin_lock(&log->l_grant_write_lock);
-               list_del_init(&tic->t_queue);
+               error = xlog_writeq_wait(log, tic, need_bytes);
                spin_unlock(&log->l_grant_write_lock);
        }
 
-       /* we've got enough space */
+       if (error)
+               return error;
+
        xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes);
        trace_xfs_log_regrant_write_exit(log, tic);
        xlog_verify_grant_tail(log);
        return 0;
-
-
- error_return_unlocked:
-       spin_lock(&log->l_grant_write_lock);
- error_return:
-       list_del_init(&tic->t_queue);
-       spin_unlock(&log->l_grant_write_lock);
-       trace_xfs_log_regrant_write_error(log, tic);
-
-       /*
-        * If we are failing, make sure the ticket doesn't have any
-        * current reservations. We don't want to add this back when
-        * the ticket/transaction gets cancelled.
-        */
-       tic->t_curr_res = 0;
-       tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */
-       return XFS_ERROR(EIO);
-}      /* xlog_regrant_write_log_space */
-
+}
 
 /* The first cnt-1 times through here we don't need to
  * move the grant write head because the permanent
index 78c9039994afab9739c4f338a62741aea8bd17cb..3f7bf451c03446f920484a03eb6e073706127a2f 100644 (file)
@@ -137,7 +137,7 @@ struct xfs_trans;
 void   xfs_log_item_init(struct xfs_mount      *mp,
                        struct xfs_log_item     *item,
                        int                     type,
-                       struct xfs_item_ops     *ops);
+                       const struct xfs_item_ops *ops);
 
 xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
                       struct xlog_ticket *ticket,
index 5cff443f6cdb782f4d89cfed6e767bdb24a32e06..0bbb1a41998bc95563813ef8a584e104aad5c462 100644 (file)
@@ -674,7 +674,8 @@ xfs_qm_dqattach_one(
         * disk and we didn't ask it to allocate;
         * ESRCH if quotas got turned off suddenly.
         */
-       error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
+       error = xfs_qm_dqget(ip->i_mount, ip, id, type,
+                            doalloc | XFS_QMOPT_DOWARN, &dqp);
        if (error)
                return error;
 
index aa3dc1a4d53d4f85f97a38f0db217bfcc4e3c953..be5c51d8f7572d715fc51f0c86563b46aba380c8 100644 (file)
@@ -770,6 +770,17 @@ restart:
        if (!xfs_iflock_nowait(ip)) {
                if (!(sync_mode & SYNC_WAIT))
                        goto out;
+
+               /*
+                * If we only have a single dirty inode in a cluster there is
+                * a fair chance that the AIL push may have pushed it into
+                * the buffer, but xfsbufd won't touch it until 30 seconds
+                * from now, and thus we will lock up here.
+                *
+                * Promote the inode buffer to the front of the delwri list
+                * and wake up xfsbufd now.
+                */
+               xfs_promote_inode(ip);
                xfs_iflock(ip);
        }
 
index f1d2802b2f0782130954248f11237c10cf09e92f..49403579887324b87c821bc7eb62b0114314ce20 100644 (file)
@@ -834,18 +834,14 @@ DEFINE_LOGGRANT_EVENT(xfs_log_umount_write);
 DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter);
 DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit);
 DEFINE_LOGGRANT_EVENT(xfs_log_grant_error);
-DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1);
-DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1);
-DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2);
-DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2);
+DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep);
+DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake);
 DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error);
-DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1);
-DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1);
-DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2);
-DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2);
+DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep);
+DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter);
 DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit);
index 603f3eb52041ef84b89177956ff74ffc6ef1a114..3ae713c0abd9a04b3964d3ff8a9305155cd3b97a 100644 (file)
@@ -326,7 +326,7 @@ typedef struct xfs_log_item {
                                                 struct xfs_log_item *);
                                                        /* buffer item iodone */
                                                        /* callback func */
-       struct xfs_item_ops             *li_ops;        /* function list */
+       const struct xfs_item_ops       *li_ops;        /* function list */
 
        /* delayed logging */
        struct list_head                li_cil;         /* CIL pointers */
@@ -341,7 +341,7 @@ typedef struct xfs_log_item {
        { XFS_LI_IN_AIL,        "IN_AIL" }, \
        { XFS_LI_ABORTED,       "ABORTED" }
 
-typedef struct xfs_item_ops {
+struct xfs_item_ops {
        uint (*iop_size)(xfs_log_item_t *);
        void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
        void (*iop_pin)(xfs_log_item_t *);
@@ -352,7 +352,7 @@ typedef struct xfs_item_ops {
        void (*iop_push)(xfs_log_item_t *);
        bool (*iop_pushbuf)(xfs_log_item_t *);
        void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
-} xfs_item_ops_t;
+};
 
 #define IOP_SIZE(ip)           (*(ip)->li_ops->iop_size)(ip)
 #define IOP_FORMAT(ip,vp)      (*(ip)->li_ops->iop_format)(ip, vp)
index 4ecf2a549060295b0d354847a538eba890083631..ce9268a2f56be487a161b950d36fc88590877c29 100644 (file)
@@ -112,7 +112,7 @@ xfs_readlink(
        char            *link)
 {
        xfs_mount_t     *mp = ip->i_mount;
-       int             pathlen;
+       xfs_fsize_t     pathlen;
        int             error = 0;
 
        trace_xfs_readlink(ip);
@@ -122,13 +122,19 @@ xfs_readlink(
 
        xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-       ASSERT(S_ISLNK(ip->i_d.di_mode));
-       ASSERT(ip->i_d.di_size <= MAXPATHLEN);
-
        pathlen = ip->i_d.di_size;
        if (!pathlen)
                goto out;
 
+       if (pathlen < 0 || pathlen > MAXPATHLEN) {
+               xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
+                        __func__, (unsigned long long) ip->i_ino,
+                        (long long) pathlen);
+               ASSERT(0);
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+
+
        if (ip->i_df.if_flags & XFS_IFINLINE) {
                memcpy(link, ip->i_df.if_u1.if_data, pathlen);
                link[pathlen] = '\0';
index e49c36d38d7ee23900f60c20ef826ea969f0fd21..bb145e4b935e79760146f17d5f6bd4c70843278d 100644 (file)
@@ -144,7 +144,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
 {
 }
 static inline int register_hotplug_dock_device(acpi_handle handle,
-                                              struct acpi_dock_ops *ops,
+                                              const struct acpi_dock_ops *ops,
                                               void *context)
 {
        return -ENODEV;
index b67231bef632714add11abf65eac32c82cda4dd6..ed73f6705c860d2bc8c28db91b7191c13c144b31 100644 (file)
@@ -470,7 +470,6 @@ typedef u64 acpi_integer;
  */
 #define ACPI_FULL_INITIALIZATION        0x00
 #define ACPI_NO_ADDRESS_SPACE_INIT      0x01
-#define ACPI_NO_HARDWARE_INIT           0x02
 #define ACPI_NO_EVENT_INIT              0x04
 #define ACPI_NO_HANDLER_INIT            0x08
 #define ACPI_NO_ACPI_ENABLE             0x10
index f72403c4b51a6a6c01b3f587202a48a1165c5da5..f4b2effe03334e0e52807d7934217803e7aba9f2 100644 (file)
@@ -55,7 +55,6 @@
 
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/sched.h>
 #include <asm/system.h>
index 67055f180330b6a59f653833ebe51c8afd151a29..610f6fb1bbc2ed71109c3ad4e290d51febbb4376 100644 (file)
@@ -329,6 +329,7 @@ extern void acpi_processor_throttling_init(void);
 int acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device);
 int acpi_processor_cst_has_changed(struct acpi_processor *pr);
+int acpi_processor_hotplug(struct acpi_processor *pr);
 int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device);
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
index f4c38d8c6674a3dd71ea08a47dc68e89e81e0d92..2292d1af9d705f129ae523ce00a6b7794fb1648c 100644 (file)
@@ -685,9 +685,15 @@ __SYSCALL(__NR_syncfs, sys_syncfs)
 __SYSCALL(__NR_setns, sys_setns)
 #define __NR_sendmmsg 269
 __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
+#define __NR_process_vm_readv 270
+__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
+          compat_sys_process_vm_readv)
+#define __NR_process_vm_writev 271
+__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
+          compat_sys_process_vm_writev)
 
 #undef __NR_syscalls
-#define __NR_syscalls 270
+#define __NR_syscalls 272
 
 /*
  * All syscalls below here should go away really,
index cf3b446139ea8a3f7ea1ecea86f7f41e4cdc4c09..1f9e9516e2b75da38aa87abbf774d1505803cc98 100644 (file)
@@ -42,7 +42,6 @@
  * can build the DRM (part of PI DRI). 4/21/2000 S + B */
 #include <asm/current.h>
 #endif                         /* __alpha__ */
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
@@ -80,6 +79,8 @@
 #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
 #define __OS_HAS_MTRR (defined(CONFIG_MTRR))
 
+struct module;
+
 struct drm_file;
 struct drm_device;
 
@@ -989,7 +990,9 @@ struct drm_minor {
        struct proc_dir_entry *proc_root;  /**< proc directory entry */
        struct drm_info_node proc_nodes;
        struct dentry *debugfs_root;
-       struct drm_info_node debugfs_nodes;
+
+       struct list_head debugfs_list;
+       struct mutex debugfs_lock; /* Protects debugfs_list. */
 
        struct drm_master *master; /* currently active master for this node */
        struct list_head master_list;
index 0d2f727e96be8dd1e29c65e64f06c664f6d1992d..93df2d72750b1878e8822bf8716b77926941ae91 100644 (file)
@@ -72,6 +72,7 @@
 
 #define DP_MAIN_LINK_CHANNEL_CODING         0x006
 
+#define DP_EDP_CONFIGURATION_CAP            0x00d
 #define DP_TRAINING_AUX_RD_INTERVAL         0x00e
 
 #define DP_PSR_SUPPORT                      0x070
 # define DP_CP_IRQ                         (1 << 2)
 # define DP_SINK_SPECIFIC_IRQ              (1 << 6)
 
+#define DP_EDP_CONFIGURATION_SET            0x10a
+
 #define DP_LANE0_1_STATUS                  0x202
 #define DP_LANE2_3_STATUS                  0x203
 # define DP_LANE_CR_DONE                   (1 << 0)
index c4961ea50a494b69d996873e09e8e509956660c0..ddd46db65b57257164f13d703186bb7da5e7bb3a 100644 (file)
@@ -120,11 +120,12 @@ struct drm_mode_crtc {
        struct drm_mode_modeinfo mode;
 };
 
-#define DRM_MODE_ENCODER_NONE  0
-#define DRM_MODE_ENCODER_DAC   1
-#define DRM_MODE_ENCODER_TMDS  2
-#define DRM_MODE_ENCODER_LVDS  3
-#define DRM_MODE_ENCODER_TVDAC 4
+#define DRM_MODE_ENCODER_NONE   0
+#define DRM_MODE_ENCODER_DAC    1
+#define DRM_MODE_ENCODER_TMDS   2
+#define DRM_MODE_ENCODER_LVDS   3
+#define DRM_MODE_ENCODER_TVDAC  4
+#define DRM_MODE_ENCODER_VIRTUAL 5
 
 struct drm_mode_get_encoder {
        __u32 encoder_id;
@@ -162,6 +163,7 @@ struct drm_mode_get_encoder {
 #define DRM_MODE_CONNECTOR_HDMIB       12
 #define DRM_MODE_CONNECTOR_TV          13
 #define DRM_MODE_CONNECTOR_eDP         14
+#define DRM_MODE_CONNECTOR_VIRTUAL      15
 
 struct drm_mode_get_connector {
 
@@ -233,6 +235,8 @@ struct drm_mode_fb_cmd {
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS         0x03
 
+#define DRM_MODE_FB_DIRTY_MAX_CLIPS     256
+
 /*
  * Mark a region of a framebuffer as dirty.
  *
index 3d53efd25ab906889e081acb8ae10f1065ef180a..4e4fbb820e204156729017b1488b77fe679ee30a 100644 (file)
@@ -4,6 +4,7 @@
 */
 #define radeon_PCI_IDS \
        {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
+       {0x1002, 0x3151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -55,6 +56,7 @@
        {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
+       {0x1002, 0x4C6E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
        {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
        {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6842, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6843, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6849, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x6859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
index 874c4d271328572cc96dc5efc5dc4710d9d037fd..12050434d57a248909d695a80445e958dea81e32 100644 (file)
 /**
  * User-desired buffer creation information structure.
  *
- * @size: requested size for the object.
+ * @size: user-desired memory allocation size.
  *     - this size value would be page-aligned internally.
  * @flags: user request for setting memory type or cache attributes.
- * @handle: returned handle for the object.
+ * @handle: returned a handle to created gem object.
+ *     - this handle will be set by gem module of kernel side.
  */
 struct drm_exynos_gem_create {
-       unsigned int size;
+       uint64_t size;
        unsigned int flags;
        unsigned int handle;
 };
index b65be6054a183efe7b0ea5daa7c8afd7b1aa6a72..be94be6d6f17afdd027b3cf61679c73651ac6f9e 100644 (file)
@@ -874,6 +874,10 @@ struct drm_radeon_gem_pwrite {
 
 #define RADEON_CHUNK_ID_RELOCS 0x01
 #define RADEON_CHUNK_ID_IB     0x02
+#define RADEON_CHUNK_ID_FLAGS  0x03
+
+/* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */
+#define RADEON_CS_KEEP_TILING_FLAGS 0x01
 
 struct drm_radeon_cs_chunk {
        uint32_t                chunk_id;
index cd7cd8162ed62d4aaba66ea3546c44444dc583db..bcb0912afe7a4a233a171f2d1b4bb7d518c6884e 100644 (file)
@@ -54,7 +54,7 @@
 #define DRM_VMW_FENCE_EVENT          17
 #define DRM_VMW_PRESENT              18
 #define DRM_VMW_PRESENT_READBACK     19
-
+#define DRM_VMW_UPDATE_LAYOUT        20
 
 /*************************************************************************/
 /**
@@ -550,31 +550,6 @@ struct drm_vmw_get_3d_cap_arg {
        uint32_t pad64;
 };
 
-/*************************************************************************/
-/**
- * DRM_VMW_UPDATE_LAYOUT - Update layout
- *
- * Updates the preferred modes and connection status for connectors. The
- * command conisits of one drm_vmw_update_layout_arg pointing out a array
- * of num_outputs drm_vmw_rect's.
- */
-
-/**
- * struct drm_vmw_update_layout_arg
- *
- * @num_outputs: number of active
- * @rects: pointer to array of drm_vmw_rect
- *
- * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
- */
-
-struct drm_vmw_update_layout_arg {
-       uint32_t num_outputs;
-       uint32_t pad64;
-       uint64_t rects;
-};
-
-
 /*************************************************************************/
 /**
  * DRM_VMW_FENCE_WAIT
@@ -788,4 +763,28 @@ struct drm_vmw_present_readback_arg {
         uint64_t clips_ptr;
         uint64_t fence_rep;
 };
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UPDATE_LAYOUT - Update layout
+ *
+ * Updates the preferred modes and connection status for connectors. The
+ * command consists of one drm_vmw_update_layout_arg pointing to an array
+ * of num_outputs drm_vmw_rect's.
+ */
+
+/**
+ * struct drm_vmw_update_layout_arg
+ *
+ * @num_outputs: number of active connectors
+ * @rects: pointer to array of drm_vmw_rect cast to an uint64_t
+ *
+ * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
+ */
+struct drm_vmw_update_layout_arg {
+       uint32_t num_outputs;
+       uint32_t pad64;
+       uint64_t rects;
+};
+
 #endif
index 3b2f9cb829864753b810bd87e15e16cafc74215b..b1038bd686acfc46caf251aad8ae765e9970ceb3 100644 (file)
@@ -40,6 +40,7 @@ typedef int (congested_fn)(void *, int);
 enum bdi_stat_item {
        BDI_RECLAIMABLE,
        BDI_WRITEBACK,
+       BDI_DIRTIED,
        BDI_WRITTEN,
        NR_BDI_STAT_ITEMS
 };
@@ -74,10 +75,20 @@ struct backing_dev_info {
        struct percpu_counter bdi_stat[NR_BDI_STAT_ITEMS];
 
        unsigned long bw_time_stamp;    /* last time write bw is updated */
+       unsigned long dirtied_stamp;
        unsigned long written_stamp;    /* pages written at bw_time_stamp */
        unsigned long write_bandwidth;  /* the estimated write bandwidth */
        unsigned long avg_write_bandwidth; /* further smoothed write bw */
 
+       /*
+        * The base dirty throttle rate, re-calculated on every 200ms.
+        * All the bdi tasks' dirty rate will be curbed under it.
+        * @dirty_ratelimit tracks the estimated @balanced_dirty_ratelimit
+        * in small steps and is much more smooth/stable than the latter.
+        */
+       unsigned long dirty_ratelimit;
+       unsigned long balanced_dirty_ratelimit;
+
        struct prop_local_percpu completions;
        int dirty_exceeded;
 
@@ -107,7 +118,8 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
 void bdi_unregister(struct backing_dev_info *bdi);
 int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
-void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages);
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
+                       enum wb_reason reason);
 void bdi_start_background_writeback(struct backing_dev_info *bdi);
 int bdi_writeback_thread(void *data);
 int bdi_has_dirty_io(struct backing_dev_info *bdi);
index 5dbd7055cb86204c6cd8d2d18f5709c4e6604c1e..4d4b59de9467116ce34b19846b061db56a2a2a7c 100644 (file)
@@ -170,10 +170,9 @@ struct bcma_driver {
 };
 extern
 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
-static inline int bcma_driver_register(struct bcma_driver *drv)
-{
-       return __bcma_driver_register(drv, THIS_MODULE);
-}
+#define bcma_driver_register(drv) \
+       __bcma_driver_register(drv, THIS_MODULE)
+
 extern void bcma_driver_unregister(struct bcma_driver *drv);
 
 struct bcma_bus {
index a3c071c9e18934765e44b84d8330e9fd979d6dc4..847994aef0e9755a3a39d76dd42f87c9f43d23be 100644 (file)
@@ -211,8 +211,8 @@ extern void bio_pair_release(struct bio_pair *dbio);
 extern struct bio_set *bioset_create(unsigned int, unsigned int);
 extern void bioset_free(struct bio_set *);
 
-extern struct bio *bio_alloc(gfp_t, int);
-extern struct bio *bio_kmalloc(gfp_t, int);
+extern struct bio *bio_alloc(gfp_t, unsigned int);
+extern struct bio *bio_kmalloc(gfp_t, unsigned int);
 extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
 extern void bio_put(struct bio *);
 extern void bio_free(struct bio *, struct bio_set *);
@@ -519,7 +519,11 @@ extern void bio_integrity_init(void);
 #define bioset_integrity_create(a, b)  (0)
 #define bio_integrity_prep(a)          (0)
 #define bio_integrity_enabled(a)       (0)
-#define bio_integrity_clone(a, b, c, d)        (0)
+static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
+                                     gfp_t gfp_mask, struct bio_set *bs)
+{
+       return 0;
+}
 #define bioset_integrity_free(a)       do { } while (0)
 #define bio_integrity_free(a, b)       do { } while (0)
 #define bio_integrity_endio(a, b)      do { } while (0)
index 5267cd2f20dc9618b42421c66cb27b382e264c3a..8bca04873f533626fee3f0ff3db70148839da080 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/wait.h>
 #include <linux/mempool.h>
 #include <linux/bio.h>
-#include <linux/module.h>
 #include <linux/stringify.h>
 #include <linux/gfp.h>
 #include <linux/bsg.h>
@@ -22,6 +21,7 @@
 
 #include <asm/scatterlist.h>
 
+struct module;
 struct scsi_ioctl_command;
 
 struct request_queue;
@@ -111,10 +111,14 @@ struct request {
         * Three pointers are available for the IO schedulers, if they need
         * more they have to dynamically allocate it.  Flush requests are
         * never put on the IO scheduler. So let the flush fields share
-        * space with the three elevator_private pointers.
+        * space with the elevator data.
         */
        union {
-               void *elevator_private[3];
+               struct {
+                       struct io_cq            *icq;
+                       void                    *priv[2];
+               } elv;
+
                struct {
                        unsigned int            seq;
                        struct list_head        list;
@@ -310,6 +314,12 @@ struct request_queue {
         */
        unsigned long           queue_flags;
 
+       /*
+        * ida allocated id for this queue.  Used to index queues from
+        * ioctx.
+        */
+       int                     id;
+
        /*
         * queue needs bounce pages for pages above this limit
         */
@@ -351,6 +361,8 @@ struct request_queue {
        struct timer_list       timeout;
        struct list_head        timeout_list;
 
+       struct list_head        icq_list;
+
        struct queue_limits     limits;
 
        /*
@@ -387,6 +399,9 @@ struct request_queue {
        /* Throttle data */
        struct throtl_data *td;
 #endif
+#ifdef CONFIG_LOCKDEP
+       int                     ioc_release_depth;
+#endif
 };
 
 #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
@@ -481,6 +496,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 
 #define blk_queue_tagged(q)    test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
 #define blk_queue_stopped(q)   test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
+#define blk_queue_dead(q)      test_bit(QUEUE_FLAG_DEAD, &(q)->queue_flags)
 #define blk_queue_nomerges(q)  test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
 #define blk_queue_noxmerges(q) \
        test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags)
@@ -660,7 +676,6 @@ extern void __blk_put_request(struct request_queue *, struct request *);
 extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
 extern struct request *blk_make_request(struct request_queue *, struct bio *,
                                        gfp_t);
-extern void blk_insert_request(struct request_queue *, struct request *, int, void *);
 extern void blk_requeue_request(struct request_queue *, struct request *);
 extern void blk_add_request_payload(struct request *rq, struct page *page,
                unsigned int len);
@@ -859,7 +874,7 @@ extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatte
 extern void blk_dump_rq_flags(struct request *, char *);
 extern long nr_blockdev_pages(void);
 
-int blk_get_queue(struct request_queue *);
+bool __must_check blk_get_queue(struct request_queue *);
 struct request_queue *blk_alloc_queue(gfp_t);
 struct request_queue *blk_alloc_queue_node(gfp_t, int);
 extern void blk_put_queue(struct request_queue *);
index f88eacb111d4151dc5491797fe0e03faaadc26a9..7c05ac202d90650069d4713ac2e13b3be9b86024 100644 (file)
 #include "osdmap.h"
 #include "messenger.h"
 
+/* 
+ * Maximum object name size 
+ * (must be at least as big as RBD_MAX_MD_NAME_LEN -- currently 100) 
+ */
+#define MAX_OBJ_NAME_SIZE 100
+
 struct ceph_msg;
 struct ceph_snap_context;
 struct ceph_osd_request;
@@ -75,7 +81,7 @@ struct ceph_osd_request {
        struct inode *r_inode;                /* for use by callbacks */
        void *r_priv;                         /* ditto */
 
-       char              r_oid[40];          /* object name */
+       char              r_oid[MAX_OBJ_NAME_SIZE];          /* object name */
        int               r_oid_len;
        unsigned long     r_stamp;            /* send OR check time */
 
index 139c4db55f1736eebc35cc4601ee98d0d10a40c7..c86c940d1de3a58b73fd4027b80524daca997478 100644 (file)
@@ -156,6 +156,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
  * @mult:              cycle to nanosecond multiplier
  * @shift:             cycle to nanosecond divisor (power of two)
  * @max_idle_ns:       max idle time permitted by the clocksource (nsecs)
+ * @maxadj             maximum adjustment value to mult (~11%)
  * @flags:             flags describing special properties
  * @archdata:          arch-specific data
  * @suspend:           suspend function for the clocksource, if necessary
@@ -172,7 +173,7 @@ struct clocksource {
        u32 mult;
        u32 shift;
        u64 max_idle_ns;
-
+       u32 maxadj;
 #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
        struct arch_clocksource_data archdata;
 #endif
index 154bf56830156876d56c1ced7d4c1e6c96973805..66ed067fb7291e89f1548718e581d1ed348c4120 100644 (file)
@@ -552,5 +552,14 @@ extern ssize_t compat_rw_copy_check_uvector(int type,
 
 extern void __user *compat_alloc_user_space(unsigned long len);
 
+asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
+               const struct compat_iovec __user *lvec,
+               unsigned long liovcnt, const struct compat_iovec __user *rvec,
+               unsigned long riovcnt, unsigned long flags);
+asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
+               const struct compat_iovec __user *lvec,
+               unsigned long liovcnt, const struct compat_iovec __user *rvec,
+               unsigned long riovcnt, unsigned long flags);
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
index b1a635acf72a3c9bb8930c63e835cd88f7fa67eb..6cb60fd2ea8454f4dad52cb4c32cd62a3301072f 100644 (file)
@@ -196,13 +196,9 @@ static inline void cpu_hotplug_driver_unlock(void)
 #endif         /* CONFIG_HOTPLUG_CPU */
 
 #ifdef CONFIG_PM_SLEEP_SMP
-extern int suspend_cpu_hotplug;
-
 extern int disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else /* !CONFIG_PM_SLEEP_SMP */
-#define suspend_cpu_hotplug    0
-
 static inline int disable_nonboot_cpus(void) { return 0; }
 static inline void enable_nonboot_cpus(void) {}
 #endif /* !CONFIG_PM_SLEEP_SMP */
index b51629e15cfcfee56982da848cfc8b47c77be18c..7408af843b8ac891b1fd59557c5cb7faa117c0bd 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/percpu.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/completion.h>
 
 #define CPUIDLE_NAME_LEN       16
 #define CPUIDLE_DESC_LEN       32
 
+struct module;
+
 struct cpuidle_device;
+struct cpuidle_driver;
 
 
 /****************************
  * CPUIDLE DEVICE INTERFACE *
  ****************************/
 
+struct cpuidle_state_usage {
+       void            *driver_data;
+
+       unsigned long long      usage;
+       unsigned long long      time; /* in US */
+};
+
 struct cpuidle_state {
        char            name[CPUIDLE_NAME_LEN];
        char            desc[CPUIDLE_DESC_LEN];
-       void            *driver_data;
 
        unsigned int    flags;
        unsigned int    exit_latency; /* in US */
        unsigned int    power_usage; /* in mW */
        unsigned int    target_residency; /* in US */
 
-       unsigned long long      usage;
-       unsigned long long      time; /* in US */
-
        int (*enter)    (struct cpuidle_device *dev,
-                        struct cpuidle_state *state);
+                       struct cpuidle_driver *drv,
+                       int index);
 };
 
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID        (0x01) /* is residency time measurable? */
-#define CPUIDLE_FLAG_IGNORE    (0x100) /* ignore during this idle period */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
 
 /**
  * cpuidle_get_statedata - retrieves private driver state data
- * @state: the state
+ * @st_usage: the state usage statistics
  */
-static inline void * cpuidle_get_statedata(struct cpuidle_state *state)
+static inline void *cpuidle_get_statedata(struct cpuidle_state_usage *st_usage)
 {
-       return state->driver_data;
+       return st_usage->driver_data;
 }
 
 /**
  * cpuidle_set_statedata - stores private driver state data
- * @state: the state
+ * @st_usage: the state usage statistics
  * @data: the private data
  */
 static inline void
-cpuidle_set_statedata(struct cpuidle_state *state, void *data)
+cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data)
 {
-       state->driver_data = data;
+       st_usage->driver_data = data;
 }
 
 struct cpuidle_state_kobj {
        struct cpuidle_state *state;
+       struct cpuidle_state_usage *state_usage;
        struct completion kobj_unregister;
        struct kobject kobj;
 };
@@ -80,22 +86,17 @@ struct cpuidle_state_kobj {
 struct cpuidle_device {
        unsigned int            registered:1;
        unsigned int            enabled:1;
-       unsigned int            power_specified:1;
        unsigned int            cpu;
 
        int                     last_residency;
        int                     state_count;
-       struct cpuidle_state    states[CPUIDLE_STATE_MAX];
+       struct cpuidle_state_usage      states_usage[CPUIDLE_STATE_MAX];
        struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
-       struct cpuidle_state    *last_state;
 
        struct list_head        device_list;
        struct kobject          kobj;
        struct completion       kobj_unregister;
        void                    *governor_data;
-       struct cpuidle_state    *safe_state;
-
-       int (*prepare)          (struct cpuidle_device *dev);
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
@@ -119,6 +120,11 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
 struct cpuidle_driver {
        char                    name[CPUIDLE_NAME_LEN];
        struct module           *owner;
+
+       unsigned int            power_specified:1;
+       struct cpuidle_state    states[CPUIDLE_STATE_MAX];
+       int                     state_count;
+       int                     safe_state_index;
 };
 
 #ifdef CONFIG_CPU_IDLE
@@ -165,11 +171,14 @@ struct cpuidle_governor {
        struct list_head        governor_list;
        unsigned int            rating;
 
-       int  (*enable)          (struct cpuidle_device *dev);
-       void (*disable)         (struct cpuidle_device *dev);
+       int  (*enable)          (struct cpuidle_driver *drv,
+                                       struct cpuidle_device *dev);
+       void (*disable)         (struct cpuidle_driver *drv,
+                                       struct cpuidle_device *dev);
 
-       int  (*select)          (struct cpuidle_device *dev);
-       void (*reflect)         (struct cpuidle_device *dev);
+       int  (*select)          (struct cpuidle_driver *drv,
+                                       struct cpuidle_device *dev);
+       void (*reflect)         (struct cpuidle_device *dev, int index);
 
        struct module           *owner;
 };
index de9adec5693c7fd17a9c738439c6d6dda6facf8c..8a94217b298ed0ec3bdbcccc63fc2ac64b5d8c28 100644 (file)
@@ -18,7 +18,6 @@
 #define _LINUX_CRYPTO_H
 
 #include <linux/atomic.h>
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -510,11 +509,6 @@ static inline int crypto_tfm_alg_priority(struct crypto_tfm *tfm)
        return tfm->__crt_alg->cra_priority;
 }
 
-static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
-{
-       return module_name(tfm->__crt_alg->cra_module);
-}
-
 static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
 {
        return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
index 4df926199369622bffed05e3e60eeff8c42e4532..ed9f74f6c519a1f071348d691d69c7ed5795e938 100644 (file)
@@ -339,7 +339,8 @@ extern int d_validate(struct dentry *, struct dentry *);
  */
 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 
-extern char *__d_path(const struct path *path, struct path *root, char *, int);
+extern char *__d_path(const struct path *, const struct path *, char *, int);
+extern char *d_absolute_path(const struct path *, char *, int);
 extern char *d_path(const struct path *, char *, int);
 extern char *d_path_with_unreachable(const struct path *, char *, int);
 extern char *dentry_path_raw(struct dentry *, char *, int);
index afb94583960c9f0b0c1bc2a896ec747f4422e156..98ce8124b1cc5e5fb2e61fcf89cc8bd3cc0a7e82 100644 (file)
@@ -41,7 +41,7 @@ struct devfreq_dev_status {
        unsigned long total_time;
        unsigned long busy_time;
        unsigned long current_frequency;
-       void *private_date;
+       void *private_data;
 };
 
 /**
index e88abeecfadf44b45b3325e66cdcac82e8901185..3136ede5a1e1bb8434a0e2d52840f84de39647de 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/lockdep.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/pm.h>
 #include <linux/atomic.h>
 #include <asm/device.h>
@@ -29,6 +29,7 @@ struct device;
 struct device_private;
 struct device_driver;
 struct driver_private;
+struct module;
 struct class;
 struct subsys_private;
 struct bus_type;
@@ -68,7 +69,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  * @resume:    Called to bring a device on this bus out of sleep mode.
  * @pm:                Power management operations of this bus, callback the specific
  *             device driver's pm-ops.
- * @iommu_ops   IOMMU specific operations for this bus, used to attach IOMMU
+ * @iommu_ops:  IOMMU specific operations for this bus, used to attach IOMMU
  *              driver implementations to a bus and allow the driver to do
  *              bus-specific setup
  * @p:         The private data of the driver core, only the driver core can
@@ -681,6 +682,11 @@ static inline bool device_async_suspend_enabled(struct device *dev)
        return !!dev->power.async_suspend;
 }
 
+static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
+{
+       dev->power.ignore_children = enable;
+}
+
 static inline void device_lock(struct device *dev)
 {
        mutex_lock(&dev->mutex);
@@ -723,10 +729,14 @@ extern int dev_set_drvdata(struct device *dev, void *data);
  */
 extern struct device *__root_device_register(const char *name,
                                             struct module *owner);
-static inline struct device *root_device_register(const char *name)
-{
-       return __root_device_register(name, THIS_MODULE);
-}
+
+/*
+ * This is a macro to avoid include problems with THIS_MODULE,
+ * just as per what is done for device_schedule_callback() above.
+ */
+#define root_device_register(name) \
+       __root_device_register(name, THIS_MODULE)
+
 extern void root_device_unregister(struct device *root);
 
 static inline void *dev_get_platdata(const struct device *dev)
index 7aad1f440867e796ed6f5d2c811771e700e7ad15..8b64221b432b2b3258e119912f08ac475fc1727c 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/module.h>
 #include <linux/fs.h>
 
 #ifdef CONFIG_CGROUP_DEVICE
index be86ae13893fcead97e4f9546c71ea500f867e3d..e13117cbd2f7daefa62d067124cbd815b860aea9 100644 (file)
@@ -42,6 +42,9 @@ struct dma_map_ops {
        int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
        int (*dma_supported)(struct device *dev, u64 mask);
        int (*set_dma_mask)(struct device *dev, u64 mask);
+#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+       u64 (*get_required_mask)(struct device *dev);
+#endif
        int is_phys;
 };
 
index ace51af4369f668ea647f47c2d87f76d4478b121..75f53f874b24a0c0abb790f501f2f60ace48e17e 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/uio.h>
 #include <linux/dma-direction.h>
 #include <linux/scatterlist.h>
+#include <linux/bitmap.h>
+#include <asm/page.h>
 
 /**
  * typedef dma_cookie_t - an opaque DMA cookie
index 1d0f7a2ff73b22c0dc38a2a88a11081980e5a5be..c24f3d7fbf1e4543f3159155618cab9186e600d9 100644 (file)
@@ -5,6 +5,8 @@
 
 #ifdef CONFIG_BLOCK
 
+struct io_cq;
+
 typedef int (elevator_merge_fn) (struct request_queue *, struct request **,
                                 struct bio *);
 
@@ -24,6 +26,8 @@ typedef struct request *(elevator_request_list_fn) (struct request_queue *, stru
 typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
 typedef int (elevator_may_queue_fn) (struct request_queue *, int);
 
+typedef void (elevator_init_icq_fn) (struct io_cq *);
+typedef void (elevator_exit_icq_fn) (struct io_cq *);
 typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, gfp_t);
 typedef void (elevator_put_req_fn) (struct request *);
 typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *);
@@ -56,6 +60,9 @@ struct elevator_ops
        elevator_request_list_fn *elevator_former_req_fn;
        elevator_request_list_fn *elevator_latter_req_fn;
 
+       elevator_init_icq_fn *elevator_init_icq_fn;     /* see iocontext.h */
+       elevator_exit_icq_fn *elevator_exit_icq_fn;     /* ditto */
+
        elevator_set_req_fn *elevator_set_req_fn;
        elevator_put_req_fn *elevator_put_req_fn;
 
@@ -63,7 +70,6 @@ struct elevator_ops
 
        elevator_init_fn *elevator_init_fn;
        elevator_exit_fn *elevator_exit_fn;
-       void (*trim)(struct io_context *);
 };
 
 #define ELV_NAME_MAX   (16)
@@ -79,11 +85,20 @@ struct elv_fs_entry {
  */
 struct elevator_type
 {
-       struct list_head list;
+       /* managed by elevator core */
+       struct kmem_cache *icq_cache;
+
+       /* fields provided by elevator implementation */
        struct elevator_ops ops;
+       size_t icq_size;        /* see iocontext.h */
+       size_t icq_align;       /* ditto */
        struct elv_fs_entry *elevator_attrs;
        char elevator_name[ELV_NAME_MAX];
        struct module *elevator_owner;
+
+       /* managed by elevator core */
+       char icq_cache_name[ELV_NAME_MAX + 5];  /* elvname + "_io_cq" */
+       struct list_head list;
 };
 
 /*
@@ -91,10 +106,9 @@ struct elevator_type
  */
 struct elevator_queue
 {
-       struct elevator_ops *ops;
+       struct elevator_type *type;
        void *elevator_data;
        struct kobject kobj;
-       struct elevator_type *elevator_type;
        struct mutex sysfs_lock;
        struct hlist_head *hash;
        unsigned int registered:1;
@@ -129,7 +143,7 @@ extern void elv_drain_elevator(struct request_queue *);
 /*
  * io scheduler registration
  */
-extern void elv_register(struct elevator_type *);
+extern int elv_register(struct elevator_type *);
 extern void elv_unregister(struct elevator_type *);
 
 /*
@@ -197,22 +211,5 @@ enum {
        INIT_LIST_HEAD(&(rq)->csd.list);        \
        } while (0)
 
-/*
- * io context count accounting
- */
-#define elv_ioc_count_mod(name, __val) this_cpu_add(name, __val)
-#define elv_ioc_count_inc(name)        this_cpu_inc(name)
-#define elv_ioc_count_dec(name)        this_cpu_dec(name)
-
-#define elv_ioc_count_read(name)                               \
-({                                                             \
-       unsigned long __val = 0;                                \
-       int __cpu;                                              \
-       smp_wmb();                                              \
-       for_each_possible_cpu(__cpu)                            \
-               __val += per_cpu(name, __cpu);                  \
-       __val;                                                  \
-})
-
 #endif /* CONFIG_BLOCK */
 #endif
index 45f00b61c096ec025dfac142c7aaef501bd449dc..de33de1e205295150efb604dbcf6a56f9b4e91e5 100644 (file)
@@ -1097,10 +1097,12 @@ struct ethtool_ops {
 #define SPEED_1000             1000
 #define SPEED_2500             2500
 #define SPEED_10000            10000
+#define SPEED_UNKNOWN          -1
 
 /* Duplex, half or full. */
 #define DUPLEX_HALF            0x00
 #define DUPLEX_FULL            0x01
+#define DUPLEX_UNKNOWN         0xff
 
 /* Which connector port. */
 #define PORT_TP                        0x00
diff --git a/include/linux/export.h b/include/linux/export.h
new file mode 100644 (file)
index 0000000..696c0f4
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef _LINUX_EXPORT_H
+#define _LINUX_EXPORT_H
+/*
+ * Export symbols from the kernel to modules.  Forked from module.h
+ * to reduce the amount of pointless cruft we feed to gcc when only
+ * exporting a simple symbol or two.
+ *
+ * If you feel the need to add #include <linux/foo.h> to this file
+ * then you are doing something wrong and should go away silently.
+ */
+
+/* Some toolchains use a `_' prefix for all user symbols. */
+#ifdef CONFIG_SYMBOL_PREFIX
+#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
+#else
+#define MODULE_SYMBOL_PREFIX ""
+#endif
+
+struct kernel_symbol
+{
+       unsigned long value;
+       const char *name;
+};
+
+#ifdef MODULE
+extern struct module __this_module;
+#define THIS_MODULE (&__this_module)
+#else
+#define THIS_MODULE ((struct module *)0)
+#endif
+
+#ifdef CONFIG_MODULES
+
+#ifndef __GENKSYMS__
+#ifdef CONFIG_MODVERSIONS
+/* Mark the CRC weak since genksyms apparently decides not to
+ * generate a checksums for some symbols */
+#define __CRC_SYMBOL(sym, sec)                                 \
+       extern void *__crc_##sym __attribute__((weak));         \
+       static const unsigned long __kcrctab_##sym              \
+       __used                                                  \
+       __attribute__((section("___kcrctab" sec "+" #sym), unused))     \
+       = (unsigned long) &__crc_##sym;
+#else
+#define __CRC_SYMBOL(sym, sec)
+#endif
+
+/* For every exported symbol, place a struct in the __ksymtab section */
+#define __EXPORT_SYMBOL(sym, sec)                              \
+       extern typeof(sym) sym;                                 \
+       __CRC_SYMBOL(sym, sec)                                  \
+       static const char __kstrtab_##sym[]                     \
+       __attribute__((section("__ksymtab_strings"), aligned(1))) \
+       = MODULE_SYMBOL_PREFIX #sym;                            \
+       static const struct kernel_symbol __ksymtab_##sym       \
+       __used                                                  \
+       __attribute__((section("___ksymtab" sec "+" #sym), unused))     \
+       = { (unsigned long)&sym, __kstrtab_##sym }
+
+#define EXPORT_SYMBOL(sym)                                     \
+       __EXPORT_SYMBOL(sym, "")
+
+#define EXPORT_SYMBOL_GPL(sym)                                 \
+       __EXPORT_SYMBOL(sym, "_gpl")
+
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
+       __EXPORT_SYMBOL(sym, "_gpl_future")
+
+#ifdef CONFIG_UNUSED_SYMBOLS
+#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
+#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
+#else
+#define EXPORT_UNUSED_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+#endif
+
+#endif /* __GENKSYMS__ */
+
+#else /* !CONFIG_MODULES... */
+
+#define EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL(sym)
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)
+#define EXPORT_UNUSED_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+
+#endif /* CONFIG_MODULES */
+
+#endif /* _LINUX_EXPORT_H */
index 21b3e7588abd32e29b482b2ce4797b2a808e27b4..1e7c01189fa698980e4ae1bbb1dbaa75ac8fbafa 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _LINUX_FIRMWARE_H
 #define _LINUX_FIRMWARE_H
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/gfp.h>
@@ -15,6 +14,7 @@ struct firmware {
        struct page **pages;
 };
 
+struct module;
 struct device;
 
 struct builtin_fw {
index a49b52934c55419a6b282698bc56365733aa67df..a5386e3ee756d6c85981b033dc0000deebfa59b7 100644 (file)
@@ -143,14 +143,9 @@ static inline void set_freezable_with_signal(void)
 #define wait_event_freezekillable(wq, condition)                       \
 ({                                                                     \
        int __retval;                                                   \
-       do {                                                            \
-               __retval = wait_event_killable(wq,                      \
-                               (condition) || freezing(current));      \
-               if (__retval && !freezing(current))                     \
-                       break;                                          \
-               else if (!(condition))                                  \
-                       __retval = -ERESTARTSYS;                        \
-       } while (try_to_freeze());                                      \
+       freezer_do_not_count();                                         \
+       __retval = wait_event_killable(wq, (condition));                \
+       freezer_count();                                                \
        __retval;                                                       \
 })
 
index 0c4df261af7e6a32d5b5c80633fa6a643e2d6285..e0bc4ffb8e7f0ec42a916219ab02f43a112609d1 100644 (file)
@@ -393,8 +393,8 @@ struct inodes_stat_t {
 #include <linux/semaphore.h>
 #include <linux/fiemap.h>
 #include <linux/rculist_bl.h>
-#include <linux/shrinker.h>
 #include <linux/atomic.h>
+#include <linux/shrinker.h>
 
 #include <asm/byteorder.h>
 
@@ -1886,6 +1886,7 @@ extern struct dentry *mount_single(struct file_system_type *fs_type,
 extern struct dentry *mount_nodev(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int));
+extern struct dentry *mount_subtree(struct vfsmount *mnt, const char *path);
 void generic_shutdown_super(struct super_block *sb);
 void kill_block_super(struct super_block *sb);
 void kill_anon_super(struct super_block *sb);
@@ -1941,6 +1942,7 @@ extern int fd_statfs(int, struct kstatfs *);
 extern int statfs_by_dentry(struct dentry *, struct kstatfs *);
 extern int freeze_super(struct super_block *super);
 extern int thaw_super(struct super_block *super);
+extern bool our_mnt(struct vfsmount *mnt);
 
 extern int current_umask(void);
 
index f0c0e8a47ae61f67ed0bbf5b3f723acfdc5df435..26eafcef75be715b0e59d29429bc3a680c6b9bc0 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/kallsyms.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
-#include <linux/module.h>
 #include <linux/ktime.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -19,6 +18,7 @@
 
 #include <asm/ftrace.h>
 
+struct module;
 struct ftrace_hash;
 
 #ifdef CONFIG_FUNCTION_TRACER
index 96efa6794ea5293a59f40638d344005b2497f0bc..c3da42dd22baf17cbf853e6defaed7796bfba950 100644 (file)
@@ -172,6 +172,7 @@ enum {
        TRACE_EVENT_FL_FILTERED_BIT,
        TRACE_EVENT_FL_RECORDED_CMD_BIT,
        TRACE_EVENT_FL_CAP_ANY_BIT,
+       TRACE_EVENT_FL_NO_SET_FILTER_BIT,
 };
 
 enum {
@@ -179,6 +180,7 @@ enum {
        TRACE_EVENT_FL_FILTERED         = (1 << TRACE_EVENT_FL_FILTERED_BIT),
        TRACE_EVENT_FL_RECORDED_CMD     = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT),
        TRACE_EVENT_FL_CAP_ANY          = (1 << TRACE_EVENT_FL_CAP_ANY_BIT),
+       TRACE_EVENT_FL_NO_SET_FILTER    = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT),
 };
 
 struct ftrace_event_call {
index 069ee41391055477101204a44f5a6143e7caec2b..b456b08d70ed4bd68aa77ef511b8cc9b05851d97 100644 (file)
@@ -71,10 +71,9 @@ void gameport_close(struct gameport *gameport);
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 
 void __gameport_register_port(struct gameport *gameport, struct module *owner);
-static inline void gameport_register_port(struct gameport *gameport)
-{
-       __gameport_register_port(gameport, THIS_MODULE);
-}
+/* use a define to avoid include chaining to get THIS_MODULE */
+#define gameport_register_port(gameport) \
+       __gameport_register_port(gameport, THIS_MODULE)
 
 void gameport_unregister_port(struct gameport *gameport);
 
@@ -145,12 +144,12 @@ static inline void gameport_unpin_driver(struct gameport *gameport)
        mutex_unlock(&gameport->drv_mutex);
 }
 
-int __gameport_register_driver(struct gameport_driver *drv,
+int __must_check __gameport_register_driver(struct gameport_driver *drv,
                                struct module *owner, const char *mod_name);
-static inline int __must_check gameport_register_driver(struct gameport_driver *drv)
-{
-       return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
-}
+
+/* use a define to avoid include chaining to get THIS_MODULE & friends */
+#define gameport_register_driver(drv) \
+       __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME)
 
 void gameport_unregister_driver(struct gameport_driver *drv);
 
index 9de31bc98c8803bc96bac1f0751da3ca695bf8df..6d18f3531f180f401d35e8028b3395b339182c2e 100644 (file)
@@ -21,8 +21,6 @@
 #define dev_to_part(device)    container_of((device), struct hd_struct, __dev)
 #define disk_to_dev(disk)      (&(disk)->part0.__dev)
 #define part_to_dev(part)      (&((part)->__dev))
-#define alias_name(disk)       ((disk)->alias ? (disk)->alias : \
-                                                (disk)->disk_name)
 
 extern struct device_type part_type;
 extern struct kobject *block_depr;
@@ -60,7 +58,6 @@ enum {
 
 #define DISK_MAX_PARTS                 256
 #define DISK_NAME_LEN                  32
-#define ALIAS_LEN                      256
 
 #include <linux/major.h>
 #include <linux/device.h>
@@ -166,7 +163,6 @@ struct gendisk {
                                          * disks that can't be partitioned. */
 
        char disk_name[DISK_NAME_LEN];  /* name of major driver */
-       char *alias;                    /* alias name of disk */
        char *(*devnode)(struct gendisk *gd, mode_t *mode);
 
        unsigned int events;            /* supported events */
index deed5f9a1e1c5bf4dc73597b33823370b6254550..c235e4e8767c5468bdb3057d6513b386d99dc576 100644 (file)
@@ -697,10 +697,11 @@ extern void hid_destroy_device(struct hid_device *);
 
 extern int __must_check __hid_register_driver(struct hid_driver *,
                struct module *, const char *mod_name);
-static inline int __must_check hid_register_driver(struct hid_driver *driver)
-{
-       return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
-}
+
+/* use a define to avoid include chaining to get THIS_MODULE & friends */
+#define hid_register_driver(driver) \
+       __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
+
 extern void hid_unregister_driver(struct hid_driver *);
 
 extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
index 19644e0016bdbb4837e1fa8f28cd276797fd00a4..d9d6c868b86bc01226031d63ce5ee72eb44ebed6 100644 (file)
@@ -110,11 +110,6 @@ static inline void copy_huge_page(struct page *dst, struct page *src)
 
 #define hugetlb_change_protection(vma, address, end, newprot)
 
-#ifndef HPAGE_MASK
-#define HPAGE_MASK     PAGE_MASK               /* Keep the compiler happy */
-#define HPAGE_SIZE     PAGE_SIZE
-#endif
-
 #endif /* !CONFIG_HUGETLB_PAGE */
 
 #define HUGETLB_ANON_FILE "anon_hugepage"
index 08a2fee40659667819d01bc95a184e059d0fd9b1..aad6bd4b3efdf97046edabd3fe75fbb3ed052465 100644 (file)
@@ -118,7 +118,6 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 static inline
 void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 {
-       return 0;
 }
 
 static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
index 38a21c3edd2cb01191949efe8db7f14b76f084c9..07d103a06d64a04e17e06a2b9011f773ef60d8f1 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/types.h>
 #ifdef __KERNEL__
-#include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/device.h>      /* for struct device */
 #include <linux/sched.h>       /* for completion */
@@ -49,6 +48,8 @@ struct i2c_driver;
 union i2c_smbus_data;
 struct i2c_board_info;
 
+struct module;
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 /*
  * The master routines are the ones normally used to transmit data to devices
@@ -431,9 +432,6 @@ void i2c_unlock_adapter(struct i2c_adapter *);
 /* Internal numbers to terminate lists */
 #define I2C_CLIENT_END         0xfffeU
 
-/* The numbers to use to set I2C bus address */
-#define ANY_I2C_BUS            0xffff
-
 /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
 #define I2C_ADDRS(addr, addrs...) \
        ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
@@ -451,10 +449,9 @@ extern int i2c_add_numbered_adapter(struct i2c_adapter *);
 extern int i2c_register_driver(struct module *, struct i2c_driver *);
 extern void i2c_del_driver(struct i2c_driver *);
 
-static inline int i2c_add_driver(struct i2c_driver *driver)
-{
-       return i2c_register_driver(THIS_MODULE, driver);
-}
+/* use a define to avoid include chaining to get THIS_MODULE */
+#define i2c_add_driver(driver) \
+       i2c_register_driver(THIS_MODULE, driver)
 
 extern struct i2c_client *i2c_use_client(struct i2c_client *client);
 extern void i2c_release_client(struct i2c_client *client);
index 80b480c97532f25801c952fef3d515df907b9c8e..abf5028db98193bb36c5a4c590ac588cc2b1b9ca 100644 (file)
@@ -98,9 +98,10 @@ enum {
        INET_DIAG_VEGASINFO,
        INET_DIAG_CONG,
        INET_DIAG_TOS,
+       INET_DIAG_TCLASS,
 };
 
-#define INET_DIAG_MAX INET_DIAG_TOS
+#define INET_DIAG_MAX INET_DIAG_TCLASS
 
 
 /* INET_DIAG_MEM */
index 08ffab01e76c357cc47b378fd07f2895561f6cc3..32574eef93941bab73a9b43138cd8a67511101ec 100644 (file)
@@ -126,6 +126,8 @@ extern struct cred init_cred;
 # define INIT_PERF_EVENTS(tsk)
 #endif
 
+#define INIT_TASK_COMM "swapper"
+
 /*
  *  INIT_TASK is used to set up the first task table, touch at
  * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -162,7 +164,7 @@ extern struct cred init_cred;
        .group_leader   = &tsk,                                         \
        RCU_INIT_POINTER(.real_cred, &init_cred),                       \
        RCU_INIT_POINTER(.cred, &init_cred),                            \
-       .comm           = "swapper",                                    \
+       .comm           = INIT_TASK_COMM,                               \
        .thread         = INIT_THREAD,                                  \
        .fs             = &init_fs,                                     \
        .files          = &init_files,                                  \
@@ -184,7 +186,6 @@ extern struct cred init_cred;
                [PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),            \
        },                                                              \
        .thread_group   = LIST_HEAD_INIT(tsk.thread_group),             \
-       .dirties = INIT_PROP_LOCAL_SINGLE(dirties),                     \
        INIT_IDS                                                        \
        INIT_PERF_EVENTS(tsk)                                           \
        INIT_TRACE_IRQFLAGS                                             \
index 5037a0ad231245b3b2779c81bf76f912df467879..7e1371c4bccf93143e6234e15b11924b4375274f 100644 (file)
@@ -3,32 +3,92 @@
 
 #include <linux/radix-tree.h>
 #include <linux/rcupdate.h>
+#include <linux/workqueue.h>
 
-struct cfq_queue;
-struct cfq_ttime {
-       unsigned long last_end_request;
-
-       unsigned long ttime_total;
-       unsigned long ttime_samples;
-       unsigned long ttime_mean;
+enum {
+       ICQ_IOPRIO_CHANGED,
+       ICQ_CGROUP_CHANGED,
 };
 
-struct cfq_io_context {
-       void *key;
-
-       struct cfq_queue *cfqq[2];
-
-       struct io_context *ioc;
-
-       struct cfq_ttime ttime;
-
-       struct list_head queue_list;
-       struct hlist_node cic_list;
-
-       void (*dtor)(struct io_context *); /* destructor */
-       void (*exit)(struct io_context *); /* called on task exit */
+/*
+ * An io_cq (icq) is association between an io_context (ioc) and a
+ * request_queue (q).  This is used by elevators which need to track
+ * information per ioc - q pair.
+ *
+ * Elevator can request use of icq by setting elevator_type->icq_size and
+ * ->icq_align.  Both size and align must be larger than that of struct
+ * io_cq and elevator can use the tail area for private information.  The
+ * recommended way to do this is defining a struct which contains io_cq as
+ * the first member followed by private members and using its size and
+ * align.  For example,
+ *
+ *     struct snail_io_cq {
+ *             struct io_cq    icq;
+ *             int             poke_snail;
+ *             int             feed_snail;
+ *     };
+ *
+ *     struct elevator_type snail_elv_type {
+ *             .ops =          { ... },
+ *             .icq_size =     sizeof(struct snail_io_cq),
+ *             .icq_align =    __alignof__(struct snail_io_cq),
+ *             ...
+ *     };
+ *
+ * If icq_size is set, block core will manage icq's.  All requests will
+ * have its ->elv.icq field set before elevator_ops->elevator_set_req_fn()
+ * is called and be holding a reference to the associated io_context.
+ *
+ * Whenever a new icq is created, elevator_ops->elevator_init_icq_fn() is
+ * called and, on destruction, ->elevator_exit_icq_fn().  Both functions
+ * are called with both the associated io_context and queue locks held.
+ *
+ * Elevator is allowed to lookup icq using ioc_lookup_icq() while holding
+ * queue lock but the returned icq is valid only until the queue lock is
+ * released.  Elevators can not and should not try to create or destroy
+ * icq's.
+ *
+ * As icq's are linked from both ioc and q, the locking rules are a bit
+ * complex.
+ *
+ * - ioc lock nests inside q lock.
+ *
+ * - ioc->icq_list and icq->ioc_node are protected by ioc lock.
+ *   q->icq_list and icq->q_node by q lock.
+ *
+ * - ioc->icq_tree and ioc->icq_hint are protected by ioc lock, while icq
+ *   itself is protected by q lock.  However, both the indexes and icq
+ *   itself are also RCU managed and lookup can be performed holding only
+ *   the q lock.
+ *
+ * - icq's are not reference counted.  They are destroyed when either the
+ *   ioc or q goes away.  Each request with icq set holds an extra
+ *   reference to ioc to ensure it stays until the request is completed.
+ *
+ * - Linking and unlinking icq's are performed while holding both ioc and q
+ *   locks.  Due to the lock ordering, q exit is simple but ioc exit
+ *   requires reverse-order double lock dance.
+ */
+struct io_cq {
+       struct request_queue    *q;
+       struct io_context       *ioc;
 
-       struct rcu_head rcu_head;
+       /*
+        * q_node and ioc_node link io_cq through icq_list of q and ioc
+        * respectively.  Both fields are unused once ioc_exit_icq() is
+        * called and shared with __rcu_icq_cache and __rcu_head which are
+        * used for RCU free of io_cq.
+        */
+       union {
+               struct list_head        q_node;
+               struct kmem_cache       *__rcu_icq_cache;
+       };
+       union {
+               struct hlist_node       ioc_node;
+               struct rcu_head         __rcu_head;
+       };
+
+       unsigned long           changed;
 };
 
 /*
@@ -43,11 +103,6 @@ struct io_context {
        spinlock_t lock;
 
        unsigned short ioprio;
-       unsigned short ioprio_changed;
-
-#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
-       unsigned short cgroup_changed;
-#endif
 
        /*
         * For request batching
@@ -55,9 +110,11 @@ struct io_context {
        int nr_batch_requests;     /* Number of requests left in the batch */
        unsigned long last_waited; /* Time last woken after wait for request */
 
-       struct radix_tree_root radix_root;
-       struct hlist_head cic_list;
-       void __rcu *ioc_data;
+       struct radix_tree_root  icq_tree;
+       struct io_cq __rcu      *icq_hint;
+       struct hlist_head       icq_list;
+
+       struct work_struct release_work;
 };
 
 static inline struct io_context *ioc_task_link(struct io_context *ioc)
@@ -76,20 +133,17 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc)
 
 struct task_struct;
 #ifdef CONFIG_BLOCK
-int put_io_context(struct io_context *ioc);
+void put_io_context(struct io_context *ioc, struct request_queue *locked_q);
 void exit_io_context(struct task_struct *task);
-struct io_context *get_io_context(gfp_t gfp_flags, int node);
-struct io_context *alloc_io_context(gfp_t gfp_flags, int node);
+struct io_context *get_task_io_context(struct task_struct *task,
+                                      gfp_t gfp_flags, int node);
+void ioc_ioprio_changed(struct io_context *ioc, int ioprio);
+void ioc_cgroup_changed(struct io_context *ioc);
 #else
-static inline void exit_io_context(struct task_struct *task)
-{
-}
-
 struct io_context;
-static inline int put_io_context(struct io_context *ioc)
-{
-       return 1;
-}
+static inline void put_io_context(struct io_context *ioc,
+                                 struct request_queue *locked_q) { }
+static inline void exit_io_context(struct task_struct *task) { }
 #endif
 
 #endif
index ca85cf894e33fb4a89653aebcf8c10642a346a8e..bbd156bb953b8773b1f727898d9889612ac91bc1 100644 (file)
@@ -220,10 +220,11 @@ struct kernel_ipmi_msg {
  * The in-kernel interface.
  */
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 
+struct module;
+
 /* Opaque type for a IPMI message user.  One of these is needed to
    send and receive messages. */
 typedef struct ipmi_user *ipmi_user_t;
index 204f9cd26c16012126206106f5d36be3c0af21cf..3ef0d8b6aa6faf19c8e8d24a3033f15fc728a39b 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <linux/ipmi_msgdefs.h>
 #include <linux/proc_fs.h>
-#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/ipmi.h>
index 59e49c80cc2ce573d77fa4bb64e86483540c1b03..bff29c58da23013e5e1e19f0cdeaf2ad45d602fc 100644 (file)
 #include <linux/errno.h>
 #include <linux/topology.h>
 #include <linux/wait.h>
-#include <linux/module.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
 #include <asm/irq_regs.h>
 
 struct seq_file;
+struct module;
 struct irq_desc;
 struct irq_data;
 typedef        void (*irq_flow_handler_t)(unsigned int irq,
@@ -567,29 +567,21 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
                struct module *owner);
 
-static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt,
-               int node)
-{
-       return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE);
-}
+/* use macros to avoid needing export.h for THIS_MODULE */
+#define irq_alloc_descs(irq, from, cnt, node)  \
+       __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE)
 
-void irq_free_descs(unsigned int irq, unsigned int cnt);
-int irq_reserve_irqs(unsigned int from, unsigned int cnt);
+#define irq_alloc_desc(node)                   \
+       irq_alloc_descs(-1, 0, 1, node)
 
-static inline int irq_alloc_desc(int node)
-{
-       return irq_alloc_descs(-1, 0, 1, node);
-}
+#define irq_alloc_desc_at(at, node)            \
+       irq_alloc_descs(at, at, 1, node)
 
-static inline int irq_alloc_desc_at(unsigned int at, int node)
-{
-       return irq_alloc_descs(at, at, 1, node);
-}
+#define irq_alloc_desc_from(from, node)                \
+       irq_alloc_descs(-1, from, 1, node)
 
-static inline int irq_alloc_desc_from(unsigned int from, int node)
-{
-       return irq_alloc_descs(-1, from, 1, node);
-}
+void irq_free_descs(unsigned int irq, unsigned int cnt);
+int irq_reserve_irqs(unsigned int from, unsigned int cnt);
 
 static inline void irq_free_desc(unsigned int irq)
 {
index 6b69c2c9dff1d5056e9fd2272407b31917ab8d8a..f1e2527006bd92f4780584b874c829bef49523e5 100644 (file)
@@ -11,6 +11,7 @@
 struct irq_affinity_notify;
 struct proc_dir_entry;
 struct timer_rand_state;
+struct module;
 /**
  * struct irq_desc - interrupt descriptor
  * @irq_data:          per irq and chip data passed down to chip functions
index 66f23dc5e76a636bf2ed54542c6565fc82dbc6a4..388b0d425b507add656cca2aa7b48a346bf159ec 100644 (file)
@@ -16,7 +16,7 @@ struct jump_label_key {
 
 # include <asm/jump_label.h>
 # define HAVE_JUMP_LABEL
-#endif
+#endif /* CC_HAVE_ASM_GOTO && CONFIG_JUMP_LABEL */
 
 enum jump_label_type {
        JUMP_LABEL_DISABLE = 0,
@@ -28,9 +28,9 @@ struct module;
 #ifdef HAVE_JUMP_LABEL
 
 #ifdef CONFIG_MODULES
-#define JUMP_LABEL_INIT {{ 0 }, NULL, NULL}
+#define JUMP_LABEL_INIT {ATOMIC_INIT(0), NULL, NULL}
 #else
-#define JUMP_LABEL_INIT {{ 0 }, NULL}
+#define JUMP_LABEL_INIT {ATOMIC_INIT(0), NULL}
 #endif
 
 static __always_inline bool static_branch(struct jump_label_key *key)
@@ -41,18 +41,20 @@ static __always_inline bool static_branch(struct jump_label_key *key)
 extern struct jump_entry __start___jump_table[];
 extern struct jump_entry __stop___jump_table[];
 
+extern void jump_label_init(void);
 extern void jump_label_lock(void);
 extern void jump_label_unlock(void);
 extern void arch_jump_label_transform(struct jump_entry *entry,
-                                enum jump_label_type type);
-extern void arch_jump_label_text_poke_early(jump_label_t addr);
+                                     enum jump_label_type type);
+extern void arch_jump_label_transform_static(struct jump_entry *entry,
+                                            enum jump_label_type type);
 extern int jump_label_text_reserved(void *start, void *end);
 extern void jump_label_inc(struct jump_label_key *key);
 extern void jump_label_dec(struct jump_label_key *key);
 extern bool jump_label_enabled(struct jump_label_key *key);
 extern void jump_label_apply_nops(struct module *mod);
 
-#else
+#else  /* !HAVE_JUMP_LABEL */
 
 #include <linux/atomic.h>
 
@@ -62,6 +64,10 @@ struct jump_label_key {
        atomic_t enabled;
 };
 
+static __always_inline void jump_label_init(void)
+{
+}
+
 static __always_inline bool static_branch(struct jump_label_key *key)
 {
        if (unlikely(atomic_read(&key->enabled)))
@@ -96,7 +102,6 @@ static inline int jump_label_apply_nops(struct module *mod)
 {
        return 0;
 }
+#endif /* HAVE_JUMP_LABEL */
 
-#endif
-
-#endif
+#endif /* _LINUX_JUMP_LABEL_H */
index 4c0d3b2fd5fc9182034918835a25482868414fd8..e8b1597b5cf2592b85157674b1d1fcbd555d309a 100644 (file)
@@ -371,6 +371,7 @@ extern enum system_states {
 #define TAINT_WARN                     9
 #define TAINT_CRAP                     10
 #define TAINT_FIRMWARE_WORKAROUND      11
+#define TAINT_OOT_MODULE               12
 
 extern const char hex_asc[];
 #define hex_asc_lo(x)  hex_asc[((x) & 0x0f)]
index f47fcd30273dd2ce904b6ac0cf11fb963c04826c..c3892fc1d5389c86c664a43ca57bffa0f008d4b8 100644 (file)
@@ -555,7 +555,6 @@ struct kvm_ppc_pvinfo {
 #define KVM_CAP_PPC_SMT 64
 #define KVM_CAP_PPC_RMA        65
 #define KVM_CAP_MAX_VCPUS 66       /* returns max vcpus per vm */
-#define KVM_CAP_PPC_HIOR 67
 #define KVM_CAP_PPC_PAPR 68
 #define KVM_CAP_S390_GMAP 71
 
index 8ea9a42a4c02c6702f562fd46e60137f5e4f7a0a..0fe00cd4c93ca3b26fb8841b6becfd8ef10a02cd 100644 (file)
@@ -2,7 +2,8 @@
 #define __LINUX_MDIO_BITBANG_H
 
 #include <linux/phy.h>
-#include <linux/module.h>
+
+struct module;
 
 struct mdiobb_ctrl;
 
index 82b4c8801a4fc673fc4c7c0451bdb11330c821c7..8bf2cb9502dd7ba492680d371279577392c6d3fe 100644 (file)
 
 
 /*Registers VDD1, VDD2 voltage values definitions */
-#define VDD1_2_NUM_VOLTS                               73
+#define VDD1_2_NUM_VOLT_FINE                           73
+#define VDD1_2_NUM_VOLT_COARSE                         3
 #define VDD1_2_MIN_VOLT                                        6000
 #define VDD1_2_OFFSET                                  125
 
index fae295048a8b00e3dbdbd6d8471a8d7c7f728358..83a9caec0e4311e72b3997130d1291030616537f 100644 (file)
 #define WM8958_MICB2_DISCH_SHIFT                     0  /* MICB2_DISCH */
 #define WM8958_MICB2_DISCH_WIDTH                     1  /* MICB2_DISCH */
 
+/*
+ * R210 (0xD2) - Mic Detect 3
+ */
+#define WM8958_MICD_LVL_MASK                    0x07FC  /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_SHIFT                        2  /* MICD_LVL - [10:2] */
+#define WM8958_MICD_LVL_WIDTH                        9  /* MICD_LVL - [10:2] */
+#define WM8958_MICD_VALID                       0x0002  /* MICD_VALID */
+#define WM8958_MICD_VALID_MASK                  0x0002  /* MICD_VALID */
+#define WM8958_MICD_VALID_SHIFT                      1  /* MICD_VALID */
+#define WM8958_MICD_VALID_WIDTH                      1  /* MICD_VALID */
+#define WM8958_MICD_STS                         0x0001  /* MICD_STS */
+#define WM8958_MICD_STS_MASK                    0x0001  /* MICD_STS */
+#define WM8958_MICD_STS_SHIFT                        0  /* MICD_STS */
+#define WM8958_MICD_STS_WIDTH                        1  /* MICD_STS */
+
 /*
  * R76 (0x4C) - Charge Pump (1)
  */
index c309b1ecdc1c8b089725258cce9613e5ff7d9bbc..c41d7270c6c6e681eae994ce60b5b9b013c6492c 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef _LINUX_MISCDEVICE_H
 #define _LINUX_MISCDEVICE_H
-#include <linux/module.h>
 #include <linux/major.h>
+#include <linux/list.h>
+#include <linux/types.h>
 
 /*
  *     These allocations are managed by device@lanana.org. If you use an
index 3dc3a8c2c4858a1d3400aa2d5fd029d36a1177c6..4baadd18f4ad3402f47fbd2ac919bafba519bed4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mmzone.h>
 #include <linux/rbtree.h>
 #include <linux/prio_tree.h>
+#include <linux/atomic.h>
 #include <linux/debug_locks.h>
 #include <linux/mm_types.h>
 #include <linux/range.h>
index 863921637d9fc1eba5b0ebeb63eb90b7ec84144c..3cb7839a60b96ffc6e4fe9b28d0ddf491275b2f6 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kobject.h>
 #include <linux/moduleparam.h>
 #include <linux/tracepoint.h>
+#include <linux/export.h>
 
 #include <linux/percpu.h>
 #include <asm/module.h>
 /* Not Yet Implemented */
 #define MODULE_SUPPORTED_DEVICE(name)
 
-/* Some toolchains use a `_' prefix for all user symbols. */
-#ifdef CONFIG_SYMBOL_PREFIX
-#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
-#else
-#define MODULE_SYMBOL_PREFIX ""
-#endif
-
 #define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN
 
-struct kernel_symbol
-{
-       unsigned long value;
-       const char *name;
-};
-
 struct modversion_info
 {
        unsigned long crc;
@@ -98,11 +86,8 @@ void trim_init_extable(struct module *m);
 extern const struct gtype##_id __mod_##gtype##_table           \
   __attribute__ ((unused, alias(__stringify(name))))
 
-extern struct module __this_module;
-#define THIS_MODULE (&__this_module)
 #else  /* !MODULE */
 #define MODULE_GENERIC_TABLE(gtype,name)
-#define THIS_MODULE ((struct module *)0)
 #endif
 
 /* Generic info of form tag = "info" */
@@ -150,11 +135,6 @@ extern struct module __this_module;
 /* What your module does. */
 #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
 
-/* One for each parameter, describing how to use it.  Some files do
-   multiple of these per line, so can't just use MODULE_INFO. */
-#define MODULE_PARM_DESC(_parm, desc) \
-       __MODULE_INFO(parm, _parm, #_parm ":" desc)
-
 #define MODULE_DEVICE_TABLE(type,name)         \
   MODULE_GENERIC_TABLE(type##_device,name)
 
@@ -218,52 +198,6 @@ struct module_use {
        struct module *source, *target;
 };
 
-#ifndef __GENKSYMS__
-#ifdef CONFIG_MODVERSIONS
-/* Mark the CRC weak since genksyms apparently decides not to
- * generate a checksums for some symbols */
-#define __CRC_SYMBOL(sym, sec)                                 \
-       extern void *__crc_##sym __attribute__((weak));         \
-       static const unsigned long __kcrctab_##sym              \
-       __used                                                  \
-       __attribute__((section("___kcrctab" sec "+" #sym), unused))     \
-       = (unsigned long) &__crc_##sym;
-#else
-#define __CRC_SYMBOL(sym, sec)
-#endif
-
-/* For every exported symbol, place a struct in the __ksymtab section */
-#define __EXPORT_SYMBOL(sym, sec)                              \
-       extern typeof(sym) sym;                                 \
-       __CRC_SYMBOL(sym, sec)                                  \
-       static const char __kstrtab_##sym[]                     \
-       __attribute__((section("__ksymtab_strings"), aligned(1))) \
-       = MODULE_SYMBOL_PREFIX #sym;                            \
-       static const struct kernel_symbol __ksymtab_##sym       \
-       __used                                                  \
-       __attribute__((section("___ksymtab" sec "+" #sym), unused))     \
-       = { (unsigned long)&sym, __kstrtab_##sym }
-
-#define EXPORT_SYMBOL(sym)                                     \
-       __EXPORT_SYMBOL(sym, "")
-
-#define EXPORT_SYMBOL_GPL(sym)                                 \
-       __EXPORT_SYMBOL(sym, "_gpl")
-
-#define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
-       __EXPORT_SYMBOL(sym, "_gpl_future")
-
-
-#ifdef CONFIG_UNUSED_SYMBOLS
-#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
-#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
-#else
-#define EXPORT_UNUSED_SYMBOL(sym)
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)
-#endif
-
-#endif
-
 enum module_state
 {
        MODULE_STATE_LIVE,
@@ -581,11 +515,6 @@ int unregister_module_notifier(struct notifier_block * nb);
 extern void print_modules(void);
 
 #else /* !CONFIG_MODULES... */
-#define EXPORT_SYMBOL(sym)
-#define EXPORT_SYMBOL_GPL(sym)
-#define EXPORT_SYMBOL_GPL_FUTURE(sym)
-#define EXPORT_UNUSED_SYMBOL(sym)
-#define EXPORT_UNUSED_SYMBOL_GPL(sym)
 
 /* Given an address, look for it in the exception tables. */
 static inline const struct exception_table_entry *
index fffb10bd55145a8e72768526bf97c0157d942073..7939f636c8bae3c747b604c98472d34de620ab70 100644 (file)
@@ -31,6 +31,11 @@ static const char __module_cat(name,__LINE__)[]                                \
 #define __MODULE_PARM_TYPE(name, _type)                                          \
   __MODULE_INFO(parmtype, name##type, #name ":" _type)
 
+/* One for each parameter, describing how to use it.  Some files do
+   multiple of these per line, so can't just use MODULE_INFO. */
+#define MODULE_PARM_DESC(_parm, desc) \
+       __MODULE_INFO(parm, _parm, #_parm ":" desc)
+
 struct kernel_param;
 
 struct kernel_param_ops {
index 57cc0e63714f9651462450db8fbbc78df79b82f1..c4eec228eef9756c660b538018550ab6bfc8790e 100644 (file)
@@ -86,24 +86,39 @@ struct nand_bbt_descr {
 #define NAND_BBT_VERSION       0x00000100
 /* Create a bbt if none exists */
 #define NAND_BBT_CREATE                0x00000200
+/*
+ * Create an empty BBT with no vendor information. Vendor's information may be
+ * unavailable, for example, if the NAND controller has a different data and OOB
+ * layout or if this information is already purged. Must be used in conjunction
+ * with NAND_BBT_CREATE.
+ */
+#define NAND_BBT_CREATE_EMPTY  0x00000400
 /* Search good / bad pattern through all pages of a block */
-#define NAND_BBT_SCANALLPAGES  0x00000400
+#define NAND_BBT_SCANALLPAGES  0x00000800
 /* Scan block empty during good / bad block scan */
-#define NAND_BBT_SCANEMPTY     0x00000800
+#define NAND_BBT_SCANEMPTY     0x00001000
 /* Write bbt if neccecary */
-#define NAND_BBT_WRITE         0x00001000
+#define NAND_BBT_WRITE         0x00002000
 /* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x00002000
+#define NAND_BBT_SAVECONTENT   0x00004000
 /* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x00004000
+#define NAND_BBT_SCAN2NDPAGE   0x00008000
 /* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x00008000
-/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
-#define NAND_BBT_SCANBYTE1AND6 0x00100000
-/* The nand_bbt_descr was created dynamicaly and must be freed */
-#define NAND_BBT_DYNAMICSTRUCT 0x00200000
-/* The bad block table does not OOB for marker */
-#define NAND_BBT_NO_OOB                0x00400000
+#define NAND_BBT_SCANLASTPAGE  0x00010000
+/*
+ * Use a flash based bad block table. By default, OOB identifier is saved in
+ * OOB area. This option is passed to the default bad block table function.
+ */
+#define NAND_BBT_USE_FLASH     0x00020000
+/* Do not store flash based bad block table in OOB area; store it in-band */
+#define NAND_BBT_NO_OOB                0x00040000
+
+/*
+ * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
+ * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
+ * in nand_chip.bbt_options.
+ */
+#define NAND_BBT_DYNAMICSTRUCT 0x80000000
 
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS        4
index 2541fb848daa7c2108c7ff74e27a44d146731642..9f5b312af7838d5275ff9611030da3861ec2d612 100644 (file)
@@ -21,7 +21,6 @@
 #define __MTD_MTD_H__
 
 #include <linux/types.h>
-#include <linux/module.h>
 #include <linux/uio.h>
 #include <linux/notifier.h>
 #include <linux/device.h>
 #define MTD_CHAR_MAJOR 90
 #define MTD_BLOCK_MAJOR 31
 
-#define MTD_ERASE_PENDING              0x01
+#define MTD_ERASE_PENDING      0x01
 #define MTD_ERASING            0x02
 #define MTD_ERASE_SUSPEND      0x04
-#define MTD_ERASE_DONE          0x08
-#define MTD_ERASE_FAILED        0x10
+#define MTD_ERASE_DONE         0x08
+#define MTD_ERASE_FAILED       0x10
 
 #define MTD_FAIL_ADDR_UNKNOWN -1LL
 
-/* If the erase fails, fail_addr might indicate exactly which block failed.  If
-   fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not
-   specific to any particular block. */
+/*
+ * If the erase fails, fail_addr might indicate exactly which block failed. If
+ * fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
+ * or was not specific to any particular block.
+ */
 struct erase_info {
        struct mtd_info *mtd;
        uint64_t addr;
@@ -60,26 +61,12 @@ struct erase_info {
 };
 
 struct mtd_erase_region_info {
-       uint64_t offset;                        /* At which this region starts, from the beginning of the MTD */
+       uint64_t offset;                /* At which this region starts, from the beginning of the MTD */
        uint32_t erasesize;             /* For this region */
        uint32_t numblocks;             /* Number of blocks of erasesize in this region */
        unsigned long *lockmap;         /* If keeping bitmap of locks */
 };
 
-/*
- * oob operation modes
- *
- * MTD_OOB_PLACE:      oob data are placed at the given offset
- * MTD_OOB_AUTO:       oob data are automatically placed at the free areas
- *                     which are defined by the ecclayout
- * MTD_OOB_RAW:                mode to read oob and data without doing ECC checking
- */
-typedef enum {
-       MTD_OOB_PLACE,
-       MTD_OOB_AUTO,
-       MTD_OOB_RAW,
-} mtd_oob_mode_t;
-
 /**
  * struct mtd_oob_ops - oob operation operands
  * @mode:      operation mode
@@ -91,7 +78,7 @@ typedef enum {
  * @ooblen:    number of oob bytes to write/read
  * @oobretlen: number of oob bytes written/read
  * @ooboffs:   offset of oob data in the oob area (only relevant when
- *             mode = MTD_OOB_PLACE)
+ *             mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
  * @datbuf:    data buffer - if NULL only oob data are read/written
  * @oobbuf:    oob data buffer
  *
@@ -100,7 +87,7 @@ typedef enum {
  * OOB area.
  */
 struct mtd_oob_ops {
-       mtd_oob_mode_t  mode;
+       unsigned int    mode;
        size_t          len;
        size_t          retlen;
        size_t          ooblen;
@@ -125,6 +112,8 @@ struct nand_ecclayout {
        struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
 };
 
+struct module; /* only needed for owner field in mtd_info */
+
 struct mtd_info {
        u_char type;
        uint32_t flags;
@@ -172,7 +161,7 @@ struct mtd_info {
        const char *name;
        int index;
 
-       /* ecc layout structure pointer - read only ! */
+       /* ECC layout structure pointer - read only! */
        struct nand_ecclayout *ecclayout;
 
        /* Data for variable erase regions. If numeraseregions is zero,
@@ -323,10 +312,15 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
        /* Kernel-side ioctl definitions */
 
 struct mtd_partition;
-
-extern int mtd_device_register(struct mtd_info *master,
-                              const struct mtd_partition *parts,
-                              int nr_parts);
+struct mtd_part_parser_data;
+
+extern int mtd_device_parse_register(struct mtd_info *mtd,
+                             const char **part_probe_types,
+                             struct mtd_part_parser_data *parser_data,
+                             const struct mtd_partition *defparts,
+                             int defnr_parts);
+#define mtd_device_register(master, parts, nr_parts)   \
+       mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
 extern int mtd_device_unregister(struct mtd_info *master);
 extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
 extern int __get_mtd_device(struct mtd_info *mtd);
@@ -355,27 +349,16 @@ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
 
 void mtd_erase_callback(struct erase_info *instr);
 
-/*
- * Debugging macro and defines
- */
-#define MTD_DEBUG_LEVEL0       (0)     /* Quiet   */
-#define MTD_DEBUG_LEVEL1       (1)     /* Audible */
-#define MTD_DEBUG_LEVEL2       (2)     /* Loud    */
-#define MTD_DEBUG_LEVEL3       (3)     /* Noisy   */
-
-#ifdef CONFIG_MTD_DEBUG
-#define DEBUG(n, args...)                              \
-       do {                                            \
-               if (n <= CONFIG_MTD_DEBUG_VERBOSE)      \
-                       printk(KERN_INFO args);         \
-       } while(0)
-#else /* CONFIG_MTD_DEBUG */
-#define DEBUG(n, args...)                              \
-       do {                                            \
-               if (0)                                  \
-                       printk(KERN_INFO args);         \
-       } while(0)
-
-#endif /* CONFIG_MTD_DEBUG */
+static inline int mtd_is_bitflip(int err) {
+       return err == -EUCLEAN;
+}
+
+static inline int mtd_is_eccerr(int err) {
+       return err == -EBADMSG;
+}
+
+static inline int mtd_is_bitflip_or_eccerr(int err) {
+       return mtd_is_bitflip(err) || mtd_is_eccerr(err);
+}
 
 #endif /* __MTD_MTD_H__ */
index c2b9ac4fbc4ab588074acd2d77f2ad20bc1bddb6..904131bab501380e9a82dbfdafa412609531b7f1 100644 (file)
@@ -42,10 +42,10 @@ extern void nand_release(struct mtd_info *mtd);
 /* Internal helper for board drivers which need to override command function */
 extern void nand_wait_ready(struct mtd_info *mtd);
 
-/* locks all blockes present in the device */
+/* locks all blocks present in the device */
 extern int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 
-/* unlocks specified locked blockes */
+/* unlocks specified locked blocks */
 extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 
 /* The maximum number of NAND chips in an array */
@@ -150,7 +150,7 @@ typedef enum {
 #define NAND_ECC_READ          0
 /* Reset Hardware ECC for write */
 #define NAND_ECC_WRITE         1
-/* Enable Hardware ECC before syndrom is read back from flash */
+/* Enable Hardware ECC before syndrome is read back from flash */
 #define NAND_ECC_READSYN       2
 
 /* Bit mask for flags passed to do_nand_read_ecc */
@@ -163,7 +163,7 @@ typedef enum {
  */
 /* Chip can not auto increment pages */
 #define NAND_NO_AUTOINCR       0x00000001
-/* Buswitdh is 16 bit */
+/* Buswidth is 16 bit */
 #define NAND_BUSWIDTH_16       0x00000002
 /* Device supports partial programming without padding */
 #define NAND_NO_PADDING                0x00000004
@@ -219,27 +219,15 @@ typedef enum {
 #define NAND_CHIPOPTIONS_MSK   (0x0000ffff & ~NAND_NO_AUTOINCR)
 
 /* Non chip related options */
-/*
- * Use a flash based bad block table. OOB identifier is saved in OOB area.
- * This option is passed to the default bad block table function.
- */
-#define NAND_USE_FLASH_BBT     0x00010000
 /* This option skips the bbt scan during initialization. */
-#define NAND_SKIP_BBTSCAN      0x00020000
+#define NAND_SKIP_BBTSCAN      0x00010000
 /*
  * This option is defined if the board driver allocates its own buffers
  * (e.g. because it needs them DMA-coherent).
  */
-#define NAND_OWN_BUFFERS       0x00040000
+#define NAND_OWN_BUFFERS       0x00020000
 /* Chip may not exist, so silence any errors in scan */
-#define NAND_SCAN_SILENT_NODEV 0x00080000
-/*
- * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
- * the OOB area.
- */
-#define NAND_USE_FLASH_BBT_NO_OOB      0x00800000
-/* Create an empty BBT with no vendor information if the BBT is available */
-#define NAND_CREATE_EMPTY_BBT          0x01000000
+#define NAND_SCAN_SILENT_NODEV 0x00040000
 
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
@@ -331,27 +319,29 @@ struct nand_hw_control {
 };
 
 /**
- * struct nand_ecc_ctrl - Control structure for ecc
- * @mode:      ecc mode
- * @steps:     number of ecc steps per page
- * @size:      data bytes per ecc step
- * @bytes:     ecc bytes per step
- * @total:     total number of ecc bytes per page
- * @prepad:    padding information for syndrome based ecc generators
- * @postpad:   padding information for syndrome based ecc generators
+ * struct nand_ecc_ctrl - Control structure for ECC
+ * @mode:      ECC mode
+ * @steps:     number of ECC steps per page
+ * @size:      data bytes per ECC step
+ * @bytes:     ECC bytes per step
+ * @total:     total number of ECC bytes per page
+ * @prepad:    padding information for syndrome based ECC generators
+ * @postpad:   padding information for syndrome based ECC generators
  * @layout:    ECC layout control struct pointer
- * @priv:      pointer to private ecc control data
- * @hwctl:     function to control hardware ecc generator. Must only
+ * @priv:      pointer to private ECC control data
+ * @hwctl:     function to control hardware ECC generator. Must only
  *             be provided if an hardware ECC is available
- * @calculate: function for ecc calculation or readback from ecc hardware
- * @correct:   function for ecc correction, matching to ecc generator (sw/hw)
+ * @calculate: function for ECC calculation or readback from ECC hardware
+ * @correct:   function for ECC correction, matching to ECC generator (sw/hw)
  * @read_page_raw:     function to read a raw page without ECC
  * @write_page_raw:    function to write a raw page without ECC
- * @read_page: function to read a page according to the ecc generator
+ * @read_page: function to read a page according to the ECC generator
  *             requirements.
  * @read_subpage:      function to read parts of the page covered by ECC.
- * @write_page:        function to write a page according to the ecc generator
+ * @write_page:        function to write a page according to the ECC generator
  *             requirements.
+ * @write_oob_raw:     function to write chip OOB data without ECC
+ * @read_oob_raw:      function to read chip OOB data without ECC
  * @read_oob:  function to read chip OOB data
  * @write_oob: function to write chip OOB data
  */
@@ -380,6 +370,10 @@ struct nand_ecc_ctrl {
                        uint32_t offs, uint32_t len, uint8_t *buf);
        void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
                        const uint8_t *buf);
+       int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int page);
+       int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int page, int sndcmd);
        int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page,
                        int sndcmd);
        int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
@@ -388,8 +382,8 @@ struct nand_ecc_ctrl {
 
 /**
  * struct nand_buffers - buffer structure for read/write
- * @ecccalc:   buffer for calculated ecc
- * @ecccode:   buffer for ecc read from flash
+ * @ecccalc:   buffer for calculated ECC
+ * @ecccode:   buffer for ECC read from flash
  * @databuf:   buffer for data - dynamically sized
  *
  * Do not change the order of buffers. databuf and oobrbuf must be in
@@ -422,7 +416,7 @@ struct nand_buffers {
  *                     mtd->oobsize, mtd->writesize and so on.
  *                     @id_data contains the 8 bytes values of NAND_CMD_READID.
  *                     Return with the bus width.
- * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing
+ * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accessing
  *                     device ready/busy line. If set to NULL no access to
  *                     ready/busy is available and the ready/busy information
  *                     is read from the chip status register.
@@ -430,17 +424,17 @@ struct nand_buffers {
  *                     commands to the chip.
  * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on
  *                     ready.
- * @ecc:               [BOARDSPECIFIC] ecc control ctructure
+ * @ecc:               [BOARDSPECIFIC] ECC control structure
  * @buffers:           buffer structure for read/write
  * @hwcontrol:         platform-specific hardware control structure
- * @ops:               oob operation operands
  * @erase_cmd:         [INTERN] erase command write function, selectable due
  *                     to AND support.
  * @scan_bbt:          [REPLACEABLE] function to scan bad block table
  * @chip_delay:                [BOARDSPECIFIC] chip dependent delay for transferring
  *                     data from array to read regs (tR).
  * @state:             [INTERN] the current state of the NAND device
- * @oob_poi:           poison value buffer
+ * @oob_poi:           "poison value buffer," used for laying out OOB data
+ *                     before writing
  * @page_shift:                [INTERN] number of address bits in a page (column
  *                     address bits).
  * @phys_erase_shift:  [INTERN] number of address bits in a physical eraseblock
@@ -449,6 +443,9 @@ struct nand_buffers {
  * @options:           [BOARDSPECIFIC] various chip options. They can partly
  *                     be set to inform nand_scan about special functionality.
  *                     See the defines for further explanation.
+ * @bbt_options:       [INTERN] bad block specific options. All options used
+ *                     here must come from bbm.h. By default, these options
+ *                     will be copied to the appropriate nand_bbt_descr's.
  * @badblockpos:       [INTERN] position of the bad block marker in the oob
  *                     area.
  * @badblockbits:      [INTERN] number of bits to left-shift the bad block
@@ -464,7 +461,7 @@ struct nand_buffers {
  *                     non 0 if ONFI supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
- * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
+ * @ecclayout:         [REPLACEABLE] the default ECC placement scheme
  * @bbt:               [INTERN] bad block table pointer
  * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
  *                     lookup.
@@ -472,9 +469,9 @@ struct nand_buffers {
  * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial
  *                     bad block scan.
  * @controller:                [REPLACEABLE] a pointer to a hardware controller
- *                     structure which is shared among multiple independend
+ *                     structure which is shared among multiple independent
  *                     devices.
- * @priv:              [OPTIONAL] pointer to private chip date
+ * @priv:              [OPTIONAL] pointer to private chip data
  * @errstat:           [OPTIONAL] hardware specific function to perform
  *                     additional error status checks (determine if errors are
  *                     correctable).
@@ -509,6 +506,7 @@ struct nand_chip {
 
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
 
        int page_shift;
        int phys_erase_shift;
@@ -536,8 +534,6 @@ struct nand_chip {
        struct nand_buffers *buffers;
        struct nand_hw_control hwcontrol;
 
-       struct mtd_oob_ops ops;
-
        uint8_t *bbt;
        struct nand_bbt_descr *bbt_td;
        struct nand_bbt_descr *bbt_md;
@@ -611,10 +607,9 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
  * @partitions:                mtd partition list
  * @chip_delay:                R/B delay value in us
  * @options:           Option flags, e.g. 16bit buswidth
- * @ecclayout:         ecc layout info structure
+ * @bbt_options:       BBT option flags, e.g. NAND_BBT_USE_FLASH
+ * @ecclayout:         ECC layout info structure
  * @part_probe_types:  NULL-terminated array of probe types
- * @set_parts:         platform specific function to set partitions
- * @priv:              hardware controller specific settings
  */
 struct platform_nand_chip {
        int nr_chips;
@@ -624,9 +619,8 @@ struct platform_nand_chip {
        struct nand_ecclayout *ecclayout;
        int chip_delay;
        unsigned int options;
+       unsigned int bbt_options;
        const char **part_probe_types;
-       void (*set_parts)(uint64_t size, struct platform_nand_chip *chip);
-       void *priv;
 };
 
 /* Keep gcc happy */
index 52b6f187bf49bfdc3038dff70f3117eb4e9a1a97..4596503c9da9e0952d4953fa856572898aabc9be 100644 (file)
@@ -184,6 +184,9 @@ struct onenand_chip {
 #define ONENAND_IS_CACHE_PROGRAM(this)                                 \
        (this->options & ONENAND_HAS_CACHE_PROGRAM)
 
+#define ONENAND_IS_NOP_1(this)                                         \
+       (this->options & ONENAND_HAS_NOP_1)
+
 /* Check byte access in OneNAND */
 #define ONENAND_CHECK_BYTE_ACCESS(addr)                (addr & 0x1)
 
@@ -195,6 +198,7 @@ struct onenand_chip {
 #define ONENAND_HAS_2PLANE             (0x0004)
 #define ONENAND_HAS_4KB_PAGE           (0x0008)
 #define ONENAND_HAS_CACHE_PROGRAM      (0x0010)
+#define ONENAND_HAS_NOP_1              (0x0020)
 #define ONENAND_SKIP_UNLOCK_CHECK      (0x0100)
 #define ONENAND_PAGEBUF_ALLOC          (0x1000)
 #define ONENAND_OOBBUF_ALLOC           (0x2000)
index 3a6f0372fc9658f267fabdf61190b9a32ed4d7e3..2475228c1158e6f54e4f7ce02b2607ee9f487922 100644 (file)
@@ -24,7 +24,9 @@
  *     will extend to the end of the master MTD device.
  * offset: absolute starting position within the master MTD device; if
  *     defined as MTDPART_OFS_APPEND, the partition will start where the
- *     previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
+ *     previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block;
+ *     if MTDPART_OFS_RETAIN, consume as much as possible, leaving size
+ *     after the end of partition.
  * mask_flags: contains flags that have to be masked (removed) from the
  *     master MTD flag set for the corresponding MTD partition.
  *     For example, to force a read-only partition, simply adding
@@ -42,12 +44,25 @@ struct mtd_partition {
        struct nand_ecclayout *ecclayout;       /* out of band layout for this partition (NAND only) */
 };
 
+#define MTDPART_OFS_RETAIN     (-3)
 #define MTDPART_OFS_NXTBLK     (-2)
 #define MTDPART_OFS_APPEND     (-1)
 #define MTDPART_SIZ_FULL       (0)
 
 
 struct mtd_info;
+struct device_node;
+
+/**
+ * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
+ * @origin: for RedBoot, start address of MTD device
+ * @of_node: for OF parsers, device node containing partitioning information
+ */
+struct mtd_part_parser_data {
+       unsigned long origin;
+       struct device_node *of_node;
+};
+
 
 /*
  * Functions dealing with the various ways of partitioning the space
@@ -57,37 +72,12 @@ struct mtd_part_parser {
        struct list_head list;
        struct module *owner;
        const char *name;
-       int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
+       int (*parse_fn)(struct mtd_info *, struct mtd_partition **,
+                       struct mtd_part_parser_data *);
 };
 
 extern int register_mtd_parser(struct mtd_part_parser *parser);
 extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
-                               struct mtd_partition **pparts, unsigned long origin);
-
-#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
-
-struct device;
-struct device_node;
-
-#ifdef CONFIG_MTD_OF_PARTS
-int __devinit of_mtd_parse_partitions(struct device *dev,
-                                      struct device_node *node,
-                                      struct mtd_partition **pparts);
-#else
-static inline int of_mtd_parse_partitions(struct device *dev,
-                                         struct device_node *node,
-                                         struct mtd_partition **pparts)
-{
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-static inline int mtd_has_cmdlinepart(void) { return 1; }
-#else
-static inline int mtd_has_cmdlinepart(void) { return 0; }
-#endif
 
 int mtd_is_partition(struct mtd_info *mtd);
 int mtd_add_partition(struct mtd_info *master, char *name,
index e5f21d293c70175f1395c3355b3da5a230ee0d99..04e018160e2b516be1e29c383e983036c31ffef6 100644 (file)
@@ -32,21 +32,4 @@ struct physmap_flash_data {
        struct mtd_partition    *parts;
 };
 
-/*
- * Board needs to specify the exact mapping during their setup time.
- */
-void physmap_configure(unsigned long addr, unsigned long size,
-               int bankwidth, void (*set_vpp)(struct map_info *, int) );
-
-/*
- * Machines that wish to do flash partition may want to call this function in
- * their setup routine.
- *
- *     physmap_set_partitions(mypartitions, num_parts);
- *
- * Note that one can always override this hard-coded partition with
- * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
- */
-void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
-
 #endif /* __LINUX_MTD_PHYSMAP__ */
index cbeb5867cff79d7d70952cc6285063c3feb92e7c..a82ad4dd306a657565f5c9987f4b888468325ba2 100644 (file)
@@ -2536,6 +2536,8 @@ extern void               net_disable_timestamp(void);
 extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
 extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 extern void dev_seq_stop(struct seq_file *seq, void *v);
+extern int dev_seq_open_ops(struct inode *inode, struct file *file,
+                           const struct seq_operations *ops);
 #endif
 
 extern int netdev_class_create_file(struct class_attribute *class_attr);
index ab2c6343361ae3e82f242df7880f292c189e442d..92ecf5585facf20511cd865db281d33ea828bdad 100644 (file)
@@ -410,6 +410,9 @@ extern const struct inode_operations nfs_file_inode_operations;
 extern const struct inode_operations nfs3_file_inode_operations;
 #endif /* CONFIG_NFS_V3 */
 extern const struct file_operations nfs_file_operations;
+#ifdef CONFIG_NFS_V4
+extern const struct file_operations nfs4_file_operations;
+#endif /* CONFIG_NFS_V4 */
 extern const struct address_space_operations nfs_file_aops;
 extern const struct address_space_operations nfs_dir_aops;
 
index c74595ba70947926d2b1a99f4157ca7f485dbd13..2a7c533be5dd8aa2f584fde1faad94c558130d75 100644 (file)
@@ -1192,6 +1192,7 @@ struct nfs_rpc_ops {
        const struct dentry_operations *dentry_ops;
        const struct inode_operations *dir_inode_ops;
        const struct inode_operations *file_inode_ops;
+       const struct file_operations *file_ops;
 
        int     (*getroot) (struct nfs_server *, struct nfs_fh *,
                            struct nfs_fsinfo *);
index 0e89aa0bf07ad079ea27b2c05f2c960af8fc2c75..4948552d60f5e5d436bcadfc773d69e5b48eaf0b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 
 #include <asm/byteorder.h>
+#include <asm/errno.h>
 
 typedef u32 phandle;
 typedef u32 ihandle;
index 5a6f458a4bb745c0ab4058448a5c2c4834cf809d..040ce2f6e8decc5e5774a8ef584b6b0ff37b6b4b 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 #ifdef CONFIG_OF_DEVICE
-#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/pm.h>
index 87a9208f8aec24bafe60ba3206c2f1a4d904c626..ee94b33080c207332e43291caaf240a62541a919 100644 (file)
@@ -97,11 +97,11 @@ static inline int opp_disable(struct device *dev, unsigned long freq)
        return 0;
 }
 
-struct srcu_notifier_head *opp_get_notifier(struct device *dev)
+static inline struct srcu_notifier_head *opp_get_notifier(struct device *dev)
 {
        return ERR_PTR(-EINVAL);
 }
-#endif         /* CONFIG_PM */
+#endif         /* CONFIG_PM_OPP */
 
 #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
 int opp_init_cpufreq_table(struct device *dev,
index e3d0b3890249163881eec330894cdd8bb945295a..7ef68724f0f054f88427d2dbc18c63b962a16394 100644 (file)
@@ -12,7 +12,7 @@ struct pci_ats {
        unsigned int is_enabled:1;      /* Enable bit is set */
 };
 
-#ifdef CONFIG_PCI_IOV
+#ifdef CONFIG_PCI_ATS
 
 extern int pci_enable_ats(struct pci_dev *dev, int ps);
 extern void pci_disable_ats(struct pci_dev *dev);
@@ -29,7 +29,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
        return dev->ats && dev->ats->is_enabled;
 }
 
-#else /* CONFIG_PCI_IOV */
+#else /* CONFIG_PCI_ATS */
 
 static inline int pci_enable_ats(struct pci_dev *dev, int ps)
 {
@@ -50,7 +50,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
        return 0;
 }
 
-#endif /* CONFIG_PCI_IOV */
+#endif /* CONFIG_PCI_ATS */
 
 #ifdef CONFIG_PCI_PRI
 
index 337df0d5d5f7eb2e80410e4e0980afe4ef4ed83a..7cda65b5f79806005af9aada8831f8403a519db7 100644 (file)
@@ -338,7 +338,7 @@ struct pci_dev {
        struct list_head msi_list;
 #endif
        struct pci_vpd *vpd;
-#ifdef CONFIG_PCI_IOV
+#ifdef CONFIG_PCI_ATS
        union {
                struct pci_sriov *sriov;        /* SR-IOV capability related */
                struct pci_dev *physfn; /* the PF this VF is associated with */
index 5d09cbafa7dbfa17b814866e6f56e306f75351d7..45fc162cbdc06b0d3d0320c50575b14b5a8b5828 100644 (file)
@@ -132,13 +132,9 @@ extern int pci_hp_deregister(struct hotplug_slot *slot);
 extern int __must_check pci_hp_change_slot_info        (struct hotplug_slot *slot,
                                                 struct hotplug_slot_info *info);
 
-static inline int pci_hp_register(struct hotplug_slot *slot,
-                                 struct pci_bus *pbus,
-                                 int devnr, const char *name)
-{
-       return __pci_hp_register(slot, pbus, devnr, name,
-                                THIS_MODULE, KBUILD_MODNAME);
-}
+/* use a define to avoid include chaining to get THIS_MODULE & friends */
+#define pci_hp_register(slot, pbus, devnr, name) \
+       __pci_hp_register(slot, pbus, devnr, name, THIS_MODULE, KBUILD_MODNAME)
 
 /* PCI Setting Record (Type 0) */
 struct hpp_type0 {
index 1679ff6931f977146bade5b851bb245dd72cec7c..2aaee0ca9da847ec447abc59df56c916f18bc6ac 100644 (file)
 #define PCI_DEVICE_ID_AMD_11H_NB_DRAM  0x1302
 #define PCI_DEVICE_ID_AMD_11H_NB_MISC  0x1303
 #define PCI_DEVICE_ID_AMD_11H_NB_LINK  0x1304
+#define PCI_DEVICE_ID_AMD_15H_NB_F0    0x1600
+#define PCI_DEVICE_ID_AMD_15H_NB_F1    0x1601
+#define PCI_DEVICE_ID_AMD_15H_NB_F2    0x1602
 #define PCI_DEVICE_ID_AMD_15H_NB_F3    0x1603
 #define PCI_DEVICE_ID_AMD_15H_NB_F4    0x1604
+#define PCI_DEVICE_ID_AMD_15H_NB_F5    0x1605
 #define PCI_DEVICE_ID_AMD_CNB17H_F3    0x1703
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME   0x2001
 
 #define PCI_VENDOR_ID_AZWAVE           0x1a3b
 
+#define PCI_VENDOR_ID_ASMEDIA          0x1b21
+
 #define PCI_VENDOR_ID_TEKRAM           0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290     0xdc29
 
 
 #define PCI_VENDOR_ID_XEN              0x5853
 #define PCI_DEVICE_ID_XEN_PLATFORM     0x0001
+
+#define PCI_VENDOR_ID_OCZ              0x1b85
index 1e9ebe5e0091e7fa1b1fabb72f72af979f35104c..b1f89122bf6a820102f43714fd42246d1dadd207 100644 (file)
@@ -822,6 +822,7 @@ struct perf_event {
        int                             mmap_locked;
        struct user_struct              *mmap_user;
        struct ring_buffer              *rb;
+       struct list_head                rb_entry;
 
        /* poll related */
        wait_queue_head_t               waitq;
index 3605e947fa90db9258363d5ca638082f9512dfbd..04c011038f32080ff6489c5a8cd11aad4878f571 100644 (file)
@@ -121,6 +121,7 @@ extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev);
 extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
 #else
 
+struct pinctrl_dev;
 
 /* Sufficiently stupid default function when pinctrl is not in use */
 static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
index c5336705921fdae6a3feb8ea99dfa252ae012c52..7281d5acf2f971a2fbae880b7935ac37cdea01df 100644 (file)
@@ -30,7 +30,7 @@
  */
 
 struct tc_stats {
-       __u64   bytes;                  /* NUmber of enqueues bytes */
+       __u64   bytes;                  /* Number of enqueued bytes */
        __u32   packets;                /* Number of enqueued packets   */
        __u32   drops;                  /* Packets dropped because of lack of resources */
        __u32   overlimits;             /* Number of throttle events when this
@@ -297,7 +297,7 @@ struct tc_htb_glob {
        __u32 debug;            /* debug flags */
 
        /* stats */
-       __u32 direct_pkts; /* count of non shapped packets */
+       __u32 direct_pkts; /* count of non shaped packets */
 };
 enum {
        TCA_HTB_UNSPEC,
@@ -503,7 +503,7 @@ enum {
 };
 #define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1)
 
-/* State transition probablities for 4 state model */
+/* State transition probabilities for 4 state model */
 struct tc_netem_gimodel {
        __u32   p13;
        __u32   p31;
index f15acb64681351b72c5b1c460bf0174ad2f33749..3f3ed83a9aa52cf69df6fd7a925d521cbca96f6d 100644 (file)
@@ -54,118 +54,145 @@ typedef struct pm_message {
 /**
  * struct dev_pm_ops - device PM callbacks
  *
- * Several driver power state transitions are externally visible, affecting
+ * Several device power state transitions are externally visible, affecting
  * the state of pending I/O queues and (for drivers that touch hardware)
  * interrupts, wakeups, DMA, and other hardware state.  There may also be
- * internal transitions to various low power modes, which are transparent
+ * internal transitions to various low-power modes which are transparent
  * to the rest of the driver stack (such as a driver that's ON gating off
  * clocks which are not in active use).
  *
- * The externally visible transitions are handled with the help of the following
- * callbacks included in this structure:
- *
- * @prepare: Prepare the device for the upcoming transition, but do NOT change
- *     its hardware state.  Prevent new children of the device from being
- *     registered after @prepare() returns (the driver's subsystem and
- *     generally the rest of the kernel is supposed to prevent new calls to the
- *     probe method from being made too once @prepare() has succeeded).  If
- *     @prepare() detects a situation it cannot handle (e.g. registration of a
- *     child already in progress), it may return -EAGAIN, so that the PM core
- *     can execute it once again (e.g. after the new child has been registered)
- *     to recover from the race condition.  This method is executed for all
- *     kinds of suspend transitions and is followed by one of the suspend
- *     callbacks: @suspend(), @freeze(), or @poweroff().
- *     The PM core executes @prepare() for all devices before starting to
- *     execute suspend callbacks for any of them, so drivers may assume all of
- *     the other devices to be present and functional while @prepare() is being
- *     executed.  In particular, it is safe to make GFP_KERNEL memory
- *     allocations from within @prepare().  However, drivers may NOT assume
- *     anything about the availability of the user space at that time and it
- *     is not correct to request firmware from within @prepare() (it's too
- *     late to do that).  [To work around this limitation, drivers may
- *     register suspend and hibernation notifiers that are executed before the
- *     freezing of tasks.]
+ * The externally visible transitions are handled with the help of callbacks
+ * included in this structure in such a way that two levels of callbacks are
+ * involved.  First, the PM core executes callbacks provided by PM domains,
+ * device types, classes and bus types.  They are the subsystem-level callbacks
+ * supposed to execute callbacks provided by device drivers, although they may
+ * choose not to do that.  If the driver callbacks are executed, they have to
+ * collaborate with the subsystem-level callbacks to achieve the goals
+ * appropriate for the given system transition, given transition phase and the
+ * subsystem the device belongs to.
+ *
+ * @prepare: The principal role of this callback is to prevent new children of
+ *     the device from being registered after it has returned (the driver's
+ *     subsystem and generally the rest of the kernel is supposed to prevent
+ *     new calls to the probe method from being made too once @prepare() has
+ *     succeeded).  If @prepare() detects a situation it cannot handle (e.g.
+ *     registration of a child already in progress), it may return -EAGAIN, so
+ *     that the PM core can execute it once again (e.g. after a new child has
+ *     been registered) to recover from the race condition.
+ *     This method is executed for all kinds of suspend transitions and is
+ *     followed by one of the suspend callbacks: @suspend(), @freeze(), or
+ *     @poweroff().  The PM core executes subsystem-level @prepare() for all
+ *     devices before starting to invoke suspend callbacks for any of them, so
+ *     generally devices may be assumed to be functional or to respond to
+ *     runtime resume requests while @prepare() is being executed.  However,
+ *     device drivers may NOT assume anything about the availability of user
+ *     space at that time and it is NOT valid to request firmware from within
+ *     @prepare() (it's too late to do that).  It also is NOT valid to allocate
+ *     substantial amounts of memory from @prepare() in the GFP_KERNEL mode.
+ *     [To work around these limitations, drivers may register suspend and
+ *     hibernation notifiers to be executed before the freezing of tasks.]
  *
  * @complete: Undo the changes made by @prepare().  This method is executed for
  *     all kinds of resume transitions, following one of the resume callbacks:
  *     @resume(), @thaw(), @restore().  Also called if the state transition
- *     fails before the driver's suspend callback (@suspend(), @freeze(),
- *     @poweroff()) can be executed (e.g. if the suspend callback fails for one
+ *     fails before the driver's suspend callback: @suspend(), @freeze() or
+ *     @poweroff(), can be executed (e.g. if the suspend callback fails for one
  *     of the other devices that the PM core has unsuccessfully attempted to
  *     suspend earlier).
- *     The PM core executes @complete() after it has executed the appropriate
- *     resume callback for all devices.
+ *     The PM core executes subsystem-level @complete() after it has executed
+ *     the appropriate resume callbacks for all devices.
  *
  * @suspend: Executed before putting the system into a sleep state in which the
- *     contents of main memory are preserved.  Quiesce the device, put it into
- *     a low power state appropriate for the upcoming system state (such as
- *     PCI_D3hot), and enable wakeup events as appropriate.
+ *     contents of main memory are preserved.  The exact action to perform
+ *     depends on the device's subsystem (PM domain, device type, class or bus
+ *     type), but generally the device must be quiescent after subsystem-level
+ *     @suspend() has returned, so that it doesn't do any I/O or DMA.
+ *     Subsystem-level @suspend() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @resume: Executed after waking the system up from a sleep state in which the
- *     contents of main memory were preserved.  Put the device into the
- *     appropriate state, according to the information saved in memory by the
- *     preceding @suspend().  The driver starts working again, responding to
- *     hardware events and software requests.  The hardware may have gone
- *     through a power-off reset, or it may have maintained state from the
- *     previous suspend() which the driver may rely on while resuming.  On most
- *     platforms, there are no restrictions on availability of resources like
- *     clocks during @resume().
+ *     contents of main memory were preserved.  The exact action to perform
+ *     depends on the device's subsystem, but generally the driver is expected
+ *     to start working again, responding to hardware events and software
+ *     requests (the device itself may be left in a low-power state, waiting
+ *     for a runtime resume to occur).  The state of the device at the time its
+ *     driver's @resume() callback is run depends on the platform and subsystem
+ *     the device belongs to.  On most platforms, there are no restrictions on
+ *     availability of resources like clocks during @resume().
+ *     Subsystem-level @resume() is executed for all devices after invoking
+ *     subsystem-level @resume_noirq() for all of them.
  *
  * @freeze: Hibernation-specific, executed before creating a hibernation image.
- *     Quiesce operations so that a consistent image can be created, but do NOT
- *     otherwise put the device into a low power device state and do NOT emit
- *     system wakeup events.  Save in main memory the device settings to be
- *     used by @restore() during the subsequent resume from hibernation or by
- *     the subsequent @thaw(), if the creation of the image or the restoration
- *     of main memory contents from it fails.
+ *     Analogous to @suspend(), but it should not enable the device to signal
+ *     wakeup events or change its power state.  The majority of subsystems
+ *     (with the notable exception of the PCI bus type) expect the driver-level
+ *     @freeze() to save the device settings in memory to be used by @restore()
+ *     during the subsequent resume from hibernation.
+ *     Subsystem-level @freeze() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @thaw: Hibernation-specific, executed after creating a hibernation image OR
- *     if the creation of the image fails.  Also executed after a failing
+ *     if the creation of an image has failed.  Also executed after a failing
  *     attempt to restore the contents of main memory from such an image.
  *     Undo the changes made by the preceding @freeze(), so the device can be
  *     operated in the same way as immediately before the call to @freeze().
+ *     Subsystem-level @thaw() is executed for all devices after invoking
+ *     subsystem-level @thaw_noirq() for all of them.  It also may be executed
+ *     directly after @freeze() in case of a transition error.
  *
  * @poweroff: Hibernation-specific, executed after saving a hibernation image.
- *     Quiesce the device, put it into a low power state appropriate for the
- *     upcoming system state (such as PCI_D3hot), and enable wakeup events as
- *     appropriate.
+ *     Analogous to @suspend(), but it need not save the device's settings in
+ *     memory.
+ *     Subsystem-level @poweroff() is executed for all devices after invoking
+ *     subsystem-level @prepare() for all of them.
  *
  * @restore: Hibernation-specific, executed after restoring the contents of main
- *     memory from a hibernation image.  Driver starts working again,
- *     responding to hardware events and software requests.  Drivers may NOT
- *     make ANY assumptions about the hardware state right prior to @restore().
- *     On most platforms, there are no restrictions on availability of
- *     resources like clocks during @restore().
- *
- * @suspend_noirq: Complete the operations of ->suspend() by carrying out any
- *     actions required for suspending the device that need interrupts to be
- *     disabled
- *
- * @resume_noirq: Prepare for the execution of ->resume() by carrying out any
- *     actions required for resuming the device that need interrupts to be
- *     disabled
- *
- * @freeze_noirq: Complete the operations of ->freeze() by carrying out any
- *     actions required for freezing the device that need interrupts to be
- *     disabled
- *
- * @thaw_noirq: Prepare for the execution of ->thaw() by carrying out any
- *     actions required for thawing the device that need interrupts to be
- *     disabled
- *
- * @poweroff_noirq: Complete the operations of ->poweroff() by carrying out any
- *     actions required for handling the device that need interrupts to be
- *     disabled
- *
- * @restore_noirq: Prepare for the execution of ->restore() by carrying out any
- *     actions required for restoring the operations of the device that need
- *     interrupts to be disabled
+ *     memory from a hibernation image, analogous to @resume().
+ *
+ * @suspend_noirq: Complete the actions started by @suspend().  Carry out any
+ *     additional operations required for suspending the device that might be
+ *     racing with its driver's interrupt handler, which is guaranteed not to
+ *     run while @suspend_noirq() is being executed.
+ *     It generally is expected that the device will be in a low-power state
+ *     (appropriate for the target system sleep state) after subsystem-level
+ *     @suspend_noirq() has returned successfully.  If the device can generate
+ *     system wakeup signals and is enabled to wake up the system, it should be
+ *     configured to do so at that time.  However, depending on the platform
+ *     and device's subsystem, @suspend() may be allowed to put the device into
+ *     the low-power state and configure it to generate wakeup signals, in
+ *     which case it generally is not necessary to define @suspend_noirq().
+ *
+ * @resume_noirq: Prepare for the execution of @resume() by carrying out any
+ *     operations required for resuming the device that might be racing with
+ *     its driver's interrupt handler, which is guaranteed not to run while
+ *     @resume_noirq() is being executed.
+ *
+ * @freeze_noirq: Complete the actions started by @freeze().  Carry out any
+ *     additional operations required for freezing the device that might be
+ *     racing with its driver's interrupt handler, which is guaranteed not to
+ *     run while @freeze_noirq() is being executed.
+ *     The power state of the device should not be changed by either @freeze()
+ *     or @freeze_noirq() and it should not be configured to signal system
+ *     wakeup by any of these callbacks.
+ *
+ * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
+ *     operations required for thawing the device that might be racing with its
+ *     driver's interrupt handler, which is guaranteed not to run while
+ *     @thaw_noirq() is being executed.
+ *
+ * @poweroff_noirq: Complete the actions started by @poweroff().  Analogous to
+ *     @suspend_noirq(), but it need not save the device's settings in memory.
+ *
+ * @restore_noirq: Prepare for the execution of @restore() by carrying out any
+ *     operations required for thawing the device that might be racing with its
+ *     driver's interrupt handler, which is guaranteed not to run while
+ *     @restore_noirq() is being executed.  Analogous to @resume_noirq().
  *
  * All of the above callbacks, except for @complete(), return error codes.
  * However, the error codes returned by the resume operations, @resume(),
- * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq() do
+ * @thaw(), @restore(), @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do
  * not cause the PM core to abort the resume transition during which they are
- * returned.  The error codes returned in that cases are only printed by the PM
+ * returned.  The error codes returned in those cases are only printed by the PM
  * core to the system logs for debugging purposes.  Still, it is recommended
  * that drivers only return error codes from their resume methods in case of an
  * unrecoverable failure (i.e. when the device being handled refuses to resume
@@ -174,31 +201,43 @@ typedef struct pm_message {
  * their children.
  *
  * It is allowed to unregister devices while the above callbacks are being
- * executed.  However, it is not allowed to unregister a device from within any
- * of its own callbacks.
+ * executed.  However, a callback routine must NOT try to unregister the device
+ * it was called for, although it may unregister children of that device (for
+ * example, if it detects that a child was unplugged while the system was
+ * asleep).
+ *
+ * Refer to Documentation/power/devices.txt for more information about the role
+ * of the above callbacks in the system suspend process.
  *
- * There also are the following callbacks related to run-time power management
- * of devices:
+ * There also are callbacks related to runtime power management of devices.
+ * Again, these callbacks are executed by the PM core only for subsystems
+ * (PM domains, device types, classes and bus types) and the subsystem-level
+ * callbacks are supposed to invoke the driver callbacks.  Moreover, the exact
+ * actions to be performed by a device driver's callbacks generally depend on
+ * the platform and subsystem the device belongs to.
  *
  * @runtime_suspend: Prepare the device for a condition in which it won't be
  *     able to communicate with the CPU(s) and RAM due to power management.
- *     This need not mean that the device should be put into a low power state.
+ *     This need not mean that the device should be put into a low-power state.
  *     For example, if the device is behind a link which is about to be turned
  *     off, the device may remain at full power.  If the device does go to low
- *     power and is capable of generating run-time wake-up events, remote
- *     wake-up (i.e., a hardware mechanism allowing the device to request a
- *     change of its power state via a wake-up event, such as PCI PME) should
- *     be enabled for it.
+ *     power and is capable of generating runtime wakeup events, remote wakeup
+ *     (i.e., a hardware mechanism allowing the device to request a change of
+ *     its power state via an interrupt) should be enabled for it.
  *
  * @runtime_resume: Put the device into the fully active state in response to a
- *     wake-up event generated by hardware or at the request of software.  If
- *     necessary, put the device into the full power state and restore its
+ *     wakeup event generated by hardware or at the request of software.  If
+ *     necessary, put the device into the full-power state and restore its
  *     registers, so that it is fully operational.
  *
- * @runtime_idle: Device appears to be inactive and it might be put into a low
- *     power state if all of the necessary conditions are satisfied.  Check
+ * @runtime_idle: Device appears to be inactive and it might be put into a
+ *     low-power state if all of the necessary conditions are satisfied.  Check
  *     these conditions and handle the device as appropriate, possibly queueing
  *     a suspend request for it.  The return value is ignored by the PM core.
+ *
+ * Refer to Documentation/power/runtime_pm.txt for more information about the
+ * role of the above callbacks in device runtime power management.
+ *
  */
 
 struct dev_pm_ops {
@@ -447,6 +486,7 @@ struct dev_pm_info {
        unsigned int            async_suspend:1;
        bool                    is_prepared:1;  /* Owned by the PM core */
        bool                    is_suspended:1; /* Ditto */
+       bool                    ignore_children:1;
        spinlock_t              lock;
 #ifdef CONFIG_PM_SLEEP
        struct list_head        entry;
@@ -464,7 +504,6 @@ struct dev_pm_info {
        atomic_t                usage_count;
        atomic_t                child_count;
        unsigned int            disable_depth:3;
-       unsigned int            ignore_children:1;
        unsigned int            idle_notification:1;
        unsigned int            request_pending:1;
        unsigned int            deferred_resume:1;
index 70b284024d9ea52abb5d54f178815c39369c13ed..d3085e72a0ee9b43bbd024bf33b93939e1535d42 100644 (file)
@@ -10,6 +10,7 @@
 #define _LINUX_PM_RUNTIME_H
 
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/pm.h>
 
 #include <linux/jiffies.h>
@@ -51,11 +52,6 @@ static inline bool pm_children_suspended(struct device *dev)
                || !atomic_read(&dev->power.child_count);
 }
 
-static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
-{
-       dev->power.ignore_children = enable;
-}
-
 static inline void pm_runtime_get_noresume(struct device *dev)
 {
        atomic_inc(&dev->power.usage_count);
@@ -129,7 +125,6 @@ static inline void pm_runtime_allow(struct device *dev) {}
 static inline void pm_runtime_forbid(struct device *dev) {}
 
 static inline bool pm_children_suspended(struct device *dev) { return false; }
-static inline void pm_suspend_ignore_children(struct device *dev, bool en) {}
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
 static inline bool device_run_wake(struct device *dev) { return false; }
index ea567321ae3c3b2ac02967680f99de1687f99982..2ca8cde5459d3445b2897c02d58ac2d12dba5bba 100644 (file)
@@ -35,10 +35,12 @@ struct pstore_info {
        spinlock_t      buf_lock;       /* serialize access to 'buf' */
        char            *buf;
        size_t          bufsize;
+       struct mutex    read_mutex;     /* serialize open/read/close */
        int             (*open)(struct pstore_info *psi);
        int             (*close)(struct pstore_info *psi);
        ssize_t         (*read)(u64 *id, enum pstore_type_id *type,
-                       struct timespec *time, struct pstore_info *psi);
+                       struct timespec *time, char **buf,
+                       struct pstore_info *psi);
        int             (*write)(enum pstore_type_id type, u64 *id,
                        unsigned int part, size_t size, struct pstore_info *psi);
        int             (*erase)(enum pstore_type_id type, u64 id,
index 3daac2d8dc37c427bd49d173fe1e0b2d645bed2b..690276a642cf75dd5dbfcd1d620b8a94880714fc 100644 (file)
@@ -15,8 +15,8 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
-#include <linux/module.h>
 
+struct module;
 struct i2c_client;
 struct spi_device;
 
index 12a1aa04b720cdb3491a2d35f32cb85a9bdcc6ff..52c89ae32f64c8829dd68162d65b3dc2ae135afd 100644 (file)
@@ -16,6 +16,7 @@
 #define __LINUX_REGULATOR_DRIVER_H_
 
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/regulator/consumer.h>
 
 struct regulator_dev;
index e8acce717d2abcc225461ad08a02ee7e3cb7a86a..1c4f3e9b9bc50e52ea57623f5b886691fb52db14 100644 (file)
@@ -1521,7 +1521,13 @@ struct task_struct {
 #ifdef CONFIG_FAULT_INJECTION
        int make_it_fail;
 #endif
-       struct prop_local_single dirties;
+       /*
+        * when (nr_dirtied >= nr_dirtied_pause), it's time to call
+        * balance_dirty_pages() for some dirty throttling pause
+        */
+       int nr_dirtied;
+       int nr_dirtied_pause;
+
 #ifdef CONFIG_LATENCYTOP
        int latency_record_count;
        struct latency_record latency_record[LT_SAVECOUNT];
index 97ff8e27a6cccfdc0678211db90b1fcde056f1da..3d86517fe7d5bf71f16efa468cec3fb9b4485c17 100644 (file)
@@ -207,13 +207,15 @@ struct serial_icounter_struct {
 
 struct serial_rs485 {
        __u32   flags;                  /* RS485 feature flags */
-#define SER_RS485_ENABLED              (1 << 0)
-#define SER_RS485_RTS_ON_SEND          (1 << 1)
-#define SER_RS485_RTS_AFTER_SEND       (1 << 2)
-#define SER_RS485_RTS_BEFORE_SEND      (1 << 3)
+#define SER_RS485_ENABLED              (1 << 0)        /* If enabled */
+#define SER_RS485_RTS_ON_SEND          (1 << 1)        /* Logical level for
+                                                          RTS pin when
+                                                          sending */
+#define SER_RS485_RTS_AFTER_SEND       (1 << 2)        /* Logical level for
+                                                          RTS pin after sent*/
 #define SER_RS485_RX_DURING_TX         (1 << 4)
-       __u32   delay_rts_before_send;  /* Milliseconds */
-       __u32   delay_rts_after_send;   /* Milliseconds */
+       __u32   delay_rts_before_send;  /* Delay before send (milliseconds) */
+       __u32   delay_rts_after_send;   /* Delay after send (milliseconds) */
        __u32   padding[5];             /* Memory is cheap, new structs
                                           are a royal PITA .. */
 };
index 0efa1f10bc2b35a844b2f3b62589b5269a30b889..369273a5267908791efc203537e0f349edaef0cf 100644 (file)
@@ -67,6 +67,7 @@ enum {
        SCIx_IRDA_REGTYPE,
        SCIx_SCIFA_REGTYPE,
        SCIx_SCIFB_REGTYPE,
+       SCIx_SH2_SCIF_FIFODATA_REGTYPE,
        SCIx_SH3_SCIF_REGTYPE,
        SCIx_SH4_SCIF_REGTYPE,
        SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
index be7dfb0f12d0d0fce28259782fd1a8c4cbe535a7..ca82861b0e461d6798e6a05a977352dca24335e5 100644 (file)
@@ -79,19 +79,21 @@ void serio_reconnect(struct serio *serio);
 irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags);
 
 void __serio_register_port(struct serio *serio, struct module *owner);
-static inline void serio_register_port(struct serio *serio)
-{
-       __serio_register_port(serio, THIS_MODULE);
-}
+
+/* use a define to avoid include chaining to get THIS_MODULE */
+#define serio_register_port(serio) \
+       __serio_register_port(serio, THIS_MODULE)
 
 void serio_unregister_port(struct serio *serio);
 void serio_unregister_child_port(struct serio *serio);
 
-int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name);
-static inline int __must_check serio_register_driver(struct serio_driver *drv)
-{
-       return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
-}
+int __must_check __serio_register_driver(struct serio_driver *drv,
+                               struct module *owner, const char *mod_name);
+
+/* use a define to avoid include chaining to get THIS_MODULE & friends */
+#define serio_register_driver(drv) \
+       __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME)
+
 void serio_unregister_driver(struct serio_driver *drv);
 
 static inline int serio_write(struct serio *serio, unsigned char data)
index 3ccf18648d0ae885d5421695b45b8b16b2856f61..a20831cf336a5ef5f6cc427b6b131766a34ca761 100644 (file)
@@ -52,7 +52,6 @@ struct clk {
 
        unsigned long           arch_flags;
        void                    *priv;
-       struct dentry           *dentry;
        struct clk_mapping      *mapping;
        struct cpufreq_frequency_table *freq_table;
        unsigned int            nr_freqs;
@@ -94,6 +93,9 @@ int clk_rate_table_find(struct clk *clk,
 long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
                              unsigned int div_max, unsigned long rate);
 
+long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
+                              unsigned int mult_max, unsigned long rate);
+
 long clk_round_parent(struct clk *clk, unsigned long target,
                      unsigned long *best_freq, unsigned long *parent_freq,
                      unsigned int div_min, unsigned int div_max);
index bc8c9208f7e21c455fcc4463601ec217de6ec4da..8446789216e568008fb71e9c85189758bf0197a4 100644 (file)
@@ -104,4 +104,80 @@ struct pinmux_info {
 int register_pinmux(struct pinmux_info *pip);
 int unregister_pinmux(struct pinmux_info *pip);
 
+/* helper macro for port */
+#define PORT_1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define PORT_10(fn, pfx, sfx) \
+       PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx),       \
+       PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx),       \
+       PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx),       \
+       PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx),       \
+       PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx)
+
+#define PORT_90(fn, pfx, sfx) \
+       PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx),     \
+       PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx),     \
+       PORT_10(fn, pfx##5, sfx), PORT_10(fn, pfx##6, sfx),     \
+       PORT_10(fn, pfx##7, sfx), PORT_10(fn, pfx##8, sfx),     \
+       PORT_10(fn, pfx##9, sfx)
+
+#define _PORT_ALL(pfx, sfx) pfx##_##sfx
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define PORT_ALL(str)  CPU_ALL_PORT(_PORT_ALL, PORT, str)
+#define GPIO_PORT_ALL()        CPU_ALL_PORT(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+/* helper macro for pinmux_enum_t */
+#define PORT_DATA_I(nr)        \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr)     \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
+                   PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr)     \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,    \
+                   PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr)  \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,                    \
+                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr)                \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr)       \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,    \
+                   PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr)    \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,    \
+                   PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr)    \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,    \
+                   PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+       PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,    \
+                   PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+/* helper macro for top 4 bits in PORTnCR */
+#define _PCRH(in, in_pd, in_pu, out)   \
+       0, (out), (in), 0,              \
+       0, 0, 0, 0,                     \
+       0, 0, (in_pd), 0,               \
+       0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg)                                                        \
+       {                                                               \
+               PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {             \
+                       _PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,          \
+                             PORT##nr##_IN_PU, PORT##nr##_OUT),        \
+                               PORT##nr##_FN0, PORT##nr##_FN1,         \
+                               PORT##nr##_FN2, PORT##nr##_FN3,         \
+                               PORT##nr##_FN4, PORT##nr##_FN5,         \
+                               PORT##nr##_FN6, PORT##nr##_FN7 }        \
+       }
+
 #endif /* __SH_PFC_H */
index a83833a1f7a26f589a7584252ff413333286f5ea..07ceb97d53facc505bae4b489d3cae96bd7d4021 100644 (file)
@@ -35,7 +35,7 @@ struct shrinker {
 
        /* These are for internal use */
        struct list_head list;
-       long nr;        /* objs pending delete */
+       atomic_long_t nr_in_batch; /* objs pending delete */
 };
 #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */
 extern void register_shrinker(struct shrinker *);
index e2accb3164d8d969245e4567b0f308d4a35cb152..d0de882c0d96d5277f23306bf1d2884c40807292 100644 (file)
@@ -24,7 +24,7 @@ struct sigma_firmware {
 struct sigma_firmware_header {
        unsigned char magic[7];
        u8 version;
-       u32 crc;
+       __le32 crc;
 };
 
 enum {
@@ -40,19 +40,14 @@ enum {
 struct sigma_action {
        u8 instr;
        u8 len_hi;
-       u16 len;
-       u16 addr;
+       __le16 len;
+       __be16 addr;
        unsigned char payload[];
 };
 
 static inline u32 sigma_action_len(struct sigma_action *sa)
 {
-       return (sa->len_hi << 16) | sa->len;
-}
-
-static inline size_t sigma_action_size(struct sigma_action *sa, u32 payload_len)
-{
-       return sizeof(*sa) + payload_len + (payload_len % 2);
+       return (sa->len_hi << 16) | le16_to_cpu(sa->len);
 }
 
 extern int process_sigma_firmware(struct i2c_client *client, const char *name);
index f10ed7b4a714b99abac271bbd09a2ec483cf6246..061e560251b4d24a3177ace483b6d9e24e5a8411 100644 (file)
@@ -231,10 +231,9 @@ struct ssb_driver {
 #define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
 
 extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
-static inline int ssb_driver_register(struct ssb_driver *drv)
-{
-       return __ssb_driver_register(drv, THIS_MODULE);
-}
+#define ssb_driver_register(drv) \
+       __ssb_driver_register(drv, THIS_MODULE)
+
 extern void ssb_driver_unregister(struct ssb_driver *drv);
 
 
index 2d04ea91676037e2c71bc8e1ff103253157888cd..c170edc3bf5f62d0c1cca31ae332c0a29c24389f 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/smp.h>
 #include <linux/list.h>
 #include <asm/system.h>
 
index 7ad9751a0d8796e677fb2fdfd50cc4854bcf0eb7..8620f79658d42e593e313124b189d22c1cde7a42 100644 (file)
@@ -8,7 +8,8 @@
 #define SUNRPC_SVC_XPRT_H
 
 #include <linux/sunrpc/svc.h>
-#include <linux/module.h>
+
+struct module;
 
 struct svc_xprt_ops {
        struct svc_xprt *(*xpo_create)(struct svc_serv *,
index d35e783a598c39065f66aae6d7497c7107a0a75e..20f63d3e6144654f0124170827eab474a1b41faa 100644 (file)
@@ -22,7 +22,6 @@
 #define _SYSDEV_H_
 
 #include <linux/kobject.h>
-#include <linux/module.h>
 #include <linux/pm.h>
 
 
index d9a85d616385d3791c198fbd223a9b7cf222c30d..cfaee869146f6ec6f877681f9b041171ef238806 100644 (file)
@@ -4,10 +4,11 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
+struct module;
+
 struct ts_config;
 
 #define TS_AUTOLOAD    1 /* Automatically load textsearch modules when needed */
index fc839bfa7935aff66380a22e9b95589127ec66d2..e26db031303b69cee9954780f3ce3f8d276d8644 100644 (file)
@@ -201,6 +201,10 @@ int arch_update_cpu_topology(void);
        .balance_interval       = 64,                                   \
 }
 
+#ifndef SD_NODES_PER_DOMAIN
+#define SD_NODES_PER_DOMAIN 16
+#endif
+
 #ifdef CONFIG_SCHED_BOOK
 #ifndef SD_BOOK_INIT
 #error Please define an appropriate SD_BOOK_INIT in include/asm/topology.h!!!
index fd99ff9298c68519fca3dd3ff12b6e1f8d51f567..1ad4724458de0127424795eede13c63ef344476f 100644 (file)
 #ifndef _UIO_DRIVER_H_
 #define _UIO_DRIVER_H_
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 
+struct module;
 struct uio_map;
 
 /**
@@ -101,11 +101,11 @@ extern int __must_check
        __uio_register_device(struct module *owner,
                              struct device *parent,
                              struct uio_info *info);
-static inline int __must_check
-       uio_register_device(struct device *parent, struct uio_info *info)
-{
-       return __uio_register_device(THIS_MODULE, parent, info);
-}
+
+/* use a define to avoid include chaining to get THIS_MODULE */
+#define uio_register_device(parent, info) \
+       __uio_register_device(THIS_MODULE, parent, info)
+
 extern void uio_unregister_device(struct uio_info *info);
 extern void uio_event_notify(struct uio_info *info);
 
index 6f49a1b39fa64e3a8224ca1b9312ad7f63aebf54..d3d0c1374334d58c684e5f1b4d13422aa8f57ae8 100644 (file)
@@ -946,10 +946,11 @@ struct usb_class_driver {
  */
 extern int usb_register_driver(struct usb_driver *, struct module *,
                               const char *);
-static inline int usb_register(struct usb_driver *driver)
-{
-       return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
-}
+
+/* use a define to avoid include chaining to get THIS_MODULE & friends */
+#define usb_register(driver) \
+       usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
+
 extern void usb_deregister(struct usb_driver *);
 
 extern int usb_register_device_driver(struct usb_device_driver *,
index b0c564ec21603de31bf196299cc7f972ff244e84..7dbbee9741b78ba0d3adac99aeb084767a149ec0 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 #include <linux/uwb/spec.h>
+#include <asm/page.h>
 
 struct uwb_dev;
 struct uwb_beca_e;
index 7b4842028ca73420dde81dae18bf3ff50bbc409f..891d1d5f394768e69883849e63928104dd2fb6b2 100644 (file)
@@ -111,10 +111,9 @@ int __must_check __umc_driver_register(struct umc_driver *umc_drv,
  * umc_driver_register - register a UMC capabiltity driver.
  * @umc_drv:  pointer to the driver.
  */
-static inline int __must_check umc_driver_register(struct umc_driver *umc_drv)
-{
-       return __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME);
-}
+#define umc_driver_register(umc_drv) \
+       __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME)
+
 void umc_driver_unregister(struct umc_driver *umc_drv);
 
 /*
index cf97b5b9d1fe8928bca85db1e5ae888681a39519..6f8fbcf10dfb8ac6dd3ead787c5e4cf27e142c42 100644 (file)
@@ -1,5 +1,4 @@
 #include <generated/utsrelease.h>
-#include <linux/module.h>
 
 /* Simply sanity version stamp for modules. */
 #ifdef CONFIG_SMP
index add4790b21fe4ee18635db9456a43db71bb39997..e9e72bda1b72b89b8f4354b507f7b392291ec0ec 100644 (file)
@@ -85,6 +85,8 @@
  * @reset: reset the device
  *     vdev: the virtio device
  *     After this, status and feature negotiation must be done again
+ *     Device must not be reset from its vq/config callbacks, or in
+ *     parallel with being added/removed.
  * @find_vqs: find virtqueues and instantiate them.
  *     vdev: the virtio_device
  *     nvqs: the number of virtqueues to find
index 27c7edefbc86ea6cad445f3503de9970b1088bf7..5c7b6f0daef8f1f228c6daed124e589acdfdb649 100644 (file)
@@ -63,7 +63,7 @@
 #define VIRTIO_MMIO_GUEST_FEATURES     0x020
 
 /* Activated features set selector - Write Only */
-#define VIRTIO_MMIO_GUEST_FEATURES_SET 0x024
+#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024
 
 /* Guest's memory page size in bytes - Write Only */
 #define VIRTIO_MMIO_GUEST_PAGE_SIZE    0x028
index 8f6a95882b093f1e792b59db7ec164de626a2fe3..017d4a53d55ef9c7158c5cdaa6c199f4136b3975 100644 (file)
 #define __VLYNQ_H__
 
 #include <linux/device.h>
-#include <linux/module.h>
 #include <linux/types.h>
 
+struct module;
+
 #define VLYNQ_NUM_IRQS 32
 
 struct vlynq_mapping {
index 687fb11e20107d9c22467e1923d5e736bde16d3e..4bde182fcf93f23bb8f1b8b68d2a087ba20ae2c3 100644 (file)
@@ -119,7 +119,7 @@ unmap_kernel_range(unsigned long addr, unsigned long size)
 #endif
 
 /* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size);
+extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
 extern void free_vm_area(struct vm_struct *area);
 
 /* for /dev/kmem */
index 2b8963ff0f359b4c6dab919e2ccc3c2c0324b5bb..a378c295851f8cf9fe4d804080b30f72cf5101cd 100644 (file)
@@ -38,6 +38,23 @@ enum writeback_sync_modes {
        WB_SYNC_ALL,    /* Wait on every mapping */
 };
 
+/*
+ * why some writeback work was initiated
+ */
+enum wb_reason {
+       WB_REASON_BACKGROUND,
+       WB_REASON_TRY_TO_FREE_PAGES,
+       WB_REASON_SYNC,
+       WB_REASON_PERIODIC,
+       WB_REASON_LAPTOP_TIMER,
+       WB_REASON_FREE_MORE_MEM,
+       WB_REASON_FS_FREE_SPACE,
+       WB_REASON_FORKER_THREAD,
+
+       WB_REASON_MAX,
+};
+extern const char *wb_reason_name[];
+
 /*
  * A control structure which tells the writeback code what to do.  These are
  * always on the stack, and hence need no locking.  They are always initialised
@@ -69,14 +86,17 @@ struct writeback_control {
  */    
 struct bdi_writeback;
 int inode_wait(void *);
-void writeback_inodes_sb(struct super_block *);
-void writeback_inodes_sb_nr(struct super_block *, unsigned long nr);
-int writeback_inodes_sb_if_idle(struct super_block *);
-int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr);
+void writeback_inodes_sb(struct super_block *, enum wb_reason reason);
+void writeback_inodes_sb_nr(struct super_block *, unsigned long nr,
+                                                       enum wb_reason reason);
+int writeback_inodes_sb_if_idle(struct super_block *, enum wb_reason reason);
+int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr,
+                                                       enum wb_reason reason);
 void sync_inodes_sb(struct super_block *);
-long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages);
+long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
+                               enum wb_reason reason);
 long wb_do_writeback(struct bdi_writeback *wb, int force_wait);
-void wakeup_flusher_threads(long nr_pages);
+void wakeup_flusher_threads(long nr_pages, enum wb_reason reason);
 
 /* writeback.h requires fs.h; it, too, is not included from here. */
 static inline void wait_on_inode(struct inode *inode)
@@ -143,6 +163,7 @@ unsigned long bdi_dirty_limit(struct backing_dev_info *bdi,
 
 void __bdi_update_bandwidth(struct backing_dev_info *bdi,
                            unsigned long thresh,
+                           unsigned long bg_thresh,
                            unsigned long dirty,
                            unsigned long bdi_thresh,
                            unsigned long bdi_dirty,
index 5017500eda1bfc42e83a77b1d2088899acc60c6c..0f037e8edf9a6a59d1995a50da1148255f51c863 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __SAA7146__
 #define __SAA7146__
 
-#include <linux/module.h>      /* for module-version */
 #include <linux/delay.h>       /* for delay-stuff */
 #include <linux/slab.h>                /* for kmalloc/kfree */
 #include <linux/pci.h>         /* for pci-config-stuff, vendor ids etc. */
@@ -55,6 +54,8 @@ do {                                                                  \
 #define SAA7146_ISR_CLEAR(x,y) \
        saa7146_write(x, ISR, (y));
 
+struct module;
+
 struct saa7146_dev;
 struct saa7146_extension;
 struct saa7146_vv;
index fbf585561570bc7fbc43859fd9aa70a4bfdc68f6..e6aa2318367baa39bff7c260b828cfab15c4d8ac 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef V4L2_INT_DEVICE_H
 #define V4L2_INT_DEVICE_H
 
-#include <linux/module.h>
 #include <media/v4l2-common.h>
 
 #define V4L2NAMESIZE 32
@@ -41,6 +40,8 @@ enum v4l2_int_type {
        v4l2_int_type_slave
 };
 
+struct module;
+
 struct v4l2_int_device;
 
 struct v4l2_int_master {
index 2f7d45bcbd243c1b13e726c726dd887ba0c787d2..1a7e1d20adf9ee657044935a5bfc43874d585bb7 100644 (file)
@@ -45,6 +45,51 @@ struct mtd_oob_buf64 {
        __u64 usr_ptr;
 };
 
+/**
+ * MTD operation modes
+ *
+ * @MTD_OPS_PLACE_OOB: OOB data are placed at the given offset (default)
+ * @MTD_OPS_AUTO_OOB:  OOB data are automatically placed at the free areas
+ *                     which are defined by the internal ecclayout
+ * @MTD_OPS_RAW:       data are transferred as-is, with no error correction;
+ *                     this mode implies %MTD_OPS_PLACE_OOB
+ *
+ * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
+ * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
+ * %MTD_FILE_MODE_RAW.
+ */
+enum {
+       MTD_OPS_PLACE_OOB = 0,
+       MTD_OPS_AUTO_OOB = 1,
+       MTD_OPS_RAW = 2,
+};
+
+/**
+ * struct mtd_write_req - data structure for requesting a write operation
+ *
+ * @start:     start address
+ * @len:       length of data buffer
+ * @ooblen:    length of OOB buffer
+ * @usr_data:  user-provided data buffer
+ * @usr_oob:   user-provided OOB buffer
+ * @mode:      MTD mode (see "MTD operation modes")
+ * @padding:   reserved, must be set to 0
+ *
+ * This structure supports ioctl(MEMWRITE) operations, allowing data and/or OOB
+ * writes in various modes. To write to OOB-only, set @usr_data == NULL, and to
+ * write data-only, set @usr_oob == NULL. However, setting both @usr_data and
+ * @usr_oob to NULL is not allowed.
+ */
+struct mtd_write_req {
+       __u64 start;
+       __u64 len;
+       __u64 ooblen;
+       __u64 usr_data;
+       __u64 usr_oob;
+       __u8 mode;
+       __u8 padding[7];
+};
+
 #define MTD_ABSENT             0
 #define MTD_RAM                        1
 #define MTD_ROM                        2
@@ -59,13 +104,13 @@ struct mtd_oob_buf64 {
 #define MTD_NO_ERASE           0x1000  /* No erase necessary */
 #define MTD_POWERUP_LOCK       0x2000  /* Always locked after reset */
 
-// Some common devices / combinations of capabilities
+/* Some common devices / combinations of capabilities */
 #define MTD_CAP_ROM            0
 #define MTD_CAP_RAM            (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 #define MTD_CAP_NORFLASH       (MTD_WRITEABLE | MTD_BIT_WRITEABLE)
 #define MTD_CAP_NANDFLASH      (MTD_WRITEABLE)
 
-/* ECC byte placement */
+/* Obsolete ECC byte placement modes (used with obsolete MEMGETOOBSEL) */
 #define MTD_NANDECC_OFF                0       // Switch off ECC (Not recommended)
 #define MTD_NANDECC_PLACE      1       // Use the given placement in the structure (YAFFS1 legacy mode)
 #define MTD_NANDECC_AUTOPLACE  2       // Use the default placement scheme
@@ -80,21 +125,18 @@ struct mtd_oob_buf64 {
 struct mtd_info_user {
        __u8 type;
        __u32 flags;
-       __u32 size;      // Total size of the MTD
+       __u32 size;     /* Total size of the MTD */
        __u32 erasesize;
        __u32 writesize;
-       __u32 oobsize;   // Amount of OOB data per block (e.g. 16)
-       /* The below two fields are obsolete and broken, do not use them
-        * (TODO: remove at some point) */
-       __u32 ecctype;
-       __u32 eccsize;
+       __u32 oobsize;  /* Amount of OOB data per block (e.g. 16) */
+       __u64 padding;  /* Old obsolete field; do not use */
 };
 
 struct region_info_user {
        __u32 offset;           /* At which this region starts,
-                                        * from the beginning of the MTD */
-       __u32 erasesize;                /* For this region */
-       __u32 numblocks;                /* Number of blocks in this region */
+                                * from the beginning of the MTD */
+       __u32 erasesize;        /* For this region */
+       __u32 numblocks;        /* Number of blocks in this region */
        __u32 regionindex;
 };
 
@@ -104,29 +146,61 @@ struct otp_info {
        __u32 locked;
 };
 
+/*
+ * Note, the following ioctl existed in the past and was removed:
+ * #define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
+ * Try to avoid adding a new ioctl with the same ioctl number.
+ */
+
+/* Get basic MTD characteristics info (better to use sysfs) */
 #define MEMGETINFO             _IOR('M', 1, struct mtd_info_user)
+/* Erase segment of MTD */
 #define MEMERASE               _IOW('M', 2, struct erase_info_user)
+/* Write out-of-band data from MTD */
 #define MEMWRITEOOB            _IOWR('M', 3, struct mtd_oob_buf)
+/* Read out-of-band data from MTD */
 #define MEMREADOOB             _IOWR('M', 4, struct mtd_oob_buf)
+/* Lock a chip (for MTD that supports it) */
 #define MEMLOCK                        _IOW('M', 5, struct erase_info_user)
+/* Unlock a chip (for MTD that supports it) */
 #define MEMUNLOCK              _IOW('M', 6, struct erase_info_user)
+/* Get the number of different erase regions */
 #define MEMGETREGIONCOUNT      _IOR('M', 7, int)
+/* Get information about the erase region for a specific index */
 #define MEMGETREGIONINFO       _IOWR('M', 8, struct region_info_user)
-#define MEMSETOOBSEL           _IOW('M', 9, struct nand_oobinfo)
+/* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */
 #define MEMGETOOBSEL           _IOR('M', 10, struct nand_oobinfo)
+/* Check if an eraseblock is bad */
 #define MEMGETBADBLOCK         _IOW('M', 11, __kernel_loff_t)
+/* Mark an eraseblock as bad */
 #define MEMSETBADBLOCK         _IOW('M', 12, __kernel_loff_t)
+/* Set OTP (One-Time Programmable) mode (factory vs. user) */
 #define OTPSELECT              _IOR('M', 13, int)
+/* Get number of OTP (One-Time Programmable) regions */
 #define OTPGETREGIONCOUNT      _IOW('M', 14, int)
+/* Get all OTP (One-Time Programmable) info about MTD */
 #define OTPGETREGIONINFO       _IOW('M', 15, struct otp_info)
+/* Lock a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
 #define OTPLOCK                        _IOR('M', 16, struct otp_info)
+/* Get ECC layout (deprecated) */
 #define ECCGETLAYOUT           _IOR('M', 17, struct nand_ecclayout_user)
+/* Get statistics about corrected/uncorrected errors */
 #define ECCGETSTATS            _IOR('M', 18, struct mtd_ecc_stats)
+/* Set MTD mode on a per-file-descriptor basis (see "MTD file modes") */
 #define MTDFILEMODE            _IO('M', 19)
+/* Erase segment of MTD (supports 64-bit address) */
 #define MEMERASE64             _IOW('M', 20, struct erase_info_user64)
+/* Write data to OOB (64-bit version) */
 #define MEMWRITEOOB64          _IOWR('M', 21, struct mtd_oob_buf64)
+/* Read data from OOB (64-bit version) */
 #define MEMREADOOB64           _IOWR('M', 22, struct mtd_oob_buf64)
+/* Check if chip is locked (for MTD that supports it) */
 #define MEMISLOCKED            _IOR('M', 23, struct erase_info_user)
+/*
+ * Most generic write interface; can write in-band and/or out-of-band in various
+ * modes (see "struct mtd_write_req")
+ */
+#define MEMWRITE               _IOWR('M', 24, struct mtd_write_req)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
@@ -177,13 +251,27 @@ struct mtd_ecc_stats {
 };
 
 /*
- * Read/write file modes for access to MTD
+ * MTD file modes - for read/write access to MTD
+ *
+ * @MTD_FILE_MODE_NORMAL:      OTP disabled, ECC enabled
+ * @MTD_FILE_MODE_OTP_FACTORY: OTP enabled in factory mode
+ * @MTD_FILE_MODE_OTP_USER:    OTP enabled in user mode
+ * @MTD_FILE_MODE_RAW:         OTP disabled, ECC disabled
+ *
+ * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained
+ * separately for each open file descriptor.
+ *
+ * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW -
+ * raw access to the flash, without error correction or autoplacement schemes.
+ * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode
+ * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is
+ * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).
  */
 enum mtd_file_modes {
-       MTD_MODE_NORMAL = MTD_OTP_OFF,
-       MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY,
-       MTD_MODE_OTP_USER = MTD_OTP_USER,
-       MTD_MODE_RAW,
+       MTD_FILE_MODE_NORMAL = MTD_OTP_OFF,
+       MTD_FILE_MODE_OTP_FACTORY = MTD_OTP_FACTORY,
+       MTD_FILE_MODE_OTP_USER = MTD_OTP_USER,
+       MTD_FILE_MODE_RAW,
 };
 
 #endif /* __MTD_ABI_H__ */
index 5b924423cf205ad9e927c7de4045e86160f1a082..3779ea3622576e9746dc72ebac57780c0f377e11 100644 (file)
@@ -513,11 +513,15 @@ static inline void __hci_dev_put(struct hci_dev *d)
                d->destruct(d);
 }
 
-static inline void hci_dev_put(struct hci_dev *d)
-{
-       __hci_dev_put(d);
-       module_put(d->owner);
-}
+/*
+ * hci_dev_put and hci_dev_hold are macros to avoid dragging all the
+ * overhead of all the modular infrastructure into this header.
+ */
+#define hci_dev_put(d)         \
+do {                           \
+       __hci_dev_put(d);       \
+       module_put(d->owner);   \
+} while (0)
 
 static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
 {
@@ -525,12 +529,10 @@ static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
        return d;
 }
 
-static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
-{
-       if (try_module_get(d->owner))
-               return __hci_dev_hold(d);
-       return NULL;
-}
+#define hci_dev_hold(d)                                                \
+({                                                             \
+       try_module_get(d->owner) ? __hci_dev_hold(d) : NULL;    \
+})
 
 #define hci_dev_lock(d)                spin_lock(&d->lock)
 #define hci_dev_unlock(d)      spin_unlock(&d->lock)
index ab90ae0970a69b2f3646c712aac0b56e2332509e..6cc18f37167519260e15d1ad20d7bf2f145c86c5 100644 (file)
 #define L2CAP_DEFAULT_ACK_TO           200
 #define L2CAP_LE_DEFAULT_MTU           23
 
-#define L2CAP_CONN_TIMEOUT     (40000) /* 40 seconds */
-#define L2CAP_INFO_TIMEOUT     (4000)  /*  4 seconds */
+#define L2CAP_DISC_TIMEOUT             (100)
+#define L2CAP_DISC_REJ_TIMEOUT         (5000)  /*  5 seconds */
+#define L2CAP_ENC_TIMEOUT              (5000)  /*  5 seconds */
+#define L2CAP_CONN_TIMEOUT             (40000) /* 40 seconds */
+#define L2CAP_INFO_TIMEOUT             (4000)  /*  4 seconds */
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
index d5eee2093b1eed75575764d9848655ee90825b80..e2e3ecad100830a6cb42765c65ca804304eb5fca 100644 (file)
@@ -211,6 +211,7 @@ struct rfcomm_dlc {
 #define RFCOMM_AUTH_ACCEPT  6
 #define RFCOMM_AUTH_REJECT  7
 #define RFCOMM_DEFER_SETUP  8
+#define RFCOMM_ENC_DROP     9
 
 /* Scheduling flags and events */
 #define RFCOMM_SCHED_WAKEUP 31
index 92cf1c2c30c9f0a94d193753a037cb851f8a60cd..95852e36713b5e302e365033957d16910de01952 100644 (file)
@@ -456,6 +456,9 @@ enum station_parameters_apply_mask {
  *     as the AC bitmap in the QoS info field
  * @max_sp: max Service Period. same format as the MAX_SP in the
  *     QoS info field (but already shifted down)
+ * @sta_modify_mask: bitmap indicating which parameters changed
+ *     (for those that don't have a natural "no change" value),
+ *     see &enum station_parameters_apply_mask
  */
 struct station_parameters {
        u8 *supported_rates;
@@ -615,6 +618,7 @@ struct sta_bss_parameters {
  *     user space MLME/SME implementation. The information is provided for
  *     the cfg80211_new_sta() calls to notify user space of the IEs.
  * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets.
+ * @sta_flags: station flags mask & values
  */
 struct station_info {
        u32 filled;
index 4fb6c43817918992f8334c49022d5184ea45c8e4..6faec1a6021629d73896fb425b49f7820720c151 100644 (file)
@@ -205,12 +205,7 @@ dst_feature(const struct dst_entry *dst, u32 feature)
 
 static inline u32 dst_mtu(const struct dst_entry *dst)
 {
-       u32 mtu = dst_metric_raw(dst, RTAX_MTU);
-
-       if (!mtu)
-               mtu = dst->ops->default_mtu(dst);
-
-       return mtu;
+       return dst->ops->mtu(dst);
 }
 
 /* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
index 9adb99845a5695b8159cc6c208bc6004ebf7b25c..e1c2ee0eef47506020f743230e923d840e64e7a9 100644 (file)
@@ -17,7 +17,7 @@ struct dst_ops {
        int                     (*gc)(struct dst_ops *ops);
        struct dst_entry *      (*check)(struct dst_entry *, __u32 cookie);
        unsigned int            (*default_advmss)(const struct dst_entry *);
-       unsigned int            (*default_mtu)(const struct dst_entry *);
+       unsigned int            (*mtu)(const struct dst_entry *);
        u32 *                   (*cow_metrics)(struct dst_entry *, unsigned long);
        void                    (*destroy)(struct dst_entry *);
        void                    (*ifdown)(struct dst_entry *,
index b897d6e6d0a5a35f6a19b5403bbd7b5cefa47a39..f941964a9931978002b7ab4a137408b0d69c09d9 100644 (file)
@@ -31,6 +31,7 @@
 /** struct ip_options - IP Options
  *
  * @faddr - Saved first hop address
+ * @nexthop - Saved nexthop address in LSRR and SSRR
  * @is_data - Options in __data, rather than skb
  * @is_strictroute - Strict source route
  * @srr_is_hit - Packet destination addr was our one
@@ -41,6 +42,7 @@
  */
 struct ip_options {
        __be32          faddr;
+       __be32          nexthop;
        unsigned char   optlen;
        unsigned char   srr;
        unsigned char   rr;
index f91a1fb5da7ce470f44409af0cfb8fcae51fabf3..e8c25b98120523711f115867b247995e1db80a57 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/kmemcheck.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
index 78c83e62218fbfff60506e4323f72343aed2b83a..e9ff3fc5e688615b6b4df99b0aef82af0621ab57 100644 (file)
@@ -35,6 +35,7 @@ struct inet_peer {
 
        u32                     metrics[RTAX_MAX];
        u32                     rate_tokens;    /* rate limiting for ICMP */
+       int                     redirect_genid;
        unsigned long           rate_last;
        unsigned long           pmtu_expires;
        u32                     pmtu_orig;
index 05b08c926aded3927f5532a63f6d5a78ee058f2c..873d5be7926c1bef17c83ea7c79eecafede9149e 100644 (file)
@@ -1126,17 +1126,16 @@ int unregister_ip_vs_pe(struct ip_vs_pe *pe);
 struct ip_vs_pe *ip_vs_pe_getbyname(const char *name);
 struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name);
 
-static inline void ip_vs_pe_get(const struct ip_vs_pe *pe)
-{
-       if (pe && pe->module)
+/*
+ * Use a #define to avoid all of module.h just for these trivial ops
+ */
+#define ip_vs_pe_get(pe)                       \
+       if (pe && pe->module)                   \
                __module_get(pe->module);
-}
 
-static inline void ip_vs_pe_put(const struct ip_vs_pe *pe)
-{
-       if (pe && pe->module)
+#define ip_vs_pe_put(pe)                       \
+       if (pe && pe->module)                   \
                module_put(pe->module);
-}
 
 /*
  *     IPVS protocol functions (from ip_vs_proto.c)
index 2ec896bb72b21787962fb1546b4565b930e503da..d178c26a55588743dbfa9509d1712935b70e3f9b 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/atomic.h>
 #include <linux/if.h>
 #include <linux/skbuff.h>
@@ -42,6 +41,8 @@ enum {
        IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
 };
 
+struct module;
+
 struct lib80211_crypto_ops {
        const char *name;
        struct list_head list;
index dc1123aa8181d08a9b91bf2fe3281577088e56d1..72eddd1b410b9c8418216c17d74910585fdec975 100644 (file)
@@ -3567,8 +3567,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
                        return i;
 
        /* warn when we cannot find a rate. */
-       WARN_ON(1);
+       WARN_ON_ONCE(1);
 
+       /* and return 0 (the lowest index) */
        return 0;
 }
 
index 0b7f05e4a927270630404bccf71e39f492f27230..8a2b0ae7dbd2bc1aa0a4a71b25a13bee1f8e4235 100644 (file)
@@ -313,6 +313,8 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
        return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
 }
 
+struct kernel_param;
+
 extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
 extern unsigned int nf_conntrack_htable_size;
 extern unsigned int nf_conntrack_max;
index 4283508b3e185882bff18fe267f205df4eda39cc..a88fb6939387f228ac5826949f68151e0fceaf16 100644 (file)
@@ -67,18 +67,18 @@ struct nf_ct_event_notifier {
        int (*fcn)(unsigned int events, struct nf_ct_event *item);
 };
 
-extern struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
-extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
-extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
+extern int nf_conntrack_register_notifier(struct net *net, struct nf_ct_event_notifier *nb);
+extern void nf_conntrack_unregister_notifier(struct net *net, struct nf_ct_event_notifier *nb);
 
 extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
 
 static inline void
 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 {
+       struct net *net = nf_ct_net(ct);
        struct nf_conntrack_ecache *e;
 
-       if (nf_conntrack_event_cb == NULL)
+       if (net->ct.nf_conntrack_event_cb == NULL)
                return;
 
        e = nf_ct_ecache_find(ct);
@@ -95,11 +95,12 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
                              int report)
 {
        int ret = 0;
+       struct net *net = nf_ct_net(ct);
        struct nf_ct_event_notifier *notify;
        struct nf_conntrack_ecache *e;
 
        rcu_read_lock();
-       notify = rcu_dereference(nf_conntrack_event_cb);
+       notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
        if (notify == NULL)
                goto out_unlock;
 
@@ -164,9 +165,8 @@ struct nf_exp_event_notifier {
        int (*fcn)(unsigned int events, struct nf_exp_event *item);
 };
 
-extern struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
-extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
-extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);
+extern int nf_ct_expect_register_notifier(struct net *net, struct nf_exp_event_notifier *nb);
+extern void nf_ct_expect_unregister_notifier(struct net *net, struct nf_exp_event_notifier *nb);
 
 static inline void
 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
@@ -174,11 +174,12 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
                          u32 pid,
                          int report)
 {
+       struct net *net = nf_ct_exp_net(exp);
        struct nf_exp_event_notifier *notify;
        struct nf_conntrack_ecache *e;
 
        rcu_read_lock();
-       notify = rcu_dereference(nf_expect_event_cb);
+       notify = rcu_dereference(net->ct.nf_expect_event_cb);
        if (notify == NULL)
                goto out_unlock;
 
index 98c185441bee0c2bf8b36caeb5637b13878cfaff..cb1f3504687fb74df065191ce65add598f063dac 100644 (file)
@@ -192,8 +192,15 @@ enum {
  *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
  *    NLA_FLAG             Unused
  *    NLA_BINARY           Maximum length of attribute payload
- *    NLA_NESTED_COMPAT    Exact length of structure payload
- *    All other            Exact length of attribute payload
+ *    NLA_NESTED           Don't use `len' field -- length verification is
+ *                         done by checking len of nested header (or empty)
+ *    NLA_NESTED_COMPAT    Minimum length of structure payload
+ *    NLA_U8, NLA_U16,
+ *    NLA_U32, NLA_U64,
+ *    NLA_MSECS            Leaving the length field zero will verify the
+ *                         given type fits, using it verifies minimum length
+ *                         just like "All other"
+ *    All other            Minimum length of attribute payload
  *
  * Example:
  * static const struct nla_policy my_policy[ATTR_MAX+1] = {
index 0249399e51a773608814e6cabaeb36915d7c6533..7a911eca0f18b4a751b3410b75223080d5da4dbe 100644 (file)
@@ -18,6 +18,8 @@ struct netns_ct {
        struct hlist_nulls_head unconfirmed;
        struct hlist_nulls_head dying;
        struct ip_conntrack_stat __percpu *stat;
+       struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
+       struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
        int                     sysctl_events;
        unsigned int            sysctl_events_retry_timeout;
        int                     sysctl_acct;
index 3319f16b3beb899727c7a434e75fb1010d7ee139..b72a3b83393604b29845514942a5cb8ad8729970 100644 (file)
@@ -116,7 +116,7 @@ struct red_parms {
        u32             qR;             /* Cached random number */
 
        unsigned long   qavg;           /* Average queue length: A scaled */
-       psched_time_t   qidlestart;     /* Start of current idle period */
+       ktime_t         qidlestart;     /* Start of current idle period */
 };
 
 static inline u32 red_rmask(u8 Plog)
@@ -148,17 +148,17 @@ static inline void red_set_parms(struct red_parms *p,
 
 static inline int red_is_idling(struct red_parms *p)
 {
-       return p->qidlestart != PSCHED_PASTPERFECT;
+       return p->qidlestart.tv64 != 0;
 }
 
 static inline void red_start_of_idle_period(struct red_parms *p)
 {
-       p->qidlestart = psched_get_time();
+       p->qidlestart = ktime_get();
 }
 
 static inline void red_end_of_idle_period(struct red_parms *p)
 {
-       p->qidlestart = PSCHED_PASTPERFECT;
+       p->qidlestart.tv64 = 0;
 }
 
 static inline void red_restart(struct red_parms *p)
@@ -170,13 +170,10 @@ static inline void red_restart(struct red_parms *p)
 
 static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
 {
-       psched_time_t now;
-       long us_idle;
+       s64 delta = ktime_us_delta(ktime_get(), p->qidlestart);
+       long us_idle = min_t(s64, delta, p->Scell_max);
        int  shift;
 
-       now = psched_get_time();
-       us_idle = psched_tdiff_bounded(now, p->qidlestart, p->Scell_max);
-
        /*
         * The problem: ideally, average length queue recalcultion should
         * be done over constant clock intervals. This is too expensive, so
index db7b3432f07c41ce124c9d2a792035cead8b048d..91855d185b537f96fc0ea09134c96a93b63aa3d3 100644 (file)
@@ -71,12 +71,12 @@ struct rtable {
        struct fib_info         *fi; /* for client ref to shared metrics */
 };
 
-static inline bool rt_is_input_route(struct rtable *rt)
+static inline bool rt_is_input_route(const struct rtable *rt)
 {
        return rt->rt_route_iif != 0;
 }
 
-static inline bool rt_is_output_route(struct rtable *rt)
+static inline bool rt_is_output_route(const struct rtable *rt)
 {
        return rt->rt_route_iif == 0;
 }
index 2eb207ea4eafe9534d179761292be03f0142e425..f6bb08b73ca4c81a923a2d575801c5a38940efa4 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/rcupdate.h>
-#include <linux/module.h>
 #include <linux/pkt_sched.h>
 #include <linux/pkt_cls.h>
 #include <net/gen_stats.h>
index c6658bef7f328dc72f801503a6b982d5c5ce9e27..abb6e0f0c3c3e59b79f23fc72d2e9d8d389e3774 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/list_nulls.h>
 #include <linux/timer.h>
 #include <linux/cache.h>
-#include <linux/module.h>
 #include <linux/lockdep.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>      /* struct sk_buff */
@@ -729,6 +728,7 @@ struct request_sock_ops;
 struct timewait_sock_ops;
 struct inet_hashinfo;
 struct raw_hashinfo;
+struct module;
 
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
index 91d513879a7834043dfa6e7c591cc221bc60e571..3be5ab782b99c74d6f0a1326eaf28f6108dfa708 100644 (file)
@@ -22,7 +22,6 @@
  *
  */
 
-#include <linux/module.h>
 #include <linux/sched.h>               /* wake_up() */
 #include <linux/mutex.h>               /* struct mutex */
 #include <linux/rwsem.h>               /* struct rw_semaphore */
@@ -43,6 +42,7 @@
 #ifdef CONFIG_PCI
 struct pci_dev;
 #endif
+struct module;
 
 /* device allocation stuff */
 
index 35aa786f93da35a8fa1d6b8859ae6ced92f6ff9e..6873c7dd9145d2a23f682d9e8d2c695a7571d656 100644 (file)
@@ -89,7 +89,6 @@ enum transport_state_table {
        TRANSPORT_PROCESS_TMR   = 9,
        TRANSPORT_ISTATE_PROCESSING = 11,
        TRANSPORT_NEW_CMD_MAP   = 16,
-       TRANSPORT_FREE_CMD_INTR = 17,
        TRANSPORT_COMPLETE_QF_WP = 18,
        TRANSPORT_COMPLETE_QF_OK = 19,
 };
@@ -104,9 +103,10 @@ enum se_cmd_flags_table {
        SCF_SCSI_NON_DATA_CDB           = 0x00000040,
        SCF_SCSI_CDB_EXCEPTION          = 0x00000080,
        SCF_SCSI_RESERVATION_CONFLICT   = 0x00000100,
-       SCF_SE_CMD_FAILED               = 0x00000400,
+       SCF_FUA                         = 0x00000200,
        SCF_SE_LUN_CMD                  = 0x00000800,
        SCF_SE_ALLOW_EOO                = 0x00001000,
+       SCF_BIDI                        = 0x00002000,
        SCF_SENT_CHECK_CONDITION        = 0x00004000,
        SCF_OVERFLOW_BIT                = 0x00008000,
        SCF_UNDERFLOW_BIT               = 0x00010000,
@@ -115,7 +115,6 @@ enum se_cmd_flags_table {
        SCF_DELAYED_CMD_FROM_SAM_ATTR   = 0x00080000,
        SCF_UNUSED                      = 0x00100000,
        SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00400000,
-       SCF_EMULATE_CDB_ASYNC           = 0x01000000,
 };
 
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
@@ -156,6 +155,7 @@ enum tcm_sense_reason_table {
        TCM_CHECK_CONDITION_ABORT_CMD           = 0x0d,
        TCM_CHECK_CONDITION_UNIT_ATTENTION      = 0x0e,
        TCM_CHECK_CONDITION_NOT_READY           = 0x0f,
+       TCM_RESERVATION_CONFLICT                = 0x10,
 };
 
 struct se_obj {
@@ -213,7 +213,6 @@ struct t10_alua_lu_gp {
        u16     lu_gp_id;
        int     lu_gp_valid_id;
        u32     lu_gp_members;
-       atomic_t lu_gp_shutdown;
        atomic_t lu_gp_ref_cnt;
        spinlock_t lu_gp_lock;
        struct config_group lu_gp_group;
@@ -424,8 +423,9 @@ struct se_cmd {
        int                     sam_task_attr;
        /* Transport protocol dependent state, see transport_state_table */
        enum transport_state_table t_state;
-       /* Transport specific error status */
-       int                     transport_error_status;
+       /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */
+       unsigned                check_release:1;
+       unsigned                cmd_wait_set:1;
        /* See se_cmd_flags_table */
        u32                     se_cmd_flags;
        u32                     se_ordered_id;
@@ -440,28 +440,25 @@ struct se_cmd {
        /* Used for sense data */
        void                    *sense_buffer;
        struct list_head        se_delayed_node;
-       struct list_head        se_ordered_node;
        struct list_head        se_lun_node;
        struct list_head        se_qf_node;
        struct se_device      *se_dev;
        struct se_dev_entry   *se_deve;
-       struct se_device        *se_obj_ptr;
-       struct se_device        *se_orig_obj_ptr;
        struct se_lun           *se_lun;
        /* Only used for internal passthrough and legacy TCM fabric modules */
        struct se_session       *se_sess;
        struct se_tmr_req       *se_tmr_req;
        struct list_head        se_queue_node;
+       struct list_head        se_cmd_list;
+       struct completion       cmd_wait_comp;
        struct target_core_fabric_ops *se_tfo;
-       int (*transport_emulate_cdb)(struct se_cmd *);
+       int (*execute_task)(struct se_task *);
        void (*transport_complete_callback)(struct se_cmd *);
 
        unsigned char           *t_task_cdb;
        unsigned char           __t_task_cdb[TCM_MAX_COMMAND_SIZE];
        unsigned long long      t_task_lba;
        int                     t_tasks_failed;
-       int                     t_tasks_fua;
-       bool                    t_tasks_bidi;
        u32                     t_tasks_sg_chained_no;
        atomic_t                t_fe_count;
        atomic_t                t_se_count;
@@ -486,14 +483,6 @@ struct se_cmd {
 
        struct work_struct      work;
 
-       /*
-        * Used for pre-registered fabric SGL passthrough WRITE and READ
-        * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop
-        * and other HW target mode fabric modules.
-        */
-       struct scatterlist      *t_task_pt_sgl;
-       u32                     t_task_pt_sgl_num;
-
        struct scatterlist      *t_data_sg;
        unsigned int            t_data_nents;
        struct scatterlist      *t_bidi_data_sg;
@@ -559,12 +548,16 @@ struct se_node_acl {
 } ____cacheline_aligned;
 
 struct se_session {
+       unsigned                sess_tearing_down:1;
        u64                     sess_bin_isid;
        struct se_node_acl      *se_node_acl;
        struct se_portal_group *se_tpg;
        void                    *fabric_sess_ptr;
        struct list_head        sess_list;
        struct list_head        sess_acl_list;
+       struct list_head        sess_cmd_list;
+       struct list_head        sess_wait_list;
+       spinlock_t              sess_cmd_lock;
 } ____cacheline_aligned;
 
 struct se_device;
@@ -676,7 +669,6 @@ struct se_subsystem_dev {
        struct t10_reservation t10_pr;
        spinlock_t      se_dev_lock;
        void            *se_dev_su_ptr;
-       struct list_head se_dev_node;
        struct config_group se_dev_group;
        /* For T10 Reservations */
        struct config_group se_dev_pr_group;
@@ -685,9 +677,6 @@ struct se_subsystem_dev {
 } ____cacheline_aligned;
 
 struct se_device {
-       /* Set to 1 if thread is NOT sleeping on thread_sem */
-       u8                      thread_active;
-       u8                      dev_status_timer_flags;
        /* RELATIVE TARGET PORT IDENTIFER Counter */
        u16                     dev_rpti_counter;
        /* Used for SAM Task Attribute ordering */
@@ -712,14 +701,10 @@ struct se_device {
        u64                     write_bytes;
        spinlock_t              stats_lock;
        /* Active commands on this virtual SE device */
-       atomic_t                active_cmds;
        atomic_t                simple_cmds;
        atomic_t                depth_left;
        atomic_t                dev_ordered_id;
-       atomic_t                dev_tur_active;
        atomic_t                execute_tasks;
-       atomic_t                dev_status_thr_count;
-       atomic_t                dev_hoq_count;
        atomic_t                dev_ordered_sync;
        atomic_t                dev_qf_count;
        struct se_obj           dev_obj;
@@ -727,14 +712,9 @@ struct se_device {
        struct se_obj           dev_export_obj;
        struct se_queue_obj     dev_queue_obj;
        spinlock_t              delayed_cmd_lock;
-       spinlock_t              ordered_cmd_lock;
        spinlock_t              execute_task_lock;
-       spinlock_t              state_task_lock;
-       spinlock_t              dev_alua_lock;
        spinlock_t              dev_reservation_lock;
-       spinlock_t              dev_state_lock;
        spinlock_t              dev_status_lock;
-       spinlock_t              dev_status_thr_lock;
        spinlock_t              se_port_lock;
        spinlock_t              se_tmr_lock;
        spinlock_t              qf_cmd_lock;
@@ -746,14 +726,10 @@ struct se_device {
        struct t10_pr_registration *dev_pr_res_holder;
        struct list_head        dev_sep_list;
        struct list_head        dev_tmr_list;
-       struct timer_list       dev_status_timer;
        /* Pointer to descriptor for processing thread */
        struct task_struct      *process_thread;
-       pid_t                   process_thread_pid;
-       struct task_struct              *dev_mgmt_thread;
        struct work_struct      qf_work_queue;
        struct list_head        delayed_cmd_list;
-       struct list_head        ordered_cmd_list;
        struct list_head        execute_task_list;
        struct list_head        state_task_list;
        struct list_head        qf_cmd_list;
@@ -764,8 +740,6 @@ struct se_device {
        struct se_subsystem_api *transport;
        /* Linked list for struct se_hba struct se_device list */
        struct list_head        dev_list;
-       /* Linked list for struct se_global->g_se_dev_list */
-       struct list_head        g_se_dev_list;
 }  ____cacheline_aligned;
 
 struct se_hba {
@@ -827,7 +801,6 @@ struct se_port {
        u32             sep_index;
        struct scsi_port_stats sep_stats;
        /* Used for ALUA Target Port Groups membership */
-       atomic_t        sep_tg_pt_gp_active;
        atomic_t        sep_tg_pt_secondary_offline;
        /* Used for PR ALL_TG_PT=1 */
        atomic_t        sep_tg_pt_ref_cnt;
index 46571912086c1b5c7cc5592e91a4ec4ace9fd50d..2be31ff8763b25cb2e3a5f1b641e7af3ded2defd 100644 (file)
@@ -17,7 +17,7 @@ extern int core_dev_export(struct se_device *, struct se_portal_group *,
                                        struct se_lun *);
 extern void core_dev_unexport(struct se_device *, struct se_portal_group *,
                                        struct se_lun *);
-extern int transport_core_report_lun_response(struct se_cmd *);
+extern int target_report_luns(struct se_task *);
 extern void se_release_device_for_hba(struct se_device *);
 extern void se_release_vpd_for_dev(struct se_device *);
 extern void se_clear_dev_ports(struct se_device *);
index 126c675f4f14e5b41afd30694615b84d5eedbcbc..0256825f923dbd8d5e1824cb45c4af5d1ae3e197 100644 (file)
@@ -46,9 +46,16 @@ struct target_core_fabric_ops {
        int (*new_cmd_map)(struct se_cmd *);
        /*
         * Optional to release struct se_cmd and fabric dependent allocated
-        * I/O descriptor in transport_cmd_check_stop()
+        * I/O descriptor in transport_cmd_check_stop().
+        *
+        * Returning 1 will signal a descriptor has been released.
+        * Returning 0 will signal a descriptor has not been released.
         */
-       void (*check_stop_free)(struct se_cmd *);
+       int (*check_stop_free)(struct se_cmd *);
+       /*
+        * Optional check for active I/O shutdown
+        */
+       int (*check_release_cmd)(struct se_cmd *);
        void (*release_cmd)(struct se_cmd *);
        /*
         * Called with spin_lock_bh(struct se_portal_group->session_lock held.
index a037a1a6fbbac5d0d2219c8cc7a53edf023ba653..dac4f2d859fd72734fbc54ffda839216fe554079 100644 (file)
 
 #define PYX_TRANSPORT_STATUS_INTERVAL          5 /* In seconds */
 
-#define PYX_TRANSPORT_SENT_TO_TRANSPORT                0
-#define PYX_TRANSPORT_WRITE_PENDING            1
-
-#define PYX_TRANSPORT_UNKNOWN_SAM_OPCODE       -1
-#define PYX_TRANSPORT_HBA_QUEUE_FULL           -2
-#define PYX_TRANSPORT_REQ_TOO_MANY_SECTORS     -3
-#define PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES  -4
-#define PYX_TRANSPORT_INVALID_CDB_FIELD                -5
-#define PYX_TRANSPORT_INVALID_PARAMETER_LIST   -6
-#define PYX_TRANSPORT_LU_COMM_FAILURE          -7
-#define PYX_TRANSPORT_UNKNOWN_MODE_PAGE                -8
-#define PYX_TRANSPORT_WRITE_PROTECTED          -9
-#define PYX_TRANSPORT_RESERVATION_CONFLICT     -10
-#define PYX_TRANSPORT_ILLEGAL_REQUEST          -11
-#define PYX_TRANSPORT_USE_SENSE_REASON         -12
-
-#ifndef SAM_STAT_RESERVATION_CONFLICT
-#define SAM_STAT_RESERVATION_CONFLICT          0x18
-#endif
-
-#define TRANSPORT_PLUGIN_FREE                  0
-#define TRANSPORT_PLUGIN_REGISTERED            1
-
 #define TRANSPORT_PLUGIN_PHBA_PDEV             1
 #define TRANSPORT_PLUGIN_VHBA_PDEV             2
 #define TRANSPORT_PLUGIN_VHBA_VDEV             3
@@ -158,19 +135,21 @@ extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *);
 extern int transport_handle_cdb_direct(struct se_cmd *);
 extern int transport_generic_handle_cdb_map(struct se_cmd *);
 extern int transport_generic_handle_data(struct se_cmd *);
-extern void transport_new_cmd_failure(struct se_cmd *);
 extern int transport_generic_handle_tmr(struct se_cmd *);
-extern void transport_generic_free_cmd_intr(struct se_cmd *);
 extern bool target_stop_task(struct se_task *task, unsigned long *flags);
 extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
                                struct scatterlist *, u32);
 extern int transport_clear_lun_from_sessions(struct se_lun *);
-extern void transport_wait_for_tasks(struct se_cmd *);
+extern bool transport_wait_for_tasks(struct se_cmd *);
 extern int transport_check_aborted_status(struct se_cmd *, int);
 extern int transport_send_check_condition_and_sense(struct se_cmd *, u8, int);
 extern void transport_send_task_abort(struct se_cmd *);
 extern void transport_release_cmd(struct se_cmd *);
 extern void transport_generic_free_cmd(struct se_cmd *, int);
+extern void target_get_sess_cmd(struct se_session *, struct se_cmd *);
+extern int target_put_sess_cmd(struct se_session *, struct se_cmd *);
+extern void target_splice_sess_cmd_list(struct se_session *);
+extern void target_wait_for_sess_cmds(struct se_session *, int);
 extern void transport_generic_wait_for_cmds(struct se_cmd *, int);
 extern void transport_do_task_sg_chain(struct se_cmd *);
 extern void transport_generic_process_write(struct se_cmd *);
index da39b22636f711548b7e6300a5ebf2b7699ed019..b0b4eb24d592fb1f8ecba11294c10e802ff7cd2b 100644 (file)
 #undef CREATE_TRACE_POINTS
 
 #include <linux/stringify.h>
-/*
- * module.h includes tracepoints, and because ftrace.h
- * pulls in module.h:
- *  trace/ftrace.h -> linux/ftrace_event.h -> linux/perf_event.h ->
- *  linux/ftrace.h -> linux/module.h
- * we must include module.h here before we play with any of
- * the TRACE_EVENT() macros, otherwise the tracepoints included
- * by module.h may break the build.
- */
-#include <linux/module.h>
 
 #undef TRACE_EVENT
 #define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
index 21a546d27c0c499e371852b1023be7c67a160140..1619327374164909b6f8aaea6a730b0821ec6ee2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Because linux/module.h has tracepoints in the header, and ftrace.h
- * eventually includes this file, define_trace.h includes linux/module.h
+ * used to include this file, define_trace.h includes linux/module.h
  * But we do not want the module.h to override the TRACE_SYSTEM macro
  * variable that define_trace.h is processing, so we only set it
  * when module events are being processed, which would happen when
index 5f172703eb4f2cafc74064388462ac9ec5192144..b99caa8b780c624af834caeab4130549479e3844 100644 (file)
@@ -34,6 +34,7 @@ DECLARE_EVENT_CLASS(writeback_work_class,
                __field(int, for_kupdate)
                __field(int, range_cyclic)
                __field(int, for_background)
+               __field(int, reason)
        ),
        TP_fast_assign(
                strncpy(__entry->name, dev_name(bdi->dev), 32);
@@ -43,16 +44,18 @@ DECLARE_EVENT_CLASS(writeback_work_class,
                __entry->for_kupdate = work->for_kupdate;
                __entry->range_cyclic = work->range_cyclic;
                __entry->for_background = work->for_background;
+               __entry->reason = work->reason;
        ),
        TP_printk("bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d "
-                 "kupdate=%d range_cyclic=%d background=%d",
+                 "kupdate=%d range_cyclic=%d background=%d reason=%s",
                  __entry->name,
                  MAJOR(__entry->sb_dev), MINOR(__entry->sb_dev),
                  __entry->nr_pages,
                  __entry->sync_mode,
                  __entry->for_kupdate,
                  __entry->range_cyclic,
-                 __entry->for_background
+                 __entry->for_background,
+                 wb_reason_name[__entry->reason]
        )
 );
 #define DEFINE_WRITEBACK_WORK_EVENT(name) \
@@ -104,30 +107,6 @@ DEFINE_WRITEBACK_EVENT(writeback_bdi_register);
 DEFINE_WRITEBACK_EVENT(writeback_bdi_unregister);
 DEFINE_WRITEBACK_EVENT(writeback_thread_start);
 DEFINE_WRITEBACK_EVENT(writeback_thread_stop);
-DEFINE_WRITEBACK_EVENT(balance_dirty_start);
-DEFINE_WRITEBACK_EVENT(balance_dirty_wait);
-
-TRACE_EVENT(balance_dirty_written,
-
-       TP_PROTO(struct backing_dev_info *bdi, int written),
-
-       TP_ARGS(bdi, written),
-
-       TP_STRUCT__entry(
-               __array(char,   name, 32)
-               __field(int,    written)
-       ),
-
-       TP_fast_assign(
-               strncpy(__entry->name, dev_name(bdi->dev), 32);
-               __entry->written = written;
-       ),
-
-       TP_printk("bdi %s written %d",
-                 __entry->name,
-                 __entry->written
-       )
-);
 
 DECLARE_EVENT_CLASS(wbc_class,
        TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi),
@@ -181,27 +160,31 @@ DEFINE_WBC_EVENT(wbc_writepage);
 
 TRACE_EVENT(writeback_queue_io,
        TP_PROTO(struct bdi_writeback *wb,
-                unsigned long *older_than_this,
+                struct wb_writeback_work *work,
                 int moved),
-       TP_ARGS(wb, older_than_this, moved),
+       TP_ARGS(wb, work, moved),
        TP_STRUCT__entry(
                __array(char,           name, 32)
                __field(unsigned long,  older)
                __field(long,           age)
                __field(int,            moved)
+               __field(int,            reason)
        ),
        TP_fast_assign(
+               unsigned long *older_than_this = work->older_than_this;
                strncpy(__entry->name, dev_name(wb->bdi->dev), 32);
                __entry->older  = older_than_this ?  *older_than_this : 0;
                __entry->age    = older_than_this ?
                                  (jiffies - *older_than_this) * 1000 / HZ : -1;
                __entry->moved  = moved;
+               __entry->reason = work->reason;
        ),
-       TP_printk("bdi %s: older=%lu age=%ld enqueue=%d",
+       TP_printk("bdi %s: older=%lu age=%ld enqueue=%d reason=%s",
                __entry->name,
                __entry->older, /* older_than_this in jiffies */
                __entry->age,   /* older_than_this in relative milliseconds */
-               __entry->moved)
+               __entry->moved,
+               wb_reason_name[__entry->reason])
 );
 
 TRACE_EVENT(global_dirty_state,
@@ -250,6 +233,124 @@ TRACE_EVENT(global_dirty_state,
        )
 );
 
+#define KBps(x)                        ((x) << (PAGE_SHIFT - 10))
+
+TRACE_EVENT(bdi_dirty_ratelimit,
+
+       TP_PROTO(struct backing_dev_info *bdi,
+                unsigned long dirty_rate,
+                unsigned long task_ratelimit),
+
+       TP_ARGS(bdi, dirty_rate, task_ratelimit),
+
+       TP_STRUCT__entry(
+               __array(char,           bdi, 32)
+               __field(unsigned long,  write_bw)
+               __field(unsigned long,  avg_write_bw)
+               __field(unsigned long,  dirty_rate)
+               __field(unsigned long,  dirty_ratelimit)
+               __field(unsigned long,  task_ratelimit)
+               __field(unsigned long,  balanced_dirty_ratelimit)
+       ),
+
+       TP_fast_assign(
+               strlcpy(__entry->bdi, dev_name(bdi->dev), 32);
+               __entry->write_bw       = KBps(bdi->write_bandwidth);
+               __entry->avg_write_bw   = KBps(bdi->avg_write_bandwidth);
+               __entry->dirty_rate     = KBps(dirty_rate);
+               __entry->dirty_ratelimit = KBps(bdi->dirty_ratelimit);
+               __entry->task_ratelimit = KBps(task_ratelimit);
+               __entry->balanced_dirty_ratelimit =
+                                         KBps(bdi->balanced_dirty_ratelimit);
+       ),
+
+       TP_printk("bdi %s: "
+                 "write_bw=%lu awrite_bw=%lu dirty_rate=%lu "
+                 "dirty_ratelimit=%lu task_ratelimit=%lu "
+                 "balanced_dirty_ratelimit=%lu",
+                 __entry->bdi,
+                 __entry->write_bw,            /* write bandwidth */
+                 __entry->avg_write_bw,        /* avg write bandwidth */
+                 __entry->dirty_rate,          /* bdi dirty rate */
+                 __entry->dirty_ratelimit,     /* base ratelimit */
+                 __entry->task_ratelimit, /* ratelimit with position control */
+                 __entry->balanced_dirty_ratelimit /* the balanced ratelimit */
+       )
+);
+
+TRACE_EVENT(balance_dirty_pages,
+
+       TP_PROTO(struct backing_dev_info *bdi,
+                unsigned long thresh,
+                unsigned long bg_thresh,
+                unsigned long dirty,
+                unsigned long bdi_thresh,
+                unsigned long bdi_dirty,
+                unsigned long dirty_ratelimit,
+                unsigned long task_ratelimit,
+                unsigned long dirtied,
+                long pause,
+                unsigned long start_time),
+
+       TP_ARGS(bdi, thresh, bg_thresh, dirty, bdi_thresh, bdi_dirty,
+               dirty_ratelimit, task_ratelimit,
+               dirtied, pause, start_time),
+
+       TP_STRUCT__entry(
+               __array(         char,  bdi, 32)
+               __field(unsigned long,  limit)
+               __field(unsigned long,  setpoint)
+               __field(unsigned long,  dirty)
+               __field(unsigned long,  bdi_setpoint)
+               __field(unsigned long,  bdi_dirty)
+               __field(unsigned long,  dirty_ratelimit)
+               __field(unsigned long,  task_ratelimit)
+               __field(unsigned int,   dirtied)
+               __field(unsigned int,   dirtied_pause)
+               __field(unsigned long,  paused)
+               __field(         long,  pause)
+       ),
+
+       TP_fast_assign(
+               unsigned long freerun = (thresh + bg_thresh) / 2;
+               strlcpy(__entry->bdi, dev_name(bdi->dev), 32);
+
+               __entry->limit          = global_dirty_limit;
+               __entry->setpoint       = (global_dirty_limit + freerun) / 2;
+               __entry->dirty          = dirty;
+               __entry->bdi_setpoint   = __entry->setpoint *
+                                               bdi_thresh / (thresh + 1);
+               __entry->bdi_dirty      = bdi_dirty;
+               __entry->dirty_ratelimit = KBps(dirty_ratelimit);
+               __entry->task_ratelimit = KBps(task_ratelimit);
+               __entry->dirtied        = dirtied;
+               __entry->dirtied_pause  = current->nr_dirtied_pause;
+               __entry->pause          = pause * 1000 / HZ;
+               __entry->paused         = (jiffies - start_time) * 1000 / HZ;
+       ),
+
+
+       TP_printk("bdi %s: "
+                 "limit=%lu setpoint=%lu dirty=%lu "
+                 "bdi_setpoint=%lu bdi_dirty=%lu "
+                 "dirty_ratelimit=%lu task_ratelimit=%lu "
+                 "dirtied=%u dirtied_pause=%u "
+                 "paused=%lu pause=%ld",
+                 __entry->bdi,
+                 __entry->limit,
+                 __entry->setpoint,
+                 __entry->dirty,
+                 __entry->bdi_setpoint,
+                 __entry->bdi_dirty,
+                 __entry->dirty_ratelimit,
+                 __entry->task_ratelimit,
+                 __entry->dirtied,
+                 __entry->dirtied_pause,
+                 __entry->paused,      /* ms */
+                 __entry->pause        /* ms */
+         )
+);
+
 DECLARE_EVENT_CLASS(writeback_congest_waited_template,
 
        TP_PROTO(unsigned int usec_timeout, unsigned int usec_delayed),
index b66ebb2032c6d6b87c928876cab69c235d2425f3..378c7ed6760be0563b501971df2a60e03a672ea7 100644 (file)
@@ -307,15 +307,8 @@ struct omap_dss_board_info {
        void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
 };
 
-#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS)
 /* Init with the board info */
 extern int omap_display_init(struct omap_dss_board_info *board_data);
-#else
-static inline int omap_display_init(struct omap_dss_board_info *board_data)
-{
-       return 0;
-}
-#endif
 
 struct omap_display_platform_data {
        struct omap_dss_board_info *board_data;
index 6b99bfbd785dddb8d3810bdb5c669dee96c7e93e..11e2dfce42f82ecca25fec9e8e6508d47d3615c4 100644 (file)
@@ -43,7 +43,6 @@
 #include <xen/interface/grant_table.h>
 
 #include <asm/xen/hypervisor.h>
-#include <asm/xen/grant_table.h>
 
 #include <xen/features.h>
 
index 9324488f23f0b2eaab58e50f7cdda0b6d4b152ef..ee338bfde18b25d45bb0252ff41ea4160095d6e7 100644 (file)
@@ -84,6 +84,21 @@ typedef uint64_t blkif_sector_t;
  *     e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
  * http://www.seagate.com/staticfiles/support/disc/manuals/
  *     Interface%20manuals/100293068c.pdf
+ * The backend can optionally provide three extra XenBus attributes to
+ * further optimize the discard functionality:
+ * 'discard-aligment' - Devices that support discard functionality may
+ * internally allocate space in units that are bigger than the exported
+ * logical block size. The discard-alignment parameter indicates how many bytes
+ * the beginning of the partition is offset from the internal allocation unit's
+ * natural alignment.
+ * 'discard-granularity'  - Devices that support discard functionality may
+ * internally allocate space using units that are bigger than the logical block
+ * size. The discard-granularity parameter indicates the size of the internal
+ * allocation unit in bytes if reported by the device. Otherwise the
+ * discard-granularity will be set to match the device's physical block size.
+ * 'discard-secure' - All copies of the discarded sectors (potentially created
+ * by garbage collection) must also be erased.  To use this feature, the flag
+ * BLKIF_DISCARD_SECURE must be set in the blkif_request_trim.
  */
 #define BLKIF_OP_DISCARD           5
 
@@ -95,6 +110,12 @@ typedef uint64_t blkif_sector_t;
 #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
 
 struct blkif_request_rw {
+       uint8_t        nr_segments;  /* number of segments                   */
+       blkif_vdev_t   handle;       /* only for read/write requests         */
+#ifdef CONFIG_X86_64
+       uint32_t       _pad1;        /* offsetof(blkif_request,u.rw.id) == 8 */
+#endif
+       uint64_t       id;           /* private guest value, echoed in resp  */
        blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
        struct blkif_request_segment {
                grant_ref_t gref;        /* reference to I/O buffer frame        */
@@ -102,23 +123,28 @@ struct blkif_request_rw {
                /* @last_sect: last sector in frame to transfer (inclusive).     */
                uint8_t     first_sect, last_sect;
        } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-};
+} __attribute__((__packed__));
 
 struct blkif_request_discard {
+       uint8_t        flag;         /* BLKIF_DISCARD_SECURE or zero.        */
+#define BLKIF_DISCARD_SECURE (1<<0)  /* ignored if discard-secure=0          */
+       blkif_vdev_t   _pad1;        /* only for read/write requests         */
+#ifdef CONFIG_X86_64
+       uint32_t       _pad2;        /* offsetof(blkif_req..,u.discard.id)==8*/
+#endif
+       uint64_t       id;           /* private guest value, echoed in resp  */
        blkif_sector_t sector_number;
-       uint64_t nr_sectors;
-};
+       uint64_t       nr_sectors;
+       uint8_t        _pad3;
+} __attribute__((__packed__));
 
 struct blkif_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
-       uint8_t        nr_segments;  /* number of segments                   */
-       blkif_vdev_t   handle;       /* only for read/write requests         */
-       uint64_t       id;           /* private guest value, echoed in resp  */
        union {
                struct blkif_request_rw rw;
                struct blkif_request_discard discard;
        } u;
-};
+} __attribute__((__packed__));
 
 struct blkif_response {
        uint64_t        id;              /* copied from request */
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
new file mode 100644 (file)
index 0000000..c168468
--- /dev/null
@@ -0,0 +1,320 @@
+/******************************************************************************
+ * platform.h
+ *
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#ifndef __XEN_PUBLIC_PLATFORM_H__
+#define __XEN_PUBLIC_PLATFORM_H__
+
+#include "xen.h"
+
+#define XENPF_INTERFACE_VERSION 0x03000001
+
+/*
+ * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
+ * 1 January, 1970 if the current system time was <system_time>.
+ */
+#define XENPF_settime             17
+struct xenpf_settime {
+       /* IN variables. */
+       uint32_t secs;
+       uint32_t nsecs;
+       uint64_t system_time;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t);
+
+/*
+ * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
+ * On x86, @type is an architecture-defined MTRR memory type.
+ * On success, returns the MTRR that was used (@reg) and a handle that can
+ * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting.
+ * (x86-specific).
+ */
+#define XENPF_add_memtype         31
+struct xenpf_add_memtype {
+       /* IN variables. */
+       unsigned long mfn;
+       uint64_t nr_mfns;
+       uint32_t type;
+       /* OUT variables. */
+       uint32_t handle;
+       uint32_t reg;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_add_memtype_t);
+
+/*
+ * Tear down an existing memory-range type. If @handle is remembered then it
+ * should be passed in to accurately tear down the correct setting (in case
+ * of overlapping memory regions with differing types). If it is not known
+ * then @handle should be set to zero. In all cases @reg must be set.
+ * (x86-specific).
+ */
+#define XENPF_del_memtype         32
+struct xenpf_del_memtype {
+       /* IN variables. */
+       uint32_t handle;
+       uint32_t reg;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_del_memtype_t);
+
+/* Read current type of an MTRR (x86-specific). */
+#define XENPF_read_memtype        33
+struct xenpf_read_memtype {
+       /* IN variables. */
+       uint32_t reg;
+       /* OUT variables. */
+       unsigned long mfn;
+       uint64_t nr_mfns;
+       uint32_t type;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_read_memtype_t);
+
+#define XENPF_microcode_update    35
+struct xenpf_microcode_update {
+       /* IN variables. */
+       GUEST_HANDLE(void) data;          /* Pointer to microcode data */
+       uint32_t length;                  /* Length of microcode data. */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_microcode_update_t);
+
+#define XENPF_platform_quirk      39
+#define QUIRK_NOIRQBALANCING      1 /* Do not restrict IO-APIC RTE targets */
+#define QUIRK_IOAPIC_BAD_REGSEL   2 /* IO-APIC REGSEL forgets its value    */
+#define QUIRK_IOAPIC_GOOD_REGSEL  3 /* IO-APIC REGSEL behaves properly     */
+struct xenpf_platform_quirk {
+       /* IN variables. */
+       uint32_t quirk_id;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
+
+#define XENPF_firmware_info       50
+#define XEN_FW_DISK_INFO          1 /* from int 13 AH=08/41/48 */
+#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
+#define XEN_FW_VBEDDC_INFO        3 /* from int 10 AX=4f15 */
+struct xenpf_firmware_info {
+       /* IN variables. */
+       uint32_t type;
+       uint32_t index;
+       /* OUT variables. */
+       union {
+               struct {
+                       /* Int13, Fn48: Check Extensions Present. */
+                       uint8_t device;                   /* %dl: bios device number */
+                       uint8_t version;                  /* %ah: major version      */
+                       uint16_t interface_support;       /* %cx: support bitmap     */
+                       /* Int13, Fn08: Legacy Get Device Parameters. */
+                       uint16_t legacy_max_cylinder;     /* %cl[7:6]:%ch: max cyl # */
+                       uint8_t legacy_max_head;          /* %dh: max head #         */
+                       uint8_t legacy_sectors_per_track; /* %cl[5:0]: max sector #  */
+                       /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
+                       /* NB. First uint16_t of buffer must be set to buffer size.      */
+                       GUEST_HANDLE(void) edd_params;
+               } disk_info; /* XEN_FW_DISK_INFO */
+               struct {
+                       uint8_t device;                   /* bios device number  */
+                       uint32_t mbr_signature;           /* offset 0x1b8 in mbr */
+               } disk_mbr_signature; /* XEN_FW_DISK_MBR_SIGNATURE */
+               struct {
+                       /* Int10, AX=4F15: Get EDID info. */
+                       uint8_t capabilities;
+                       uint8_t edid_transfer_time;
+                       /* must refer to 128-byte buffer */
+                       GUEST_HANDLE(uchar) edid;
+               } vbeddc_info; /* XEN_FW_VBEDDC_INFO */
+       } u;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t);
+
+#define XENPF_enter_acpi_sleep    51
+struct xenpf_enter_acpi_sleep {
+       /* IN variables */
+       uint16_t pm1a_cnt_val;      /* PM1a control value. */
+       uint16_t pm1b_cnt_val;      /* PM1b control value. */
+       uint32_t sleep_state;       /* Which state to enter (Sn). */
+       uint32_t flags;             /* Must be zero. */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t);
+
+#define XENPF_change_freq         52
+struct xenpf_change_freq {
+       /* IN variables */
+       uint32_t flags; /* Must be zero. */
+       uint32_t cpu;   /* Physical cpu. */
+       uint64_t freq;  /* New frequency (Hz). */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_change_freq_t);
+
+/*
+ * Get idle times (nanoseconds since boot) for physical CPUs specified in the
+ * @cpumap_bitmap with range [0..@cpumap_nr_cpus-1]. The @idletime array is
+ * indexed by CPU number; only entries with the corresponding @cpumap_bitmap
+ * bit set are written to. On return, @cpumap_bitmap is modified so that any
+ * non-existent CPUs are cleared. Such CPUs have their @idletime array entry
+ * cleared.
+ */
+#define XENPF_getidletime         53
+struct xenpf_getidletime {
+       /* IN/OUT variables */
+       /* IN: CPUs to interrogate; OUT: subset of IN which are present */
+       GUEST_HANDLE(uchar) cpumap_bitmap;
+       /* IN variables */
+       /* Size of cpumap bitmap. */
+       uint32_t cpumap_nr_cpus;
+       /* Must be indexable for every cpu in cpumap_bitmap. */
+       GUEST_HANDLE(uint64_t) idletime;
+       /* OUT variables */
+       /* System time when the idletime snapshots were taken. */
+       uint64_t now;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_getidletime_t);
+
+#define XENPF_set_processor_pminfo      54
+
+/* ability bits */
+#define XEN_PROCESSOR_PM_CX    1
+#define XEN_PROCESSOR_PM_PX    2
+#define XEN_PROCESSOR_PM_TX    4
+
+/* cmd type */
+#define XEN_PM_CX   0
+#define XEN_PM_PX   1
+#define XEN_PM_TX   2
+
+/* Px sub info type */
+#define XEN_PX_PCT   1
+#define XEN_PX_PSS   2
+#define XEN_PX_PPC   4
+#define XEN_PX_PSD   8
+
+struct xen_power_register {
+       uint32_t     space_id;
+       uint32_t     bit_width;
+       uint32_t     bit_offset;
+       uint32_t     access_size;
+       uint64_t     address;
+};
+
+struct xen_processor_csd {
+       uint32_t    domain;      /* domain number of one dependent group */
+       uint32_t    coord_type;  /* coordination type */
+       uint32_t    num;         /* number of processors in same domain */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_processor_csd);
+
+struct xen_processor_cx {
+       struct xen_power_register  reg; /* GAS for Cx trigger register */
+       uint8_t     type;     /* cstate value, c0: 0, c1: 1, ... */
+       uint32_t    latency;  /* worst latency (ms) to enter/exit this cstate */
+       uint32_t    power;    /* average power consumption(mW) */
+       uint32_t    dpcnt;    /* number of dependency entries */
+       GUEST_HANDLE(xen_processor_csd) dp; /* NULL if no dependency */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_processor_cx);
+
+struct xen_processor_flags {
+       uint32_t bm_control:1;
+       uint32_t bm_check:1;
+       uint32_t has_cst:1;
+       uint32_t power_setup_done:1;
+       uint32_t bm_rld_set:1;
+};
+
+struct xen_processor_power {
+       uint32_t count;  /* number of C state entries in array below */
+       struct xen_processor_flags flags;  /* global flags of this processor */
+       GUEST_HANDLE(xen_processor_cx) states; /* supported c states */
+};
+
+struct xen_pct_register {
+       uint8_t  descriptor;
+       uint16_t length;
+       uint8_t  space_id;
+       uint8_t  bit_width;
+       uint8_t  bit_offset;
+       uint8_t  reserved;
+       uint64_t address;
+};
+
+struct xen_processor_px {
+       uint64_t core_frequency; /* megahertz */
+       uint64_t power;      /* milliWatts */
+       uint64_t transition_latency; /* microseconds */
+       uint64_t bus_master_latency; /* microseconds */
+       uint64_t control;        /* control value */
+       uint64_t status;     /* success indicator */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_processor_px);
+
+struct xen_psd_package {
+       uint64_t num_entries;
+       uint64_t revision;
+       uint64_t domain;
+       uint64_t coord_type;
+       uint64_t num_processors;
+};
+
+struct xen_processor_performance {
+       uint32_t flags;     /* flag for Px sub info type */
+       uint32_t platform_limit;  /* Platform limitation on freq usage */
+       struct xen_pct_register control_register;
+       struct xen_pct_register status_register;
+       uint32_t state_count;     /* total available performance states */
+       GUEST_HANDLE(xen_processor_px) states;
+       struct xen_psd_package domain_info;
+       uint32_t shared_type;     /* coordination type of this processor */
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_processor_performance);
+
+struct xenpf_set_processor_pminfo {
+       /* IN variables */
+       uint32_t id;    /* ACPI CPU ID */
+       uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX} */
+       union {
+               struct xen_processor_power          power;/* Cx: _CST/_CSD */
+               struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD */
+       };
+};
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_set_processor_pminfo);
+
+struct xen_platform_op {
+       uint32_t cmd;
+       uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
+       union {
+               struct xenpf_settime           settime;
+               struct xenpf_add_memtype       add_memtype;
+               struct xenpf_del_memtype       del_memtype;
+               struct xenpf_read_memtype      read_memtype;
+               struct xenpf_microcode_update  microcode;
+               struct xenpf_platform_quirk    platform_quirk;
+               struct xenpf_firmware_info     firmware_info;
+               struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
+               struct xenpf_change_freq       change_freq;
+               struct xenpf_getidletime       getidletime;
+               struct xenpf_set_processor_pminfo set_pminfo;
+               uint8_t                        pad[128];
+       } u;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_platform_op_t);
+
+#endif /* __XEN_PUBLIC_PLATFORM_H__ */
index 6acd9cefd5171ea11f5373be66bc863f4947beb6..6a6e91449347078a3ac2c3d66a10578e19e465fd 100644 (file)
@@ -492,6 +492,7 @@ struct dom0_vga_console_info {
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
 #define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */
+#define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm options */
 
 typedef uint64_t cpumap_t;
 
index a785a3b0c8c7d89d9a46e1a1d90300cb91da5308..438c256c274b3b7984155399f87e26cd13d27cd7 100644 (file)
@@ -29,8 +29,7 @@
 static inline int xen_must_unplug_nics(void) {
 #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
                defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
-               (defined(CONFIG_XEN_PLATFORM_PCI) || \
-                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+               defined(CONFIG_XEN_PVHVM)
         return 1;
 #else
         return 0;
@@ -40,8 +39,7 @@ static inline int xen_must_unplug_nics(void) {
 static inline int xen_must_unplug_disks(void) {
 #if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
                defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
-               (defined(CONFIG_XEN_PLATFORM_PCI) || \
-                defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
+               defined(CONFIG_XEN_PVHVM)
         return 1;
 #else
         return 0;
index b9f9fb5af0d844d5e89c23fbb825653c33829645..b1b6676c1c438485ad48b04db6f8d87f2ed3c432 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 #include <linux/completion.h>
 #include <linux/init.h>
 #include <linux/slab.h>
index 63f5f6f8dc3bd32c82e4b77f1082d879e98556a4..217ed23e94875d59ffd7b6a95562fcba36112e08 100644 (file)
@@ -512,6 +512,9 @@ asmlinkage void __init start_kernel(void)
        parse_args("Booting kernel", static_command_line, __start___param,
                   __stop___param - __start___param,
                   &unknown_bootoption);
+
+       jump_label_init();
+
        /*
         * These use large bootmem allocations and must precede
         * kmem_cache_init()
index 4c2843c0043ea205d358d7c65b086f290e09cd68..80b74b88fefe43076d2fbb0fc1d2d8c3d5b989fd 100644 (file)
@@ -51,7 +51,7 @@ asynchronous and synchronous parts of the kernel.
 #include <linux/async.h>
 #include <linux/atomic.h>
 #include <linux/ktime.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
index 0a1355ca3d7927145d12bfeff3b62db138ccf124..09fae2677a45e11ab650b91b1dee7877a2ee8957 100644 (file)
@@ -45,7 +45,7 @@
 #include <asm/types.h>
 #include <linux/atomic.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/kthread.h>
index ce4b054acee512ba46351b024951797464eb1ceb..47b7fc1ea8935aebcf306ea54caf969274dfa7c8 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/socket.h>
index 283c529f8b1cfd2199e90e238aa3d2a67370c414..b463871a4e695448d8ec3246e6347e917ae5ac88 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/audit.h>
 #include <linux/capability.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/pid_namespace.h>
index e691818d7e450f5f8785b8b97a08cdbb2f4e1493..213c0351dad8fc8315d6d79a5bf3706a59c823bd 100644 (file)
@@ -14,7 +14,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/cgroup.h>
 #include <linux/fs.h>
@@ -153,6 +153,13 @@ static void freezer_destroy(struct cgroup_subsys *ss,
        kfree(cgroup_freezer(cgroup));
 }
 
+/* task is frozen or will freeze immediately when next it gets woken */
+static bool is_task_frozen_enough(struct task_struct *task)
+{
+       return frozen(task) ||
+               (task_is_stopped_or_traced(task) && freezing(task));
+}
+
 /*
  * The call to cgroup_lock() in the freezer.state write method prevents
  * a write to that file racing against an attach, and hence the
@@ -231,7 +238,7 @@ static void update_if_frozen(struct cgroup *cgroup,
        cgroup_iter_start(cgroup, &it);
        while ((task = cgroup_iter_next(cgroup, &it))) {
                ntotal++;
-               if (frozen(task))
+               if (is_task_frozen_enough(task))
                        nfrozen++;
        }
 
@@ -284,7 +291,7 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        while ((task = cgroup_iter_next(cgroup, &it))) {
                if (!freeze_task(task, true))
                        continue;
-               if (frozen(task))
+               if (is_task_frozen_enough(task))
                        continue;
                if (!freezing(task) && !freezer_should_skip(task))
                        num_cant_freeze_now++;
index e2435ee9993a329bee48252a38af4ca69e6c4742..f346cedfe24d1ce2a0a4c803e9adeca62534c017 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/unistd.h>
 #include <linux/security.h>
 #include <linux/timex.h>
+#include <linux/export.h>
 #include <linux/migrate.h>
 #include <linux/posix-timers.h>
 #include <linux/times.h>
index 12b7458f23b12a2a68b30857fa913f424cb71a4c..563f136094704fb8e6211636d72c3cc050da5f96 100644 (file)
 #include <linux/sched.h>
 #include <linux/unistd.h>
 #include <linux/cpu.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kthread.h>
 #include <linux/stop_machine.h>
 #include <linux/mutex.h>
 #include <linux/gfp.h>
+#include <linux/suspend.h>
 
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -476,6 +477,79 @@ static int alloc_frozen_cpus(void)
        return 0;
 }
 core_initcall(alloc_frozen_cpus);
+
+/*
+ * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
+ * hotplug when tasks are about to be frozen. Also, don't allow the freezer
+ * to continue until any currently running CPU hotplug operation gets
+ * completed.
+ * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
+ * 'cpu_add_remove_lock'. And this same lock is also taken by the regular
+ * CPU hotplug path and released only after it is complete. Thus, we
+ * (and hence the freezer) will block here until any currently running CPU
+ * hotplug operation gets completed.
+ */
+void cpu_hotplug_disable_before_freeze(void)
+{
+       cpu_maps_update_begin();
+       cpu_hotplug_disabled = 1;
+       cpu_maps_update_done();
+}
+
+
+/*
+ * When tasks have been thawed, re-enable regular CPU hotplug (which had been
+ * disabled while beginning to freeze tasks).
+ */
+void cpu_hotplug_enable_after_thaw(void)
+{
+       cpu_maps_update_begin();
+       cpu_hotplug_disabled = 0;
+       cpu_maps_update_done();
+}
+
+/*
+ * When callbacks for CPU hotplug notifications are being executed, we must
+ * ensure that the state of the system with respect to the tasks being frozen
+ * or not, as reported by the notification, remains unchanged *throughout the
+ * duration* of the execution of the callbacks.
+ * Hence we need to prevent the freezer from racing with regular CPU hotplug.
+ *
+ * This synchronization is implemented by mutually excluding regular CPU
+ * hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
+ * Hibernate notifications.
+ */
+static int
+cpu_hotplug_pm_callback(struct notifier_block *nb,
+                       unsigned long action, void *ptr)
+{
+       switch (action) {
+
+       case PM_SUSPEND_PREPARE:
+       case PM_HIBERNATION_PREPARE:
+               cpu_hotplug_disable_before_freeze();
+               break;
+
+       case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+               cpu_hotplug_enable_after_thaw();
+               break;
+
+       default:
+               return NOTIFY_DONE;
+       }
+
+       return NOTIFY_OK;
+}
+
+
+int cpu_hotplug_pm_sync_init(void)
+{
+       pm_notifier(cpu_hotplug_pm_callback, 0);
+       return 0;
+}
+core_initcall(cpu_hotplug_pm_sync_init);
+
 #endif /* CONFIG_PM_SLEEP_SMP */
 
 /**
index ed0ff443f03640f16d0c3f68e95a5c644a948882..9fe58c46a426de719da9636d8c74d8c9f6bb312d 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/mempolicy.h>
 #include <linux/mm.h>
 #include <linux/memory.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pagemap.h>
index 69ebf3380bac362afc73904be855dc87abdb52ee..c766ee54c0b18bd27f87d4fcfb7f3caa24781343 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/crash_dump.h>
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 /*
  * If we have booted due to a crash, max_pfn will be a very low value. We need
index bb55d052d858f6c2f356d32f36a77445dcda20fa..5791612a404503aa95bd708fcc9d6928d85327a6 100644 (file)
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the Licence, or (at your option) any later version.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/cred.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
index d9ca9aa481ecec52edc5a7b41ef000cabe6c5af6..8b68ce78ff170b8777be887a3bc8407c59863ba5 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kgdb.h>
 #include <linux/kdb.h>
 #include <linux/kdebug.h>
+#include <linux/export.h>
 #include "kdb_private.h"
 #include "../debug_core.h"
 
index f903189c530440395417f7b873aff50e9936dc47..68a2306522c8d972121676a94b96ddad1b25a243 100644 (file)
@@ -9,7 +9,7 @@
  *   [It also happened to remove the sizeof(char *) == sizeof(int)
  *   assumption introduced because of those /proc/dma patches. -- Hennus]
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
index e1253faa34ddcf013c6cf577b98ab85ac4dd5634..d3b9df5962c25bdbd3ca324756474366ff8c6d68 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/reboot.h>
 #include <linux/vmstat.h>
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/vmalloc.h>
 #include <linux/hardirq.h>
 #include <linux/rculist.h>
@@ -184,6 +185,9 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx,
 static void update_context_time(struct perf_event_context *ctx);
 static u64 perf_event_time(struct perf_event *event);
 
+static void ring_buffer_attach(struct perf_event *event,
+                              struct ring_buffer *rb);
+
 void __weak perf_event_print_debug(void)       { }
 
 extern __weak const char *perf_pmu_name(void)
@@ -2170,9 +2174,10 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx,
         */
        cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE);
 
-       perf_event_sched_in(cpuctx, ctx, task);
+       if (ctx->nr_events)
+               cpuctx->task_ctx = ctx;
 
-       cpuctx->task_ctx = ctx;
+       perf_event_sched_in(cpuctx, cpuctx->task_ctx, task);
 
        perf_pmu_enable(ctx->pmu);
        perf_ctx_unlock(cpuctx, ctx);
@@ -3189,12 +3194,33 @@ static unsigned int perf_poll(struct file *file, poll_table *wait)
        struct ring_buffer *rb;
        unsigned int events = POLL_HUP;
 
+       /*
+        * Race between perf_event_set_output() and perf_poll(): perf_poll()
+        * grabs the rb reference but perf_event_set_output() overrides it.
+        * Here is the timeline for two threads T1, T2:
+        * t0: T1, rb = rcu_dereference(event->rb)
+        * t1: T2, old_rb = event->rb
+        * t2: T2, event->rb = new rb
+        * t3: T2, ring_buffer_detach(old_rb)
+        * t4: T1, ring_buffer_attach(rb1)
+        * t5: T1, poll_wait(event->waitq)
+        *
+        * To avoid this problem, we grab mmap_mutex in perf_poll()
+        * thereby ensuring that the assignment of the new ring buffer
+        * and the detachment of the old buffer appear atomic to perf_poll()
+        */
+       mutex_lock(&event->mmap_mutex);
+
        rcu_read_lock();
        rb = rcu_dereference(event->rb);
-       if (rb)
+       if (rb) {
+               ring_buffer_attach(event, rb);
                events = atomic_xchg(&rb->poll, 0);
+       }
        rcu_read_unlock();
 
+       mutex_unlock(&event->mmap_mutex);
+
        poll_wait(file, &event->waitq, wait);
 
        return events;
@@ -3495,6 +3521,49 @@ unlock:
        return ret;
 }
 
+static void ring_buffer_attach(struct perf_event *event,
+                              struct ring_buffer *rb)
+{
+       unsigned long flags;
+
+       if (!list_empty(&event->rb_entry))
+               return;
+
+       spin_lock_irqsave(&rb->event_lock, flags);
+       if (!list_empty(&event->rb_entry))
+               goto unlock;
+
+       list_add(&event->rb_entry, &rb->event_list);
+unlock:
+       spin_unlock_irqrestore(&rb->event_lock, flags);
+}
+
+static void ring_buffer_detach(struct perf_event *event,
+                              struct ring_buffer *rb)
+{
+       unsigned long flags;
+
+       if (list_empty(&event->rb_entry))
+               return;
+
+       spin_lock_irqsave(&rb->event_lock, flags);
+       list_del_init(&event->rb_entry);
+       wake_up_all(&event->waitq);
+       spin_unlock_irqrestore(&rb->event_lock, flags);
+}
+
+static void ring_buffer_wakeup(struct perf_event *event)
+{
+       struct ring_buffer *rb;
+
+       rcu_read_lock();
+       rb = rcu_dereference(event->rb);
+       list_for_each_entry_rcu(event, &rb->event_list, rb_entry) {
+               wake_up_all(&event->waitq);
+       }
+       rcu_read_unlock();
+}
+
 static void rb_free_rcu(struct rcu_head *rcu_head)
 {
        struct ring_buffer *rb;
@@ -3520,9 +3589,19 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event)
 
 static void ring_buffer_put(struct ring_buffer *rb)
 {
+       struct perf_event *event, *n;
+       unsigned long flags;
+
        if (!atomic_dec_and_test(&rb->refcount))
                return;
 
+       spin_lock_irqsave(&rb->event_lock, flags);
+       list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) {
+               list_del_init(&event->rb_entry);
+               wake_up_all(&event->waitq);
+       }
+       spin_unlock_irqrestore(&rb->event_lock, flags);
+
        call_rcu(&rb->rcu_head, rb_free_rcu);
 }
 
@@ -3545,6 +3624,7 @@ static void perf_mmap_close(struct vm_area_struct *vma)
                atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
                vma->vm_mm->pinned_vm -= event->mmap_locked;
                rcu_assign_pointer(event->rb, NULL);
+               ring_buffer_detach(event, rb);
                mutex_unlock(&event->mmap_mutex);
 
                ring_buffer_put(rb);
@@ -3699,7 +3779,7 @@ static const struct file_operations perf_fops = {
 
 void perf_event_wakeup(struct perf_event *event)
 {
-       wake_up_all(&event->waitq);
+       ring_buffer_wakeup(event);
 
        if (event->pending_kill) {
                kill_fasync(&event->fasync, SIGIO, event->pending_kill);
@@ -5821,6 +5901,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
        INIT_LIST_HEAD(&event->group_entry);
        INIT_LIST_HEAD(&event->event_entry);
        INIT_LIST_HEAD(&event->sibling_list);
+       INIT_LIST_HEAD(&event->rb_entry);
+
        init_waitqueue_head(&event->waitq);
        init_irq_work(&event->pending, perf_pending_event);
 
@@ -6027,6 +6109,8 @@ set:
 
        old_rb = event->rb;
        rcu_assign_pointer(event->rb, rb);
+       if (old_rb)
+               ring_buffer_detach(event, old_rb);
        ret = 0;
 unlock:
        mutex_unlock(&event->mmap_mutex);
index 09097dd8116c0e0bf5120d4da26c5f539a7f600a..64568a699375f105232eb588963da8707f926295 100644 (file)
@@ -22,6 +22,9 @@ struct ring_buffer {
        local_t                         lost;           /* nr records lost   */
 
        long                            watermark;      /* wakeup watermark  */
+       /* poll crap */
+       spinlock_t                      event_lock;
+       struct list_head                event_list;
 
        struct perf_event_mmap_page     *user_page;
        void                            *data_pages[0];
index a2a29205cc0fc10913277132162e0a515a944552..7f3011c6b57fa3288c7e4c46a555736763765a84 100644 (file)
@@ -209,6 +209,9 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
                rb->writable = 1;
 
        atomic_set(&rb->refcount, 1);
+
+       INIT_LIST_HEAD(&rb->event_list);
+       spin_lock_init(&rb->event_lock);
 }
 
 #ifndef CONFIG_PERF_USE_VMALLOC
index 70d76191afb9449033f09ef2c3532d450defdd49..2753449f2038af61f6ac1cb1e3f305adbd3063f0 100644 (file)
@@ -162,7 +162,6 @@ static void account_kernel_stack(struct thread_info *ti, int account)
 
 void free_task(struct task_struct *tsk)
 {
-       prop_local_destroy_single(&tsk->dirties);
        account_kernel_stack(tsk->stack, -1);
        free_thread_info(tsk->stack);
        rt_mutex_debug_task_free(tsk);
@@ -274,10 +273,6 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 
        tsk->stack = ti;
 
-       err = prop_local_init_single(&tsk->dirties);
-       if (err)
-               goto out;
-
        setup_thread_stack(tsk, orig);
        clear_user_return_notifier(tsk);
        clear_tsk_need_resched(tsk);
@@ -875,6 +870,7 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
 {
 #ifdef CONFIG_BLOCK
        struct io_context *ioc = current->io_context;
+       struct io_context *new_ioc;
 
        if (!ioc)
                return 0;
@@ -886,11 +882,12 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
                if (unlikely(!tsk->io_context))
                        return -ENOMEM;
        } else if (ioprio_valid(ioc->ioprio)) {
-               tsk->io_context = alloc_io_context(GFP_KERNEL, -1);
-               if (unlikely(!tsk->io_context))
+               new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);
+               if (unlikely(!new_ioc))
                        return -ENOMEM;
 
-               tsk->io_context->ioprio = ioc->ioprio;
+               new_ioc->ioprio = ioc->ioprio;
+               put_io_context(new_ioc, NULL);
        }
 #endif
        return 0;
@@ -1299,6 +1296,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->pdeath_signal = 0;
        p->exit_state = 0;
 
+       p->nr_dirtied = 0;
+       p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
+
        /*
         * Ok, make it visible to the rest of the system.
         * We dont wake it up yet.
index 66a594e8ad2fe8b37bc238e940f162392663d1bf..7be56c53439723bb1f95ff43b6cb620ef1524193 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/syscalls.h>
 #include <linux/freezer.h>
 
@@ -67,7 +67,7 @@ static void fake_signal_wake_up(struct task_struct *p)
        unsigned long flags;
 
        spin_lock_irqsave(&p->sighand->siglock, flags);
-       signal_wake_up(p, 1);
+       signal_wake_up(p, 0);
        spin_unlock_irqrestore(&p->sighand->siglock, flags);
 }
 
index 1511dff0cfd6ff8f7e9d820456b2ac416b56d48d..ea87f4d2f455c8c99164cb555287ad1c9fb165e3 100644 (file)
@@ -55,7 +55,7 @@
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/magic.h>
 #include <linux/pid.h>
 #include <linux/nsproxy.h>
index 1cc476d52dd3b6e477ebd2d70a0d97b61219f189..99b53d1eb7ea50856424329f52f6e6ab3cc83d61 100644 (file)
@@ -2,7 +2,7 @@
  * Supplementary group IDs
  */
 #include <linux/cred.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
index a9205e32a059cde761f924c498d2984b0aacb36c..ae34bf51682b4a204de93f62943055350cd5c4d0 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include <linux/cpu.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/hrtimer.h>
 #include <linux/notifier.h>
@@ -885,10 +885,13 @@ static void __remove_hrtimer(struct hrtimer *timer,
                             struct hrtimer_clock_base *base,
                             unsigned long newstate, int reprogram)
 {
+       struct timerqueue_node *next_timer;
        if (!(timer->state & HRTIMER_STATE_ENQUEUED))
                goto out;
 
-       if (&timer->node == timerqueue_getnext(&base->active)) {
+       next_timer = timerqueue_getnext(&base->active);
+       timerqueue_del(&base->active, &timer->node);
+       if (&timer->node == next_timer) {
 #ifdef CONFIG_HIGH_RES_TIMERS
                /* Reprogram the clock event device. if enabled */
                if (reprogram && hrtimer_hres_active()) {
@@ -901,7 +904,6 @@ static void __remove_hrtimer(struct hrtimer *timer,
                }
 #endif
        }
-       timerqueue_del(&base->active, &timer->node);
        if (!timerqueue_getnext(&base->active))
                base->cpu_base->active_bases &= ~(1 << base->index);
 out:
index ea640120ab8606195e8fcddabe5c81180598b4cb..8b1748d0172c7e35672c98c9ab6e93b4d815f850 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/lockdep.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sysctl.h>
 
 /*
index 6cb7613e4bf4250e57ad05c54f0a0a62668676a4..c89295a8f6687098db746f9f81b99132a2f0c145 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/syscore_ops.h>
index 1550e8447a16b06a10e9ff1d95cd46633e9176a8..d86e254b95eb06123a57da2349b320871faa4f8a 100644 (file)
@@ -9,7 +9,7 @@
  */
 #include <linux/irq.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/radix-tree.h>
index 67ce837ae52cdd70115a8ce436f923e96a26adc4..1da999f5e746caedacb8b40d0015e7c3f273ad04 100644 (file)
@@ -623,8 +623,9 @@ static irqreturn_t irq_nested_primary_handler(int irq, void *dev_id)
 
 static int irq_wait_for_interrupt(struct irqaction *action)
 {
+       set_current_state(TASK_INTERRUPTIBLE);
+
        while (!kthread_should_stop()) {
-               set_current_state(TASK_INTERRUPTIBLE);
 
                if (test_and_clear_bit(IRQTF_RUNTHREAD,
                                       &action->thread_flags)) {
@@ -632,7 +633,9 @@ static int irq_wait_for_interrupt(struct irqaction *action)
                        return 0;
                }
                schedule();
+               set_current_state(TASK_INTERRUPTIBLE);
        }
+       __set_current_state(TASK_RUNNING);
        return -1;
 }
 
@@ -1596,7 +1599,7 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler,
                return -ENOMEM;
 
        action->handler = handler;
-       action->flags = IRQF_PERCPU;
+       action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND;
        action->name = devname;
        action->percpu_dev_id = dev_id;
 
index aa57d5da18c1de65e807098702ad9b841fa3788d..dc813a948be2379fe20a0218e1d270212b8408d3 100644 (file)
@@ -84,7 +84,9 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force)
         */
        action = desc->action;
        if (!action || !(action->flags & IRQF_SHARED) ||
-           (action->flags & __IRQF_TIMER) || !action->next)
+           (action->flags & __IRQF_TIMER) ||
+           (action->handler(irq, action->dev_id) == IRQ_HANDLED) ||
+           !action->next)
                goto out;
 
        /* Already running on another processor */
@@ -115,7 +117,7 @@ static int misrouted_irq(int irq)
        struct irq_desc *desc;
        int i, ok = 0;
 
-       if (atomic_inc_return(&irq_poll_active) == 1)
+       if (atomic_inc_return(&irq_poll_active) != 1)
                goto out;
 
        irq_poll_cpu = smp_processor_id();
index 0e2cde4f380ba7b8b50e37f8ba019538cfb9a6f2..c3c46c72046e37898ebbedb567b7eede3d67ae60 100644 (file)
@@ -6,9 +6,11 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/irq_work.h>
+#include <linux/percpu.h>
 #include <linux/hardirq.h>
+#include <asm/processor.h>
 
 /*
  * An entry can be in one of four states:
index a8ce45097f3d21354c7ed8c18e5fcbc4e11792d1..66ff7109f6970ca63cb4aa9bf6b4800d69ef2f3a 100644 (file)
@@ -66,8 +66,9 @@ void jump_label_inc(struct jump_label_key *key)
                return;
 
        jump_label_lock();
-       if (atomic_add_return(1, &key->enabled) == 1)
+       if (atomic_read(&key->enabled) == 0)
                jump_label_update(key, JUMP_LABEL_ENABLE);
+       atomic_inc(&key->enabled);
        jump_label_unlock();
 }
 
@@ -104,6 +105,18 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start,
        return 0;
 }
 
+/* 
+ * Update code which is definitely not currently executing.
+ * Architectures which need heavyweight synchronization to modify
+ * running code can override this to make the non-live update case
+ * cheaper.
+ */
+void __weak arch_jump_label_transform_static(struct jump_entry *entry,
+                                           enum jump_label_type type)
+{
+       arch_jump_label_transform(entry, type); 
+}
+
 static void __jump_label_update(struct jump_label_key *key,
                                struct jump_entry *entry,
                                struct jump_entry *stop, int enable)
@@ -121,14 +134,7 @@ static void __jump_label_update(struct jump_label_key *key,
        }
 }
 
-/*
- * Not all archs need this.
- */
-void __weak arch_jump_label_text_poke_early(jump_label_t addr)
-{
-}
-
-static __init int jump_label_init(void)
+void __init jump_label_init(void)
 {
        struct jump_entry *iter_start = __start___jump_table;
        struct jump_entry *iter_stop = __stop___jump_table;
@@ -139,22 +145,22 @@ static __init int jump_label_init(void)
        jump_label_sort_entries(iter_start, iter_stop);
 
        for (iter = iter_start; iter < iter_stop; iter++) {
-               arch_jump_label_text_poke_early(iter->code);
-               if (iter->key == (jump_label_t)(unsigned long)key)
+               struct jump_label_key *iterk;
+
+               iterk = (struct jump_label_key *)(unsigned long)iter->key;
+               arch_jump_label_transform_static(iter, jump_label_enabled(iterk) ?
+                                                JUMP_LABEL_ENABLE : JUMP_LABEL_DISABLE);
+               if (iterk == key)
                        continue;
 
-               key = (struct jump_label_key *)(unsigned long)iter->key;
-               atomic_set(&key->enabled, 0);
+               key = iterk;
                key->entries = iter;
 #ifdef CONFIG_MODULES
                key->next = NULL;
 #endif
        }
        jump_label_unlock();
-
-       return 0;
 }
-early_initcall(jump_label_init);
 
 #ifdef CONFIG_MODULES
 
@@ -212,7 +218,7 @@ void jump_label_apply_nops(struct module *mod)
                return;
 
        for (iter = iter_start; iter < iter_stop; iter++)
-               arch_jump_label_text_poke_early(iter->code);
+               arch_jump_label_transform_static(iter, JUMP_LABEL_DISABLE);
 }
 
 static int jump_label_add_module(struct module *mod)
index 01a0700e873f53ca60084da3c0c1142bebf49b16..c744b88c44e2d8ad0d4c4c3f395cfca0b4757a69 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/log2.h>
index 2f193d0ba7f237bc9fe87427981573ed0724dcab..e5d84644823b4094a4e6c629985daddd753bdd19 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/stddef.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/moduleloader.h>
 #include <linux/kallsyms.h>
 #include <linux/freezer.h>
index 3b053c04dd86fd926720c7843ba8a918cbc4e63d..4e316e1acf584dda201b2b7ee9369a05590229a3 100644 (file)
 #include <linux/kobject.h>
 #include <linux/string.h>
 #include <linux/sysfs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
 #include <linux/profile.h>
+#include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/capability.h>
 
index 4ba7cccb4994f24d6bc5965cda9b7f568d214f35..b6d216a92639fdeea3049a47b361660e7e44fa09 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/cpuset.h>
 #include <linux/unistd.h>
 #include <linux/file.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/freezer.h>
index 4ac8ebfcab599b79bc5becb2430f2412d85ca16c..a462b317f9a0002bb5d35de480f97c8a70b43c3f 100644 (file)
@@ -53,7 +53,7 @@
 #include <linux/notifier.h>
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/list.h>
 #include <linux/stacktrace.h>
index e69434b070da3f922909ece9417627e11234dcd6..b2e08c932d91c6507f07d637f61f0df1205778b8 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/stringify.h>
 #include <linux/bitops.h>
 #include <linux/gfp.h>
+#include <linux/kmemcheck.h>
 
 #include <asm/sections.h>
 
@@ -2948,7 +2949,12 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
 void lockdep_init_map(struct lockdep_map *lock, const char *name,
                      struct lock_class_key *key, int subclass)
 {
-       memset(lock, 0, sizeof(*lock));
+       int i;
+
+       kmemcheck_mark_initialized(lock, sizeof(*lock));
+
+       for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++)
+               lock->class_cache[i] = NULL;
 
 #ifdef CONFIG_LOCK_STAT
        lock->cpu = raw_smp_processor_id();
index 71edd2f60c026fb3f923a56302f8e445e0910fb4..91c32a0b612cd75038d96dc802c07528f1e80ade 100644 (file)
@@ -11,7 +11,7 @@
  * Code for /proc/lockdep and /proc/lockdep_stats:
  *
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/kallsyms.h>
index 93342d992f348c816bb18d091851e693695b8931..178333c48d1e5a60bfac3f3bef928452dd09aca2 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/moduleloader.h>
 #include <linux/ftrace_event.h>
 #include <linux/init.h>
@@ -2487,6 +2487,9 @@ static int check_modinfo(struct module *mod, struct load_info *info)
                return -ENOEXEC;
        }
 
+       if (!get_modinfo(info, "intree"))
+               add_taint_module(mod, TAINT_OOT_MODULE);
+
        if (get_modinfo(info, "staging")) {
                add_taint_module(mod, TAINT_CRAP);
                printk(KERN_WARNING "%s: module is from the staging directory,"
@@ -2878,8 +2881,7 @@ static struct module *load_module(void __user *umod,
        }
 
        /* This has to be done once we're sure module name is unique. */
-       if (!mod->taints || mod->taints == (1U<<TAINT_CRAP))
-               dynamic_debug_setup(info.debug, info.num_debug);
+       dynamic_debug_setup(info.debug, info.num_debug);
 
        /* Find duplicate symbols */
        err = verify_export_symbols(mod);
@@ -2915,8 +2917,7 @@ static struct module *load_module(void __user *umod,
        module_bug_cleanup(mod);
 
  ddebug:
-       if (!mod->taints || mod->taints == (1U<<TAINT_CRAP))
-               dynamic_debug_remove(info.debug);
+       dynamic_debug_remove(info.debug);
  unlock:
        mutex_unlock(&module_mutex);
        synchronize_sched();
@@ -3257,6 +3258,8 @@ static char *module_flags(struct module *mod, char *buf)
                buf[bx++] = '(';
                if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
                        buf[bx++] = 'P';
+               else if (mod->taints & (1 << TAINT_OOT_MODULE))
+                       buf[bx++] = 'O';
                if (mod->taints & (1 << TAINT_FORCED_MODULE))
                        buf[bx++] = 'F';
                if (mod->taints & (1 << TAINT_CRAP))
index 73da83aff418d30d0b488454bf95bb172467cb82..7e3443fe1f48a1dbea11f7287fd3a362f1adb2a7 100644 (file)
@@ -14,7 +14,7 @@
  */
 #include <linux/mutex.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/poison.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
index d607ed5dd4416b5a688a271d788d7c2e51190662..89096dd8786f8e6ca02fa98023a569d6d80df747 100644 (file)
@@ -19,7 +19,7 @@
  */
 #include <linux/mutex.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/debug_locks.h>
index 8d7b435806c99bc4c79371ccf54b87b2fc209fd7..2d5cc4ccff7f4b79f734bf12ea769fb14a2346b2 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/kdebug.h>
 #include <linux/kprobes.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/notifier.h>
 #include <linux/rcupdate.h>
 #include <linux/vmalloc.h>
index 9aeab4b98c6431f8b8a17ee97992925d34c3a427..b576f7f14bc6957fdf04ba0324f7416f78995c6a 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nsproxy.h>
 #include <linux/init_task.h>
 #include <linux/mnt_namespace.h>
index b91941df5e631f7d0e971ef71489a616f5f2926e..b45259931512e99cd3dfd8214cce7895ee34fe54 100644 (file)
@@ -18,7 +18,7 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/cpumask.h>
 #include <linux/err.h>
 #include <linux/cpu.h>
index d7bb6974efb56b6070a6c9067bd87ba55a7273da..b26593604214c840672b2c72a8c8ffee608c7088 100644 (file)
@@ -177,6 +177,7 @@ static const struct tnt tnts[] = {
        { TAINT_WARN,                   'W', ' ' },
        { TAINT_CRAP,                   'C', ' ' },
        { TAINT_FIRMWARE_WORKAROUND,    'I', ' ' },
+       { TAINT_OOT_MODULE,             'O', ' ' },
 };
 
 /**
@@ -194,6 +195,7 @@ static const struct tnt tnts[] = {
  *  'W' - Taint on warning.
  *  'C' - modules from drivers/staging are loaded.
  *  'I' - Working around severe firmware bug.
+ *  'O' - Out-of-tree module has been loaded.
  *
  *     The string is overwritten by the next call to print_tainted().
  */
index 821788947e40106aaaa9c3e6f646373a8264aff5..65aae11eb93f1fab5a4673ca9e9d4df9f2582e8e 100644 (file)
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
index 8cafe7e72ad2b83ff0bc7f7d0e12b710e6f9a519..fa5f72227e5f432127c4f3b1383e3c93abcd0eaa 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rculist.h>
index 4556182527f38fe88dba74dd753cec5ed0112785..69185ae6b701742de8977760234c5accda366dfd 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/syscalls.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 /*
  * Management arrays for POSIX timers.  Timers are kept in slab memory
index 1c53f7fad5f7ba9e4fd20cd85e5021755c71ada8..a6b0503574ee714b2cbe6c871741d298ad9ce5f7 100644 (file)
@@ -9,6 +9,7 @@
  * This file is released under the GPLv2.
  */
 
+#include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
 #include <linux/reboot.h>
@@ -54,6 +55,8 @@ enum {
 
 static int hibernation_mode = HIBERNATION_SHUTDOWN;
 
+static bool freezer_test_done;
+
 static const struct platform_hibernation_ops *hibernation_ops;
 
 /**
@@ -344,11 +347,24 @@ int hibernation_snapshot(int platform_mode)
 
        error = freeze_kernel_threads();
        if (error)
-               goto Close;
+               goto Cleanup;
+
+       if (hibernation_test(TEST_FREEZER) ||
+               hibernation_testmode(HIBERNATION_TESTPROC)) {
+
+               /*
+                * Indicate to the caller that we are returning due to a
+                * successful freezer test.
+                */
+               freezer_test_done = true;
+               goto Cleanup;
+       }
 
        error = dpm_prepare(PMSG_FREEZE);
-       if (error)
-               goto Complete_devices;
+       if (error) {
+               dpm_complete(msg);
+               goto Cleanup;
+       }
 
        suspend_console();
        pm_restrict_gfp_mask();
@@ -377,8 +393,6 @@ int hibernation_snapshot(int platform_mode)
                pm_restore_gfp_mask();
 
        resume_console();
-
- Complete_devices:
        dpm_complete(msg);
 
  Close:
@@ -388,6 +402,10 @@ int hibernation_snapshot(int platform_mode)
  Recover_platform:
        platform_recover(platform_mode);
        goto Resume_devices;
+
+ Cleanup:
+       swsusp_free();
+       goto Close;
 }
 
 /**
@@ -640,15 +658,13 @@ int hibernate(void)
        if (error)
                goto Finish;
 
-       if (hibernation_test(TEST_FREEZER))
-               goto Thaw;
-
-       if (hibernation_testmode(HIBERNATION_TESTPROC))
-               goto Thaw;
-
        error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
        if (error)
                goto Thaw;
+       if (freezer_test_done) {
+               freezer_test_done = false;
+               goto Thaw;
+       }
 
        if (in_suspend) {
                unsigned int flags = 0;
index a52e88425a31a351cb7b80822462503e0c74dbbe..36e0f0903c3245e60d2994121d1aaa28c8fc0a23 100644 (file)
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/export.h>
 #include <linux/kobject.h>
 #include <linux/string.h>
 #include <linux/resume-trace.h>
@@ -289,13 +290,14 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
                if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
                        break;
        }
-       if (state < PM_SUSPEND_MAX && *s)
+       if (state < PM_SUSPEND_MAX && *s) {
                error = enter_state(state);
                if (error) {
                        suspend_stats.fail++;
                        dpm_save_failed_errno(error);
                } else
                        suspend_stats.success++;
+       }
 #endif
 
  Exit:
index 1c1797dd1d1d3f05c3260f47e0f6c22efc1c815c..995e3bd3417b930902317f9cb0e23dfa4811c36c 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/kernel.h>
 
 #include <linux/uaccess.h>
+#include <linux/export.h>
 
 /*
  * locking rule: all changes to constraints or notifiers lists
@@ -69,6 +70,7 @@ static struct pm_qos_constraints cpu_dma_constraints = {
 };
 static struct pm_qos_object cpu_dma_pm_qos = {
        .constraints = &cpu_dma_constraints,
+       .name = "cpu_dma_latency",
 };
 
 static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
@@ -386,8 +388,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
                pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
                filp->private_data = req;
 
-               if (filp->private_data)
-                       return 0;
+               return 0;
        }
        return -EPERM;
 }
index fdd4263b995d4c1e15f26188b3dacf47d30dec08..4953dc054c53c2af14ca9af22e5f64394feaf244 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/kmod.h>
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
@@ -21,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
 #include <trace/events/power.h>
index 42ddbc6f0de6ffcf2d245dd9c8ec253c2780ffab..6d8f535c2b88e11952b3871ecb88d8fa0378ab40 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
 #include <linux/reboot.h>
+#include <linux/kmod.h>
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/miscdevice.h>
index 1455a0d4eedd4b386c759d689f939ba5d7a9007a..7982a0a841eaf082fe929e24a1f4bd5aefd4f015 100644 (file)
@@ -1293,10 +1293,11 @@ again:
        raw_spin_lock(&logbuf_lock);
        if (con_start != log_end)
                retry = 1;
+       raw_spin_unlock_irqrestore(&logbuf_lock, flags);
+
        if (retry && console_trylock())
                goto again;
 
-       raw_spin_unlock_irqrestore(&logbuf_lock, flags);
        if (wake_klogd)
                wake_up_klogd();
 }
index 961b389fe52fec5324910d5b85f6eb3b6749a43d..76b8e77773eecb3120b87faa0a0b23e2b4cb8fd3 100644 (file)
@@ -13,7 +13,7 @@
  *     to resolve timer interrupt livelocks, William Irwin, Oracle, 2004
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/profile.h>
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
index a70d2a5d8c7b1fd4bbbefb2d918136f5ce933875..24d04477b2575f0239782cf6287298a47d50f48c 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/capability.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
index 37fa9b99ad588356534b1457b7241d97573705b8..9b8ae2d6ed68794ac4b010999465990b24053f5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Range add and subtract
  */
-#include <linux/module.h>
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sort.h>
 
index ca0d23b6b3e86461f34cfb003858ed2028045e84..c5b98e565aee28e711c71f5acd49cd3a34b99530 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/mutex.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/hardirq.h>
 
 #define CREATE_TRACE_POINTS
index da775c87f27f6aa146bf9b929f72fe0e386d8b41..636af6d9c6e565ca6e6d7010941501901c8322b4 100644 (file)
  * For detailed explanation of Read-Copy Update mechanism see -
  *             Documentation/RCU
  */
-#include <linux/moduleparam.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/rcupdate.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/types.h>
index 02aa7139861ca2671328b253be2009ee5b4c41be..2b0484a5dc285bcb68773843a934cd0cc05212c8 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/kthread.h>
+#include <linux/module.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 
index e234eb92a17739ddaf77e764fc8c6c12e611b235..6b76d812740ce04590500a73f73f402d2f00e8ef 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/nmi.h>
 #include <linux/atomic.h>
 #include <linux/bitops.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/completion.h>
 #include <linux/moduleparam.h>
 #include <linux/percpu.h>
index 859ea5a9605fa40fe47aedcb865ab08c66a43797..226fade4d72719fc0e681fb2be6abe515756fd17 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/errno.h>
 #include <linux/stddef.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/relay.h>
 #include <linux/vmalloc.h>
index c8dc249da5ce6a9e8e90523006b24477a2355636..7640b3a947d03aac578bee5849324843a0866798 100644 (file)
@@ -7,7 +7,7 @@
  * Arbitrary resource management.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
index a2e7e7210f3e733b8b427b762b224a4c380e9ae6..8eafd1bd273ed43dd3b4f35898241530e851e719 100644 (file)
@@ -18,7 +18,7 @@
  */
 #include <linux/sched.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/kallsyms.h>
 #include <linux/syscalls.h>
index 5c9ccd3809668b48b1f9bcdfd3098eef726101ed..3d9f31cd79e70dc1510c15fb47b9b5741862a1d8 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 #include <linux/kthread.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/sysdev.h>
index 5e8d9cce7470dad6fd2427fd6c2349ddea6aeb9e..f9d8482dd4872f631b8bfb3524f5797b2eb711f4 100644 (file)
@@ -11,7 +11,7 @@
  *  See Documentation/rt-mutex-design.txt for details.
  */
 #include <linux/spinlock.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 
index 9f48f3d82e9b8e2d4b65df9588ed15da574d70ed..b152f74f02de3d211c5bc4fb0effbe3ce771c528 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/rwsem.h>
 
 #include <asm/system.h>
index d87c6e5d4e8c0e790791908fd20929e8c7e2c7c7..d6b149ccf925c320841e8a42f31fd23b6ee64dc6 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/ctype.h>
 #include <linux/ftrace.h>
 #include <linux/slab.h>
+#include <linux/init_task.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -4810,6 +4811,9 @@ EXPORT_SYMBOL(wait_for_completion);
  * This waits for either a completion of a specific task to be signaled or for a
  * specified timeout to expire. The timeout is in jiffies. It is not
  * interruptible.
+ *
+ * The return value is 0 if timed out, and positive (at least 1, or number of
+ * jiffies left till timeout) if completed.
  */
 unsigned long __sched
 wait_for_completion_timeout(struct completion *x, unsigned long timeout)
@@ -4824,6 +4828,8 @@ EXPORT_SYMBOL(wait_for_completion_timeout);
  *
  * This waits for completion of a specific task to be signaled. It is
  * interruptible.
+ *
+ * The return value is -ERESTARTSYS if interrupted, 0 if completed.
  */
 int __sched wait_for_completion_interruptible(struct completion *x)
 {
@@ -4841,6 +4847,9 @@ EXPORT_SYMBOL(wait_for_completion_interruptible);
  *
  * This waits for either a completion of a specific task to be signaled or for a
  * specified timeout to expire. It is interruptible. The timeout is in jiffies.
+ *
+ * The return value is -ERESTARTSYS if interrupted, 0 if timed out,
+ * positive (at least 1, or number of jiffies left till timeout) if completed.
  */
 long __sched
 wait_for_completion_interruptible_timeout(struct completion *x,
@@ -4856,6 +4865,8 @@ EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
  *
  * This waits to be signaled for completion of a specific task. It can be
  * interrupted by a kill signal.
+ *
+ * The return value is -ERESTARTSYS if interrupted, 0 if completed.
  */
 int __sched wait_for_completion_killable(struct completion *x)
 {
@@ -4874,6 +4885,9 @@ EXPORT_SYMBOL(wait_for_completion_killable);
  * This waits for either a completion of a specific task to be
  * signaled or for a specified timeout to expire. It can be
  * interrupted by a kill signal. The timeout is in jiffies.
+ *
+ * The return value is -ERESTARTSYS if interrupted, 0 if timed out,
+ * positive (at least 1, or number of jiffies left till timeout) if completed.
  */
 long __sched
 wait_for_completion_killable_timeout(struct completion *x,
@@ -6099,6 +6113,9 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
         */
        idle->sched_class = &idle_sched_class;
        ftrace_graph_init_idle_task(idle, cpu);
+#if defined(CONFIG_SMP)
+       sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
+#endif
 }
 
 /*
@@ -7087,8 +7104,6 @@ static int __init isolated_cpu_setup(char *str)
 
 __setup("isolcpus=", isolated_cpu_setup);
 
-#define SD_NODES_PER_DOMAIN 16
-
 #ifdef CONFIG_NUMA
 
 /**
index 9d8af0b3fb64544d9ca7076f3478d2239b46540e..c685e31492dfcd38ff830ffbc0aecbd77e29ee83 100644 (file)
@@ -62,7 +62,7 @@
  */
 #include <linux/spinlock.h>
 #include <linux/hardirq.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/ktime.h>
 #include <linux/sched.h>
index 5c9e67923b7cfd7826903c17322c3f0c55de5d74..a78ed2736ba79f02a201d8256bd9e0a56d57981e 100644 (file)
@@ -772,19 +772,32 @@ static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
                list_del_leaf_cfs_rq(cfs_rq);
 }
 
+static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
+{
+       long tg_weight;
+
+       /*
+        * Use this CPU's actual weight instead of the last load_contribution
+        * to gain a more accurate current total weight. See
+        * update_cfs_rq_load_contribution().
+        */
+       tg_weight = atomic_read(&tg->load_weight);
+       tg_weight -= cfs_rq->load_contribution;
+       tg_weight += cfs_rq->load.weight;
+
+       return tg_weight;
+}
+
 static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
 {
-       long load_weight, load, shares;
+       long tg_weight, load, shares;
 
+       tg_weight = calc_tg_weight(tg, cfs_rq);
        load = cfs_rq->load.weight;
 
-       load_weight = atomic_read(&tg->load_weight);
-       load_weight += load;
-       load_weight -= cfs_rq->load_contribution;
-
        shares = (tg->shares * load);
-       if (load_weight)
-               shares /= load_weight;
+       if (tg_weight)
+               shares /= tg_weight;
 
        if (shares < MIN_SHARES)
                shares = MIN_SHARES;
@@ -1743,7 +1756,7 @@ static void __return_cfs_rq_runtime(struct cfs_rq *cfs_rq)
 
 static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq)
 {
-       if (!cfs_rq->runtime_enabled || !cfs_rq->nr_running)
+       if (!cfs_rq->runtime_enabled || cfs_rq->nr_running)
                return;
 
        __return_cfs_rq_runtime(cfs_rq);
@@ -2036,36 +2049,100 @@ static void task_waking_fair(struct task_struct *p)
  * Adding load to a group doesn't make a group heavier, but can cause movement
  * of group shares between cpus. Assuming the shares were perfectly aligned one
  * can calculate the shift in shares.
+ *
+ * Calculate the effective load difference if @wl is added (subtracted) to @tg
+ * on this @cpu and results in a total addition (subtraction) of @wg to the
+ * total group weight.
+ *
+ * Given a runqueue weight distribution (rw_i) we can compute a shares
+ * distribution (s_i) using:
+ *
+ *   s_i = rw_i / \Sum rw_j                                            (1)
+ *
+ * Suppose we have 4 CPUs and our @tg is a direct child of the root group and
+ * has 7 equal weight tasks, distributed as below (rw_i), with the resulting
+ * shares distribution (s_i):
+ *
+ *   rw_i = {   2,   4,   1,   0 }
+ *   s_i  = { 2/7, 4/7, 1/7,   0 }
+ *
+ * As per wake_affine() we're interested in the load of two CPUs (the CPU the
+ * task used to run on and the CPU the waker is running on), we need to
+ * compute the effect of waking a task on either CPU and, in case of a sync
+ * wakeup, compute the effect of the current task going to sleep.
+ *
+ * So for a change of @wl to the local @cpu with an overall group weight change
+ * of @wl we can compute the new shares distribution (s'_i) using:
+ *
+ *   s'_i = (rw_i + @wl) / (@wg + \Sum rw_j)                           (2)
+ *
+ * Suppose we're interested in CPUs 0 and 1, and want to compute the load
+ * differences in waking a task to CPU 0. The additional task changes the
+ * weight and shares distributions like:
+ *
+ *   rw'_i = {   3,   4,   1,   0 }
+ *   s'_i  = { 3/8, 4/8, 1/8,   0 }
+ *
+ * We can then compute the difference in effective weight by using:
+ *
+ *   dw_i = S * (s'_i - s_i)                                           (3)
+ *
+ * Where 'S' is the group weight as seen by its parent.
+ *
+ * Therefore the effective change in loads on CPU 0 would be 5/56 (3/8 - 2/7)
+ * times the weight of the group. The effect on CPU 1 would be -4/56 (4/8 -
+ * 4/7) times the weight of the group.
  */
 static long effective_load(struct task_group *tg, int cpu, long wl, long wg)
 {
        struct sched_entity *se = tg->se[cpu];
 
-       if (!tg->parent)
+       if (!tg->parent)        /* the trivial, non-cgroup case */
                return wl;
 
        for_each_sched_entity(se) {
-               long lw, w;
+               long w, W;
 
                tg = se->my_q->tg;
-               w = se->my_q->load.weight;
 
-               /* use this cpu's instantaneous contribution */
-               lw = atomic_read(&tg->load_weight);
-               lw -= se->my_q->load_contribution;
-               lw += w + wg;
+               /*
+                * W = @wg + \Sum rw_j
+                */
+               W = wg + calc_tg_weight(tg, se->my_q);
 
-               wl += w;
+               /*
+                * w = rw_i + @wl
+                */
+               w = se->my_q->load.weight + wl;
 
-               if (lw > 0 && wl < lw)
-                       wl = (wl * tg->shares) / lw;
+               /*
+                * wl = S * s'_i; see (2)
+                */
+               if (W > 0 && w < W)
+                       wl = (w * tg->shares) / W;
                else
                        wl = tg->shares;
 
-               /* zero point is MIN_SHARES */
+               /*
+                * Per the above, wl is the new se->load.weight value; since
+                * those are clipped to [MIN_SHARES, ...) do so now. See
+                * calc_cfs_shares().
+                */
                if (wl < MIN_SHARES)
                        wl = MIN_SHARES;
+
+               /*
+                * wl = dw_i = S * (s'_i - s_i); see (3)
+                */
                wl -= se->load.weight;
+
+               /*
+                * Recursively apply this logic to all parent groups to compute
+                * the final effective load change on the root group. Since
+                * only the @tg group gets extra weight, all parent groups can
+                * only redistribute existing shares. @wl is the shift in shares
+                * resulting from this level per the above.
+                */
                wg = 0;
        }
 
@@ -2249,7 +2326,8 @@ static int select_idle_sibling(struct task_struct *p, int target)
        int cpu = smp_processor_id();
        int prev_cpu = task_cpu(p);
        struct sched_domain *sd;
-       int i;
+       struct sched_group *sg;
+       int i, smt = 0;
 
        /*
         * If the task is going to be woken-up on this cpu and if it is
@@ -2269,25 +2347,38 @@ static int select_idle_sibling(struct task_struct *p, int target)
         * Otherwise, iterate the domains and find an elegible idle cpu.
         */
        rcu_read_lock();
+again:
        for_each_domain(target, sd) {
-               if (!(sd->flags & SD_SHARE_PKG_RESOURCES))
-                       break;
+               if (!smt && (sd->flags & SD_SHARE_CPUPOWER))
+                       continue;
 
-               for_each_cpu_and(i, sched_domain_span(sd), tsk_cpus_allowed(p)) {
-                       if (idle_cpu(i)) {
-                               target = i;
-                               break;
+               if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) {
+                       if (!smt) {
+                               smt = 1;
+                               goto again;
                        }
+                       break;
                }
 
-               /*
-                * Lets stop looking for an idle sibling when we reached
-                * the domain that spans the current cpu and prev_cpu.
-                */
-               if (cpumask_test_cpu(cpu, sched_domain_span(sd)) &&
-                   cpumask_test_cpu(prev_cpu, sched_domain_span(sd)))
-                       break;
+               sg = sd->groups;
+               do {
+                       if (!cpumask_intersects(sched_group_cpus(sg),
+                                               tsk_cpus_allowed(p)))
+                               goto next;
+
+                       for_each_cpu(i, sched_group_cpus(sg)) {
+                               if (!idle_cpu(i))
+                                       goto next;
+                       }
+
+                       target = cpumask_first_and(sched_group_cpus(sg),
+                                       tsk_cpus_allowed(p));
+                       goto done;
+next:
+                       sg = sg->next;
+               } while (sg != sd->groups);
        }
+done:
        rcu_read_unlock();
 
        return target;
@@ -3511,7 +3602,7 @@ static bool update_sd_pick_busiest(struct sched_domain *sd,
 }
 
 /**
- * update_sd_lb_stats - Update sched_group's statistics for load balancing.
+ * update_sd_lb_stats - Update sched_domain's statistics for load balancing.
  * @sd: sched_domain whose statistics are to be updated.
  * @this_cpu: Cpu for which load balance is currently performed.
  * @idle: Idle status of this_cpu
index efa0a7b75dde7408e89bd07e5b1a490c4f68ea95..84802245abd2562acad3c0eb734fe48cc5213b8e 100644 (file)
@@ -67,3 +67,4 @@ SCHED_FEAT(NONTASK_POWER, 1)
 SCHED_FEAT(TTWU_QUEUE, 1)
 
 SCHED_FEAT(FORCE_SD_OVERLAP, 0)
+SCHED_FEAT(RT_RUNTIME_SHARE, 1)
index 056cbd2e2a27fea8cb15e76bfc711fe32de03303..583a1368afe6ed7d96879d762f73553b2068e27c 100644 (file)
@@ -560,6 +560,9 @@ static int balance_runtime(struct rt_rq *rt_rq)
 {
        int more = 0;
 
+       if (!sched_feat(RT_RUNTIME_SHARE))
+               return more;
+
        if (rt_rq->rt_time > rt_rq->rt_runtime) {
                raw_spin_unlock(&rt_rq->rt_runtime_lock);
                more = do_balance_runtime(rt_rq);
index d831841e55a7cb545a390cd5494ff6d04b3a7817..60636a4e25c3d47217100f9a89dcb3ee96452d54 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <linux/compiler.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/semaphore.h>
 #include <linux/spinlock.h>
index d252be2d3de50e5c3f3a871cbd307bb7518aeac4..b3f78d09a1053b67f62719a8879f6619ae12253b 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
index fb67dfa8394edc70174a51fd93b72965a3929b71..db197d60489b7c144f2f44fbea00e15944e31871 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/gfp.h>
index fca82c32042b73133f2ab74838287c94cf8ad152..2c71d91efff0f8e05b526bbe2f7260cba986a59a 100644 (file)
@@ -10,7 +10,7 @@
  *     Remote softirq infrastructure is by Jens Axboe.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
index be6517fb9c14e66b4b4b0d7d40e91ac8b56ee06a..84c7d96918bf44b8b155d4c72afbd35e6a3bd6cd 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/debug_locks.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 /*
  * If lockdep is enabled then we use the non-preemption spin-ops
index 73ce23feaea9d27fb79d36b23fba4ad9e8c428aa..0febf61e1aa36dc8d82fbe71ac14f14e6b1dff8d 100644 (file)
@@ -24,7 +24,7 @@
  *
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/percpu.h>
 #include <linux/preempt.h>
index d20c6983aad903636d920737dfd8e9fd0be5b4d4..00fe55cc5a829a76b5b6faee8c2052b9f64e65b7 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kallsyms.h>
 #include <linux/stacktrace.h>
 
index 5b0951aa04963dc6834e8ed1e8a9d26e08659bac..2f194e965715183786f2f8b640ddcbbf1b456dc4 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/kthread.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/stop_machine.h>
index d06c091e0345d7c5fb1d0efccf4e8c9e258bdab8..481611fbd079a90094876bd2ef9743803fa45576 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/mman.h>
@@ -12,6 +12,7 @@
 #include <linux/prctl.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
+#include <linux/kmod.h>
 #include <linux/perf_event.h>
 #include <linux/resource.h>
 #include <linux/kernel.h>
index d77606214529a9a5c75f549eb999bbdf99342a76..73e416db0a1e6b23205cc416864ea2c91b9d26d0 100644 (file)
@@ -27,7 +27,7 @@
  *     with nanosecond accuracy
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/clocksource.h>
index c436e790b21bf7cd89878eb9d92146e1b1c511d6..8a46f5d64504f15dcaf31ec4f5fcee7ea15a8bdf 100644 (file)
@@ -195,7 +195,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
                struct alarm *alarm;
                ktime_t expired = next->expires;
 
-               if (expired.tv64 >= now.tv64)
+               if (expired.tv64 > now.tv64)
                        break;
 
                alarm = container_of(next, struct alarm, node);
index 1ecd6ba36d6c6d3d0ce404450878ea5da047e01d..c4eb71c8b2ea3290c6b83f2f6d72b3c8c62a7787 100644 (file)
@@ -387,6 +387,7 @@ void clockevents_exchange_device(struct clock_event_device *old,
         * released list and do a notify add later.
         */
        if (old) {
+               old->event_handler = clockevents_handle_noop;
                clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
                list_del(&old->list);
                list_add(&old->list, &clockevents_released);
index cf52fda2e0966d005e152ff8747d5d44db5fbd7a..da2f760e780c9cdf7d1e2b4b02cbf9fffa900cea 100644 (file)
@@ -491,6 +491,22 @@ void clocksource_touch_watchdog(void)
        clocksource_resume_watchdog();
 }
 
+/**
+ * clocksource_max_adjustment- Returns max adjustment amount
+ * @cs:         Pointer to clocksource
+ *
+ */
+static u32 clocksource_max_adjustment(struct clocksource *cs)
+{
+       u64 ret;
+       /*
+        * We won't try to correct for more then 11% adjustments (110,000 ppm),
+        */
+       ret = (u64)cs->mult * 11;
+       do_div(ret,100);
+       return (u32)ret;
+}
+
 /**
  * clocksource_max_deferment - Returns max time the clocksource can be deferred
  * @cs:         Pointer to clocksource
@@ -503,25 +519,28 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
        /*
         * Calculate the maximum number of cycles that we can pass to the
         * cyc2ns function without overflowing a 64-bit signed result. The
-        * maximum number of cycles is equal to ULLONG_MAX/cs->mult which
-        * is equivalent to the below.
-        * max_cycles < (2^63)/cs->mult
-        * max_cycles < 2^(log2((2^63)/cs->mult))
-        * max_cycles < 2^(log2(2^63) - log2(cs->mult))
-        * max_cycles < 2^(63 - log2(cs->mult))
-        * max_cycles < 1 << (63 - log2(cs->mult))
+        * maximum number of cycles is equal to ULLONG_MAX/(cs->mult+cs->maxadj)
+        * which is equivalent to the below.
+        * max_cycles < (2^63)/(cs->mult + cs->maxadj)
+        * max_cycles < 2^(log2((2^63)/(cs->mult + cs->maxadj)))
+        * max_cycles < 2^(log2(2^63) - log2(cs->mult + cs->maxadj))
+        * max_cycles < 2^(63 - log2(cs->mult + cs->maxadj))
+        * max_cycles < 1 << (63 - log2(cs->mult + cs->maxadj))
         * Please note that we add 1 to the result of the log2 to account for
         * any rounding errors, ensure the above inequality is satisfied and
         * no overflow will occur.
         */
-       max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
+       max_cycles = 1ULL << (63 - (ilog2(cs->mult + cs->maxadj) + 1));
 
        /*
         * The actual maximum number of cycles we can defer the clocksource is
         * determined by the minimum of max_cycles and cs->mask.
+        * Note: Here we subtract the maxadj to make sure we don't sleep for
+        * too long if there's a large negative adjustment.
         */
        max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
-       max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
+       max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult - cs->maxadj,
+                                       cs->shift);
 
        /*
         * To ensure that the clocksource does not wrap whilst we are idle,
@@ -529,7 +548,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
         * note a margin of 12.5% is used because this can be computed with
         * a shift, versus say 10% which would require division.
         */
-       return max_nsecs - (max_nsecs >> 5);
+       return max_nsecs - (max_nsecs >> 3);
 }
 
 #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
@@ -640,7 +659,6 @@ static void clocksource_enqueue(struct clocksource *cs)
 void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 {
        u64 sec;
-
        /*
         * Calc the maximum number of seconds which we can run before
         * wrapping around. For clocksources which have a mask > 32bit
@@ -651,7 +669,7 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
         * ~ 0.06ppm granularity for NTP. We apply the same 12.5%
         * margin as we do in clocksource_max_deferment()
         */
-       sec = (cs->mask - (cs->mask >> 5));
+       sec = (cs->mask - (cs->mask >> 3));
        do_div(sec, freq);
        do_div(sec, scale);
        if (!sec)
@@ -661,6 +679,20 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 
        clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
                               NSEC_PER_SEC / scale, sec * scale);
+
+       /*
+        * for clocksources that have large mults, to avoid overflow.
+        * Since mult may be adjusted by ntp, add an safety extra margin
+        *
+        */
+       cs->maxadj = clocksource_max_adjustment(cs);
+       while ((cs->mult + cs->maxadj < cs->mult)
+               || (cs->mult - cs->maxadj > cs->mult)) {
+               cs->mult >>= 1;
+               cs->shift--;
+               cs->maxadj = clocksource_max_adjustment(cs);
+       }
+
        cs->max_idle_ns = clocksource_max_deferment(cs);
 }
 EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
@@ -701,6 +733,12 @@ EXPORT_SYMBOL_GPL(__clocksource_register_scale);
  */
 int clocksource_register(struct clocksource *cs)
 {
+       /* calculate max adjustment for given mult/shift */
+       cs->maxadj = clocksource_max_adjustment(cs);
+       WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
+               "Clocksource %s might overflow on 11%% adjustment\n",
+               cs->name);
+
        /* calculate max idle time permitted for this clocksource */
        cs->max_idle_ns = clocksource_max_deferment(cs);
 
index c340ca658f37a0c09726a31a6f126f18c9380355..ce033c7aa2e8f8a179ae4a031c176e1a358a100d 100644 (file)
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/file.h>
 #include <linux/posix-clock.h>
 #include <linux/slab.h>
index f954282d9a82758acf951960392e37b5b07c6014..fd4a7b1625a20b35fad917817e136fdbd2d48e62 100644 (file)
@@ -71,7 +71,7 @@ int tick_check_broadcast_device(struct clock_event_device *dev)
             (dev->features & CLOCK_EVT_FEAT_C3STOP))
                return 0;
 
-       clockevents_exchange_device(NULL, dev);
+       clockevents_exchange_device(tick_broadcast_device.evtdev, dev);
        tick_broadcast_device.evtdev = dev;
        if (!cpumask_empty(tick_get_broadcast_mask()))
                tick_broadcast_start_periodic(dev);
index 2b021b0e8507e7e4f9951780c88877bb2d4d56bd..237841378c031ef0f2fa6c492559e695a111b74f 100644 (file)
@@ -249,6 +249,8 @@ ktime_t ktime_get(void)
                secs = xtime.tv_sec + wall_to_monotonic.tv_sec;
                nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
                nsecs += timekeeping_get_ns();
+               /* If arch requires, add in gettimeoffset() */
+               nsecs += arch_gettimeoffset();
 
        } while (read_seqretry(&xtime_lock, seq));
        /*
@@ -280,6 +282,8 @@ void ktime_get_ts(struct timespec *ts)
                *ts = xtime;
                tomono = wall_to_monotonic;
                nsecs = timekeeping_get_ns();
+               /* If arch requires, add in gettimeoffset() */
+               nsecs += arch_gettimeoffset();
 
        } while (read_seqretry(&xtime_lock, seq));
 
@@ -802,14 +806,44 @@ static void timekeeping_adjust(s64 offset)
        s64 error, interval = timekeeper.cycle_interval;
        int adj;
 
+       /*
+        * The point of this is to check if the error is greater then half
+        * an interval.
+        *
+        * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs.
+        *
+        * Note we subtract one in the shift, so that error is really error*2.
+        * This "saves" dividing(shifting) intererval twice, but keeps the
+        * (error > interval) comparision as still measuring if error is
+        * larger then half an interval.
+        *
+        * Note: It does not "save" on aggrivation when reading the code.
+        */
        error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1);
        if (error > interval) {
+               /*
+                * We now divide error by 4(via shift), which checks if
+                * the error is greater then twice the interval.
+                * If it is greater, we need a bigadjust, if its smaller,
+                * we can adjust by 1.
+                */
                error >>= 2;
+               /*
+                * XXX - In update_wall_time, we round up to the next
+                * nanosecond, and store the amount rounded up into
+                * the error. This causes the likely below to be unlikely.
+                *
+                * The properfix is to avoid rounding up by using
+                * the high precision timekeeper.xtime_nsec instead of
+                * xtime.tv_nsec everywhere. Fixing this will take some
+                * time.
+                */
                if (likely(error <= interval))
                        adj = 1;
                else
                        adj = timekeeping_bigadjust(error, &interval, &offset);
        } else if (error < -interval) {
+               /* See comment above, this is just switched for the negative */
                error >>= 2;
                if (likely(error >= -interval)) {
                        adj = -1;
@@ -817,9 +851,65 @@ static void timekeeping_adjust(s64 offset)
                        offset = -offset;
                } else
                        adj = timekeeping_bigadjust(error, &interval, &offset);
-       } else
+       } else /* No adjustment needed */
                return;
 
+       WARN_ONCE(timekeeper.clock->maxadj &&
+                       (timekeeper.mult + adj > timekeeper.clock->mult +
+                                               timekeeper.clock->maxadj),
+                       "Adjusting %s more then 11%% (%ld vs %ld)\n",
+                       timekeeper.clock->name, (long)timekeeper.mult + adj,
+                       (long)timekeeper.clock->mult +
+                               timekeeper.clock->maxadj);
+       /*
+        * So the following can be confusing.
+        *
+        * To keep things simple, lets assume adj == 1 for now.
+        *
+        * When adj != 1, remember that the interval and offset values
+        * have been appropriately scaled so the math is the same.
+        *
+        * The basic idea here is that we're increasing the multiplier
+        * by one, this causes the xtime_interval to be incremented by
+        * one cycle_interval. This is because:
+        *      xtime_interval = cycle_interval * mult
+        * So if mult is being incremented by one:
+        *      xtime_interval = cycle_interval * (mult + 1)
+        * Its the same as:
+        *      xtime_interval = (cycle_interval * mult) + cycle_interval
+        * Which can be shortened to:
+        *      xtime_interval += cycle_interval
+        *
+        * So offset stores the non-accumulated cycles. Thus the current
+        * time (in shifted nanoseconds) is:
+        *      now = (offset * adj) + xtime_nsec
+        * Now, even though we're adjusting the clock frequency, we have
+        * to keep time consistent. In other words, we can't jump back
+        * in time, and we also want to avoid jumping forward in time.
+        *
+        * So given the same offset value, we need the time to be the same
+        * both before and after the freq adjustment.
+        *      now = (offset * adj_1) + xtime_nsec_1
+        *      now = (offset * adj_2) + xtime_nsec_2
+        * So:
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * adj_2) + xtime_nsec_2
+        * And we know:
+        *      adj_2 = adj_1 + 1
+        * So:
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * (adj_1+1)) + xtime_nsec_2
+        *      (offset * adj_1) + xtime_nsec_1 =
+        *              (offset * adj_1) + offset + xtime_nsec_2
+        * Canceling the sides:
+        *      xtime_nsec_1 = offset + xtime_nsec_2
+        * Which gives us:
+        *      xtime_nsec_2 = xtime_nsec_1 - offset
+        * Which simplfies to:
+        *      xtime_nsec -= offset
+        *
+        * XXX - TODO: Doc ntp_error calculation.
+        */
        timekeeper.mult += adj;
        timekeeper.xtime_interval += interval;
        timekeeper.xtime_nsec -= offset;
index 8cff36119e4d50f7336a06e8d01e59e8b162e694..9c3c62b0c4bc89ebd307ff79950039021d157861 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include <linux/kernel_stat.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
@@ -1368,7 +1368,7 @@ SYSCALL_DEFINE0(getppid)
        int pid;
 
        rcu_read_lock();
-       pid = task_tgid_vnr(current->real_parent);
+       pid = task_tgid_vnr(rcu_dereference(current->real_parent));
        rcu_read_unlock();
 
        return pid;
index 7c910a5593a6d850a4f43617faa27ea01c951b42..16fc34a0806fa513a247c73dc62443cc4759ff0c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/debugfs.h>
+#include <linux/export.h>
 #include <linux/time.h>
 #include <linux/uaccess.h>
 
index 077d85387908812fc699e98b1c4d8fc6362ff6b9..b1e8943fed1d3a9fd61916527c59c70d57af7d2c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/hardirq.h>
 #include <linux/kthread.h>
 #include <linux/uaccess.h>
+#include <linux/module.h>
 #include <linux/ftrace.h>
 #include <linux/sysctl.h>
 #include <linux/slab.h>
@@ -151,7 +152,6 @@ void clear_ftrace_function(void)
        ftrace_pid_function = ftrace_stub;
 }
 
-#undef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
 #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
 /*
  * For those archs that do not test ftrace_trace_stop in their
@@ -1211,7 +1211,9 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable,
        if (!src->count) {
                free_ftrace_hash_rcu(*dst);
                rcu_assign_pointer(*dst, EMPTY_HASH);
-               return 0;
+               /* still need to update the function records */
+               ret = 0;
+               goto out;
        }
 
        /*
index 581876f9f3872e9103a0110893396652599a1d6a..c212a7f934ec4841d8c9887ecf93f6a0b7526b27 100644 (file)
@@ -1078,7 +1078,6 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
        /* First see if we did not already create this dir */
        list_for_each_entry(system, &event_subsystems, list) {
                if (strcmp(system->name, name) == 0) {
-                       __get_system(system);
                        system->nr_events++;
                        return system->entry;
                }
index 816d3d074979306713836d9447382cb641aecb54..95dc31efd6dd503dbd169a159dac4c5048f5a568 100644 (file)
@@ -1649,7 +1649,9 @@ static int replace_system_preds(struct event_subsystem *system,
                 */
                err = replace_preds(call, NULL, ps, filter_string, true);
                if (err)
-                       goto fail;
+                       call->flags |= TRACE_EVENT_FL_NO_SET_FILTER;
+               else
+                       call->flags &= ~TRACE_EVENT_FL_NO_SET_FILTER;
        }
 
        list_for_each_entry(call, &ftrace_events, list) {
@@ -1658,6 +1660,9 @@ static int replace_system_preds(struct event_subsystem *system,
                if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
+               if (call->flags & TRACE_EVENT_FL_NO_SET_FILTER)
+                       continue;
+
                filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL);
                if (!filter_item)
                        goto fail_mem;
@@ -1686,7 +1691,7 @@ static int replace_system_preds(struct event_subsystem *system,
                 * replace the filter for the call.
                 */
                filter = call->filter;
-               call->filter = filter_item->filter;
+               rcu_assign_pointer(call->filter, filter_item->filter);
                filter_item->filter = filter;
 
                fail = false;
@@ -1741,7 +1746,7 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
                filter = call->filter;
                if (!filter)
                        goto out_unlock;
-               call->filter = NULL;
+               RCU_INIT_POINTER(call->filter, NULL);
                /* Make sure the filter is not being used */
                synchronize_sched();
                __free_filter(filter);
@@ -1782,7 +1787,7 @@ out:
         * string
         */
        tmp = call->filter;
-       call->filter = filter;
+       rcu_assign_pointer(call->filter, filter);
        if (tmp) {
                /* Make sure the call is done with the filter */
                synchronize_sched();
index ee7b5a0bb9f87c1b9abb5964bfd4c54fd99ccb2d..cb654542c1a1621fc325cba70699f8b2d1be9658 100644 (file)
@@ -2,6 +2,7 @@
 #include <trace/events/syscalls.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/module.h>      /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
 #include <linux/ftrace.h>
 #include <linux/perf_event.h>
 #include <asm/syscall.h>
index 1ff27a28bb7d4a11d7cb23935675bd9e41c0ac83..c54c75e9faf7a68446c1a5e80f3713af0cc64117 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/smp.h>
 
 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
index 92cb706c7fc83babcb43b7028e2bff25ce00ba80..1744bb80f1fb41ff9f74df1df0d66fdde3f44b9d 100644 (file)
@@ -2,7 +2,7 @@
 #include <linux/user-return-notifier.h>
 #include <linux/percpu.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 
 static DEFINE_PER_CPU(struct hlist_head, return_notifier_list);
 
index 9e03e9c1df8d47fb7242125a6ac3b848d71ca801..71dd2363ab0f66dcbb2a3574d7b977af08369bea 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/bitops.h>
 #include <linux/key.h>
 #include <linux/interrupt.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/user_namespace.h>
 
 /*
index 9da289c34f22f161974e6b6b5eaa753d8af960f3..3b906e98b1db5a6085cb8a115899a997f4863221 100644 (file)
@@ -5,7 +5,7 @@
  *  License.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nsproxy.h>
 #include <linux/slab.h>
 #include <linux/user_namespace.h>
index bff131b9510a425452428005afda0acf7c979507..405caf91aad578f6ae1bfa48ace29262a550f431 100644 (file)
@@ -9,7 +9,7 @@
  *  License.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/uts.h>
 #include <linux/utsname.h>
 #include <linux/err.h>
index 3b0d48ebf81d68aa50764cb4360d43a16b84e289..63da38c2d820920b270cc2f469b965e445fecc05 100644 (file)
@@ -9,7 +9,7 @@
  *  License.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/uts.h>
 #include <linux/utsname.h>
 #include <linux/sysctl.h>
index f45ea8d2a1ceee7612878cdc0c0a492d1333b91f..26fa7797f90f9812ce9454fb59619b396c82f499 100644 (file)
@@ -4,7 +4,7 @@
  * (C) 2004 William Irwin, Oracle
  */
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/wait.h>
index 1783aabc6128f3792b9a68d27481999c1211d783..42fa9ad0a810482494b5782f4ba9a23f4aa32b86 100644 (file)
@@ -23,7 +23,7 @@
  * Please read Documentation/workqueue.txt for details.
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/init.h>
index 79700fa2dfc4402b2b336f90bded2bbdcb190cf3..fea790a2b17659e9b701987101db7929bdfbe8df 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 #include <linux/device.h>
 #include <linux/types.h>
 #include <linux/sched.h>
@@ -244,7 +245,7 @@ static void put_hash_bucket(struct hash_bucket *bucket,
 
 static bool exact_match(struct dma_debug_entry *a, struct dma_debug_entry *b)
 {
-       return ((a->dev_addr == a->dev_addr) &&
+       return ((a->dev_addr == b->dev_addr) &&
                (a->dev == b->dev)) ? true : false;
 }
 
index ac09f2226dc748132cd869bdf0933a5daf7509c4..a8408b6cacdf7ff8e73fcd3bf7db8a850afb56a4 100644 (file)
@@ -20,6 +20,7 @@ static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
        [NLA_U16]       = sizeof(u16),
        [NLA_U32]       = sizeof(u32),
        [NLA_U64]       = sizeof(u64),
+       [NLA_MSECS]     = sizeof(u64),
        [NLA_NESTED]    = NLA_HDRLEN,
 };
 
index b595f560bee74ba855da88bbc1793bf7eb193312..8b02f60ffc865750f3b4e5fbbe85b329f86b0a5e 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <linux/raid/pq.h>
+#include <linux/module.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
index 3b1500843bbac2dfa85daaeb85058480294080d4..8a3780902cec8ca4141a3646169a341be2b3c7a8 100644 (file)
@@ -60,6 +60,7 @@ int main(int argc, char *argv[])
        uint8_t exptbl[256], invtbl[256];
 
        printf("#include <linux/raid/pq.h>\n");
+       printf("#include <linux/export.h>\n");
 
        /* Compute multiplication table */
        printf("\nconst u8  __attribute__((aligned(256)))\n"
index 8590d19cf52231660a6a906acdc12bcf2156c9c9..fe275d7b6b36e920e37b991d7953938d4306d95c 100644 (file)
@@ -18,6 +18,7 @@
  * the syndrome.)
  */
 
+#include <linux/export.h>
 #include <linux/raid/pq.h>
 
 /* Recover two failed data blocks. */
index 7520ef0bfd47932653948f0f3b047abd021d2ef1..71034f41a2ba92ca17c902e2f9b75d568294987f 100644 (file)
@@ -97,6 +97,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
                   "BdiDirtyThresh:     %10lu kB\n"
                   "DirtyThresh:        %10lu kB\n"
                   "BackgroundThresh:   %10lu kB\n"
+                  "BdiDirtied:         %10lu kB\n"
                   "BdiWritten:         %10lu kB\n"
                   "BdiWriteBandwidth:  %10lu kBps\n"
                   "b_dirty:            %10lu\n"
@@ -109,6 +110,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
                   K(bdi_thresh),
                   K(dirty_thresh),
                   K(background_thresh),
+                  (unsigned long) K(bdi_stat(bdi, BDI_DIRTIED)),
                   (unsigned long) K(bdi_stat(bdi, BDI_WRITTEN)),
                   (unsigned long) K(bdi->write_bandwidth),
                   nr_dirty,
@@ -473,7 +475,8 @@ static int bdi_forker_thread(void *ptr)
                                 * the bdi from the thread. Hopefully 1024 is
                                 * large enough for efficient IO.
                                 */
-                               writeback_inodes_wb(&bdi->wb, 1024);
+                               writeback_inodes_wb(&bdi->wb, 1024,
+                                                   WB_REASON_FORKER_THREAD);
                        } else {
                                /*
                                 * The spinlock makes sure we do not lose
@@ -683,6 +686,8 @@ int bdi_init(struct backing_dev_info *bdi)
        bdi->bw_time_stamp = jiffies;
        bdi->written_stamp = 0;
 
+       bdi->balanced_dirty_ratelimit = INIT_BW;
+       bdi->dirty_ratelimit = INIT_BW;
        bdi->write_bandwidth = INIT_BW;
        bdi->avg_write_bandwidth = INIT_BW;
 
@@ -719,6 +724,14 @@ void bdi_destroy(struct backing_dev_info *bdi)
 
        bdi_unregister(bdi);
 
+       /*
+        * If bdi_unregister() had already been called earlier, the
+        * wakeup_timer could still be armed because bdi_prune_sb()
+        * can race with the bdi_wakeup_thread_delayed() calls from
+        * __mark_inode_dirty().
+        */
+       del_timer_sync(&bdi->wb.wakeup_timer);
+
        for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
                percpu_counter_destroy(&bdi->bdi_stat[i]);
 
index 01d5a4b3dd0c1dd857f05f474ce096a9a2938001..1a77012ecdb3c56a92d53ef5b779c9648d54c6a3 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/pfn.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kmemleak.h>
 #include <linux/range.h>
 #include <linux/memblock.h>
index 434fb4f0c5e4e2fd4bb59dac6f3bd22e188e7554..4e9ae722af83eb3e9a113fba806356d44121a340 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/swap.h>
 #include <linux/gfp.h>
 #include <linux/bio.h>
index fbb58e3468887e27c34b7500beb628ceedebac69..c5ab33bca0a8183bffc1b00e92583b5514d45c96 100644 (file)
 #include <linux/dmapool.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/poison.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/types.h>
index 5cf820a7c8ec2c1c0e8744eb03750e35b9255ef9..c0018f2d50e04e2ea03045989b742254be0a8489 100644 (file)
@@ -9,7 +9,7 @@
  * most "normal" filesystems (but you don't /have/ to use this:
  * the NFS filesystem used to do this differently, for example)
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/compiler.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
index 93356cd12828a40eb4d635a9e0e0bea3d6ba0790..f91b2f687343315741c9519670a96435329390f1 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/fs.h>
 #include <linux/pagemap.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/uio.h>
 #include <linux/rmap.h>
 #include <linux/mmu_notifier.h>
index b8e0e2d468afb276816174bcb76a46667d74831b..9ed4fd432467ee45a5310cd152fbba4399cbf722 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/pagemap.h>
 #include <linux/swapops.h>
 #include <linux/rmap.h>
-#include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/mmu_notifier.h>
 
index e159a7b1cc226c72cdb369f30852eb343491eddd..57d82c6250c308e36089f81a8e902b729391335e 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/swap.h>
 #include <linux/bio.h>
 #include <linux/pagemap.h>
index 4298abaae153033caafe1f8ac641fdef1dee097e..36b3d988b4ef6ac8c263ee0732c1d08513afb04f 100644 (file)
@@ -2259,12 +2259,8 @@ static void khugepaged_do_scan(struct page **hpage)
 
 static void khugepaged_alloc_sleep(void)
 {
-       DEFINE_WAIT(wait);
-       add_wait_queue(&khugepaged_wait, &wait);
-       schedule_timeout_interruptible(
-               msecs_to_jiffies(
-                       khugepaged_alloc_sleep_millisecs));
-       remove_wait_queue(&khugepaged_wait, &wait);
+       wait_event_freezable_timeout(khugepaged_wait, false,
+                       msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
 }
 
 #ifndef CONFIG_NUMA
@@ -2313,14 +2309,10 @@ static void khugepaged_loop(void)
                if (unlikely(kthread_should_stop()))
                        break;
                if (khugepaged_has_work()) {
-                       DEFINE_WAIT(wait);
                        if (!khugepaged_scan_sleep_millisecs)
                                continue;
-                       add_wait_queue(&khugepaged_wait, &wait);
-                       schedule_timeout_interruptible(
-                               msecs_to_jiffies(
-                                       khugepaged_scan_sleep_millisecs));
-                       remove_wait_queue(&khugepaged_wait, &wait);
+                       wait_event_freezable_timeout(khugepaged_wait, false,
+                           msecs_to_jiffies(khugepaged_scan_sleep_millisecs));
                } else if (khugepaged_enabled())
                        wait_event_freezable(khugepaged_wait,
                                             khugepaged_wait_event());
index dae27ba3be2c8523cd032ad330e2f5a32fbffaf3..73f17c0293c0a0e57a62f65f11c969b9319532f5 100644 (file)
@@ -576,6 +576,7 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
        __SetPageHead(page);
        for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
                __SetPageTail(p);
+               set_page_count(p, 0);
                p->first_page = page;
        }
 }
@@ -2422,6 +2423,8 @@ retry_avoidcopy:
         * anon_vma prepared.
         */
        if (unlikely(anon_vma_prepare(vma))) {
+               page_cache_release(new_page);
+               page_cache_release(old_page);
                /* Caller expects lock to be held */
                spin_lock(&mm->page_table_lock);
                return VM_FAULT_OOM;
index d6880f542f955682d62fa8935497ebd8e444cb8e..f3b2a00fe9c1fa3b0d4d5bb0a419d439f00b6062 100644 (file)
@@ -69,7 +69,7 @@
 #include <linux/sched.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kthread.h>
 #include <linux/prio_tree.h>
 #include <linux/fs.h>
index 4cee182ab5f3bc1805b1850b5c13a1ec9c5fa8b6..d53adf9ba84bc340d6fe8d53a26a2c626a032c48 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Access kernel memory without faulting.
  */
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 
index 7af1d5ee1598d485ced61f57c1b165fac4e0808d..6aff93c98acaf6020eabd37f2e9b49a04135f187 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/bit_spinlock.h>
 #include <linux/rcupdate.h>
 #include <linux/limits.h>
+#include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/rbtree.h>
 #include <linux/slab.h>
index edc388db730a2cb41f6290e98853fbbc0ac04a7b..06d3479513aaa2a3eeff26f0bf25e71c13695fdd 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/sched.h>
 #include <linux/ksm.h>
 #include <linux/rmap.h>
+#include <linux/export.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <linux/backing-dev.h>
index b2b87315cdc638bea2f99775113bf736d9aac505..829d437354022959eeca37082f695e2ee73025ed 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/pagemap.h>
 #include <linux/ksm.h>
 #include <linux/rmap.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/delayacct.h>
 #include <linux/init.h>
 #include <linux/writeback.h>
index 6e7d8b21dbfa773d0e3fe116f7e57714713282bc..2168489c0bc9f309ff3347d6dac05a09039ad7d2 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 #include <linux/compiler.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pagevec.h>
 #include <linux/writeback.h>
 #include <linux/slab.h>
index cd237f478304152bdd107bd8cbbb108ed39b7154..adc395481813532efe82dced222e79115b075b0e 100644 (file)
@@ -75,7 +75,7 @@
 #include <linux/cpuset.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nsproxy.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
index 1a3bc3d4d5543d5192848bedda8162933f07ada0..e73641b79bb5f08fac06f40380a47eaeb765294f 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mempool.h>
 #include <linux/blkdev.h>
 #include <linux/writeback.h>
index 33358f8781118ae9153ac4eb3e00530ca2f20e93..177aca424a069ac1ae1b44d48a8e6d992cd42a4d 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <linux/migrate.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/swap.h>
 #include <linux/swapops.h>
 #include <linux/pagemap.h>
@@ -871,9 +871,9 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
 
        if (anon_vma)
                put_anon_vma(anon_vma);
-out:
        unlock_page(hpage);
 
+out:
        if (rc != -EAGAIN) {
                list_del(&hpage->lru);
                put_page(hpage);
index bd34b3a10852c3d3ac3b1808653721a6114549c2..4f4f53bdc65de30d11c637b2bc745aa1333a16bd 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/mempolicy.h>
 #include <linux/syscalls.h>
 #include <linux/sched.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/rmap.h>
 #include <linux/mmzone.h>
 #include <linux/hugetlb.h>
index 4e0e26591dfaa6f242c4514fd83bdb54f7194b43..1ffd97ae26d7444a6294c1c2e856b8cf8acbac02 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/kobject.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include "internal.h"
 
 #ifdef CONFIG_DEBUG_MEMORY_INIT
index 3c0061f744f50cad8fd79eab118d7a54561fa654..eae90af60ea62e066defeab345e5079f57a80dc2 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -22,7 +22,7 @@
 #include <linux/security.h>
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
index 9e82e937000e19f8210b10886457a3d82ee0870b..cf332bc0080a39df65f3ce2cb425d714f41b7292 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/mm.h>
 #include <linux/mmu_context.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 
 #include <asm/mmu_context.h>
index 8d032de4088e0a55d3f9a4d733dc530e2962a678..9a611d3a18486031d63dda0585079f66c2f7499c 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <linux/rculist.h>
 #include <linux/mmu_notifier.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/rcupdate.h>
index f5b7d1760213e53db3c46e84dde56daf219ea0cd..7cf7b7ddc7c552d4d514a696b30d6cd20a649d4d 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/stddef.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/module.h>
 
 struct pglist_data *first_online_pgdat(void)
 {
index 6e93dc7f25863628b576539648dfe0c7ba8d3f10..7fa41b4a07bf2c129d57d2df5be92b434252ca7e 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/pfn.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/kmemleak.h>
 #include <linux/range.h>
 #include <linux/memblock.h>
index 4358032566e950f25812fef04fa951dcc39f6795..b982290fd962dc2745c423d44e7b92f9c1db247a 100644 (file)
@@ -13,7 +13,7 @@
  *  Copyright (c) 2007-2010 Paul Mundt <lethal@linux-sh.org>
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
@@ -454,7 +454,7 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
  *     between processes, it syncs the pagetable across all
  *     processes.
  */
-struct vm_struct *alloc_vm_area(size_t size)
+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
 {
        BUG();
        return NULL;
index e916168b6e0a8e6b70b4cb513f28591442ed8746..76f2c5ae908e85a858c006d932edcdf9128e0cc2 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/timex.h>
 #include <linux/jiffies.h>
 #include <linux/cpuset.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/notifier.h>
 #include <linux/memcontrol.h>
 #include <linux/mempolicy.h>
@@ -185,6 +185,11 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem,
        if (!p)
                return 0;
 
+       if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) {
+               task_unlock(p);
+               return 0;
+       }
+
        /*
         * The memory controller may have a limit of 0 bytes, so avoid a divide
         * by zero, if necessary.
index 793e9874de51f39f1a1b4a2e86c974a671b6574d..71252486bc6f1f161b87592ded6e8b7e6c0dc8ee 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
  */
 #define BANDWIDTH_INTERVAL     max(HZ/5, 1)
 
+#define RATELIMIT_CALC_SHIFT   10
+
 /*
  * After a CPU has dirtied this many pages, balance_dirty_pages_ratelimited
  * will look to see if it needs to force writeback or throttling.
  */
 static long ratelimit_pages = 32;
 
-/*
- * When balance_dirty_pages decides that the caller needs to perform some
- * non-background writeback, this is how many pages it will attempt to write.
- * It should be somewhat larger than dirtied pages to ensure that reasonably
- * large amounts of I/O are submitted.
- */
-static inline long sync_writeback_pages(unsigned long dirtied)
-{
-       if (dirtied < ratelimit_pages)
-               dirtied = ratelimit_pages;
-
-       return dirtied + dirtied / 2;
-}
-
 /* The following parameters are exported via /proc/sys/vm */
 
 /*
@@ -140,7 +128,6 @@ unsigned long global_dirty_limit;
  *
  */
 static struct prop_descriptor vm_completions;
-static struct prop_descriptor vm_dirties;
 
 /*
  * couple the period to the dirty_ratio:
@@ -166,7 +153,8 @@ static void update_completion_period(void)
 {
        int shift = calc_period_shift();
        prop_change_shift(&vm_completions, shift);
-       prop_change_shift(&vm_dirties, shift);
+
+       writeback_set_ratelimit();
 }
 
 int dirty_background_ratio_handler(struct ctl_table *table, int write,
@@ -245,11 +233,6 @@ void bdi_writeout_inc(struct backing_dev_info *bdi)
 }
 EXPORT_SYMBOL_GPL(bdi_writeout_inc);
 
-void task_dirty_inc(struct task_struct *tsk)
-{
-       prop_inc_single(&vm_dirties, &tsk->dirties);
-}
-
 /*
  * Obtain an accurate fraction of the BDI's portion.
  */
@@ -260,50 +243,6 @@ static void bdi_writeout_fraction(struct backing_dev_info *bdi,
                                numerator, denominator);
 }
 
-static inline void task_dirties_fraction(struct task_struct *tsk,
-               long *numerator, long *denominator)
-{
-       prop_fraction_single(&vm_dirties, &tsk->dirties,
-                               numerator, denominator);
-}
-
-/*
- * task_dirty_limit - scale down dirty throttling threshold for one task
- *
- * task specific dirty limit:
- *
- *   dirty -= (dirty/8) * p_{t}
- *
- * To protect light/slow dirtying tasks from heavier/fast ones, we start
- * throttling individual tasks before reaching the bdi dirty limit.
- * Relatively low thresholds will be allocated to heavy dirtiers. So when
- * dirty pages grow large, heavy dirtiers will be throttled first, which will
- * effectively curb the growth of dirty pages. Light dirtiers with high enough
- * dirty threshold may never get throttled.
- */
-#define TASK_LIMIT_FRACTION 8
-static unsigned long task_dirty_limit(struct task_struct *tsk,
-                                      unsigned long bdi_dirty)
-{
-       long numerator, denominator;
-       unsigned long dirty = bdi_dirty;
-       u64 inv = dirty / TASK_LIMIT_FRACTION;
-
-       task_dirties_fraction(tsk, &numerator, &denominator);
-       inv *= numerator;
-       do_div(inv, denominator);
-
-       dirty -= inv;
-
-       return max(dirty, bdi_dirty/2);
-}
-
-/* Minimum limit for any task */
-static unsigned long task_min_dirty_limit(unsigned long bdi_dirty)
-{
-       return bdi_dirty - bdi_dirty / TASK_LIMIT_FRACTION;
-}
-
 /*
  * bdi_min_ratio keeps the sum of the minimum dirty shares of all
  * registered backing devices, which, for obvious reasons, can not
@@ -413,6 +352,12 @@ unsigned long determine_dirtyable_memory(void)
        return x + 1;   /* Ensure that we never return 0 */
 }
 
+static unsigned long dirty_freerun_ceiling(unsigned long thresh,
+                                          unsigned long bg_thresh)
+{
+       return (thresh + bg_thresh) / 2;
+}
+
 static unsigned long hard_dirty_limit(unsigned long thresh)
 {
        return max(thresh, global_dirty_limit);
@@ -497,6 +442,198 @@ unsigned long bdi_dirty_limit(struct backing_dev_info *bdi, unsigned long dirty)
        return bdi_dirty;
 }
 
+/*
+ * Dirty position control.
+ *
+ * (o) global/bdi setpoints
+ *
+ * We want the dirty pages be balanced around the global/bdi setpoints.
+ * When the number of dirty pages is higher/lower than the setpoint, the
+ * dirty position control ratio (and hence task dirty ratelimit) will be
+ * decreased/increased to bring the dirty pages back to the setpoint.
+ *
+ *     pos_ratio = 1 << RATELIMIT_CALC_SHIFT
+ *
+ *     if (dirty < setpoint) scale up   pos_ratio
+ *     if (dirty > setpoint) scale down pos_ratio
+ *
+ *     if (bdi_dirty < bdi_setpoint) scale up   pos_ratio
+ *     if (bdi_dirty > bdi_setpoint) scale down pos_ratio
+ *
+ *     task_ratelimit = dirty_ratelimit * pos_ratio >> RATELIMIT_CALC_SHIFT
+ *
+ * (o) global control line
+ *
+ *     ^ pos_ratio
+ *     |
+ *     |            |<===== global dirty control scope ======>|
+ * 2.0 .............*
+ *     |            .*
+ *     |            . *
+ *     |            .   *
+ *     |            .     *
+ *     |            .        *
+ *     |            .            *
+ * 1.0 ................................*
+ *     |            .                  .     *
+ *     |            .                  .          *
+ *     |            .                  .              *
+ *     |            .                  .                 *
+ *     |            .                  .                    *
+ *   0 +------------.------------------.----------------------*------------->
+ *           freerun^          setpoint^                 limit^   dirty pages
+ *
+ * (o) bdi control line
+ *
+ *     ^ pos_ratio
+ *     |
+ *     |            *
+ *     |              *
+ *     |                *
+ *     |                  *
+ *     |                    * |<=========== span ============>|
+ * 1.0 .......................*
+ *     |                      . *
+ *     |                      .   *
+ *     |                      .     *
+ *     |                      .       *
+ *     |                      .         *
+ *     |                      .           *
+ *     |                      .             *
+ *     |                      .               *
+ *     |                      .                 *
+ *     |                      .                   *
+ *     |                      .                     *
+ * 1/4 ...............................................* * * * * * * * * * * *
+ *     |                      .                         .
+ *     |                      .                           .
+ *     |                      .                             .
+ *   0 +----------------------.-------------------------------.------------->
+ *                bdi_setpoint^                    x_intercept^
+ *
+ * The bdi control line won't drop below pos_ratio=1/4, so that bdi_dirty can
+ * be smoothly throttled down to normal if it starts high in situations like
+ * - start writing to a slow SD card and a fast disk at the same time. The SD
+ *   card's bdi_dirty may rush to many times higher than bdi_setpoint.
+ * - the bdi dirty thresh drops quickly due to change of JBOD workload
+ */
+static unsigned long bdi_position_ratio(struct backing_dev_info *bdi,
+                                       unsigned long thresh,
+                                       unsigned long bg_thresh,
+                                       unsigned long dirty,
+                                       unsigned long bdi_thresh,
+                                       unsigned long bdi_dirty)
+{
+       unsigned long write_bw = bdi->avg_write_bandwidth;
+       unsigned long freerun = dirty_freerun_ceiling(thresh, bg_thresh);
+       unsigned long limit = hard_dirty_limit(thresh);
+       unsigned long x_intercept;
+       unsigned long setpoint;         /* dirty pages' target balance point */
+       unsigned long bdi_setpoint;
+       unsigned long span;
+       long long pos_ratio;            /* for scaling up/down the rate limit */
+       long x;
+
+       if (unlikely(dirty >= limit))
+               return 0;
+
+       /*
+        * global setpoint
+        *
+        *                           setpoint - dirty 3
+        *        f(dirty) := 1.0 + (----------------)
+        *                           limit - setpoint
+        *
+        * it's a 3rd order polynomial that subjects to
+        *
+        * (1) f(freerun)  = 2.0 => rampup dirty_ratelimit reasonably fast
+        * (2) f(setpoint) = 1.0 => the balance point
+        * (3) f(limit)    = 0   => the hard limit
+        * (4) df/dx      <= 0   => negative feedback control
+        * (5) the closer to setpoint, the smaller |df/dx| (and the reverse)
+        *     => fast response on large errors; small oscillation near setpoint
+        */
+       setpoint = (freerun + limit) / 2;
+       x = div_s64((setpoint - dirty) << RATELIMIT_CALC_SHIFT,
+                   limit - setpoint + 1);
+       pos_ratio = x;
+       pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT;
+       pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT;
+       pos_ratio += 1 << RATELIMIT_CALC_SHIFT;
+
+       /*
+        * We have computed basic pos_ratio above based on global situation. If
+        * the bdi is over/under its share of dirty pages, we want to scale
+        * pos_ratio further down/up. That is done by the following mechanism.
+        */
+
+       /*
+        * bdi setpoint
+        *
+        *        f(bdi_dirty) := 1.0 + k * (bdi_dirty - bdi_setpoint)
+        *
+        *                        x_intercept - bdi_dirty
+        *                     := --------------------------
+        *                        x_intercept - bdi_setpoint
+        *
+        * The main bdi control line is a linear function that subjects to
+        *
+        * (1) f(bdi_setpoint) = 1.0
+        * (2) k = - 1 / (8 * write_bw)  (in single bdi case)
+        *     or equally: x_intercept = bdi_setpoint + 8 * write_bw
+        *
+        * For single bdi case, the dirty pages are observed to fluctuate
+        * regularly within range
+        *        [bdi_setpoint - write_bw/2, bdi_setpoint + write_bw/2]
+        * for various filesystems, where (2) can yield in a reasonable 12.5%
+        * fluctuation range for pos_ratio.
+        *
+        * For JBOD case, bdi_thresh (not bdi_dirty!) could fluctuate up to its
+        * own size, so move the slope over accordingly and choose a slope that
+        * yields 100% pos_ratio fluctuation on suddenly doubled bdi_thresh.
+        */
+       if (unlikely(bdi_thresh > thresh))
+               bdi_thresh = thresh;
+       bdi_thresh = max(bdi_thresh, (limit - dirty) / 8);
+       /*
+        * scale global setpoint to bdi's:
+        *      bdi_setpoint = setpoint * bdi_thresh / thresh
+        */
+       x = div_u64((u64)bdi_thresh << 16, thresh + 1);
+       bdi_setpoint = setpoint * (u64)x >> 16;
+       /*
+        * Use span=(8*write_bw) in single bdi case as indicated by
+        * (thresh - bdi_thresh ~= 0) and transit to bdi_thresh in JBOD case.
+        *
+        *        bdi_thresh                    thresh - bdi_thresh
+        * span = ---------- * (8 * write_bw) + ------------------- * bdi_thresh
+        *          thresh                            thresh
+        */
+       span = (thresh - bdi_thresh + 8 * write_bw) * (u64)x >> 16;
+       x_intercept = bdi_setpoint + span;
+
+       if (bdi_dirty < x_intercept - span / 4) {
+               pos_ratio = div_u64(pos_ratio * (x_intercept - bdi_dirty),
+                                   x_intercept - bdi_setpoint + 1);
+       } else
+               pos_ratio /= 4;
+
+       /*
+        * bdi reserve area, safeguard against dirty pool underrun and disk idle
+        * It may push the desired control point of global dirty pages higher
+        * than setpoint.
+        */
+       x_intercept = bdi_thresh / 2;
+       if (bdi_dirty < x_intercept) {
+               if (bdi_dirty > x_intercept / 8)
+                       pos_ratio = div_u64(pos_ratio * x_intercept, bdi_dirty);
+               else
+                       pos_ratio *= 8;
+       }
+
+       return pos_ratio;
+}
+
 static void bdi_update_write_bandwidth(struct backing_dev_info *bdi,
                                       unsigned long elapsed,
                                       unsigned long written)
@@ -593,8 +730,153 @@ static void global_update_bandwidth(unsigned long thresh,
        spin_unlock(&dirty_lock);
 }
 
+/*
+ * Maintain bdi->dirty_ratelimit, the base dirty throttle rate.
+ *
+ * Normal bdi tasks will be curbed at or below it in long term.
+ * Obviously it should be around (write_bw / N) when there are N dd tasks.
+ */
+static void bdi_update_dirty_ratelimit(struct backing_dev_info *bdi,
+                                      unsigned long thresh,
+                                      unsigned long bg_thresh,
+                                      unsigned long dirty,
+                                      unsigned long bdi_thresh,
+                                      unsigned long bdi_dirty,
+                                      unsigned long dirtied,
+                                      unsigned long elapsed)
+{
+       unsigned long freerun = dirty_freerun_ceiling(thresh, bg_thresh);
+       unsigned long limit = hard_dirty_limit(thresh);
+       unsigned long setpoint = (freerun + limit) / 2;
+       unsigned long write_bw = bdi->avg_write_bandwidth;
+       unsigned long dirty_ratelimit = bdi->dirty_ratelimit;
+       unsigned long dirty_rate;
+       unsigned long task_ratelimit;
+       unsigned long balanced_dirty_ratelimit;
+       unsigned long pos_ratio;
+       unsigned long step;
+       unsigned long x;
+
+       /*
+        * The dirty rate will match the writeout rate in long term, except
+        * when dirty pages are truncated by userspace or re-dirtied by FS.
+        */
+       dirty_rate = (dirtied - bdi->dirtied_stamp) * HZ / elapsed;
+
+       pos_ratio = bdi_position_ratio(bdi, thresh, bg_thresh, dirty,
+                                      bdi_thresh, bdi_dirty);
+       /*
+        * task_ratelimit reflects each dd's dirty rate for the past 200ms.
+        */
+       task_ratelimit = (u64)dirty_ratelimit *
+                                       pos_ratio >> RATELIMIT_CALC_SHIFT;
+       task_ratelimit++; /* it helps rampup dirty_ratelimit from tiny values */
+
+       /*
+        * A linear estimation of the "balanced" throttle rate. The theory is,
+        * if there are N dd tasks, each throttled at task_ratelimit, the bdi's
+        * dirty_rate will be measured to be (N * task_ratelimit). So the below
+        * formula will yield the balanced rate limit (write_bw / N).
+        *
+        * Note that the expanded form is not a pure rate feedback:
+        *      rate_(i+1) = rate_(i) * (write_bw / dirty_rate)              (1)
+        * but also takes pos_ratio into account:
+        *      rate_(i+1) = rate_(i) * (write_bw / dirty_rate) * pos_ratio  (2)
+        *
+        * (1) is not realistic because pos_ratio also takes part in balancing
+        * the dirty rate.  Consider the state
+        *      pos_ratio = 0.5                                              (3)
+        *      rate = 2 * (write_bw / N)                                    (4)
+        * If (1) is used, it will stuck in that state! Because each dd will
+        * be throttled at
+        *      task_ratelimit = pos_ratio * rate = (write_bw / N)           (5)
+        * yielding
+        *      dirty_rate = N * task_ratelimit = write_bw                   (6)
+        * put (6) into (1) we get
+        *      rate_(i+1) = rate_(i)                                        (7)
+        *
+        * So we end up using (2) to always keep
+        *      rate_(i+1) ~= (write_bw / N)                                 (8)
+        * regardless of the value of pos_ratio. As long as (8) is satisfied,
+        * pos_ratio is able to drive itself to 1.0, which is not only where
+        * the dirty count meet the setpoint, but also where the slope of
+        * pos_ratio is most flat and hence task_ratelimit is least fluctuated.
+        */
+       balanced_dirty_ratelimit = div_u64((u64)task_ratelimit * write_bw,
+                                          dirty_rate | 1);
+
+       /*
+        * We could safely do this and return immediately:
+        *
+        *      bdi->dirty_ratelimit = balanced_dirty_ratelimit;
+        *
+        * However to get a more stable dirty_ratelimit, the below elaborated
+        * code makes use of task_ratelimit to filter out sigular points and
+        * limit the step size.
+        *
+        * The below code essentially only uses the relative value of
+        *
+        *      task_ratelimit - dirty_ratelimit
+        *      = (pos_ratio - 1) * dirty_ratelimit
+        *
+        * which reflects the direction and size of dirty position error.
+        */
+
+       /*
+        * dirty_ratelimit will follow balanced_dirty_ratelimit iff
+        * task_ratelimit is on the same side of dirty_ratelimit, too.
+        * For example, when
+        * - dirty_ratelimit > balanced_dirty_ratelimit
+        * - dirty_ratelimit > task_ratelimit (dirty pages are above setpoint)
+        * lowering dirty_ratelimit will help meet both the position and rate
+        * control targets. Otherwise, don't update dirty_ratelimit if it will
+        * only help meet the rate target. After all, what the users ultimately
+        * feel and care are stable dirty rate and small position error.
+        *
+        * |task_ratelimit - dirty_ratelimit| is used to limit the step size
+        * and filter out the sigular points of balanced_dirty_ratelimit. Which
+        * keeps jumping around randomly and can even leap far away at times
+        * due to the small 200ms estimation period of dirty_rate (we want to
+        * keep that period small to reduce time lags).
+        */
+       step = 0;
+       if (dirty < setpoint) {
+               x = min(bdi->balanced_dirty_ratelimit,
+                        min(balanced_dirty_ratelimit, task_ratelimit));
+               if (dirty_ratelimit < x)
+                       step = x - dirty_ratelimit;
+       } else {
+               x = max(bdi->balanced_dirty_ratelimit,
+                        max(balanced_dirty_ratelimit, task_ratelimit));
+               if (dirty_ratelimit > x)
+                       step = dirty_ratelimit - x;
+       }
+
+       /*
+        * Don't pursue 100% rate matching. It's impossible since the balanced
+        * rate itself is constantly fluctuating. So decrease the track speed
+        * when it gets close to the target. Helps eliminate pointless tremors.
+        */
+       step >>= dirty_ratelimit / (2 * step + 1);
+       /*
+        * Limit the tracking speed to avoid overshooting.
+        */
+       step = (step + 7) / 8;
+
+       if (dirty_ratelimit < balanced_dirty_ratelimit)
+               dirty_ratelimit += step;
+       else
+               dirty_ratelimit -= step;
+
+       bdi->dirty_ratelimit = max(dirty_ratelimit, 1UL);
+       bdi->balanced_dirty_ratelimit = balanced_dirty_ratelimit;
+
+       trace_bdi_dirty_ratelimit(bdi, dirty_rate, task_ratelimit);
+}
+
 void __bdi_update_bandwidth(struct backing_dev_info *bdi,
                            unsigned long thresh,
+                           unsigned long bg_thresh,
                            unsigned long dirty,
                            unsigned long bdi_thresh,
                            unsigned long bdi_dirty,
@@ -602,6 +884,7 @@ void __bdi_update_bandwidth(struct backing_dev_info *bdi,
 {
        unsigned long now = jiffies;
        unsigned long elapsed = now - bdi->bw_time_stamp;
+       unsigned long dirtied;
        unsigned long written;
 
        /*
@@ -610,6 +893,7 @@ void __bdi_update_bandwidth(struct backing_dev_info *bdi,
        if (elapsed < BANDWIDTH_INTERVAL)
                return;
 
+       dirtied = percpu_counter_read(&bdi->bdi_stat[BDI_DIRTIED]);
        written = percpu_counter_read(&bdi->bdi_stat[BDI_WRITTEN]);
 
        /*
@@ -619,18 +903,23 @@ void __bdi_update_bandwidth(struct backing_dev_info *bdi,
        if (elapsed > HZ && time_before(bdi->bw_time_stamp, start_time))
                goto snapshot;
 
-       if (thresh)
+       if (thresh) {
                global_update_bandwidth(thresh, dirty, now);
-
+               bdi_update_dirty_ratelimit(bdi, thresh, bg_thresh, dirty,
+                                          bdi_thresh, bdi_dirty,
+                                          dirtied, elapsed);
+       }
        bdi_update_write_bandwidth(bdi, elapsed, written);
 
 snapshot:
+       bdi->dirtied_stamp = dirtied;
        bdi->written_stamp = written;
        bdi->bw_time_stamp = now;
 }
 
 static void bdi_update_bandwidth(struct backing_dev_info *bdi,
                                 unsigned long thresh,
+                                unsigned long bg_thresh,
                                 unsigned long dirty,
                                 unsigned long bdi_thresh,
                                 unsigned long bdi_dirty,
@@ -639,37 +928,99 @@ static void bdi_update_bandwidth(struct backing_dev_info *bdi,
        if (time_is_after_eq_jiffies(bdi->bw_time_stamp + BANDWIDTH_INTERVAL))
                return;
        spin_lock(&bdi->wb.list_lock);
-       __bdi_update_bandwidth(bdi, thresh, dirty, bdi_thresh, bdi_dirty,
-                              start_time);
+       __bdi_update_bandwidth(bdi, thresh, bg_thresh, dirty,
+                              bdi_thresh, bdi_dirty, start_time);
        spin_unlock(&bdi->wb.list_lock);
 }
 
+/*
+ * After a task dirtied this many pages, balance_dirty_pages_ratelimited_nr()
+ * will look to see if it needs to start dirty throttling.
+ *
+ * If dirty_poll_interval is too low, big NUMA machines will call the expensive
+ * global_page_state() too often. So scale it near-sqrt to the safety margin
+ * (the number of pages we may dirty without exceeding the dirty limits).
+ */
+static unsigned long dirty_poll_interval(unsigned long dirty,
+                                        unsigned long thresh)
+{
+       if (thresh > dirty)
+               return 1UL << (ilog2(thresh - dirty) >> 1);
+
+       return 1;
+}
+
+static unsigned long bdi_max_pause(struct backing_dev_info *bdi,
+                                  unsigned long bdi_dirty)
+{
+       unsigned long bw = bdi->avg_write_bandwidth;
+       unsigned long hi = ilog2(bw);
+       unsigned long lo = ilog2(bdi->dirty_ratelimit);
+       unsigned long t;
+
+       /* target for 20ms max pause on 1-dd case */
+       t = HZ / 50;
+
+       /*
+        * Scale up pause time for concurrent dirtiers in order to reduce CPU
+        * overheads.
+        *
+        * (N * 20ms) on 2^N concurrent tasks.
+        */
+       if (hi > lo)
+               t += (hi - lo) * (20 * HZ) / 1024;
+
+       /*
+        * Limit pause time for small memory systems. If sleeping for too long
+        * time, a small pool of dirty/writeback pages may go empty and disk go
+        * idle.
+        *
+        * 8 serves as the safety ratio.
+        */
+       if (bdi_dirty)
+               t = min(t, bdi_dirty * HZ / (8 * bw + 1));
+
+       /*
+        * The pause time will be settled within range (max_pause/4, max_pause).
+        * Apply a minimal value of 4 to get a non-zero max_pause/4.
+        */
+       return clamp_val(t, 4, MAX_PAUSE);
+}
+
 /*
  * balance_dirty_pages() must be called by processes which are generating dirty
  * data.  It looks at the number of dirty pages in the machine and will force
- * the caller to perform writeback if the system is over `vm_dirty_ratio'.
+ * the caller to wait once crossing the (background_thresh + dirty_thresh) / 2.
  * If we're over `background_thresh' then the writeback threads are woken to
  * perform some writeout.
  */
 static void balance_dirty_pages(struct address_space *mapping,
-                               unsigned long write_chunk)
+                               unsigned long pages_dirtied)
 {
-       unsigned long nr_reclaimable, bdi_nr_reclaimable;
+       unsigned long nr_reclaimable;   /* = file_dirty + unstable_nfs */
+       unsigned long bdi_reclaimable;
        unsigned long nr_dirty;  /* = file_dirty + writeback + unstable_nfs */
        unsigned long bdi_dirty;
+       unsigned long freerun;
        unsigned long background_thresh;
        unsigned long dirty_thresh;
        unsigned long bdi_thresh;
-       unsigned long task_bdi_thresh;
-       unsigned long min_task_bdi_thresh;
-       unsigned long pages_written = 0;
-       unsigned long pause = 1;
+       long pause = 0;
+       long uninitialized_var(max_pause);
        bool dirty_exceeded = false;
-       bool clear_dirty_exceeded = true;
+       unsigned long task_ratelimit;
+       unsigned long uninitialized_var(dirty_ratelimit);
+       unsigned long pos_ratio;
        struct backing_dev_info *bdi = mapping->backing_dev_info;
        unsigned long start_time = jiffies;
 
        for (;;) {
+               /*
+                * Unstable writes are a feature of certain networked
+                * filesystems (i.e. NFS) in which data may have been
+                * written to the server's write cache, but has not yet
+                * been flushed to permanent storage.
+                */
                nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
                                        global_page_state(NR_UNSTABLE_NFS);
                nr_dirty = nr_reclaimable + global_page_state(NR_WRITEBACK);
@@ -681,12 +1032,28 @@ static void balance_dirty_pages(struct address_space *mapping,
                 * catch-up. This avoids (excessively) small writeouts
                 * when the bdi limits are ramping up.
                 */
-               if (nr_dirty <= (background_thresh + dirty_thresh) / 2)
+               freerun = dirty_freerun_ceiling(dirty_thresh,
+                                               background_thresh);
+               if (nr_dirty <= freerun)
                        break;
 
+               if (unlikely(!writeback_in_progress(bdi)))
+                       bdi_start_background_writeback(bdi);
+
+               /*
+                * bdi_thresh is not treated as some limiting factor as
+                * dirty_thresh, due to reasons
+                * - in JBOD setup, bdi_thresh can fluctuate a lot
+                * - in a system with HDD and USB key, the USB key may somehow
+                *   go into state (bdi_dirty >> bdi_thresh) either because
+                *   bdi_dirty starts high, or because bdi_thresh drops low.
+                *   In this case we don't want to hard throttle the USB key
+                *   dirtiers for 100 seconds until bdi_dirty drops under
+                *   bdi_thresh. Instead the auxiliary bdi control line in
+                *   bdi_position_ratio() will let the dirtier task progress
+                *   at some rate <= (write_bw / 2) for bringing down bdi_dirty.
+                */
                bdi_thresh = bdi_dirty_limit(bdi, dirty_thresh);
-               min_task_bdi_thresh = task_min_dirty_limit(bdi_thresh);
-               task_bdi_thresh = task_dirty_limit(current, bdi_thresh);
 
                /*
                 * In order to avoid the stacked BDI deadlock we need
@@ -698,82 +1065,101 @@ static void balance_dirty_pages(struct address_space *mapping,
                 * actually dirty; with m+n sitting in the percpu
                 * deltas.
                 */
-               if (task_bdi_thresh < 2 * bdi_stat_error(bdi)) {
-                       bdi_nr_reclaimable = bdi_stat_sum(bdi, BDI_RECLAIMABLE);
-                       bdi_dirty = bdi_nr_reclaimable +
+               if (bdi_thresh < 2 * bdi_stat_error(bdi)) {
+                       bdi_reclaimable = bdi_stat_sum(bdi, BDI_RECLAIMABLE);
+                       bdi_dirty = bdi_reclaimable +
                                    bdi_stat_sum(bdi, BDI_WRITEBACK);
                } else {
-                       bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
-                       bdi_dirty = bdi_nr_reclaimable +
+                       bdi_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
+                       bdi_dirty = bdi_reclaimable +
                                    bdi_stat(bdi, BDI_WRITEBACK);
                }
 
-               /*
-                * The bdi thresh is somehow "soft" limit derived from the
-                * global "hard" limit. The former helps to prevent heavy IO
-                * bdi or process from holding back light ones; The latter is
-                * the last resort safeguard.
-                */
-               dirty_exceeded = (bdi_dirty > task_bdi_thresh) ||
+               dirty_exceeded = (bdi_dirty > bdi_thresh) ||
                                  (nr_dirty > dirty_thresh);
-               clear_dirty_exceeded = (bdi_dirty <= min_task_bdi_thresh) &&
-                                       (nr_dirty <= dirty_thresh);
-
-               if (!dirty_exceeded)
-                       break;
-
-               if (!bdi->dirty_exceeded)
+               if (dirty_exceeded && !bdi->dirty_exceeded)
                        bdi->dirty_exceeded = 1;
 
-               bdi_update_bandwidth(bdi, dirty_thresh, nr_dirty,
-                                    bdi_thresh, bdi_dirty, start_time);
-
-               /* Note: nr_reclaimable denotes nr_dirty + nr_unstable.
-                * Unstable writes are a feature of certain networked
-                * filesystems (i.e. NFS) in which data may have been
-                * written to the server's write cache, but has not yet
-                * been flushed to permanent storage.
-                * Only move pages to writeback if this bdi is over its
-                * threshold otherwise wait until the disk writes catch
-                * up.
-                */
-               trace_balance_dirty_start(bdi);
-               if (bdi_nr_reclaimable > task_bdi_thresh) {
-                       pages_written += writeback_inodes_wb(&bdi->wb,
-                                                            write_chunk);
-                       trace_balance_dirty_written(bdi, pages_written);
-                       if (pages_written >= write_chunk)
-                               break;          /* We've done our duty */
+               bdi_update_bandwidth(bdi, dirty_thresh, background_thresh,
+                                    nr_dirty, bdi_thresh, bdi_dirty,
+                                    start_time);
+
+               max_pause = bdi_max_pause(bdi, bdi_dirty);
+
+               dirty_ratelimit = bdi->dirty_ratelimit;
+               pos_ratio = bdi_position_ratio(bdi, dirty_thresh,
+                                              background_thresh, nr_dirty,
+                                              bdi_thresh, bdi_dirty);
+               task_ratelimit = ((u64)dirty_ratelimit * pos_ratio) >>
+                                                       RATELIMIT_CALC_SHIFT;
+               if (unlikely(task_ratelimit == 0)) {
+                       pause = max_pause;
+                       goto pause;
+               }
+               pause = HZ * pages_dirtied / task_ratelimit;
+               if (unlikely(pause <= 0)) {
+                       trace_balance_dirty_pages(bdi,
+                                                 dirty_thresh,
+                                                 background_thresh,
+                                                 nr_dirty,
+                                                 bdi_thresh,
+                                                 bdi_dirty,
+                                                 dirty_ratelimit,
+                                                 task_ratelimit,
+                                                 pages_dirtied,
+                                                 pause,
+                                                 start_time);
+                       pause = 1; /* avoid resetting nr_dirtied_pause below */
+                       break;
                }
-               __set_current_state(TASK_UNINTERRUPTIBLE);
+               pause = min(pause, max_pause);
+
+pause:
+               trace_balance_dirty_pages(bdi,
+                                         dirty_thresh,
+                                         background_thresh,
+                                         nr_dirty,
+                                         bdi_thresh,
+                                         bdi_dirty,
+                                         dirty_ratelimit,
+                                         task_ratelimit,
+                                         pages_dirtied,
+                                         pause,
+                                         start_time);
+               __set_current_state(TASK_KILLABLE);
                io_schedule_timeout(pause);
-               trace_balance_dirty_wait(bdi);
 
-               dirty_thresh = hard_dirty_limit(dirty_thresh);
                /*
-                * max-pause area. If dirty exceeded but still within this
-                * area, no need to sleep for more than 200ms: (a) 8 pages per
-                * 200ms is typically more than enough to curb heavy dirtiers;
-                * (b) the pause time limit makes the dirtiers more responsive.
+                * This is typically equal to (nr_dirty < dirty_thresh) and can
+                * also keep "1000+ dd on a slow USB stick" under control.
                 */
-               if (nr_dirty < dirty_thresh &&
-                   bdi_dirty < (task_bdi_thresh + bdi_thresh) / 2 &&
-                   time_after(jiffies, start_time + MAX_PAUSE))
+               if (task_ratelimit)
                        break;
 
-               /*
-                * Increase the delay for each loop, up to our previous
-                * default of taking a 100ms nap.
-                */
-               pause <<= 1;
-               if (pause > HZ / 10)
-                       pause = HZ / 10;
+               if (fatal_signal_pending(current))
+                       break;
        }
 
-       /* Clear dirty_exceeded flag only when no task can exceed the limit */
-       if (clear_dirty_exceeded && bdi->dirty_exceeded)
+       if (!dirty_exceeded && bdi->dirty_exceeded)
                bdi->dirty_exceeded = 0;
 
+       current->nr_dirtied = 0;
+       if (pause == 0) { /* in freerun area */
+               current->nr_dirtied_pause =
+                               dirty_poll_interval(nr_dirty, dirty_thresh);
+       } else if (pause <= max_pause / 4 &&
+                  pages_dirtied >= current->nr_dirtied_pause) {
+               current->nr_dirtied_pause = clamp_val(
+                                       dirty_ratelimit * (max_pause / 2) / HZ,
+                                       pages_dirtied + pages_dirtied / 8,
+                                       pages_dirtied * 4);
+       } else if (pause >= max_pause) {
+               current->nr_dirtied_pause = 1 | clamp_val(
+                                       dirty_ratelimit * (max_pause / 2) / HZ,
+                                       pages_dirtied / 4,
+                                       pages_dirtied - pages_dirtied / 8);
+       }
+
        if (writeback_in_progress(bdi))
                return;
 
@@ -785,8 +1171,10 @@ static void balance_dirty_pages(struct address_space *mapping,
         * In normal mode, we start background writeout at the lower
         * background_thresh, to keep the amount of dirty memory low.
         */
-       if ((laptop_mode && pages_written) ||
-           (!laptop_mode && (nr_reclaimable > background_thresh)))
+       if (laptop_mode)
+               return;
+
+       if (nr_reclaimable > background_thresh)
                bdi_start_background_writeback(bdi);
 }
 
@@ -800,7 +1188,7 @@ void set_page_dirty_balance(struct page *page, int page_mkwrite)
        }
 }
 
-static DEFINE_PER_CPU(unsigned long, bdp_ratelimits) = 0;
+static DEFINE_PER_CPU(int, bdp_ratelimits);
 
 /**
  * balance_dirty_pages_ratelimited_nr - balance dirty memory state
@@ -820,31 +1208,39 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
                                        unsigned long nr_pages_dirtied)
 {
        struct backing_dev_info *bdi = mapping->backing_dev_info;
-       unsigned long ratelimit;
-       unsigned long *p;
+       int ratelimit;
+       int *p;
 
        if (!bdi_cap_account_dirty(bdi))
                return;
 
-       ratelimit = ratelimit_pages;
-       if (mapping->backing_dev_info->dirty_exceeded)
-               ratelimit = 8;
+       ratelimit = current->nr_dirtied_pause;
+       if (bdi->dirty_exceeded)
+               ratelimit = min(ratelimit, 32 >> (PAGE_SHIFT - 10));
+
+       current->nr_dirtied += nr_pages_dirtied;
 
+       preempt_disable();
        /*
-        * Check the rate limiting. Also, we do not want to throttle real-time
-        * tasks in balance_dirty_pages(). Period.
+        * This prevents one CPU to accumulate too many dirtied pages without
+        * calling into balance_dirty_pages(), which can happen when there are
+        * 1000+ tasks, all of them start dirtying pages at exactly the same
+        * time, hence all honoured too large initial task->nr_dirtied_pause.
         */
-       preempt_disable();
        p =  &__get_cpu_var(bdp_ratelimits);
-       *p += nr_pages_dirtied;
-       if (unlikely(*p >= ratelimit)) {
-               ratelimit = sync_writeback_pages(*p);
+       if (unlikely(current->nr_dirtied >= ratelimit))
                *p = 0;
-               preempt_enable();
-               balance_dirty_pages(mapping, ratelimit);
-               return;
+       else {
+               *p += nr_pages_dirtied;
+               if (unlikely(*p >= ratelimit_pages)) {
+                       *p = 0;
+                       ratelimit = 0;
+               }
        }
        preempt_enable();
+
+       if (unlikely(current->nr_dirtied >= ratelimit))
+               balance_dirty_pages(mapping, current->nr_dirtied);
 }
 EXPORT_SYMBOL(balance_dirty_pages_ratelimited_nr);
 
@@ -900,7 +1296,8 @@ void laptop_mode_timer_fn(unsigned long data)
         * threshold
         */
        if (bdi_has_dirty_io(&q->backing_dev_info))
-               bdi_start_writeback(&q->backing_dev_info, nr_pages);
+               bdi_start_writeback(&q->backing_dev_info, nr_pages,
+                                       WB_REASON_LAPTOP_TIMER);
 }
 
 /*
@@ -939,22 +1336,17 @@ void laptop_sync_completion(void)
  *
  * Here we set ratelimit_pages to a level which ensures that when all CPUs are
  * dirtying in parallel, we cannot go more than 3% (1/32) over the dirty memory
- * thresholds before writeback cuts in.
- *
- * But the limit should not be set too high.  Because it also controls the
- * amount of memory which the balance_dirty_pages() caller has to write back.
- * If this is too large then the caller will block on the IO queue all the
- * time.  So limit it to four megabytes - the balance_dirty_pages() caller
- * will write six megabyte chunks, max.
+ * thresholds.
  */
 
 void writeback_set_ratelimit(void)
 {
-       ratelimit_pages = vm_total_pages / (num_online_cpus() * 32);
+       unsigned long background_thresh;
+       unsigned long dirty_thresh;
+       global_dirty_limits(&background_thresh, &dirty_thresh);
+       ratelimit_pages = dirty_thresh / (num_online_cpus() * 32);
        if (ratelimit_pages < 16)
                ratelimit_pages = 16;
-       if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024)
-               ratelimit_pages = (4096 * 1024) / PAGE_CACHE_SIZE;
 }
 
 static int __cpuinit
@@ -996,7 +1388,6 @@ void __init page_writeback_init(void)
 
        shift = calc_period_shift();
        prop_descriptor_init(&vm_completions, shift);
-       prop_descriptor_init(&vm_dirties, shift);
 }
 
 /**
@@ -1324,7 +1715,7 @@ void account_page_dirtied(struct page *page, struct address_space *mapping)
                __inc_zone_page_state(page, NR_FILE_DIRTY);
                __inc_zone_page_state(page, NR_DIRTIED);
                __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
-               task_dirty_inc(current);
+               __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED);
                task_io_account_write(PAGE_CACHE_SIZE);
        }
 }
index 9dd443d89d8be665813bbeb4e17e54fafde46428..2b8ba3aebf6e2c6b46b0d12dfea058ee3ab022fe 100644 (file)
@@ -356,8 +356,8 @@ void prep_compound_page(struct page *page, unsigned long order)
        __SetPageHead(page);
        for (i = 1; i < nr_pages; i++) {
                struct page *p = page + i;
-
                __SetPageTail(p);
+               set_page_count(p, 0);
                p->first_page = page;
        }
 }
@@ -3377,9 +3377,15 @@ static void setup_zone_migrate_reserve(struct zone *zone)
        unsigned long block_migratetype;
        int reserve;
 
-       /* Get the start pfn, end pfn and the number of blocks to reserve */
+       /*
+        * Get the start pfn, end pfn and the number of blocks to reserve
+        * We have to be careful to be aligned to pageblock_nr_pages to
+        * make sure that we always check pfn_valid for the first page in
+        * the block.
+        */
        start_pfn = zone->zone_start_pfn;
        end_pfn = start_pfn + zone->spanned_pages;
+       start_pfn = roundup(start_pfn, pageblock_nr_pages);
        reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >>
                                                        pageblock_order;
 
index ea534960a04bcda7e87a18cacf67bd2eb1fc5fe0..12a48a88c0d8cb00dd55b2adcea3e536493dee1a 100644 (file)
@@ -50,14 +50,13 @@ static struct page **pcpu_get_pages_and_bitmap(struct pcpu_chunk *chunk,
 
        if (!pages || !bitmap) {
                if (may_alloc && !pages)
-                       pages = pcpu_mem_alloc(pages_size);
+                       pages = pcpu_mem_zalloc(pages_size);
                if (may_alloc && !bitmap)
-                       bitmap = pcpu_mem_alloc(bitmap_size);
+                       bitmap = pcpu_mem_zalloc(bitmap_size);
                if (!pages || !bitmap)
                        return NULL;
        }
 
-       memset(pages, 0, pages_size);
        bitmap_copy(bitmap, chunk->populated, pcpu_unit_pages);
 
        *bitmapp = bitmap;
@@ -143,8 +142,8 @@ static void pcpu_pre_unmap_flush(struct pcpu_chunk *chunk,
                                 int page_start, int page_end)
 {
        flush_cache_vunmap(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 static void __pcpu_unmap_pages(unsigned long addr, int nr_pages)
@@ -206,8 +205,8 @@ static void pcpu_post_unmap_tlb_flush(struct pcpu_chunk *chunk,
                                      int page_start, int page_end)
 {
        flush_tlb_kernel_range(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 static int __pcpu_map_pages(unsigned long addr, struct page **pages,
@@ -284,8 +283,8 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk,
                                int page_start, int page_end)
 {
        flush_cache_vmap(
-               pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
-               pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+               pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start),
+               pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end));
 }
 
 /**
index bf80e55dbed7e66fcd28f6dbc46c86fbd222a008..3bb810a72006cd65e345e16fd124b61e029964db 100644 (file)
@@ -116,9 +116,9 @@ static int pcpu_atom_size __read_mostly;
 static int pcpu_nr_slots __read_mostly;
 static size_t pcpu_chunk_struct_size __read_mostly;
 
-/* cpus with the lowest and highest unit numbers */
-static unsigned int pcpu_first_unit_cpu __read_mostly;
-static unsigned int pcpu_last_unit_cpu __read_mostly;
+/* cpus with the lowest and highest unit addresses */
+static unsigned int pcpu_low_unit_cpu __read_mostly;
+static unsigned int pcpu_high_unit_cpu __read_mostly;
 
 /* the address of the first chunk which starts with the kernel static area */
 void *pcpu_base_addr __read_mostly;
@@ -273,11 +273,11 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
             (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end)))
 
 /**
- * pcpu_mem_alloc - allocate memory
+ * pcpu_mem_zalloc - allocate memory
  * @size: bytes to allocate
  *
  * Allocate @size bytes.  If @size is smaller than PAGE_SIZE,
- * kzalloc() is used; otherwise, vmalloc() is used.  The returned
+ * kzalloc() is used; otherwise, vzalloc() is used.  The returned
  * memory is always zeroed.
  *
  * CONTEXT:
@@ -286,7 +286,7 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk,
  * RETURNS:
  * Pointer to the allocated area on success, NULL on failure.
  */
-static void *pcpu_mem_alloc(size_t size)
+static void *pcpu_mem_zalloc(size_t size)
 {
        if (WARN_ON_ONCE(!slab_is_available()))
                return NULL;
@@ -302,7 +302,7 @@ static void *pcpu_mem_alloc(size_t size)
  * @ptr: memory to free
  * @size: size of the area
  *
- * Free @ptr.  @ptr should have been allocated using pcpu_mem_alloc().
+ * Free @ptr.  @ptr should have been allocated using pcpu_mem_zalloc().
  */
 static void pcpu_mem_free(void *ptr, size_t size)
 {
@@ -384,7 +384,7 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
        size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
        unsigned long flags;
 
-       new = pcpu_mem_alloc(new_size);
+       new = pcpu_mem_zalloc(new_size);
        if (!new)
                return -ENOMEM;
 
@@ -604,11 +604,12 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
 {
        struct pcpu_chunk *chunk;
 
-       chunk = pcpu_mem_alloc(pcpu_chunk_struct_size);
+       chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size);
        if (!chunk)
                return NULL;
 
-       chunk->map = pcpu_mem_alloc(PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
+       chunk->map = pcpu_mem_zalloc(PCPU_DFL_MAP_ALLOC *
+                                               sizeof(chunk->map[0]));
        if (!chunk->map) {
                kfree(chunk);
                return NULL;
@@ -977,6 +978,17 @@ bool is_kernel_percpu_address(unsigned long addr)
  * address.  The caller is responsible for ensuring @addr stays valid
  * until this function finishes.
  *
+ * percpu allocator has special setup for the first chunk, which currently
+ * supports either embedding in linear address space or vmalloc mapping,
+ * and, from the second one, the backing allocator (currently either vm or
+ * km) provides translation.
+ *
+ * The addr can be tranlated simply without checking if it falls into the
+ * first chunk. But the current code reflects better how percpu allocator
+ * actually works, and the verification can discover both bugs in percpu
+ * allocator itself and per_cpu_ptr_to_phys() callers. So we keep current
+ * code.
+ *
  * RETURNS:
  * The physical address for @addr.
  */
@@ -984,19 +996,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
 {
        void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
        bool in_first_chunk = false;
-       unsigned long first_start, first_end;
+       unsigned long first_low, first_high;
        unsigned int cpu;
 
        /*
-        * The following test on first_start/end isn't strictly
+        * The following test on unit_low/high isn't strictly
         * necessary but will speed up lookups of addresses which
         * aren't in the first chunk.
         */
-       first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0);
-       first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu,
-                                   pcpu_unit_pages);
-       if ((unsigned long)addr >= first_start &&
-           (unsigned long)addr < first_end) {
+       first_low = pcpu_chunk_addr(pcpu_first_chunk, pcpu_low_unit_cpu, 0);
+       first_high = pcpu_chunk_addr(pcpu_first_chunk, pcpu_high_unit_cpu,
+                                    pcpu_unit_pages);
+       if ((unsigned long)addr >= first_low &&
+           (unsigned long)addr < first_high) {
                for_each_possible_cpu(cpu) {
                        void *start = per_cpu_ptr(base, cpu);
 
@@ -1233,7 +1245,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 
        for (cpu = 0; cpu < nr_cpu_ids; cpu++)
                unit_map[cpu] = UINT_MAX;
-       pcpu_first_unit_cpu = NR_CPUS;
+
+       pcpu_low_unit_cpu = NR_CPUS;
+       pcpu_high_unit_cpu = NR_CPUS;
 
        for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) {
                const struct pcpu_group_info *gi = &ai->groups[group];
@@ -1253,9 +1267,13 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
                        unit_map[cpu] = unit + i;
                        unit_off[cpu] = gi->base_offset + i * ai->unit_size;
 
-                       if (pcpu_first_unit_cpu == NR_CPUS)
-                               pcpu_first_unit_cpu = cpu;
-                       pcpu_last_unit_cpu = cpu;
+                       /* determine low/high unit_cpu */
+                       if (pcpu_low_unit_cpu == NR_CPUS ||
+                           unit_off[cpu] < unit_off[pcpu_low_unit_cpu])
+                               pcpu_low_unit_cpu = cpu;
+                       if (pcpu_high_unit_cpu == NR_CPUS ||
+                           unit_off[cpu] > unit_off[pcpu_high_unit_cpu])
+                               pcpu_high_unit_cpu = cpu;
                }
        }
        pcpu_nr_units = unit;
@@ -1889,7 +1907,7 @@ void __init percpu_init_late(void)
 
                BUILD_BUG_ON(size > PAGE_SIZE);
 
-               map = pcpu_mem_alloc(size);
+               map = pcpu_mem_zalloc(size);
                BUG_ON(!map);
 
                spin_lock_irqsave(&pcpu_lock, flags);
index 2876349339a7c275a940ea16c688885d13caa29d..9422129705297dd62bf4658287f31fa1a2f331cd 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/module.h>
 #include <linux/quicklist.h>
 
 DEFINE_PER_CPU(struct quicklist [CONFIG_NR_QUICK], quicklist);
index 867f9dd82dcde9d5c11f49bde159c3c6a0276c4e..cbcbb02f3e28ab9667d196e6316588856206df16 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
 #include <linux/task_io_accounting_ops.h>
index 6541cf7fd1d3286ee6bb50edcaba39700092f2f4..a4fd3680038be499a47cf747d1ba657646e5d36c 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -51,7 +51,7 @@
 #include <linux/ksm.h>
 #include <linux/rmap.h>
 #include <linux/rcupdate.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/memcontrol.h>
 #include <linux/mmu_notifier.h>
 #include <linux/migrate.h>
index 45b9acb575f9c5c2ad6a869d1e7c28abba3a890e..d6722506d2da72d738aa5b7040501be64437f01a 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/mm.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/swap.h>
 
 static struct vfsmount *shm_mnt;
index 708efe886154da626cfe01f4a2b6eaf055ada914..83311c9aaf9de0ad8494f04703c248f155cfc2c1 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -595,6 +595,7 @@ static enum {
        PARTIAL_AC,
        PARTIAL_L3,
        EARLY,
+       LATE,
        FULL
 } g_cpucache_up;
 
@@ -671,7 +672,7 @@ static void init_node_lock_keys(int q)
 {
        struct cache_sizes *s = malloc_sizes;
 
-       if (g_cpucache_up != FULL)
+       if (g_cpucache_up < LATE)
                return;
 
        for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) {
@@ -1666,6 +1667,8 @@ void __init kmem_cache_init_late(void)
 {
        struct kmem_cache *cachep;
 
+       g_cpucache_up = LATE;
+
        /* Annotate slab for lockdep -- annotate the malloc caches */
        init_lock_keys();
 
index bf3918187165f79351f08daac748e17cc34acd5e..8105be42cad13b9ba6d231de8fad5bf29af6de2f 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -63,7 +63,7 @@
 #include <linux/swap.h> /* struct reclaim_state */
 #include <linux/cache.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
 #include <linux/kmemleak.h>
index 7d2a996c307e4306bd233f4ae340a02d6915ffb1..ed3334d9b6da77f64796f1933f7672284b159fc2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1862,7 +1862,7 @@ static void unfreeze_partials(struct kmem_cache *s)
 {
        struct kmem_cache_node *n = NULL;
        struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
-       struct page *page;
+       struct page *page, *discard_page = NULL;
 
        while ((page = c->partial)) {
                enum slab_modes { M_PARTIAL, M_FREE };
@@ -1904,7 +1904,8 @@ static void unfreeze_partials(struct kmem_cache *s)
                                if (l == M_PARTIAL)
                                        remove_partial(n, page);
                                else
-                                       add_partial(n, page, 1);
+                                       add_partial(n, page,
+                                               DEACTIVATE_TO_TAIL);
 
                                l = m;
                        }
@@ -1915,14 +1916,22 @@ static void unfreeze_partials(struct kmem_cache *s)
                                "unfreezing slab"));
 
                if (m == M_FREE) {
-                       stat(s, DEACTIVATE_EMPTY);
-                       discard_slab(s, page);
-                       stat(s, FREE_SLAB);
+                       page->next = discard_page;
+                       discard_page = page;
                }
        }
 
        if (n)
                spin_unlock(&n->list_lock);
+
+       while (discard_page) {
+               page = discard_page;
+               discard_page = discard_page->next;
+
+               stat(s, DEACTIVATE_EMPTY);
+               discard_slab(s, page);
+               stat(s, FREE_SLAB);
+       }
 }
 
 /*
@@ -1969,7 +1978,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
                page->pobjects = pobjects;
                page->next = oldpage;
 
-       } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
+       } while (irqsafe_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
        stat(s, CPU_PARTIAL_FREE);
        return pobjects;
 }
@@ -4435,30 +4444,31 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
 
                for_each_possible_cpu(cpu) {
                        struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
+                       int node = ACCESS_ONCE(c->node);
                        struct page *page;
 
-                       if (!c || c->node < 0)
+                       if (node < 0)
                                continue;
-
-                       if (c->page) {
-                                       if (flags & SO_TOTAL)
-                                               x = c->page->objects;
+                       page = ACCESS_ONCE(c->page);
+                       if (page) {
+                               if (flags & SO_TOTAL)
+                                       x = page->objects;
                                else if (flags & SO_OBJECTS)
-                                       x = c->page->inuse;
+                                       x = page->inuse;
                                else
                                        x = 1;
 
                                total += x;
-                               nodes[c->node] += x;
+                               nodes[node] += x;
                        }
                        page = c->partial;
 
                        if (page) {
                                x = page->pobjects;
-                                total += x;
-                                nodes[c->node] += x;
+                               total += x;
+                               nodes[node] += x;
                        }
-                       per_cpu[c->node]++;
+                       per_cpu[node]++;
                }
        }
 
index 64b984091edbf0b5e23742ed8ac765d5b0f7f336..1b7e22ab9b091bf34d857b5aeb36fd08039c0378 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/mmzone.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
-#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
index 858e1dff9b2af89b0c98203cd3e9099d8feffbbd..61d7cde23111e91714dde8fe42e461a3f39c3f0d 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/mmzone.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include "internal.h"
index 87627f181c3f333075cb15773bd3d45db3ec1ea9..a91caf754d9badb5f0b1f3c54b8e86be4723ff84 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -21,7 +21,7 @@
 #include <linux/pagemap.h>
 #include <linux/pagevec.h>
 #include <linux/init.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/mm_inline.h>
 #include <linux/buffer_head.h> /* for try_to_release_page() */
 #include <linux/percpu_counter.h>
index 46680461785bef647c3618bc7d493d1909aea80f..78cc4d1f6ccefe617698761cf198a7eb8a6db2bc 100644 (file)
@@ -6,7 +6,6 @@
  *
  *  Rewritten to use page cache, (C) 1998 Stephen Tweedie
  */
-#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/gfp.h>
 #include <linux/kernel_stat.h>
index c9d654009125d506053059262a63fe6e0637a394..b1cd120607230b0770c35e0823d6389782ae734a 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/ksm.h>
 #include <linux/rmap.h>
 #include <linux/security.h>
index b40ac6d4e86e7ea7d1df670e709452948a1dcb74..632b15e29f74533a5a22434351d8d21dc07e4a54 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include <linux/pagevec.h>
index 88ea1bd661c0f5164e37a8415050808fa815808f..136ac4f322b8248a5bea3c11d93c69c001b7bda8 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -1,7 +1,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
index b669aa6f6caff34f41fac15a527a791576f9026a..1d8b32f0713977ad2e3aeb6ba3d2554bb1389b53 100644 (file)
@@ -1633,6 +1633,8 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
                goto fail;
 
        addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller);
+       if (!addr)
+               return NULL;
 
        /*
         * In this function, newly allocated vm_struct is not added
@@ -2141,23 +2143,30 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
 
 static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data)
 {
-       /* apply_to_page_range() does all the hard work. */
+       pte_t ***p = data;
+
+       if (p) {
+               *(*p) = pte;
+               (*p)++;
+       }
        return 0;
 }
 
 /**
  *     alloc_vm_area - allocate a range of kernel address space
  *     @size:          size of the area
+ *     @ptes:          returns the PTEs for the address space
  *
  *     Returns:        NULL on failure, vm_struct on success
  *
  *     This function reserves a range of kernel address space, and
  *     allocates pagetables to map that range.  No actual mappings
- *     are created.  If the kernel address space is not shared
- *     between processes, it syncs the pagetable across all
- *     processes.
+ *     are created.
+ *
+ *     If @ptes is non-NULL, pointers to the PTEs (in init_mm)
+ *     allocated for the VM area are returned.
  */
-struct vm_struct *alloc_vm_area(size_t size)
+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
 {
        struct vm_struct *area;
 
@@ -2171,19 +2180,11 @@ struct vm_struct *alloc_vm_area(size_t size)
         * of kernel virtual address space and mapped into init_mm.
         */
        if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-                               area->size, f, NULL)) {
+                               size, f, ptes ? &ptes : NULL)) {
                free_vm_area(area);
                return NULL;
        }
 
-       /*
-        * If the allocated address space is passed to a hypercall
-        * before being used then we cannot rely on a page fault to
-        * trigger an update of the page tables.  So sync all the page
-        * tables here.
-        */
-       vmalloc_sync_all();
-
        return area;
 }
 EXPORT_SYMBOL_GPL(alloc_vm_area);
index 132d1ddb2238179466f45a599b1ccd687f9ee3f8..f54a05b7a61d9eb658562b191996beb9d4cea397 100644 (file)
@@ -183,7 +183,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone,
  */
 void register_shrinker(struct shrinker *shrinker)
 {
-       shrinker->nr = 0;
+       atomic_long_set(&shrinker->nr_in_batch, 0);
        down_write(&shrinker_rwsem);
        list_add_tail(&shrinker->list, &shrinker_list);
        up_write(&shrinker_rwsem);
@@ -247,25 +247,26 @@ unsigned long shrink_slab(struct shrink_control *shrink,
 
        list_for_each_entry(shrinker, &shrinker_list, list) {
                unsigned long long delta;
-               unsigned long total_scan;
-               unsigned long max_pass;
+               long total_scan;
+               long max_pass;
                int shrink_ret = 0;
                long nr;
                long new_nr;
                long batch_size = shrinker->batch ? shrinker->batch
                                                  : SHRINK_BATCH;
 
+               max_pass = do_shrinker_shrink(shrinker, shrink, 0);
+               if (max_pass <= 0)
+                       continue;
+
                /*
                 * copy the current shrinker scan count into a local variable
                 * and zero it so that other concurrent shrinker invocations
                 * don't also do this scanning work.
                 */
-               do {
-                       nr = shrinker->nr;
-               } while (cmpxchg(&shrinker->nr, nr, 0) != nr);
+               nr = atomic_long_xchg(&shrinker->nr_in_batch, 0);
 
                total_scan = nr;
-               max_pass = do_shrinker_shrink(shrinker, shrink, 0);
                delta = (4 * nr_pages_scanned) / shrinker->seeks;
                delta *= max_pass;
                do_div(delta, lru_pages + 1);
@@ -325,12 +326,11 @@ unsigned long shrink_slab(struct shrink_control *shrink,
                 * manner that handles concurrent updates. If we exhausted the
                 * scan, there is no need to do an update.
                 */
-               do {
-                       nr = shrinker->nr;
-                       new_nr = total_scan + nr;
-                       if (total_scan <= 0)
-                               break;
-               } while (cmpxchg(&shrinker->nr, nr, new_nr) != nr);
+               if (total_scan > 0)
+                       new_nr = atomic_long_add_return(total_scan,
+                                       &shrinker->nr_in_batch);
+               else
+                       new_nr = atomic_long_read(&shrinker->nr_in_batch);
 
                trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr);
        }
@@ -2266,7 +2266,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
                 */
                writeback_threshold = sc->nr_to_reclaim + sc->nr_to_reclaim / 2;
                if (total_scanned > writeback_threshold) {
-                       wakeup_flusher_threads(laptop_mode ? 0 : total_scanned);
+                       wakeup_flusher_threads(laptop_mode ? 0 : total_scanned,
+                                               WB_REASON_TRY_TO_FREE_PAGES);
                        sc->may_writepage = 1;
                }
 
index 1e49f2d4ea9624e804ae0588d96976e32430bc9a..bd345f3d29f855f9792c4ebdf69c2aabee2d0021 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/net.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <net/arp.h>
 
 /*
index 070bf4403bf8fdde83a99c60c4c7b20b50ed831d..8e21b6db3981cc93cb5e4e00e30b820c9ff97af1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/llc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/garp.h>
index 0e136ef1e4bab47307d9fc382709b2c552281ecd..15540b7323cde090b76f0d52a33e7ef69bfa05d3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/etherdevice.h>
 #include <linux/llc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/stp.h>
index 163397f1fd5adefd655efcfb681544b1a56655bf..f5ffc02729d60396aac6abbdcbfc49bf1ebf20e1 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_vlan.h>
 #include <linux/netpoll.h>
+#include <linux/export.h>
 #include "vlan.h"
 
 bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
index be9a5c19a775aa64751b93795ccd5df1a453297a..235c2197dbb642d4bf6155f7a0975f7940cce908 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/if_vlan.h>
+#include <linux/module.h>
 #include <net/net_namespace.h>
 #include <net/netlink.h>
 #include <net/rtnetlink.h>
index 1acc69576df8114689ad30175bb61755040ebec1..173a2e82f486b4ee19411b18842e61f57b05a58c 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
 int sysctl_aarp_tick_time = AARP_TICK_TIME;
index 6ef0e761e5de28d40cdf43559271e19b4e132a1f..b5b1a221c242d981dff59a483bdcd496849ab157 100644 (file)
@@ -14,6 +14,7 @@
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <linux/atalk.h>
+#include <linux/export.h>
 
 
 static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
index 437ee70c5e629e3fcf8cbd4cdb3ac5f737802b23..3a734919c36cbeac2e59e923225096f76380620b 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/export.h>
 #include <net/sock.h>          /* for sock_no_* */
 
 #include "resources.h"         /* devs and vccs */
index 754ee4791d966d46843798be0f5b5865ed0f519d..1281049c135f269f9ab0553eb51a681cd97b2079 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/bitops.h>
 #include <net/sock.h>          /* for sock_no_* */
 #include <linux/uaccess.h>
+#include <linux/export.h>
 
 #include "resources.h"
 #include "common.h"            /* common for PVCs and SVCs */
index a1690845dc6ecf9ecb12de37ac2b9342d678de01..87fddab22e0f3b9d1961ae53461cb7f1dc49d8ac 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 static ax25_route *ax25_route_list;
 static DEFINE_RWLOCK(ax25_route_lock);
index d349be9578f5bce47be0d42243ca1c7ea34dbcdb..4c83137b59546ce01a767538a8d249796651c4ab 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/stat.h>
 #include <linux/netfilter.h>
 #include <linux/sysctl.h>
+#include <linux/export.h>
 #include <net/ip.h>
 #include <net/arp.h>
 
index c1c597e3e198e9ffba26dd4dcf2e59e2ffc923c3..e0af7237cd9245fedfc8886ec446f670ddc48500 100644 (file)
@@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
                goto encrypt;
 
 auth:
-       if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+       if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
                return 0;
 
        if (!hci_conn_auth(conn, sec_level, auth_type))
index b84458dcc2261259d83e1bad2aecef95ed622113..be84ae33ae36bec88f4f67502780b4fe5333e270 100644 (file)
@@ -613,7 +613,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
        if (!test_bit(HCI_RAW, &hdev->flags)) {
                set_bit(HCI_INIT, &hdev->flags);
                __hci_request(hdev, hci_reset_req, 0,
-                                       msecs_to_jiffies(250));
+                                       msecs_to_jiffies(HCI_INIT_TIMEOUT));
                clear_bit(HCI_INIT, &hdev->flags);
        }
 
index 22f1a6c87035b551c352acf70d53ed369d6e9dcd..661b461cf0b0873983b8fae4dbb83ad80d4de505 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/init.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 8cd12917733b2cb37f21670edd846c9071e19459..5ea94a1eecf2f9a4338aa116d645b03b77fa7bd6 100644 (file)
@@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg)
 
        if (sock_owned_by_user(sk)) {
                /* sk is owned by user. Try again later */
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                chan_put(chan);
                return;
@@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
                if (sock_owned_by_user(sk)) {
                        l2cap_state_change(chan, BT_DISCONN);
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan, HZ / 5);
+                       __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        break;
                }
 
@@ -2661,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        default:
                sk->sk_err = ECONNRESET;
-               __set_chan_timer(chan, HZ * 5);
+               __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
                l2cap_send_disconn_req(conn, chan, ECONNRESET);
                goto done;
        }
@@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
        if (sock_owned_by_user(sk)) {
                l2cap_state_change(chan, BT_DISCONN);
                __clear_chan_timer(chan);
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                return 0;
        }
@@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
        if (sock_owned_by_user(sk)) {
                l2cap_state_change(chan,BT_DISCONN);
                __clear_chan_timer(chan);
-               __set_chan_timer(chan, HZ / 5);
+               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                bh_unlock_sock(sk);
                return 0;
        }
@@ -3998,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
        if (encrypt == 0x00) {
                if (chan->sec_level == BT_SECURITY_MEDIUM) {
                        __clear_chan_timer(chan);
-                       __set_chan_timer(chan, HZ * 5);
+                       __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
                } else if (chan->sec_level == BT_SECURITY_HIGH)
                        l2cap_chan_close(chan, ECONNREFUSED);
        } else {
@@ -4066,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                        L2CAP_CONN_REQ, sizeof(req), &req);
                        } else {
                                __clear_chan_timer(chan);
-                               __set_chan_timer(chan, HZ / 10);
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        }
                } else if (chan->state == BT_CONNECT2) {
                        struct l2cap_conn_rsp rsp;
@@ -4086,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                                }
                        } else {
                                l2cap_state_change(chan, BT_DISCONN);
-                               __set_chan_timer(chan, HZ / 10);
+                               __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                                res = L2CAP_CR_SEC_BLOCK;
                                stat = L2CAP_CS_NO_INFO;
                        }
index e8292369cdcf68981b4a59969b2c4af41b703f90..5c406d3136f74fc206380968a0a98c3c4b742474 100644 (file)
@@ -27,6 +27,7 @@
 /* Bluetooth L2CAP sockets. */
 
 #include <linux/security.h>
+#include <linux/export.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
index 5a94eec06caa900f9bb422b5cd7376076d67c63d..2c76342968660f97a1911783f26d60a7a96b715a 100644 (file)
@@ -23,6 +23,7 @@
 /* Bluetooth HCI Management interface */
 
 #include <linux/uaccess.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -147,8 +148,6 @@ static int read_index_list(struct sock *sk)
 
                hci_del_off_timer(d);
 
-               set_bit(HCI_MGMT, &d->flags);
-
                if (test_bit(HCI_SETUP, &d->flags))
                        continue;
 
index 38b618c96de64a13a1d724a954352cec27264fae..4e32e18211f9187d8a98a27772a9ba97f5cf7112 100644 (file)
@@ -1802,6 +1802,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
                        continue;
                }
 
+               if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
+                       __rfcomm_dlc_close(d, ECONNREFUSED);
+                       continue;
+               }
+
                if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
                        rfcomm_dlc_clear_timer(d);
                        if (d->out) {
@@ -2077,7 +2082,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
                if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
                        rfcomm_dlc_clear_timer(d);
                        if (status || encrypt == 0x00) {
-                               __rfcomm_dlc_close(d, ECONNREFUSED);
+                               set_bit(RFCOMM_ENC_DROP, &d->flags);
                                continue;
                        }
                }
@@ -2088,7 +2093,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
                                rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
                                continue;
                        } else if (d->sec_level == BT_SECURITY_HIGH) {
-                               __rfcomm_dlc_close(d, ECONNREFUSED);
+                               set_bit(RFCOMM_ENC_DROP, &d->flags);
                                continue;
                        }
                }
index 6f9f8c014725dd74ddfdda99e0173fa3c5d2d16f..5a31731be4d066f168579552981bd3e28b2f0ac4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/netfilter_bridge.h>
+#include <linux/export.h>
 #include "br_private.h"
 
 /* Bridge group multicast address 802.1d (pg 51). */
index 995cbe0ac0b2b1e74f2b4762d61a13102d9f66bb..a5f4e5769809c74f96c1a93ab67ade401fb022d7 100644 (file)
@@ -1501,6 +1501,8 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 
        __skb_pull(skb2, offset);
        skb_reset_transport_header(skb2);
+       skb_postpull_rcsum(skb2, skb_network_header(skb2),
+                          skb_network_header_len(skb2));
 
        icmp6_type = icmp6_hdr(skb2)->icmp6_type;
 
@@ -1770,7 +1772,7 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
        int err = 0;
        struct net_bridge_mdb_htable *mdb;
 
-       spin_lock(&br->multicast_lock);
+       spin_lock_bh(&br->multicast_lock);
        if (br->multicast_disabled == !val)
                goto unlock;
 
@@ -1806,7 +1808,7 @@ rollback:
        }
 
 unlock:
-       spin_unlock(&br->multicast_lock);
+       spin_unlock_bh(&br->multicast_lock);
 
        return err;
 }
index e5f9ece3c9a0f9637c8ad98382b88705b27e1d30..a1daf8227ed11c1a1853a8fb5a246919e9deb5f5 100644 (file)
@@ -18,6 +18,7 @@
 #include <net/sock.h>
 
 #include "br_private.h"
+#include "br_private_stp.h"
 
 static inline size_t br_nlmsg_size(void)
 {
@@ -188,6 +189,11 @@ static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
 
        p->state = new_state;
        br_log_state(p);
+
+       spin_lock_bh(&p->br->lock);
+       br_port_state_selection(p->br);
+       spin_unlock_bh(&p->br->lock);
+
        br_ifinfo_notify(RTM_NEWLINK, p);
 
        return 0;
index ad0a3f7cf6cc73081ca600b241060ce5ef867e44..dd147d78a5889ab6c2139712199c3672f9e087c6 100644 (file)
@@ -399,25 +399,24 @@ void br_port_state_selection(struct net_bridge *br)
        struct net_bridge_port *p;
        unsigned int liveports = 0;
 
-       /* Don't change port states if userspace is handling STP */
-       if (br->stp_enabled == BR_USER_STP)
-               return;
-
        list_for_each_entry(p, &br->port_list, list) {
                if (p->state == BR_STATE_DISABLED)
                        continue;
 
-               if (p->port_no == br->root_port) {
-                       p->config_pending = 0;
-                       p->topology_change_ack = 0;
-                       br_make_forwarding(p);
-               } else if (br_is_designated_port(p)) {
-                       del_timer(&p->message_age_timer);
-                       br_make_forwarding(p);
-               } else {
-                       p->config_pending = 0;
-                       p->topology_change_ack = 0;
-                       br_make_blocking(p);
+               /* Don't change port states if userspace is handling STP */
+               if (br->stp_enabled != BR_USER_STP) {
+                       if (p->port_no == br->root_port) {
+                               p->config_pending = 0;
+                               p->topology_change_ack = 0;
+                               br_make_forwarding(p);
+                       } else if (br_is_designated_port(p)) {
+                               del_timer(&p->message_age_timer);
+                               br_make_forwarding(p);
+                       } else {
+                               p->config_pending = 0;
+                               p->topology_change_ack = 0;
+                               br_make_blocking(p);
+                       }
                }
 
                if (p->state == BR_STATE_FORWARDING)
index 10eda3cd1d7112759d46d245386c260ca265ca11..19308e305d851a89044434315a86d2e9ca9dc549 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/kmod.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 
index 47fc8f3a47cf237af78fbe4483fac7da0f2108ad..f1fa1f6e658d4dc84ca6eea2abceb6be6d3e8283 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/net.h>
 #include <linux/netdevice.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <net/netns/generic.h>
 #include <net/net_namespace.h>
 #include <net/pkt_sched.h>
index f39921171d0d94e51e1270891a6703be598d01e9..d3ca87bf23b7ff952a428b367f6ad525382e6740 100644 (file)
@@ -136,20 +136,21 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
 
 static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
 {
-       int tmp;
        u16 chks;
        u16 len;
+       __le16 data;
+
        struct cffrml *this = container_obj(layr);
        if (this->dofcs) {
                chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
-               tmp = cpu_to_le16(chks);
-               cfpkt_add_trail(pkt, &tmp, 2);
+               data = cpu_to_le16(chks);
+               cfpkt_add_trail(pkt, &data, 2);
        } else {
                cfpkt_pad_trail(pkt, 2);
        }
        len = cfpkt_getlen(pkt);
-       tmp = cpu_to_le16(len);
-       cfpkt_add_head(pkt, &tmp, 2);
+       data = cpu_to_le16(len);
+       cfpkt_add_head(pkt, &data, 2);
        cfpkt_info(pkt)->hdr_len += 2;
        if (cfpkt_erroneous(pkt)) {
                pr_err("Packet is erroneous!\n");
index 75d4bfae1a78714b46dc303769ff26f2b6bc8b91..df08c47183d477b96bf26cb026043f17c1abcf64 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <linux/hardirq.h>
+#include <linux/export.h>
 #include <net/caif/cfpkt.h>
 
 #define PKT_PREFIX  48
index f466930e26faf9a9b8f43730641cdf5a1b7f7dee..ad5b70801f37788edbb71b6d95cbe7d25ab94abd 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/ceph/messenger.h>
 #include <linux/ceph/decode.h>
 #include <linux/ceph/pagelist.h>
+#include <linux/export.h>
 
 /*
  * Ceph uses the messenger to exchange ceph_msg messages with other
index 733e46008b89d6e67397d779edf9ccb5cb3e5c8a..f4f3f58f5234c1a5ce5eb4b54638c730f571ffb9 100644 (file)
@@ -244,7 +244,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
                ceph_pagelist_init(req->r_trail);
        }
        /* create request message; allow space for oid */
-       msg_size += 40;
+       msg_size += MAX_OBJ_NAME_SIZE;
        if (snapc)
                msg_size += sizeof(u64) * snapc->num_snaps;
        if (use_mempool)
index c578d9382e193db92a3b5a5511d62303be4df7c5..6def90e0a1124b6772c480d099e7f6a505ba82f8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/filter.h>
 #include <linux/compat.h>
 #include <linux/security.h>
+#include <linux/export.h>
 
 #include <net/scm.h>
 #include <net/sock.h>
index 6ba50a1e404c4bac04cc7d56718865d5a1749c2f..5a13edfc9f73411f688920b51400489eb3e89ee2 100644 (file)
@@ -1396,7 +1396,7 @@ rollback:
        for_each_net(net) {
                for_each_netdev(net, dev) {
                        if (dev == last)
-                               break;
+                               goto outroll;
 
                        if (dev->flags & IFF_UP) {
                                nb->notifier_call(nb, NETDEV_GOING_DOWN, dev);
@@ -1407,6 +1407,7 @@ rollback:
                }
        }
 
+outroll:
        raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
 }
@@ -4282,6 +4283,12 @@ static int dev_seq_open(struct inode *inode, struct file *file)
                            sizeof(struct dev_iter_state));
 }
 
+int dev_seq_open_ops(struct inode *inode, struct file *file,
+                    const struct seq_operations *ops)
+{
+       return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state));
+}
+
 static const struct file_operations dev_seq_fops = {
        .owner   = THIS_MODULE,
        .open    = dev_seq_open,
index 283d1b863876ec176988d12442a71a540168ee22..febba516db6274c83d56577e7dc4d7fd61a15b72 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/export.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
 
@@ -695,8 +696,7 @@ static const struct seq_operations dev_mc_seq_ops = {
 
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_net(inode, file, &dev_mc_seq_ops,
-                           sizeof(struct seq_net_private));
+       return dev_seq_open_ops(inode, file, &dev_mc_seq_ops);
 }
 
 static const struct file_operations dev_mc_seq_fops = {
index 57e8f95110e6c39d0c562bbda5e3e140897765d3..c02e63c908da6972228735ba247dfcda6798b233 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/list.h>
+#include <linux/module.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/fib_rules.h>
index 039d51e6c284e7ab655319d399b9d40060357dcf..5ac07d31fbc9e395abf71ae46c897b5db3c7d6f8 100644 (file)
@@ -2397,7 +2397,10 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
        struct net *net = seq_file_net(seq);
        struct neigh_table *tbl = state->tbl;
 
-       pn = pn->next;
+       do {
+               pn = pn->next;
+       } while (pn && !net_eq(pneigh_net(pn), net));
+
        while (!pn) {
                if (++state->bucket > PNEIGH_HASHMASK)
                        break;
index 7604a635376bdf61f259e940ef042ba6d0820a10..c71c434a4c053e440dc816682d944c521e05c50f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <net/wext.h>
 
 #include "net-sysfs.h"
index 52380b1d552aded06478f6ac684ba0eab2a9d506..ba3c0120786c8f1f3419688067328e4524b5851e 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/inetdevice.h>
 #include <linux/inet.h>
 #include <linux/interrupt.h>
+#include <linux/export.h>
 #include <linux/netpoll.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
index 5bbdbf0d3664ce592f680d9670f26f7f96ce92cc..aefcd7acbffa9ff0ae028cc0d5cb2eb662ced477 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/nsproxy.h>
 #include <linux/proc_fs.h>
 #include <linux/file.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
index 865f0ceb81fbbb0e307f4f1081a1de7edc00b40d..f17ccd291d3902a94ebd31653959851203402468 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/rtnetlink.h>
 #include <linux/notifier.h>
+#include <linux/export.h>
 #include <net/netevent.h>
 
 static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain);
index f57d94627a2aa7eca44e45d3ed901c9499b75070..cf64c1ffa4cd95c3368de492916f0b95ded7ce64 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rcupdate.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <asm/unaligned.h>
index 182236b2510aeb16e6e0e2026264d683edf93e7e..9b570a6a33c5d8c52d777e160742dc31ec350c16 100644 (file)
  * but then some measure against one socket starving all other sockets
  * would be needed.
  *
- * It was 128 by default. Experiments with real servers show, that
+ * The minimum value of it is 128. Experiments with real servers show that
  * it is absolutely not enough even at 100conn/sec. 256 cures most
- * of problems. This value is adjusted to 128 for very small machines
- * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
+ * of problems.
+ * This value is adjusted to 128 for low memory machines,
+ * and it will increase in proportion to the memory of machine.
  * Note : Dont forget somaxconn that may limit backlog too.
  */
 int sysctl_max_syn_backlog = 256;
index 025233de25f969cb67e075d6ea5c4a9bba746bd9..925991ae6f52e67e2221f1ed7490a4583bf26b9d 100644 (file)
@@ -19,6 +19,7 @@ static int __init net_secret_init(void)
 }
 late_initcall(net_secret_init);
 
+#ifdef CONFIG_INET
 static u32 seq_scale(u32 seq)
 {
        /*
@@ -33,6 +34,7 @@ static u32 seq_scale(u32 seq)
         */
        return seq + (ktime_to_ns(ktime_get_real()) >> 6);
 }
+#endif
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
index 18a3cebb753d39d57b2962f991f32fb048d76c29..3c30ee4a57105a2746b3e1b2bfab68af8ef0c917 100644 (file)
@@ -2230,7 +2230,7 @@ static int skb_prepare_for_shift(struct sk_buff *skb)
  * @shiftlen: shift up to this many bytes
  *
  * Attempts to shift up to shiftlen worth of bytes, which may be less than
- * the length of the skb, from tgt to skb. Returns number bytes shifted.
+ * the length of the skb, from skb to tgt. Returns number bytes shifted.
  * It's up to caller to free skb if everything was shifted.
  *
  * If @tgt runs out of frags, the whole operation is aborted.
index 82fb28857b647163b931c7f11294a4cae19e7bbc..661b5a40ec1029016a4a2e70579c690c40110512 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/phy.h>
 #include <linux/ptp_classify.h>
 #include <linux/skbuff.h>
+#include <linux/export.h>
 
 static struct sock_filter ptp_filter[] = {
        PTP_FILTER
index 2d7cf3d52b4c9caea99081602dc25381bd9f02cf..1b5fefdb8198be11018da29869639b9d545ee1d7 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/dmaengine.h>
 #include <linux/socket.h>
+#include <linux/export.h>
 #include <net/tcp.h>
 #include <net/netdma.h>
 
index 665a8802105aa100e396b740275e8ce186476148..1d9eb7c60a6850d51da5a7615c012c3e55681f99 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/rtnetlink.h>
 #include <linux/notifier.h>
+#include <linux/export.h>
 
 static ATOMIC_NOTIFIER_HEAD(dcbevent_notif_chain);
 
index 9bfbc1d1b50c0a015cb60092fbfd121afa196e13..d86053002c16b896fdea34bd174b37e6c4aa3054 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/dcbnl.h>
 #include <net/dcbevent.h>
 #include <linux/rtnetlink.h>
+#include <linux/module.h>
 #include <net/sock.h>
 
 /**
index 25b7a8d1ad58eac67d2306e0c86ff8da7cea0b3b..ba07824af4c07950d8ee25c6abfccfb1fe919f5c 100644 (file)
@@ -12,6 +12,7 @@
 #include "dccp.h"
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 static struct kmem_cache *dccp_ackvec_slab;
 static struct kmem_cache *dccp_ackvec_record_slab;
index 4902029854d83af04f37015f5e4ff30a5c04584e..1f94b7e01d392929004216b1541d9aa5d88c065c 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
  * Copyright (c) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
  */
+#include <linux/moduleparam.h>
 #include "tfrc.h"
 
 #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
index 90a919afbed79ee5998f510badfaaa199a441086..3f4e5414c8e5200711839e8847437809047cb778 100644 (file)
@@ -111,6 +111,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
                               inet->inet_sport, inet->inet_dport, sk);
        if (IS_ERR(rt)) {
+               err = PTR_ERR(rt);
                rt = NULL;
                goto failure;
        }
index 7587870b7040d0d997a54efd4d2c0786a1bb8a7d..16f0b223102e6619b3b3430a108be740e2e7b373 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/dccp.h>
 #include <linux/skbuff.h>
+#include <linux/export.h>
 
 #include "dccp.h"
 
index 43450c1002269a8f32300101f057079660a1b177..94f4ec036669cc152af1a9ff9639889016235228 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/netfilter_decnet.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
+#include <linux/export.h>
 #include <asm/errno.h>
 #include <net/net_namespace.h>
 #include <net/netlink.h>
@@ -111,7 +112,7 @@ static unsigned long dn_rt_deadline;
 static int dn_dst_gc(struct dst_ops *ops);
 static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
 static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
-static unsigned int dn_dst_default_mtu(const struct dst_entry *dst);
+static unsigned int dn_dst_mtu(const struct dst_entry *dst);
 static void dn_dst_destroy(struct dst_entry *);
 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static void dn_dst_link_failure(struct sk_buff *);
@@ -134,7 +135,7 @@ static struct dst_ops dn_dst_ops = {
        .gc =                   dn_dst_gc,
        .check =                dn_dst_check,
        .default_advmss =       dn_dst_default_advmss,
-       .default_mtu =          dn_dst_default_mtu,
+       .mtu =                  dn_dst_mtu,
        .cow_metrics =          dst_cow_metrics_generic,
        .destroy =              dn_dst_destroy,
        .negative_advice =      dn_dst_negative_advice,
@@ -824,9 +825,11 @@ static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
        return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
 }
 
-static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
+static unsigned int dn_dst_mtu(const struct dst_entry *dst)
 {
-       return dst->dev->mtu;
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       return mtu ? : dst->dev->mtu;
 }
 
 static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
index f0efb0ccfeca30cd668a4e32b5aaf2059ab1f844..f65c9ddaee41cde5bdc2ba5780ea8f4cf40928f3 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/rcupdate.h>
+#include <linux/export.h>
 #include <net/neighbour.h>
 #include <net/dst.h>
 #include <net/flow.h>
index 67f691bd4acfee77b2b3402e2e9e4e5092bab8c0..d9c150cc59a952ac86585b6c600acc398b80bc14 100644 (file)
@@ -36,16 +36,13 @@ static void dn_slow_timer(unsigned long arg);
 
 void dn_start_slow_timer(struct sock *sk)
 {
-       sk->sk_timer.expires    = jiffies + SLOW_INTERVAL;
-       sk->sk_timer.function   = dn_slow_timer;
-       sk->sk_timer.data       = (unsigned long)sk;
-
-       add_timer(&sk->sk_timer);
+       setup_timer(&sk->sk_timer, dn_slow_timer, (unsigned long)sk);
+       sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
 }
 
 void dn_stop_slow_timer(struct sock *sk)
 {
-       del_timer(&sk->sk_timer);
+       sk_stop_timer(sk, &sk->sk_timer);
 }
 
 static void dn_slow_timer(unsigned long arg)
@@ -53,12 +50,10 @@ static void dn_slow_timer(unsigned long arg)
        struct sock *sk = (struct sock *)arg;
        struct dn_scp *scp = DN_SK(sk);
 
-       sock_hold(sk);
        bh_lock_sock(sk);
 
        if (sock_owned_by_user(sk)) {
-               sk->sk_timer.expires = jiffies + HZ / 10;
-               add_timer(&sk->sk_timer);
+               sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 10);
                goto out;
        }
 
@@ -100,9 +95,7 @@ static void dn_slow_timer(unsigned long arg)
                        scp->keepalive_fxn(sk);
        }
 
-       sk->sk_timer.expires = jiffies + SLOW_INTERVAL;
-
-       add_timer(&sk->sk_timer);
+       sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
 out:
        bh_unlock_sock(sk);
        sock_put(sk);
index 3fb14b7c13cf1ed3bc5bb1439e6bfc35f907af96..0dc1589343c3f38335660752433d8b51d2898089 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/dsa.h>
 #include "dsa_priv.h"
 
index 71ee1108d4f86d9509a8f3ba011d066d1a41ef7c..adaf46214905964f76bef59f7f660808c982054d 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/genetlink.h>
 #include <net/sock.h>
 #include <linux/nl802154.h>
+#include <linux/export.h>
 #include <net/af_ieee802154.h>
 #include <net/nl802154.h>
 #include <net/ieee802154.h>
index c1f4154552fc582320e276e6768831ed9ec32548..36d14406261e8c9ad486103127ae1106baca4678 100644 (file)
@@ -136,8 +136,6 @@ static void ah_output_done(struct crypto_async_request *base, int err)
                memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));
        }
 
-       err = ah->nexthdr;
-
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_output_resume(skb, err);
 }
@@ -264,12 +262,12 @@ static void ah_input_done(struct crypto_async_request *base, int err)
        if (err)
                goto out;
 
+       err = ah->nexthdr;
+
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), work_iph, ihl);
        __skb_pull(skb, ah_hlen + ihl);
        skb_set_transport_header(skb, -ihl);
-
-       err = ah->nexthdr;
 out:
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_input_resume(skb, err);
@@ -371,8 +369,6 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
                if (err == -EINPROGRESS)
                        goto out;
 
-               if (err == -EBUSY)
-                       err = NET_XMIT_DROP;
                goto out_free;
        }
 
index c6b5092f29a15511bb7c69f37a86dca2c538a164..65f01dc47565bcc26282d4472bbd9c3fb2d3712c 100644 (file)
@@ -1490,7 +1490,9 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
                             void __user *buffer,
                             size_t *lenp, loff_t *ppos)
 {
+       int old_value = *(int *)ctl->data;
        int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+       int new_value = *(int *)ctl->data;
 
        if (write) {
                struct ipv4_devconf *cnf = ctl->extra1;
@@ -1501,6 +1503,9 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
 
                if (cnf == net->ipv4.devconf_dflt)
                        devinet_copy_dflt_conf(net, i);
+               if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1)
+                       if ((new_value == 0) && (old_value != 0))
+                               rt_cache_flush(net, 0);
        }
 
        return ret;
index a53bb1b5b11825a5663629047cff9ec0509d31e6..46339ba7a2d3372b47a5eaeaffa2a71774008d0e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/rcupdate.h>
+#include <linux/export.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/tcp.h>
index 89d6f71a6a99faeec6c93a3ab0f5e48dad5e0e0e..37b671185c8192c7de2e7166e9089b9276d98121 100644 (file)
@@ -73,6 +73,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/prefetch.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/protocol.h>
index c7472eff2d514b475579d1a3e5a89269d04fce0e..b2ca095cb9dab36a4eb6e8da7308c4e55a6437cc 100644 (file)
@@ -1716,7 +1716,8 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
        if (err) {
                int j;
 
-               pmc->sfcount[sfmode]--;
+               if (!delta)
+                       pmc->sfcount[sfmode]--;
                for (j=0; j<i; j++)
                        (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
        } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
index f5e2bdaef9495eb52524089f6d9b341cd5503137..ccee270a9b6587efe63e74abcd298bae34fea779 100644 (file)
@@ -108,9 +108,6 @@ static int inet_csk_diag_fill(struct sock *sk,
                       icsk->icsk_ca_ops->name);
        }
 
-       if ((ext & (1 << (INET_DIAG_TOS - 1))) && (sk->sk_family != AF_INET6))
-               RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos);
-
        r->idiag_family = sk->sk_family;
        r->idiag_state = sk->sk_state;
        r->idiag_timer = 0;
@@ -125,16 +122,23 @@ static int inet_csk_diag_fill(struct sock *sk,
        r->id.idiag_src[0] = inet->inet_rcv_saddr;
        r->id.idiag_dst[0] = inet->inet_daddr;
 
+       /* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
+        * hence this needs to be included regardless of socket family.
+        */
+       if (ext & (1 << (INET_DIAG_TOS - 1)))
+               RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos);
+
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
        if (r->idiag_family == AF_INET6) {
                const struct ipv6_pinfo *np = inet6_sk(sk);
 
+               if (ext & (1 << (INET_DIAG_TCLASS - 1)))
+                       RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);
+
                ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
                               &np->rcv_saddr);
                ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
                               &np->daddr);
-               if (ext & (1 << (INET_DIAG_TOS - 1)))
-                       RTA_PUT_U8(skb, INET_DIAG_TOS, np->tclass);
        }
 #endif
 
index 44d65d546e30c3938c07b3b7bbc3bbb46ae26558..89168c6351ff695b95fda442f94d6805acda5a84 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/kmemcheck.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <net/inet_hashtables.h>
 #include <net/inet_timewait_sock.h>
 #include <net/ip.h>
index 3b34d1c862709e7bde3cd3665fad1e191692506d..29a07b6c7168f7369b13e25d8c96011c6118ec56 100644 (file)
@@ -84,7 +84,7 @@ int ip_forward(struct sk_buff *skb)
 
        rt = skb_rtable(skb);
 
-       if (opt->is_strictroute && ip_hdr(skb)->daddr != rt->rt_gateway)
+       if (opt->is_strictroute && opt->nexthop != rt->rt_gateway)
                goto sr_failed;
 
        if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
index ec93335901ddc45d09f7c85c53270ea9a6772207..1e60f7679075b660f489bcd1a9f462c832c5e77e 100644 (file)
@@ -568,12 +568,13 @@ void ip_forward_options(struct sk_buff *skb)
                     ) {
                        if (srrptr + 3 > srrspace)
                                break;
-                       if (memcmp(&ip_hdr(skb)->daddr, &optptr[srrptr-1], 4) == 0)
+                       if (memcmp(&opt->nexthop, &optptr[srrptr-1], 4) == 0)
                                break;
                }
                if (srrptr + 3 <= srrspace) {
                        opt->is_changed = 1;
                        ip_rt_get_source(&optptr[srrptr-1], skb, rt);
+                       ip_hdr(skb)->daddr = opt->nexthop;
                        optptr[2] = srrptr+4;
                } else if (net_ratelimit())
                        printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
@@ -640,6 +641,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
        }
        if (srrptr <= srrspace) {
                opt->srr_is_hit = 1;
+               opt->nexthop = nexthop;
                opt->is_changed = 1;
        }
        return 0;
index 472a8c4f1dc0d5ca8c4e447701c63f967e7d2006..0da2afc97f32ffae2773098391aba0dcbd004903 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/delay.h>
 #include <linux/nfs_fs.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/arp.h>
 #include <net/ip.h>
index 6164e982e0ef3da61c91863523ab277d1e52668a..76a7f07b38b6edb13b48118c583ad754b96e1b11 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/if_arp.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/compat.h>
+#include <linux/export.h>
 #include <net/ipip.h>
 #include <net/checksum.h>
 #include <net/netlink.h>
index 929b27bdeb79829801b4be02f9371d6538a161e8..4f47e064e262c2f24e7cb13eacfcebff0fad86a3 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/ip.h>
 #include <linux/skbuff.h>
 #include <linux/gfp.h>
+#include <linux/export.h>
 #include <net/route.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
@@ -63,7 +64,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
        /* Change in oif may mean change in hh_len. */
        hh_len = skb_dst(skb)->dev->hard_header_len;
        if (skb_headroom(skb) < hh_len &&
-           pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
+           pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
+                               0, GFP_ATOMIC))
                return -1;
 
        return 0;
index 1dfc18a03fd4219fe9dd419011877d0a7ce3dfa7..f19f2182894c1c1549d27eb79cb409914e5b5bf0 100644 (file)
@@ -325,7 +325,6 @@ config IP_NF_TARGET_TTL
 # raw + specific targets
 config IP_NF_RAW
        tristate  'raw table support (required for NOTRACK/TRACE)'
-       depends on NETFILTER_ADVANCED
        help
          This option adds a `raw' table to iptables. This table is the very
          first in the netfilter framework and hooks in at the PREROUTING
index 5585980fce2e351b35d2e6f0f741531f6a87d199..9682b36df38ce51213467cf0d449d465c59ab92f 100644 (file)
@@ -21,6 +21,7 @@
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_acct.h>
 #include <linux/rculist_nulls.h>
+#include <linux/export.h>
 
 struct ct_iter_state {
        struct seq_net_private p;
index f52d41ea06901253e1eae173201c8d3e613ea0c8..a3d997618602496867a7456b8205c80585d2ec75 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ip.h>
 
 #include <linux/netfilter.h>
+#include <linux/export.h>
 #include <net/secure_seq.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_core.h>
index 5744c3ec847cc26440204b7584fdd60d857f7964..9f4dc1235dc7d3458616335c50a0e09eea72f08b 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
 
index 756331d42661cf12b2964256a8204b7a588f92f8..bd5a80a62a5b9f604463b1bf0fb6c31ca1ceb52b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/sctp.h>
+#include <linux/module.h>
 #include <net/sctp/checksum.h>
 
 #include <net/netfilter/nf_nat_protocol.h>
index aa460a595d5d930e019f9bd36eb010251a5dd33e..0d67bb80130f019b48134fb675029b265d825f48 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 
index dfe65c7e292586521ad9d1f804a3f82eade1a755..0b1b8601cba79465faa036f11ab301fbf0d36e80 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/udp.h>
index 3cc8c8af39ef2fe82905fdad69b0b64af0f4e770..f83ef23e2ab708d946f54586024915b1ed489c35 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/udp.h>
 
 #include <linux/netfilter.h>
+#include <linux/module.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_protocol.h>
 
index 39b403f854c6debeb03437a2a9a0c9746083b399..43d4c3b223699aee36de3c3c79c6d82b5236a4c0 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/protocol.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/ping.h>
 #include <net/udp.h>
@@ -338,7 +339,6 @@ void ping_err(struct sk_buff *skb, u32 info)
        sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
                            ntohs(icmph->un.echo.id), skb->dev->ifindex);
        if (sk == NULL) {
-               ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
                pr_debug("no socket, dropping\n");
                return; /* No socket for error */
        }
@@ -678,7 +678,6 @@ static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
                inet_sk(sk), inet_sk(sk)->inet_num, skb);
        if (sock_queue_rcv_skb(sk, skb) < 0) {
-               ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);
                kfree_skb(skb);
                pr_debug("ping_queue_rcv_skb -> failed\n");
                return -1;
index 4bfad5da94f4e879615cf0a0b0f9ba008fd53f85..466ea8bb7a4d916e41c838389c7dcaf2b7f01b4a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/raw.h>
 
index 61714bd5292512142aa373fed50d68398372d561..007e2eb769d33ede3afdb4e4fc69c3e9de6db1b4 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/errno.h>
 #include <linux/aio.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/spinlock.h>
 #include <linux/sockios.h>
 #include <linux/socket.h>
index 155138d8ec8bb9d7ef0e907b36b0725e0910394d..46af62363b8c1e9ef452b6d750886f21e56f08b1 100644 (file)
 #include <net/secure_seq.h>
 
 #define RT_FL_TOS(oldflp4) \
-    ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)))
+       ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
 
 #define IP_MAX_MTU     0xFFF0
 
@@ -131,6 +131,7 @@ static int ip_rt_mtu_expires __read_mostly  = 10 * 60 * HZ;
 static int ip_rt_min_pmtu __read_mostly                = 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly      = 256;
 static int rt_chain_length_max __read_mostly   = 20;
+static int redirect_genid;
 
 /*
  *     Interface to generic destination cache.
@@ -138,7 +139,7 @@ static int rt_chain_length_max __read_mostly        = 20;
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int     ipv4_default_advmss(const struct dst_entry *dst);
-static unsigned int     ipv4_default_mtu(const struct dst_entry *dst);
+static unsigned int     ipv4_mtu(const struct dst_entry *dst);
 static void             ipv4_dst_destroy(struct dst_entry *dst);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
@@ -193,7 +194,7 @@ static struct dst_ops ipv4_dst_ops = {
        .gc =                   rt_garbage_collect,
        .check =                ipv4_dst_check,
        .default_advmss =       ipv4_default_advmss,
-       .default_mtu =          ipv4_default_mtu,
+       .mtu =                  ipv4_mtu,
        .cow_metrics =          ipv4_cow_metrics,
        .destroy =              ipv4_dst_destroy,
        .ifdown =               ipv4_dst_ifdown,
@@ -416,9 +417,13 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
        else {
                struct rtable *r = v;
                struct neighbour *n;
-               int len;
+               int len, HHUptod;
 
+               rcu_read_lock();
                n = dst_get_neighbour(&r->dst);
+               HHUptod = (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0;
+               rcu_read_unlock();
+
                seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
                              "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
                        r->dst.dev ? r->dst.dev->name : "*",
@@ -432,7 +437,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
                              dst_metric(&r->dst, RTAX_RTTVAR)),
                        r->rt_key_tos,
                        -1,
-                       (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0,
+                       HHUptod,
                        r->rt_spec_dst, &len);
 
                seq_printf(seq, "%*s\n", 127 - len, "");
@@ -837,6 +842,7 @@ static void rt_cache_invalidate(struct net *net)
 
        get_random_bytes(&shuffle, sizeof(shuffle));
        atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
+       redirect_genid++;
 }
 
 /*
@@ -1304,16 +1310,40 @@ static void rt_del(unsigned hash, struct rtable *rt)
        spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
+static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
+{
+       struct rtable *rt = (struct rtable *) dst;
+       __be32 orig_gw = rt->rt_gateway;
+       struct neighbour *n, *old_n;
+
+       dst_confirm(&rt->dst);
+
+       rt->rt_gateway = peer->redirect_learned.a4;
+
+       n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
+       if (IS_ERR(n)) {
+               rt->rt_gateway = orig_gw;
+               return;
+       }
+       old_n = xchg(&rt->dst._neighbour, n);
+       if (old_n)
+               neigh_release(old_n);
+       if (!(n->nud_state & NUD_VALID)) {
+               neigh_event_send(n, NULL);
+       } else {
+               rt->rt_flags |= RTCF_REDIRECTED;
+               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
+       }
+}
+
 /* called in rcu_read_lock() section */
 void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                    __be32 saddr, struct net_device *dev)
 {
        int s, i;
        struct in_device *in_dev = __in_dev_get_rcu(dev);
-       struct rtable *rt;
        __be32 skeys[2] = { saddr, 0 };
        int    ikeys[2] = { dev->ifindex, 0 };
-       struct flowi4 fl4;
        struct inet_peer *peer;
        struct net *net;
 
@@ -1336,33 +1366,44 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                        goto reject_redirect;
        }
 
-       memset(&fl4, 0, sizeof(fl4));
-       fl4.daddr = daddr;
        for (s = 0; s < 2; s++) {
                for (i = 0; i < 2; i++) {
-                       fl4.flowi4_oif = ikeys[i];
-                       fl4.saddr = skeys[s];
-                       rt = __ip_route_output_key(net, &fl4);
-                       if (IS_ERR(rt))
-                               continue;
-
-                       if (rt->dst.error || rt->dst.dev != dev ||
-                           rt->rt_gateway != old_gw) {
-                               ip_rt_put(rt);
-                               continue;
-                       }
-
-                       if (!rt->peer)
-                               rt_bind_peer(rt, rt->rt_dst, 1);
+                       unsigned int hash;
+                       struct rtable __rcu **rthp;
+                       struct rtable *rt;
+
+                       hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net));
+
+                       rthp = &rt_hash_table[hash].chain;
+
+                       while ((rt = rcu_dereference(*rthp)) != NULL) {
+                               rthp = &rt->dst.rt_next;
+
+                               if (rt->rt_key_dst != daddr ||
+                                   rt->rt_key_src != skeys[s] ||
+                                   rt->rt_oif != ikeys[i] ||
+                                   rt_is_input_route(rt) ||
+                                   rt_is_expired(rt) ||
+                                   !net_eq(dev_net(rt->dst.dev), net) ||
+                                   rt->dst.error ||
+                                   rt->dst.dev != dev ||
+                                   rt->rt_gateway != old_gw)
+                                       continue;
 
-                       peer = rt->peer;
-                       if (peer) {
-                               peer->redirect_learned.a4 = new_gw;
-                               atomic_inc(&__rt_peer_genid);
+                               if (!rt->peer)
+                                       rt_bind_peer(rt, rt->rt_dst, 1);
+
+                               peer = rt->peer;
+                               if (peer) {
+                                       if (peer->redirect_learned.a4 != new_gw ||
+                                           peer->redirect_genid != redirect_genid) {
+                                               peer->redirect_learned.a4 = new_gw;
+                                               peer->redirect_genid = redirect_genid;
+                                               atomic_inc(&__rt_peer_genid);
+                                       }
+                                       check_peer_redir(&rt->dst, peer);
+                               }
                        }
-
-                       ip_rt_put(rt);
-                       return;
                }
        }
        return;
@@ -1649,40 +1690,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
        }
 }
 
-static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer)
-{
-       struct rtable *rt = (struct rtable *) dst;
-       __be32 orig_gw = rt->rt_gateway;
-       struct neighbour *n, *old_n;
-
-       dst_confirm(&rt->dst);
-
-       rt->rt_gateway = peer->redirect_learned.a4;
-
-       n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
-       if (IS_ERR(n))
-               return PTR_ERR(n);
-       old_n = xchg(&rt->dst._neighbour, n);
-       if (old_n)
-               neigh_release(old_n);
-       if (!n || !(n->nud_state & NUD_VALID)) {
-               if (n)
-                       neigh_event_send(n, NULL);
-               rt->rt_gateway = orig_gw;
-               return -EAGAIN;
-       } else {
-               rt->rt_flags |= RTCF_REDIRECTED;
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n);
-       }
-       return 0;
-}
 
-static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+static void ipv4_validate_peer(struct rtable *rt)
 {
-       struct rtable *rt = (struct rtable *) dst;
-
-       if (rt_is_expired(rt))
-               return NULL;
        if (rt->rt_peer_genid != rt_peer_genid()) {
                struct inet_peer *peer;
 
@@ -1691,17 +1701,26 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 
                peer = rt->peer;
                if (peer) {
-                       check_peer_pmtu(dst, peer);
+                       check_peer_pmtu(&rt->dst, peer);
 
+                       if (peer->redirect_genid != redirect_genid)
+                               peer->redirect_learned.a4 = 0;
                        if (peer->redirect_learned.a4 &&
-                           peer->redirect_learned.a4 != rt->rt_gateway) {
-                               if (check_peer_redir(dst, peer))
-                                       return NULL;
-                       }
+                           peer->redirect_learned.a4 != rt->rt_gateway)
+                               check_peer_redir(&rt->dst, peer);
                }
 
                rt->rt_peer_genid = rt_peer_genid();
        }
+}
+
+static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+{
+       struct rtable *rt = (struct rtable *) dst;
+
+       if (rt_is_expired(rt))
+               return NULL;
+       ipv4_validate_peer(rt);
        return dst;
 }
 
@@ -1806,12 +1825,17 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst)
        return advmss;
 }
 
-static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
+static unsigned int ipv4_mtu(const struct dst_entry *dst)
 {
-       unsigned int mtu = dst->dev->mtu;
+       const struct rtable *rt = (const struct rtable *) dst;
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       if (mtu && rt_is_output_route(rt))
+               return mtu;
+
+       mtu = dst->dev->mtu;
 
        if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
-               const struct rtable *rt = (const struct rtable *) dst;
 
                if (rt->rt_gateway != rt->rt_dst && mtu > 576)
                        mtu = 576;
@@ -1844,6 +1868,8 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
                dst_init_metrics(&rt->dst, peer->metrics, false);
 
                check_peer_pmtu(&rt->dst, peer);
+               if (peer->redirect_genid != redirect_genid)
+                       peer->redirect_learned.a4 = 0;
                if (peer->redirect_learned.a4 &&
                    peer->redirect_learned.a4 != rt->rt_gateway) {
                        rt->rt_gateway = peer->redirect_learned.a4;
@@ -2349,6 +2375,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                    rth->rt_mark == skb->mark &&
                    net_eq(dev_net(rth->dst.dev), net) &&
                    !rt_is_expired(rth)) {
+                       ipv4_validate_peer(rth);
                        if (noref) {
                                dst_use_noref(&rth->dst, jiffies);
                                skb_dst_set_noref(skb, &rth->dst);
@@ -2407,11 +2434,11 @@ EXPORT_SYMBOL(ip_route_input_common);
 static struct rtable *__mkroute_output(const struct fib_result *res,
                                       const struct flowi4 *fl4,
                                       __be32 orig_daddr, __be32 orig_saddr,
-                                      int orig_oif, struct net_device *dev_out,
+                                      int orig_oif, __u8 orig_rtos,
+                                      struct net_device *dev_out,
                                       unsigned int flags)
 {
        struct fib_info *fi = res->fi;
-       u32 tos = RT_FL_TOS(fl4);
        struct in_device *in_dev;
        u16 type = res->type;
        struct rtable *rth;
@@ -2462,7 +2489,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
        rth->rt_genid = rt_genid(dev_net(dev_out));
        rth->rt_flags   = flags;
        rth->rt_type    = type;
-       rth->rt_key_tos = tos;
+       rth->rt_key_tos = orig_rtos;
        rth->rt_dst     = fl4->daddr;
        rth->rt_src     = fl4->saddr;
        rth->rt_route_iif = 0;
@@ -2512,7 +2539,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
 static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
 {
        struct net_device *dev_out = NULL;
-       u32 tos = RT_FL_TOS(fl4);
+       __u8 tos = RT_FL_TOS(fl4);
        unsigned int flags = 0;
        struct fib_result res;
        struct rtable *rth;
@@ -2688,7 +2715,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
 
 make_route:
        rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif,
-                              dev_out, flags);
+                              tos, dev_out, flags);
        if (!IS_ERR(rth)) {
                unsigned int hash;
 
@@ -2724,6 +2751,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4)
                            (IPTOS_RT_MASK | RTO_ONLINK)) &&
                    net_eq(dev_net(rth->dst.dev), net) &&
                    !rt_is_expired(rth)) {
+                       ipv4_validate_peer(rth);
                        dst_use(&rth->dst, jiffies);
                        RT_CACHE_STAT_INC(out_hit);
                        rcu_read_unlock_bh();
@@ -2747,9 +2775,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo
        return NULL;
 }
 
-static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst)
+static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst)
 {
-       return 0;
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       return mtu ? : dst->dev->mtu;
 }
 
 static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -2767,7 +2797,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
        .protocol               =       cpu_to_be16(ETH_P_IP),
        .destroy                =       ipv4_dst_destroy,
        .check                  =       ipv4_blackhole_dst_check,
-       .default_mtu            =       ipv4_blackhole_default_mtu,
+       .mtu                    =       ipv4_blackhole_mtu,
        .default_advmss         =       ipv4_default_advmss,
        .update_pmtu            =       ipv4_rt_blackhole_update_pmtu,
        .cow_metrics            =       ipv4_rt_blackhole_cow_metrics,
@@ -2845,7 +2875,7 @@ static int rt_fill_info(struct net *net,
        struct rtable *rt = skb_rtable(skb);
        struct rtmsg *r;
        struct nlmsghdr *nlh;
-       long expires = 0;
+       unsigned long expires = 0;
        const struct inet_peer *peer = rt->peer;
        u32 id = 0, ts = 0, tsage = 0, error;
 
@@ -2902,8 +2932,12 @@ static int rt_fill_info(struct net *net,
                        tsage = get_seconds() - peer->tcp_ts_stamp;
                }
                expires = ACCESS_ONCE(peer->pmtu_expires);
-               if (expires)
-                       expires -= jiffies;
+               if (expires) {
+                       if (time_before(jiffies, expires))
+                               expires -= jiffies;
+                       else
+                               expires = 0;
+               }
        }
 
        if (rt_is_input_route(rt)) {
index d7b89b12f6d81f4843145d86c617b484e0b5eb9b..90f6544c13e287639ae2d7686a55dc8f6c9cd168 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/random.h>
 #include <linux/cryptohash.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <net/tcp.h>
 #include <net/route.h>
 
index a7443159c400450e73ff9b83230fe40a48d0da39..a9db4b1a22156dc944addbf661187b2e71070875 100644 (file)
@@ -1510,6 +1510,7 @@ exit:
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
        return NULL;
 put_and_exit:
+       tcp_clear_xmit_timers(newsk);
        bh_unlock_sock(newsk);
        sock_put(newsk);
        goto exit;
index 980b98f6288c3f82f85da0ac61f74ecfa0cbc12b..63170e29754003c78b2cce548425ae1710c317c4 100644 (file)
@@ -1382,7 +1382,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)
 /* Return 0, if packet can be sent now without violation Nagle's rules:
  * 1. It is full sized.
  * 2. Or it contains FIN. (already checked by caller)
- * 3. Or TCP_NODELAY was set.
+ * 3. Or TCP_CORK is not set, and TCP_NODELAY is set.
  * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
  *    With Minshall's modification: all sent small packets are ACKed.
  */
index ab0966df1e2a8aec9e4ecb40e77332cbebbde466..5a65eeac1d29b8f4035314fb1db1dc403af1a428 100644 (file)
@@ -1164,7 +1164,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        struct inet_sock *inet = inet_sk(sk);
        struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
        struct sk_buff *skb;
-       unsigned int ulen;
+       unsigned int ulen, copied;
        int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
@@ -1186,9 +1186,10 @@ try_again:
                goto out;
 
        ulen = skb->len - sizeof(struct udphdr);
-       if (len > ulen)
-               len = ulen;
-       else if (len < ulen)
+       copied = len;
+       if (copied > ulen)
+               copied = ulen;
+       else if (copied < ulen)
                msg->msg_flags |= MSG_TRUNC;
 
        /*
@@ -1197,14 +1198,14 @@ try_again:
         * coverage checksum (UDP-Lite), do it before the copy.
         */
 
-       if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
+       if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
                if (udp_lib_checksum_complete(skb))
                        goto csum_copy_err;
        }
 
        if (skb_csum_unnecessary(skb))
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-                                             msg->msg_iov, len);
+                                             msg->msg_iov, copied);
        else {
                err = skb_copy_and_csum_datagram_iovec(skb,
                                                       sizeof(struct udphdr),
@@ -1233,7 +1234,7 @@ try_again:
        if (inet->cmsg_flags)
                ip_cmsg_recv(msg, skb);
 
-       err = len;
+       err = copied;
        if (flags & MSG_TRUNC)
                err = ulen;
 
index 08383eb542087a9de6699bc5179291b446d37b79..12e9499a1a6c63c7aef41a879d6e1f5a5d1479c8 100644 (file)
@@ -10,6 +10,7 @@
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
  */
+#include <linux/export.h>
 #include "udp_impl.h"
 
 struct udp_table       udplite_table __read_mostly;
index d9ac0a0058b5ed10a769cd11209483c5eabd5f8e..9258e751babaa1b9bfd954e6da771a0a80071a1b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/export.h>
 
 static int xfrm4_init_flags(struct xfrm_state *x)
 {
index d0611a5de45fbbb32a5ca5d78338fa02fb06e8fe..cf88df82e2c21ca21da8184f0370096b094dffba 100644 (file)
@@ -87,6 +87,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 /* Set to 3 to get tracing... */
 #define ACONF_DEBUG 2
index 6b03826552e14071ac268c55280d80a4b8e1797d..399287e595d7cb74c9018009305710077d30827a 100644 (file)
@@ -3,6 +3,7 @@
  * not configured or static.
  */
 
+#include <linux/export.h>
 #include <net/ipv6.h>
 
 #define IPV6_ADDR_SCOPE_TYPE(scope)    ((scope) << 16)
index 2195ae651923e0e3242c3e61738fed91d19711ff..4c0f894d08432564899bb5611483f5dab3d2ae59 100644 (file)
@@ -324,8 +324,6 @@ static void ah6_output_done(struct crypto_async_request *base, int err)
 #endif
        }
 
-       err = ah->nexthdr;
-
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_output_resume(skb, err);
 }
@@ -466,12 +464,12 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
        if (err)
                goto out;
 
+       err = ah->nexthdr;
+
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), work_iph, hdr_len);
        __skb_pull(skb, ah_hlen + hdr_len);
        skb_set_transport_header(skb, -hdr_len);
-
-       err = ah->nexthdr;
 out:
        kfree(AH_SKB_CB(skb)->tmp);
        xfrm_input_resume(skb, err);
@@ -583,8 +581,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
                if (err == -EINPROGRESS)
                        goto out;
 
-               if (err == -EBUSY)
-                       err = NET_XMIT_DROP;
                goto out_free;
        }
 
index 1318de4c3e8df2a418a828b4d249da7f68b9f76d..bf22a225f42218bbf05bf173d59eeae04acd8784 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/in6.h>
 #include <linux/icmpv6.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/dst.h>
 #include <net/sock.h>
index 14ed0a955b563e08a03dfbd010733c3f6c6d36a7..37f548b7f6dc73c4489107a59ee48e4928efa8f1 100644 (file)
@@ -2,6 +2,7 @@
  * IPv6 library code, needed by static components when full IPv6 support is
  * not configured or static.
  */
+#include <linux/export.h>
 #include <net/ipv6.h>
 
 /*
index 34d244df907d00eb0f67a09f71a292cb30f1f2bd..295571576f8383190820449f6f9b6dbe264b61d1 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/netdevice.h>
+#include <linux/export.h>
 
 #include <net/fib_rules.h>
 #include <net/ipv6.h>
index fee46d5a2f125f54451f5115dbddd050138af3a7..1567fb120392a0231dcf47f5c72ac950f952ae48 100644 (file)
@@ -85,7 +85,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
  * request_sock (formerly open request) hash tables.
  */
 static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
-                          const u32 rnd, const u16 synq_hsize)
+                          const u32 rnd, const u32 synq_hsize)
 {
        u32 c;
 
index 5430394501938dd4b288113162c060831f2b8db7..4566dbd916d36a346bdf49b0f1b2b9e5c4e866e3 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
index 027c7ff6f1e5370bc0e84d8e3daeb996875a431c..a46c64eb0a660b47b132e4b2346e1c112cc05759 100644 (file)
@@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
            ipv6_addr_loopback(&hdr->daddr))
                goto err;
 
+       /*
+        * RFC4291 2.7
+        * Multicast addresses must not be used as source addresses in IPv6
+        * packets or appear in any Routing header.
+        */
+       if (ipv6_addr_is_multicast(&hdr->saddr))
+               goto err;
+
        skb->transport_header = skb->network_header + sizeof(*hdr);
        IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
index bdc15c9003d781fbdb3d0288cf8b88aa84f71742..4e2e9ff67ef29701d4add34b20a63559aa950b4f 100644 (file)
@@ -289,6 +289,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p)
        if ((err = register_netdevice(dev)) < 0)
                goto failed_free;
 
+       strcpy(t->parms.name, dev->name);
+
        dev_hold(dev);
        ip6_tnl_link(ip6n, t);
        return t;
@@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
        struct ip6_tnl *t = netdev_priv(dev);
 
        t->dev = dev;
-       strcpy(t->parms.name, dev->name);
        dev->tstats = alloc_percpu(struct pcpu_tstats);
        if (!dev->tstats)
                return -ENOMEM;
@@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
 static int __net_init ip6_tnl_init_net(struct net *net)
 {
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
+       struct ip6_tnl *t = NULL;
        int err;
 
        ip6n->tnls[0] = ip6n->tnls_wc;
@@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
        err = register_netdev(ip6n->fb_tnl_dev);
        if (err < 0)
                goto err_register;
+
+       t = netdev_priv(ip6n->fb_tnl_dev);
+
+       strcpy(t->parms.name, ip6n->fb_tnl_dev->name);
        return 0;
 
 err_register:
index def0538e24139c02e74fe466d1ca3f877fa1848a..449a9185b8f228531ae0e10949fa755b2e3b655a 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/pim.h>
 #include <net/addrconf.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/export.h>
 #include <net/ip6_checksum.h>
 
 struct mr6_table {
index c99e3ee9781f246f82185e8a0e246e02a258cf82..26cb08c84b7488d533eafcccf44b3c134b8b9b2d 100644 (file)
@@ -503,7 +503,7 @@ done:
                        goto e_inval;
                if (val > 255 || val < -1)
                        goto e_inval;
-               np->mcast_hops = val;
+               np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val);
                retv = 0;
                break;
 
index 44e5b7f2a6c1badcbf4dbb5ed2a844ae2daa199c..0cb78d7ddaf5f74237bd6f9e871ae255e9175072 100644 (file)
@@ -1571,7 +1571,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        }
        if (!rt->rt6i_peer)
                rt6_bind_peer(rt, 1);
-       if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
+       if (!inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
                goto release;
 
        if (dev->addr_len) {
index 8992cf6651d47da90de5d3c76832672de50f547c..db31561cc8df31afbf7f18fd4dd849811be5a8dd 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/ipv6.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/export.h>
 #include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
index 448464844a253474fed5624f75c68c9bb33cd98e..f792b34cbe9cb2710e072c33e4127b4c0d416210 100644 (file)
@@ -186,7 +186,6 @@ config IP6_NF_MANGLE
 
 config IP6_NF_RAW
        tristate  'raw table support (required for TRACE)'
-       depends on NETFILTER_ADVANCED
        help
          This option adds a `raw' table to ip6tables. This table is the very
          first in the netfilter framework and hooks in at the PREROUTING
index 18ff5df7ec0273ac14a94f5e7b853c314b8b35aa..1008ce94bc339e5a97405723170ea63d4fed6ba6 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/stddef.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
 #include <net/sock.h>
index 6f7824e1cea48ea16b4a3860475e4fd367860834..331af3b882ac211ca65cb59042f14c381fe2d244 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 static struct raw_hashinfo raw_v6_hashinfo = {
        .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
index cc22099ac8b6f6562674e07ce78e71d1815e0f13..dfb164e9051aef20af12cba8072dae4dfdb058e5 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/jhash.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
index 57b82dc1ae91c8426b0894b5e4e6030453c66352..3399dd326287e1504b9c5bd72701143574dda4b4 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/capability.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/times.h>
 #include <linux/socket.h>
@@ -76,7 +77,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
                                    const struct in6_addr *dest);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int     ip6_default_advmss(const struct dst_entry *dst);
-static unsigned int     ip6_default_mtu(const struct dst_entry *dst);
+static unsigned int     ip6_mtu(const struct dst_entry *dst);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void            ip6_dst_destroy(struct dst_entry *);
 static void            ip6_dst_ifdown(struct dst_entry *,
@@ -143,7 +144,7 @@ static struct dst_ops ip6_dst_ops_template = {
        .gc_thresh              =       1024,
        .check                  =       ip6_dst_check,
        .default_advmss         =       ip6_default_advmss,
-       .default_mtu            =       ip6_default_mtu,
+       .mtu                    =       ip6_mtu,
        .cow_metrics            =       ipv6_cow_metrics,
        .destroy                =       ip6_dst_destroy,
        .ifdown                 =       ip6_dst_ifdown,
@@ -154,9 +155,11 @@ static struct dst_ops ip6_dst_ops_template = {
        .neigh_lookup           =       ip6_neigh_lookup,
 };
 
-static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
+static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
 {
-       return 0;
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       return mtu ? : dst->dev->mtu;
 }
 
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -174,7 +177,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .protocol               =       cpu_to_be16(ETH_P_IPV6),
        .destroy                =       ip6_dst_destroy,
        .check                  =       ip6_dst_check,
-       .default_mtu            =       ip6_blackhole_default_mtu,
+       .mtu                    =       ip6_blackhole_mtu,
        .default_advmss         =       ip6_default_advmss,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
        .cow_metrics            =       ip6_rt_blackhole_cow_metrics,
@@ -1040,10 +1043,15 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
        return mtu;
 }
 
-static unsigned int ip6_default_mtu(const struct dst_entry *dst)
+static unsigned int ip6_mtu(const struct dst_entry *dst)
 {
-       unsigned int mtu = IPV6_MIN_MTU;
        struct inet6_dev *idev;
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       if (mtu)
+               return mtu;
+
+       mtu = IPV6_MIN_MTU;
 
        rcu_read_lock();
        idev = __in6_dev_get(dst->dev);
index 6dcf5e7d661bd4f463f352788a5461f163e63501..166a57c47d39cd4707bc48ad541afd23c34b12d1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/ndisc.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
index 36131d122a6f3f9007776ff343a9197bd0430b0a..2dea4bb7b54a3381a7c50e60c2ade383eabe477b 100644 (file)
@@ -1255,6 +1255,13 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (!want_cookie || tmp_opt.tstamp_ok)
                TCP_ECN_create_request(req, tcp_hdr(skb));
 
+       treq->iif = sk->sk_bound_dev_if;
+
+       /* So that link locals have meaning */
+       if (!sk->sk_bound_dev_if &&
+           ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+               treq->iif = inet6_iif(skb);
+
        if (!isn) {
                struct inet_peer *peer = NULL;
 
@@ -1264,12 +1271,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
                        atomic_inc(&skb->users);
                        treq->pktopts = skb;
                }
-               treq->iif = sk->sk_bound_dev_if;
-
-               /* So that link locals have meaning */
-               if (!sk->sk_bound_dev_if &&
-                   ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
-                       treq->iif = inet6_iif(skb);
 
                if (want_cookie) {
                        isn = cookie_v6_init_sequence(sk, skb, &req->mss);
index 846f4757eb8d46394a604595be0698d485ae1ab0..8c25419151839cc2e7a8be6940de19d62a505690 100644 (file)
@@ -340,7 +340,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct inet_sock *inet = inet_sk(sk);
        struct sk_buff *skb;
-       unsigned int ulen;
+       unsigned int ulen, copied;
        int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
@@ -363,9 +363,10 @@ try_again:
                goto out;
 
        ulen = skb->len - sizeof(struct udphdr);
-       if (len > ulen)
-               len = ulen;
-       else if (len < ulen)
+       copied = len;
+       if (copied > ulen)
+               copied = ulen;
+       else if (copied < ulen)
                msg->msg_flags |= MSG_TRUNC;
 
        is_udp4 = (skb->protocol == htons(ETH_P_IP));
@@ -376,14 +377,14 @@ try_again:
         * coverage checksum (UDP-Lite), do it before the copy.
         */
 
-       if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
+       if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
                if (udp_lib_checksum_complete(skb))
                        goto csum_copy_err;
        }
 
        if (skb_csum_unnecessary(skb))
                err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-                                             msg->msg_iov,len);
+                                             msg->msg_iov, copied       );
        else {
                err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
                if (err == -EINVAL)
@@ -432,7 +433,7 @@ try_again:
                        datagram_recv_ctl(sk, msg, skb);
        }
 
-       err = len;
+       err = copied;
        if (flags & MSG_TRUNC)
                err = ulen;
 
index 8889aa22ed47197129c9ceb6585d9c2d4a06bb5b..1d08e21d9f6993e92a4a16b589784873aaf63fd8 100644 (file)
@@ -11,6 +11,7 @@
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
  */
+#include <linux/export.h>
 #include "udp_impl.h"
 
 static int udplitev6_rcv(struct sk_buff *skb)
index 248f0b2a7ee93448b30e55a884f15ec7f897a240..f2d72b8a3faa14e0cf8f7c179d86f4d33e88b961 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/export.h>
 #include <net/dsfield.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
index 26b5bfcf1d033e13cd421522ee2182fed47b544c..f8ba30dfecae430df85199c547a6884bc1461022 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/tcp_states.h>
 #include <net/ipx.h>
index 36c3f037f1727f38d4601d07ec635e5d81b77373..b0b56a339a835686c16f29fd7409aa2959718459 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irlmp.h>
index 3eca35faf2a89110eee9f944d86d55ed19e60e13..14653b8d664dba5d83129b98230ddfe010674111 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/kmod.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <asm/ioctls.h>
 #include <asm/uaccess.h>
index 285ccd623ae5758de2cc9ec336c9c58cbc08871c..32e3bb0261105f51ccc24e21026a54e90829e855 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
index 4369f7f41bcbc7065a7920cf6bb3fccf69588c77..798ffd9a705ee014671248e71a213b557031ecac 100644 (file)
@@ -30,6 +30,8 @@
  *
  ********************************************************************/
 
+#include <linux/export.h>
+
 #include <asm/byteorder.h>
 
 #include <net/irda/irda.h>
index bf8d50c67931e8e588520b7c49ad49fca51b40b3..89ff8c67943e8af26efe1bac80b306e297921ebd 100644 (file)
@@ -756,9 +756,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
                goto error;
        }
 
-       /* Point to L2TP header */
-       optr = ptr = skb->data;
-
        /* Trace packet contents, if enabled */
        if (tunnel->debug & L2TP_MSG_DATA) {
                length = min(32u, skb->len);
@@ -769,12 +766,15 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
 
                offset = 0;
                do {
-                       printk(" %02X", ptr[offset]);
+                       printk(" %02X", skb->data[offset]);
                } while (++offset < length);
 
                printk("\n");
        }
 
+       /* Point to L2TP header */
+       optr = ptr = skb->data;
+
        /* Get L2TP header flags */
        hdrflags = ntohs(*(__be16 *) ptr);
 
@@ -1072,7 +1072,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
 
        /* Get routing info from the tunnel socket */
        skb_dst_drop(skb);
-       skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
+       skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
 
        inet = inet_sk(sk);
        fl = &inet->cork.fl;
index 903242111317f14438bc84881358875729e21948..e32cab44ea959d8f49781d46580b4204afb7e3cb 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/netdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
index b38a1079a98eac59dd1737b6f5bb7e7bf5437a54..b658cba89fdd6fe97ded4b79d7fd9ae30459182d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
 #include <linux/skbuff.h>
+#include <linux/export.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 
index 7af1ff2d1f1974ff339865beece31e8c09d6d449..a1839c004357a854ca7ee50592584fb66617b441 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/proc_fs.h>
 #include <linux/errno.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/llc.h>
index 97f33588b65f6a85ff8c293e04cf45f7c4caf9e5..93b2434226592e335568195ccaeaa20e06788d19 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <linux/ieee80211.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 2ac033989e016304047dca1ecaacbd9519ae697e..b064e4df12c6d03a0534f5a8b026b9785befc190 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/ieee80211.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
@@ -160,6 +161,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                return -ENOENT;
        }
 
+       /* if we're already stopping ignore any new requests to stop */
+       if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
+               spin_unlock_bh(&sta->lock);
+               return -EALREADY;
+       }
+
        if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
                /* not even started yet! */
                ieee80211_assign_tid_tx(sta, tid, NULL);
@@ -168,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                return 0;
        }
 
+       set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
+
        spin_unlock_bh(&sta->lock);
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -175,8 +184,6 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
               sta->sta.addr, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
-       set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
-
        del_timer_sync(&tid_tx->addba_resp_timer);
 
        /*
@@ -186,6 +193,20 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
         */
        clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 
+       /*
+        * There might be a few packets being processed right now (on
+        * another CPU) that have already gotten past the aggregation
+        * check when it was still OPERATIONAL and consequently have
+        * IEEE80211_TX_CTL_AMPDU set. In that case, this code might
+        * call into the driver at the same time or even before the
+        * TX paths calls into it, which could confuse the driver.
+        *
+        * Wait for all currently running TX paths to finish before
+        * telling the driver. New packets will not go through since
+        * the aggregation session is no longer OPERATIONAL.
+        */
+       synchronize_net();
+
        tid_tx->stop_initiator = initiator;
        tid_tx->tx_stop = tx;
 
@@ -756,11 +777,27 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                goto out;
        }
 
-       del_timer(&tid_tx->addba_resp_timer);
+       del_timer_sync(&tid_tx->addba_resp_timer);
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
 #endif
+
+       /*
+        * addba_resp_timer may have fired before we got here, and
+        * caused WANT_STOP to be set. If the stop then was already
+        * processed further, STOPPING might be set.
+        */
+       if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) ||
+           test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
+#ifdef CONFIG_MAC80211_HT_DEBUG
+               printk(KERN_DEBUG
+                      "got addBA resp for tid %d but we already gave up\n",
+                      tid);
+#endif
+               goto out;
+       }
+
        /*
         * IEEE 802.11-2007 7.3.1.14:
         * In an ADDBA Response frame, when the Status Code field
index ebd7fb101fbfb26dc7e7850eae1a0c7d14283d9a..d06c65fa5526a88739a647b809067f37fd64fc24 100644 (file)
@@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        if (is_multicast_ether_addr(mac))
                return -EINVAL;
 
+       /* Only TDLS-supporting stations can add TDLS peers */
+       if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
+           !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
+             sdata->vif.type == NL80211_IFTYPE_STATION))
+               return -ENOTSUPP;
+
        sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
        if (!sta)
                return -ENOMEM;
@@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 
        sta_apply_parameters(local, sta, params);
 
-       /* Only TDLS-supporting stations can add TDLS peers */
-       if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
-           !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
-             sdata->vif.type == NL80211_IFTYPE_STATION))
-               return -ENOTSUPP;
-
        rate_control_rate_init(sta);
 
        layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
index c5f341798c16769a1e5c5b7f48937e1a15d47f80..3110cbdc501b83d3650c978d26c51c2ef7c47568 100644 (file)
@@ -274,9 +274,9 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
 
                PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack");
 
-               PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: "
-                            "3839 bytes");
                PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: "
+                            "3839 bytes");
+               PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: "
                             "7935 bytes");
 
                /*
index f80a35c0d00020fec66f47839111f418401b4758..f0fb737efa8629bc8204f2f7cb8f5a568857853c 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/ieee80211.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "rate.h"
index 4c3d1f591bec1c3fc4ee24c447a75a58bf926bf7..ea10a51babda9fa113c84ee000d46c62b86e69c6 100644 (file)
@@ -389,6 +389,7 @@ struct ieee80211_if_managed {
 
        unsigned long timers_running; /* used for quiesce/restart */
        bool powersave; /* powersave requested for this iface */
+       bool broken_ap; /* AP is broken -- turn off powersave */
        enum ieee80211_smps_mode req_smps, /* requested smps mode */
                                 ap_smps, /* smps mode AP thinks we're in */
                                 driver_smps_mode; /* smps mode request */
index 756b157c2edd7a147c9390ec773d173f074117d5..fb02ea52d2c2b46f760944de0f407f417d0fb492 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/rcupdate.h>
 #include <linux/rtnetlink.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
index 14590332c81ccca331bb6160916457df872c37a6..1bf7903496f8f4ec67ce4e861146f329bd5ad600 100644 (file)
@@ -9,6 +9,7 @@
 /* just for IFNAMSIZ */
 #include <linux/if.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include "led.h"
 
 void ieee80211_led_rx(struct ieee80211_local *local)
index d999bf3b84e1b27d0d79c91d44b7771756d92a3e..cae443563ec9d98a8230de9fae394b960fa66621 100644 (file)
@@ -757,6 +757,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (!local->int_scan_req)
                return -ENOMEM;
 
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+               if (!local->hw.wiphy->bands[band])
+                       continue;
+               local->int_scan_req->rates[band] = (u32) -1;
+       }
+
        /* if low-level driver supports AP, we also support VLAN */
        if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
                hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
index ba2da11a997b2a0fa394bdf5a3f0e2bb6af944cd..b1b1bb368f701f61b47da0040ce9b0b477d09deb 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
+#include <linux/moduleparam.h>
 #include <linux/rtnetlink.h>
 #include <linux/pm_qos.h>
 #include <linux/crc32.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
@@ -637,6 +639,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
        if (!mgd->powersave)
                return false;
 
+       if (mgd->broken_ap)
+               return false;
+
        if (!mgd->associated)
                return false;
 
@@ -1482,6 +1487,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
        int i, j, err;
        bool have_higher_than_11mbit = false;
        u16 ap_ht_cap_flags;
+       int min_rate = INT_MAX, min_rate_index = -1;
 
        /* AssocResp and ReassocResp have identical structure */
 
@@ -1489,10 +1495,21 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
        capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
 
        if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
-               printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
-                      "set\n", sdata->name, aid);
+               printk(KERN_DEBUG
+                      "%s: invalid AID value 0x%x; bits 15:14 not set\n",
+                      sdata->name, aid);
        aid &= ~(BIT(15) | BIT(14));
 
+       ifmgd->broken_ap = false;
+
+       if (aid == 0 || aid > IEEE80211_MAX_AID) {
+               printk(KERN_DEBUG
+                      "%s: invalid AID value %d (out of range), turn off PS\n",
+                      sdata->name, aid);
+               aid = 0;
+               ifmgd->broken_ap = true;
+       }
+
        pos = mgmt->u.assoc_resp.variable;
        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 
@@ -1537,6 +1554,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                                rates |= BIT(j);
                                if (is_basic)
                                        basic_rates |= BIT(j);
+                               if (rate < min_rate) {
+                                       min_rate = rate;
+                                       min_rate_index = j;
+                               }
                                break;
                        }
                }
@@ -1554,11 +1575,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
                                rates |= BIT(j);
                                if (is_basic)
                                        basic_rates |= BIT(j);
+                               if (rate < min_rate) {
+                                       min_rate = rate;
+                                       min_rate_index = j;
+                               }
                                break;
                        }
                }
        }
 
+       /*
+        * some buggy APs don't advertise basic_rates. use the lowest
+        * supported rate instead.
+        */
+       if (unlikely(!basic_rates) && min_rate_index >= 0) {
+               printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
+                      "Using min supported rate instead.\n", sdata->name);
+               basic_rates = BIT(min_rate_index);
+       }
+
        sta->sta.supp_rates[wk->chan->band] = rates;
        sdata->vif.bss_conf.basic_rates = basic_rates;
 
@@ -2253,6 +2288,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 
        cancel_work_sync(&ifmgd->request_smps_work);
 
+       cancel_work_sync(&ifmgd->monitor_work);
        cancel_work_sync(&ifmgd->beacon_connection_loss_work);
        if (del_timer_sync(&ifmgd->timer))
                set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -2261,7 +2297,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
        if (del_timer_sync(&ifmgd->chswitch_timer))
                set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
 
-       cancel_work_sync(&ifmgd->monitor_work);
        /* these will just be re-established on connection */
        del_timer_sync(&ifmgd->conn_mon_timer);
        del_timer_sync(&ifmgd->bcn_mon_timer);
index 13427b194ced05d961dcf32fabf0e2c02cd073d5..3d414411a96e212ee7fc25247373b86d1d382072 100644 (file)
@@ -12,6 +12,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "driver-trace.h"
index ff5c3aa48a153a774275d7604df5c11f0d1a0cad..5a5a7767d541c2a952aecbeefca79125dfe17052 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/rtnetlink.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "rate.h"
 #include "ieee80211_i.h"
 #include "debugfs.h"
index a290ad231d772b23ca6cf7d2c1377736ae77f4ad..d5a56226e675970c3a396df9d73b22135dabc39e 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/debugfs.h>
 #include <linux/ieee80211.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "rc80211_minstrel.h"
 
index cefcb5d2dae6e40888af8d712ed564a00cebc42c..e788f76a1dfe5811fb81614a88fc08f139f37f00 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/skbuff.h>
 #include <linux/debugfs.h>
 #include <linux/ieee80211.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "rc80211_minstrel.h"
 #include "rc80211_minstrel_ht.h"
index 4851e9e2daeda8e7988de6e74ca90913e8c30c0d..c97a0657c0435bece74ce534e173df74b62a16ae 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/mac80211.h>
 #include "rate.h"
index b867bd55de7aab4c9e622eaeff88da9c93671417..fb123e2e081a4c51495331f4d8cad945e53c3f40 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rcupdate.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include <net/ieee80211_radiotap.h>
 
@@ -140,8 +141,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        pos++;
 
        /* IEEE80211_RADIOTAP_RATE */
-       if (status->flag & RX_FLAG_HT) {
+       if (!rate || status->flag & RX_FLAG_HT) {
                /*
+                * Without rate information don't add it. If we have,
                 * MCS information is a separate field in radiotap,
                 * added below. The byte here is needed as padding
                 * for the channel though, so initialise it to 0.
@@ -162,12 +164,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        else if (status->flag & RX_FLAG_HT)
                put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
                                   pos);
-       else if (rate->flags & IEEE80211_RATE_ERP_G)
+       else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
                put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
                                   pos);
-       else
+       else if (rate)
                put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
                                   pos);
+       else
+               put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);
        pos += 2;
 
        /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
index 83a0b050b374f8b290eb8c12a01998c89ff4afc7..105436dbb90dda1a3430fea9923fd46fa47bca00 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pm_qos.h>
 #include <net/sch_generic.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/mac80211.h>
 
 #include "ieee80211_i.h"
index ce962d2c8782e5ec148884ca1ef90a0aaa8e6c18..8eaa746ec7a26d7281e28d42ed3064eb970c874c 100644 (file)
@@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
                         * Use MoreData flag to indicate whether there are
                         * more buffered frames for this STA
                         */
-                       if (!more_data)
-                               hdr->frame_control &=
-                                       cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
-                       else
+                       if (more_data || !skb_queue_empty(&frames))
                                hdr->frame_control |=
                                        cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+                       else
+                               hdr->frame_control &=
+                                       cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
 
                        if (ieee80211_is_data_qos(hdr->frame_control) ||
                            ieee80211_is_qos_nullfunc(hdr->frame_control))
index df643cedf9b9e17514281a811189e902f1411b6a..16518f386117ad8f35dc075bd7ee4f244ab298c4 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/export.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "rate.h"
@@ -259,7 +260,7 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_radiotap_header *rthdr;
        unsigned char *pos;
-       __le16 txflags;
+       u16 txflags;
 
        rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
 
@@ -289,13 +290,13 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
        txflags = 0;
        if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
            !is_multicast_ether_addr(hdr->addr1))
-               txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
+               txflags |= IEEE80211_RADIOTAP_F_TX_FAIL;
 
        if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
            (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
-               txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
+               txflags |= IEEE80211_RADIOTAP_F_TX_CTS;
        else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-               txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
+               txflags |= IEEE80211_RADIOTAP_F_TX_RTS;
 
        put_unaligned_le16(txflags, pos);
        pos += 2;
index f49d00a4c7fdc42287c32068f267c050ab8e02d0..51077a956a83cdb025955bbfe367237a6784d136 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/netdevice.h>
+#include <linux/export.h>
 #include <asm/unaligned.h>
 
 #include <net/mac80211.h>
index 48bbb96d8edb896a85b7650490eb427cb0cf2fee..1f8b120146d1d714c97dc949495a9fbb0afab51b 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/etherdevice.h>
 #include <linux/bitmap.h>
 #include <linux/rcupdate.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/ieee80211_radiotap.h>
 #include <net/cfg80211.h>
index 7439d26bf5f9e281f66cb9e47e05a80a825d7d37..d5230ecc784d2702feb580da4d80e9ef1d3ec0bd 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <net/mac80211.h>
 #include <linux/netdevice.h>
+#include <linux/export.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/skbuff.h>
@@ -880,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
                                     ssid, ssid_len,
                                     buf, buf_len);
+       if (!skb)
+               goto out;
 
        if (dst) {
                mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -888,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        }
 
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+ out:
        kfree(buf);
 
        return skb;
@@ -1034,7 +1039,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                             struct ieee80211_sub_if_data,
                                             u.ap);
 
-                       memset(&sta->sta.drv_priv, 0, hw->sta_data_size);
                        WARN_ON(drv_sta_add(local, sdata, &sta->sta));
                }
        }
index 94472eb34d76452acfddfb624eba7e44f46e3445..6c53b6d1002b5a2046837fe2ec60d7687bd0c973 100644 (file)
@@ -1084,14 +1084,13 @@ static void ieee80211_work_work(struct work_struct *work)
                        continue;
                if (wk->chan != local->tmp_channel)
                        continue;
-               if (ieee80211_work_ct_coexists(wk->chan_type,
-                                              local->tmp_channel_type))
+               if (!ieee80211_work_ct_coexists(wk->chan_type,
+                                               local->tmp_channel_type))
                        continue;
                remain_off_channel = true;
        }
 
        if (!remain_off_channel && local->tmp_channel) {
-               bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
                local->tmp_channel = NULL;
                /* If tmp_channel wasn't operating channel, then
                 * we need to go back on-channel.
@@ -1101,7 +1100,7 @@ static void ieee80211_work_work(struct work_struct *work)
                 * we still need to do a hardware config.  Currently,
                 * we cannot be here while scanning, however.
                 */
-               if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
+               if (!ieee80211_cfg_on_oper_channel(local))
                        ieee80211_hw_config(local, 0);
 
                /* At the least, we need to disable offchannel_ps,
index 8260b13d93c926cf9964d7a4f4e225be0123a68c..d5597b759ba39724e7bc3fe5376b7b5bb02eb13c 100644 (file)
@@ -201,7 +201,6 @@ config NF_CONNTRACK_BROADCAST
 
 config NF_CONNTRACK_NETBIOS_NS
        tristate "NetBIOS name service protocol support"
-       depends on NETFILTER_ADVANCED
        select NF_CONNTRACK_BROADCAST
        help
          NetBIOS name service requests are sent as broadcast messages from an
@@ -542,7 +541,6 @@ config NETFILTER_XT_TARGET_NOTRACK
        tristate  '"NOTRACK" target support'
        depends on IP_NF_RAW || IP6_NF_RAW
        depends on NF_CONNTRACK
-       depends on NETFILTER_ADVANCED
        help
          The NOTRACK target allows a select rule to specify
          which packets *not* to enter the conntrack/NAT
index 757143b2240af36395e71f6561e3809f3394e688..052579fe389ab774b0d7fa704d1c7b371fc96b8f 100644 (file)
@@ -17,6 +17,7 @@
 #include <net/ipv6.h>
 
 #include <linux/netfilter/ipset/ip_set_getport.h>
+#include <linux/export.h>
 
 /* We must handle non-linear skbs */
 static bool
index 6ee10f5d59bd8a4fde8ad54447c5552d11863303..37d667e3f6f82d82e442b66d4c38dd592cba06d3 100644 (file)
@@ -158,7 +158,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipport4_elem data = { };
-       u32 ip, ip_to, p = 0, port, port_to;
+       u32 ip, ip_to = 0, p = 0, port, port_to;
        u32 timeout = h->timeout;
        bool with_ports = false;
        int ret;
index fb90e344e90709f205bef4c2a61b3855be1c7f56..e69e2718fbe162343eaf97defd30153155ee2ef1 100644 (file)
@@ -162,7 +162,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportip4_elem data = { };
-       u32 ip, ip_to, p = 0, port, port_to;
+       u32 ip, ip_to = 0, p = 0, port, port_to;
        u32 timeout = h->timeout;
        bool with_ports = false;
        int ret;
index deb3e3dfa5fcb13ba9f125f0a9dbcc7042d0735a..64199b4e93c952e24ca8c5508af1d3788b1286f8 100644 (file)
@@ -184,7 +184,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
        const struct ip_set_hash *h = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
-       u32 ip, ip_to, p = 0, port, port_to;
+       u32 ip, ip_to = 0, p = 0, port, port_to;
        u32 ip2_from = 0, ip2_to, ip2_last, ip2;
        u32 timeout = h->timeout;
        bool with_ports = false;
index bd13d66220f154801b4b21662f25990b27d829b8..4f29fa97044b18523967cdc8b8c6ab272376a2fb 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/export.h>
 #include <linux/netfilter/ipset/pfxlen.h>
 
 /*
index 5178c691ecbf448a0ebd7d6e2f656b2118c6efe5..369df3f08d42635da9245558eca0cd950d1417f5 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
+#include <linux/export.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_extend.h>
index 3add994390596231802aed21169e570313d797bb..b62c4148b92131444f6e132cb55a058991d68379 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
 
 static DEFINE_MUTEX(nf_ct_ecache_mutex);
 
-struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb __read_mostly;
-EXPORT_SYMBOL_GPL(nf_conntrack_event_cb);
-
-struct nf_exp_event_notifier __rcu *nf_expect_event_cb __read_mostly;
-EXPORT_SYMBOL_GPL(nf_expect_event_cb);
-
 /* deliver cached events and clear cache entry - must be called with locally
  * disabled softirqs */
 void nf_ct_deliver_cached_events(struct nf_conn *ct)
 {
+       struct net *net = nf_ct_net(ct);
        unsigned long events;
        struct nf_ct_event_notifier *notify;
        struct nf_conntrack_ecache *e;
 
        rcu_read_lock();
-       notify = rcu_dereference(nf_conntrack_event_cb);
+       notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
        if (notify == NULL)
                goto out_unlock;
 
@@ -82,19 +78,20 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 
-int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
+int nf_conntrack_register_notifier(struct net *net,
+                                  struct nf_ct_event_notifier *new)
 {
        int ret = 0;
        struct nf_ct_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference_protected(nf_conntrack_event_cb,
+       notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        if (notify != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
-       RCU_INIT_POINTER(nf_conntrack_event_cb, new);
+       RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, new);
        mutex_unlock(&nf_ct_ecache_mutex);
        return ret;
 
@@ -104,32 +101,34 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
-void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
+void nf_conntrack_unregister_notifier(struct net *net,
+                                     struct nf_ct_event_notifier *new)
 {
        struct nf_ct_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference_protected(nf_conntrack_event_cb,
+       notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        BUG_ON(notify != new);
-       RCU_INIT_POINTER(nf_conntrack_event_cb, NULL);
+       RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
-int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
+int nf_ct_expect_register_notifier(struct net *net,
+                                  struct nf_exp_event_notifier *new)
 {
        int ret = 0;
        struct nf_exp_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference_protected(nf_expect_event_cb,
+       notify = rcu_dereference_protected(net->ct.nf_expect_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        if (notify != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
-       RCU_INIT_POINTER(nf_expect_event_cb, new);
+       RCU_INIT_POINTER(net->ct.nf_expect_event_cb, new);
        mutex_unlock(&nf_ct_ecache_mutex);
        return ret;
 
@@ -139,15 +138,16 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
-void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
+void nf_ct_expect_unregister_notifier(struct net *net,
+                                     struct nf_exp_event_notifier *new)
 {
        struct nf_exp_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference_protected(nf_expect_event_cb,
+       notify = rcu_dereference_protected(net->ct.nf_expect_event_cb,
                                           lockdep_is_held(&nf_ct_ecache_mutex));
        BUG_ON(notify != new);
-       RCU_INIT_POINTER(nf_expect_event_cb, NULL);
+       RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
index cd1e8e0970f226b5a2dd5e82aa2d121680ff24a3..340c80d968d412ac77684a79b9bb98ceccb68b3f 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/percpu.h>
 #include <linux/kernel.h>
 #include <linux/jhash.h>
+#include <linux/moduleparam.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 
 #include <net/netfilter/nf_conntrack.h>
index e58aa9b1fe8a043226c4bc7ee90f5145a7adc316..ef21b221f0363a8700fbbc3aadd316423c4f9d66 100644 (file)
@@ -4,7 +4,7 @@
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
- * (C) 2005-2008 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
  *
  * Initial connection tracking via netlink development funded and
  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
@@ -2163,6 +2163,54 @@ MODULE_ALIAS("ip_conntrack_netlink");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
+static int __net_init ctnetlink_net_init(struct net *net)
+{
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+       int ret;
+
+       ret = nf_conntrack_register_notifier(net, &ctnl_notifier);
+       if (ret < 0) {
+               pr_err("ctnetlink_init: cannot register notifier.\n");
+               goto err_out;
+       }
+
+       ret = nf_ct_expect_register_notifier(net, &ctnl_notifier_exp);
+       if (ret < 0) {
+               pr_err("ctnetlink_init: cannot expect register notifier.\n");
+               goto err_unreg_notifier;
+       }
+#endif
+       return 0;
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+err_unreg_notifier:
+       nf_conntrack_unregister_notifier(net, &ctnl_notifier);
+err_out:
+       return ret;
+#endif
+}
+
+static void ctnetlink_net_exit(struct net *net)
+{
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+       nf_ct_expect_unregister_notifier(net, &ctnl_notifier_exp);
+       nf_conntrack_unregister_notifier(net, &ctnl_notifier);
+#endif
+}
+
+static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
+{
+       struct net *net;
+
+       list_for_each_entry(net, net_exit_list, exit_list)
+               ctnetlink_net_exit(net);
+}
+
+static struct pernet_operations ctnetlink_net_ops = {
+       .init           = ctnetlink_net_init,
+       .exit_batch     = ctnetlink_net_exit_batch,
+};
+
 static int __init ctnetlink_init(void)
 {
        int ret;
@@ -2180,28 +2228,15 @@ static int __init ctnetlink_init(void)
                goto err_unreg_subsys;
        }
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-       ret = nf_conntrack_register_notifier(&ctnl_notifier);
-       if (ret < 0) {
-               pr_err("ctnetlink_init: cannot register notifier.\n");
+       if (register_pernet_subsys(&ctnetlink_net_ops)) {
+               pr_err("ctnetlink_init: cannot register pernet operations\n");
                goto err_unreg_exp_subsys;
        }
 
-       ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
-       if (ret < 0) {
-               pr_err("ctnetlink_init: cannot expect register notifier.\n");
-               goto err_unreg_notifier;
-       }
-#endif
-
        return 0;
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-err_unreg_notifier:
-       nf_conntrack_unregister_notifier(&ctnl_notifier);
 err_unreg_exp_subsys:
        nfnetlink_subsys_unregister(&ctnl_exp_subsys);
-#endif
 err_unreg_subsys:
        nfnetlink_subsys_unregister(&ctnl_subsys);
 err_out:
@@ -2213,11 +2248,7 @@ static void __exit ctnetlink_exit(void)
        pr_info("ctnetlink: unregistering from nfnetlink.\n");
 
        nf_ct_remove_userspace_expectations();
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-       nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
-       nf_conntrack_unregister_notifier(&ctnl_notifier);
-#endif
-
+       unregister_pernet_subsys(&ctnetlink_net_ops);
        nfnetlink_subsys_unregister(&ctnl_exp_subsys);
        nfnetlink_subsys_unregister(&ctnl_subsys);
 }
index 71441b934ffd5c4a3381a10c80de251554852f2e..8d987c3573fd4ca9e1708e188d487e53ebd7dfd7 100644 (file)
@@ -14,6 +14,7 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/net.h>
 #include <linux/proc_fs.h>
index 70eb2b4984ddb277e052458f325599910e57d875..44c8eb4c9d6680aef8f3473ca0b677f3888a68ca 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_quota.h>
+#include <linux/module.h>
 
 struct xt_quota_priv {
        spinlock_t      lock;
index 42ecb71d445fe6d009ac252d1b030cd86befcfb1..4fe4fb4276d0076061610418b8154e9d11cd80b8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/netfilter/xt_statistic.h>
 #include <linux/netfilter/x_tables.h>
+#include <linux/module.h>
 
 struct xt_statistic_priv {
        atomic_t count;
index 9c24de10a6579b78e452e47912c56e5d894e58ea..824f184f7a9bbecbfd9217e86fd474485b135ade 100644 (file)
@@ -111,8 +111,6 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
        struct netlbl_domaddr_map *addrmap = NULL;
        struct netlbl_domaddr4_map *map4 = NULL;
        struct netlbl_domaddr6_map *map6 = NULL;
-       const struct in_addr *addr4, *mask4;
-       const struct in6_addr *addr6, *mask6;
 
        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (entry == NULL)
@@ -133,9 +131,9 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                INIT_LIST_HEAD(&addrmap->list6);
 
                switch (family) {
-               case AF_INET:
-                       addr4 = addr;
-                       mask4 = mask;
+               case AF_INET: {
+                       const struct in_addr *addr4 = addr;
+                       const struct in_addr *mask4 = mask;
                        map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
                        if (map4 == NULL)
                                goto cfg_unlbl_map_add_failure;
@@ -148,9 +146,11 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                        if (ret_val != 0)
                                goto cfg_unlbl_map_add_failure;
                        break;
-               case AF_INET6:
-                       addr6 = addr;
-                       mask6 = mask;
+                       }
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+               case AF_INET6: {
+                       const struct in6_addr *addr6 = addr;
+                       const struct in6_addr *mask6 = mask;
                        map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
                        if (map6 == NULL)
                                goto cfg_unlbl_map_add_failure;
@@ -162,11 +162,13 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
                        map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
                        ipv6_addr_copy(&map6->list.mask, mask6);
                        map6->list.valid = 1;
-                       ret_val = netlbl_af4list_add(&map4->list,
-                                                    &addrmap->list4);
+                       ret_val = netlbl_af6list_add(&map6->list,
+                                                    &addrmap->list6);
                        if (ret_val != 0)
                                goto cfg_unlbl_map_add_failure;
                        break;
+                       }
+#endif /* IPv6 */
                default:
                        goto cfg_unlbl_map_add_failure;
                        break;
@@ -225,9 +227,11 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
        case AF_INET:
                addr_len = sizeof(struct in_addr);
                break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        case AF_INET6:
                addr_len = sizeof(struct in6_addr);
                break;
+#endif /* IPv6 */
        default:
                return -EPFNOSUPPORT;
        }
@@ -266,9 +270,11 @@ int netlbl_cfg_unlbl_static_del(struct net *net,
        case AF_INET:
                addr_len = sizeof(struct in_addr);
                break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        case AF_INET6:
                addr_len = sizeof(struct in6_addr);
                break;
+#endif /* IPv6 */
        default:
                return -EPFNOSUPPORT;
        }
index cd5ddb2ebc430c5a78c025e806317ef8d4c0fa43..915a87ba23e188faa31861aac9a38d3b2f180827 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <net/netrom.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 static unsigned int nr_neigh_no = 1;
 
index e982cef8f49d1c8b03895ddfaeed4f86fb437f83..da67756425ce927f233bd9f490e58befbefd4390 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/nfc.h>
+#include <linux/module.h>
 
 #include "nfc.h"
 
index 4047e29acb3b0f1eeac3d030c8ae7642399d80f1..3925c6578767ea61be8cc66933d38a6c500cd1d2 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include <linux/completion.h>
+#include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
index 9fd652a51424bc88fb0a3a9bad7fc8e120418c4f..ee7b2b365ef2225e7bf6f4d2f71b0a03edfb7888 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <net/tcp_states.h>
 #include <linux/nfc.h>
+#include <linux/export.h>
 
 #include "nfc.h"
 
index 2f032381bd4554226cd7d30a4bd104777caa5758..bf35b4e1a14c02dfe8f3c8f03dbcb19084bcaaf7 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/sock.h>
 
 #include <linux/phonet.h>
+#include <linux/export.h>
 #include <net/phonet/phonet.h>
 
 static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);
index f17fd841f9487d944adcab970e3ff238ea2c9287..2ba6e9fb4cbcd9554b6cf3eadb9088ca9e577ad7 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/ioctls.h>
 
 #include <linux/phonet.h>
+#include <linux/module.h>
 #include <net/phonet/phonet.h>
 #include <net/phonet/pep.h>
 #include <net/phonet/gprs.h>
index 676d18dc75b76fb4cb036c8465f9a29a6697389d..3f8d0b1603b98f5c1c2ad5105b6a3226c27df1f3 100644 (file)
@@ -31,6 +31,7 @@
 #include <net/tcp_states.h>
 
 #include <linux/phonet.h>
+#include <linux/export.h>
 #include <net/phonet/phonet.h>
 #include <net/phonet/pep.h>
 #include <net/phonet/pn_dev.h>
index 4cf6dc7910e4b0c13a2baf32447bd9000feb1f19..ec753b3ae72ade6005cecee012ec1e2759a7fb45 100644 (file)
@@ -9,7 +9,6 @@ config RDS
 
 config RDS_RDMA
        tristate "RDS over Infiniband and iWARP"
-       select LLIST
        depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS
        ---help---
          Allow RDS to use Infiniband and iWARP as a transport.
index 6daaa49d133f1eb389e11da9d931f71814d3ec68..e5b65acd650b54622b19aa9b879de6b2425a4a66 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/types.h>
 #include <linux/rbtree.h>
 #include <linux/bitops.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index 9334d892366ebb16091bd18fbdaacc9697eabb2a..9e07c756d1f95252c66726fe6157e7dea9c8fe8f 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/inet_hashtables.h>
 
 #include "rds.h"
index 3b83086bcc3045a2231dab3d84753dd0af7bed51..b4c8b0022feeebea1aec424542e37a8391d87297 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/if_arp.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "rds.h"
 #include "ib.h"
index 4fdf1b6e84fff6fd25b2040544245921332b9f89..f1c016c4146ec4092202f18db1abd0c0ce104017 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index f7474844f096e50b9d340055c32c9a81f9a5c96a..7826d46baa7038366872ec412d97ecd94eb1d13f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/if_arp.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include "rds.h"
 #include "iw.h"
index 1fd3d29023d7684d524cff00a2da35b2eb03b2b4..f0a4658f3273e2e87bac1ae88058e1209ed3332a 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index b82d63e77b031a807392924dfa134f8453841f7f..2499cd1084216aa54df919556111fd8dc9c4b8ab 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/cpu.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index f8760e1b6688b4d68247e1f0f5a45a11f55702f1..c2be901d19ee133b60c1b77006f02c88d8b1ec42 100644 (file)
@@ -30,6 +30,7 @@
  * SOFTWARE.
  *
  */
+#include <linux/module.h>
 #include <rdma/rdma_cm.h>
 
 #include "rdma_transport.h"
index 596689e592727f93eaf749490cf6fb6af4956463..bc3f8cd6d07063689b37f3fe32e790fc9195a7e9 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <net/sock.h>
 #include <linux/in.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index aa57e22539ef2f905e6469079e4f7105a4b6ceaa..e2d63c59e7c2f1195eb4289e9279d03b9850670e 100644 (file)
  *
  */
 #include <linux/kernel.h>
+#include <linux/moduleparam.h>
 #include <linux/gfp.h>
 #include <net/sock.h>
 #include <linux/in.h>
 #include <linux/list.h>
 #include <linux/ratelimit.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index 10c759ccac0c7a5d134e1cd49b41c45651e657c1..7be790d60b900d30053256b2f6cb1753056b0ba3 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/percpu.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index 8e0a32001c90c531a2ad8361dc4bb0c399b812fe..edac9ef2bc8b1c2060a2030deb4225d14c2fcc89 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/in.h>
+#include <linux/module.h>
 #include <net/tcp.h>
 
 #include "rds.h"
index 0fd90f8c5f59c75c18c244701f3230f93c408d85..65eaefcab241f105fdcaeac11be3d81328f8b0cc 100644 (file)
@@ -32,6 +32,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/random.h>
+#include <linux/export.h>
 
 #include "rds.h"
 
index 1bca6d49ec968bbe32cc75248f07ea6fa59265df..24c55c53e6a2fe150c2a34b181c60e2527278a55 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/input.h>
 #include <linux/slab.h>
+#include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 #include <linux/init.h>
 #include <linux/rfkill.h>
index d389de197089506d7ee27040604d06933eb3fa35..cd9b7ee60f3e6937a3c6193423c4a274f171136b 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <net/rose.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 
 static unsigned int rose_neigh_no = 1;
 
index 5f22e263eda748ffdbe06f802626588a70776004..338d793c71130f7546ac713c21a3cc01bae7f1e4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/skbuff.h>
 #include <linux/circ_buf.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
index 0c65013e3bfee6395a3cd70846416ff03dfad4f3..4b48687c3890fc64c186b797181062a4cc9ac4fa 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/net.h>
 #include <linux/skbuff.h>
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
index f2fb67e701a36a69b6a8beb0091363dd1b3ec4f7..93fdf131bd75e3e8e1969f1889c9d2a2cff90c67 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/sch_generic.h>
index 9e087d885675cc7b2a4286635d93299ed9a89c46..7b582300d051dcb81765f07714b4e9d16e056a6a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ipv6.h>
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <net/pkt_cls.h>
 #include <net/ip.h>
index ec5cbc8489636738b7c4bc02c9f9e0096d0d7e92..0a4b2f9a0094185ff43271d7aa01ad00c3d4d6dd 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
index ea17cbed29eff7215c062efe04c32de6bf513596..f88256cbacbfe4b89c202d591514fb28feaac11b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
+#include <linux/module.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <net/sch_generic.h>
index 6649463da1b68e6e59e6709c7e1d0b527a60ab63..d617161f8dd3904ddda7ac23da1178ccd03a79c4 100644 (file)
@@ -209,8 +209,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
                                 ctl->Plog, ctl->Scell_log,
                                 nla_data(tb[TCA_RED_STAB]));
 
-       if (skb_queue_empty(&sch->q))
-               red_end_of_idle_period(&q->parms);
+       if (!q->qdisc->q.qlen)
+               red_start_of_idle_period(&q->parms);
 
        sch_tree_unlock(sch);
        return 0;
index a3b7120fcc74c45cb642a7edc3813bde893240f1..4f4c52c0eeb3b28459d1abad498531a777c598bc 100644 (file)
@@ -225,11 +225,11 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
 
 
 static int
-__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
+__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
+              struct net_device *dev, struct netdev_queue *txq,
+              struct neighbour *mn)
 {
-       struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0);
-       struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc);
-       struct neighbour *mn = dst_get_neighbour(skb_dst(skb));
+       struct teql_sched_data *q = qdisc_priv(txq->qdisc);
        struct neighbour *n = q->ncache;
 
        if (mn->tbl == NULL)
@@ -262,17 +262,26 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
 }
 
 static inline int teql_resolve(struct sk_buff *skb,
-                              struct sk_buff *skb_res, struct net_device *dev)
+                              struct sk_buff *skb_res,
+                              struct net_device *dev,
+                              struct netdev_queue *txq)
 {
-       struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+       struct dst_entry *dst = skb_dst(skb);
+       struct neighbour *mn;
+       int res;
+
        if (txq->qdisc == &noop_qdisc)
                return -ENODEV;
 
-       if (dev->header_ops == NULL ||
-           skb_dst(skb) == NULL ||
-           dst_get_neighbour(skb_dst(skb)) == NULL)
+       if (!dev->header_ops || !dst)
                return 0;
-       return __teql_resolve(skb, skb_res, dev);
+
+       rcu_read_lock();
+       mn = dst_get_neighbour(dst);
+       res = mn ? __teql_resolve(skb, skb_res, dev, txq, mn) : 0;
+       rcu_read_unlock();
+
+       return res;
 }
 
 static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -307,7 +316,7 @@ restart:
                        continue;
                }
 
-               switch (teql_resolve(skb, skb_res, slave)) {
+               switch (teql_resolve(skb, skb_res, slave, slave_txq)) {
                case 0:
                        if (__netif_tx_trylock(slave_txq)) {
                                unsigned int length = qdisc_pkt_len(skb);
index 865e68fef21c326c631183c7c7d5ded4ad842647..bf812048cf6f7a244c547e0cd31a731351abfab3 100644 (file)
@@ -82,7 +82,7 @@ static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)
        struct sctp_auth_bytes *key;
 
        /* Verify that we are not going to overflow INT_MAX */
-       if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes))
+       if (key_len > (INT_MAX - sizeof(struct sctp_auth_bytes)))
                return NULL;
 
        /* Allocate the shared key */
index 05a6ce2147147b4e4fbb9de92d7913d3877e4fb2..1e2eee88c3ea4750c093e44b3c3080f8ad3551fd 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/types.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/export.h>
 #include <net/sctp/sctp.h>
 #include <net/ip.h> /* for snmp_fold_field */
 
index 836aa63ee121977d820e4f648135e65e3dd2f5d8..13bf5fcdbff1b9f80d2d0c6288ab98762d499e74 100644 (file)
@@ -78,6 +78,7 @@
 #include <net/inet_common.h>
 
 #include <linux/socket.h> /* for sa_family_t */
+#include <linux/export.h>
 #include <net/sock.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
index 4548757c98712d8d8dee0390e67fec1c7e0ad249..67a655ee82a94060ef5e0760c3aec61e7bc52c9e 100644 (file)
@@ -19,6 +19,7 @@
 #include <net/ipv6.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 
index 91eaa26e4c425e184bb74088d00fe47d233c4343..3ad435a14ada7ecd4afce4374f7dfb32dca77c52 100644 (file)
@@ -24,6 +24,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <linux/tcp.h>
 #include <linux/slab.h>
 #include <linux/sunrpc/xprt.h>
+#include <linux/export.h>
 
 #ifdef RPC_DEBUG
 #define RPCDBG_FACILITY        RPCDBG_TRANS
index 10b4319ebbca5816f02b4719f923852ea0301025..145e6784f508cb69d18fd67b80a475037f26e977 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pagemap.h>
 #include <linux/udp.h>
 #include <linux/sunrpc/xdr.h>
+#include <linux/export.h>
 
 
 /**
index d86bb673e1f68be3da207fb252e86dbf5a26417d..447cd0eb415c095fb58958b24e5353d17667c2d0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/sunrpc/svc_xprt.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/xprt.h>
+#include <linux/module.h>
 
 #define RPCDBG_FACILITY        RPCDBG_SVCXPRT
 
index dfd686eb0b7f2de3c75132e69194da8dfba7672a..71bed1c1c77a168da2299a1a009fa27e83253b1e 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/net.h>
index a385430c722aca3c0fb857ee17edc2c99ad75227..ba1296d88de0295258281db5d76ac1f2c1f0a34a 100644 (file)
@@ -50,6 +50,7 @@
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
 #include <linux/sunrpc/svc_rdma.h>
+#include <linux/export.h>
 
 #define RPCDBG_FACILITY        RPCDBG_SVCXPRT
 
index d7f97ef265904f0ddc0d691360f1e920dc63210b..55472c48825e6fd43c3357a2f58b398231a2767e 100644 (file)
@@ -496,7 +496,7 @@ static int xs_nospace(struct rpc_task *task)
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
-       int ret = 0;
+       int ret = -EAGAIN;
 
        dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
                        task->tk_pid, req->rq_slen - req->rq_bytes_sent,
@@ -508,7 +508,6 @@ static int xs_nospace(struct rpc_task *task)
        /* Don't race with disconnect */
        if (xprt_connected(xprt)) {
                if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
-                       ret = -EAGAIN;
                        /*
                         * Notify TCP that we're limited by the application
                         * window size
@@ -2530,8 +2529,10 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
                int err;
                err = xs_init_anyaddr(args->dstaddr->sa_family,
                                        (struct sockaddr *)&new->srcaddr);
-               if (err != 0)
+               if (err != 0) {
+                       xprt_free(xprt);
                        return ERR_PTR(err);
+               }
        }
 
        return xprt;
index ca84212cfbfede9c42f4b99cdd484149b6bc0471..e75813904f266e158a3df4649ed3813d14f47539 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/export.h>
 #include <linux/sysctl.h>
 #include <linux/nsproxy.h>
 
index 943b6af842650f97bab1ad576e96a78ba5c16b74..c21331d58fdb5d5839b1f9669757e45420dcb8fd 100644 (file)
@@ -34,6 +34,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/module.h>
+
 #include "core.h"
 #include "ref.h"
 #include "name_table.h"
index 9440a3d48ca04755dc5cff871bd5a3d258af2760..42b8324ff2eef6e27834c9ba1d9efd994dd3ba75 100644 (file)
@@ -34,6 +34,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <linux/export.h>
 #include <net/sock.h>
 
 #include "core.h"
index 466fbcc5cf77a92ef491be50eb836f652165da16..b595a3d8679f016a7b0936683170a69cc86c7905 100644 (file)
@@ -1957,6 +1957,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                        if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
                            (UNIXCB(skb).cred != siocb->scm->cred)) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
+                               sk->sk_data_ready(sk, skb->len);
                                break;
                        }
                } else {
@@ -1974,6 +1975,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                chunk = min_t(unsigned int, skb->len, size);
                if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
                        skb_queue_head(&sk->sk_receive_queue, skb);
+                       sk->sk_data_ready(sk, skb->len);
                        if (copied == 0)
                                copied = -EFAULT;
                        break;
@@ -1991,6 +1993,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                        /* put the skb back if we didn't use it up.. */
                        if (skb->len) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
+                               sk->sk_data_ready(sk, skb->len);
                                break;
                        }
 
@@ -2006,6 +2009,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                        /* put message back and return */
                        skb_queue_head(&sk->sk_receive_queue, skb);
+                       sk->sk_data_ready(sk, skb->len);
                        break;
                }
        } while (size);
index f346395314ba8ba6ba9c3754c91bcf18b735b80f..c43612ee96bb517ea2b2f806e5e999e39c6cbc0c 100644 (file)
@@ -81,7 +81,6 @@ static struct proc_dir_entry *proc_router;
  *     Iterator
  */
 static void *r_start(struct seq_file *m, loff_t *pos)
-       __acquires(kernel_lock)
 {
        struct wan_device *wandev;
        loff_t l = *pos;
@@ -103,7 +102,6 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 }
 
 static void r_stop(struct seq_file *m, void *v)
-       __releases(kernel_lock)
 {
        mutex_unlock(&config_mutex);
 }
index d5b7c3779c431b66520d7584ac5a31faa34b765b..0694d62e4dbc1b03f2b075269e23957c28ce85a2 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/netdevice.h>
 #include <linux/wimax.h>
 #include <linux/security.h>
+#include <linux/export.h>
 #include "wimax-internal.h"
 
 
index 68bedf3e544357f17f51615eb3c99de8024dabe2..7ceffe39d70e4bb69b046b2de1e604834412abb5 100644 (file)
@@ -32,6 +32,7 @@
 #include <net/genetlink.h>
 #include <linux/wimax.h>
 #include <linux/security.h>
+#include <linux/export.h>
 #include "wimax-internal.h"
 
 #define D_SUBMODULE op_reset
index 2609e445fe7d6c5bb6c8196a6241a95bafd18a8b..7ab60babdd22a32bd44bd28afc80972e4311084c 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/wimax.h>
 #include <linux/security.h>
 #include <linux/rfkill.h>
+#include <linux/export.h>
 #include "wimax-internal.h"
 
 #define D_SUBMODULE op_rfkill
index ee99e7dfcdbaa2a87d81d9044e0c30690013e45d..3c65eae701c463f1a3d4c720873b2cbf44240fbc 100644 (file)
@@ -55,6 +55,7 @@
 #include <net/genetlink.h>
 #include <linux/netdevice.h>
 #include <linux/wimax.h>
+#include <linux/module.h>
 #include "wimax-internal.h"
 
 
index f33fbb79437c3280b980447c9f36cd8c99436dc7..30f20fe4a5fe406316fb55140b35371caa390572 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 #include "wext-compat.h"
 #include "nl80211.h"
index 4423e64c7d983e3d8b294dcb6d2ebc3d4d5b6e88..b7b7868f4128b0f883eaa881027c6d211c9c7fc6 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/ieee80211.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 #include "nl80211.h"
 #include "core.h"
index 48260c2d092a820873f10769b9100a7864e8d2e0..ffafda5022c2b72d8f45714458e5fdd16203c4ee 100644 (file)
@@ -89,8 +89,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
        [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
 
-       [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
-       [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN },
+       [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
+       [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
 
        [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
        [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
@@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
        [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
 
-       [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
-                                        .len = NL80211_HT_CAPABILITY_LEN },
+       [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
 
        [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
        [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@@ -1253,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                        goto bad_res;
                }
 
+               if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+                   netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
+                       result = -EINVAL;
+                       goto bad_res;
+               }
+
                nla_for_each_nested(nl_txq_params,
                                    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
                                    rem_txq_params) {
index dbe35e138e945f1bfc63aae4fdcb3a0c1e371b0b..c4ad7958af52e84754b073915d009531299b9864 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 #include <net/ieee80211_radiotap.h>
 #include <asm/unaligned.h>
index 2520a1b7e7db7947754dafe3c814405ea26798e7..3302c56f60d1511d292a2e9b4f71ad87b6d6f722 100644 (file)
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/random.h>
 #include <linux/ctype.h>
 #include <linux/nl80211.h>
 #include <linux/platform_device.h>
+#include <linux/moduleparam.h>
 #include <net/cfg80211.h>
 #include "core.h"
 #include "reg.h"
 #define REG_DBG_PRINT(args...)
 #endif
 
+static struct regulatory_request core_request_world = {
+       .initiator = NL80211_REGDOM_SET_BY_CORE,
+       .alpha2[0] = '0',
+       .alpha2[1] = '0',
+       .intersect = false,
+       .processed = true,
+       .country_ie_env = ENVIRON_ANY,
+};
+
 /* Receipt of information from last regulatory request */
-static struct regulatory_request *last_request;
+static struct regulatory_request *last_request = &core_request_world;
 
 /* To trigger userspace events */
 static struct platform_device *reg_pdev;
@@ -148,7 +159,7 @@ static char user_alpha2[2];
 module_param(ieee80211_regdom, charp, 0444);
 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
 
-static void reset_regdomains(void)
+static void reset_regdomains(bool full_reset)
 {
        /* avoid freeing static information or freeing something twice */
        if (cfg80211_regdomain == cfg80211_world_regdom)
@@ -163,6 +174,13 @@ static void reset_regdomains(void)
 
        cfg80211_world_regdom = &world_regdom;
        cfg80211_regdomain = NULL;
+
+       if (!full_reset)
+               return;
+
+       if (last_request != &core_request_world)
+               kfree(last_request);
+       last_request = &core_request_world;
 }
 
 /*
@@ -173,7 +191,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
 {
        BUG_ON(!last_request);
 
-       reset_regdomains();
+       reset_regdomains(false);
 
        cfg80211_world_regdom = rd;
        cfg80211_regdomain = rd;
@@ -1405,7 +1423,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
        }
 
 new_request:
-       kfree(last_request);
+       if (last_request != &core_request_world)
+               kfree(last_request);
 
        last_request = pending_request;
        last_request->intersect = intersect;
@@ -1575,9 +1594,6 @@ static int regulatory_hint_core(const char *alpha2)
 {
        struct regulatory_request *request;
 
-       kfree(last_request);
-       last_request = NULL;
-
        request = kzalloc(sizeof(struct regulatory_request),
                          GFP_KERNEL);
        if (!request)
@@ -1775,7 +1791,7 @@ static void restore_regulatory_settings(bool reset_user)
        mutex_lock(&cfg80211_mutex);
        mutex_lock(&reg_mutex);
 
-       reset_regdomains();
+       reset_regdomains(true);
        restore_alpha2(alpha2, reset_user);
 
        /*
@@ -2035,12 +2051,18 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
        }
 
        request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
+       if (!request_wiphy &&
+           (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
+            last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
+               schedule_delayed_work(&reg_timeout, 0);
+               return -ENODEV;
+       }
 
        if (!last_request->intersect) {
                int r;
 
                if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
-                       reset_regdomains();
+                       reset_regdomains(false);
                        cfg80211_regdomain = rd;
                        return 0;
                }
@@ -2061,7 +2083,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                if (r)
                        return r;
 
-               reset_regdomains();
+               reset_regdomains(false);
                cfg80211_regdomain = rd;
                return 0;
        }
@@ -2086,7 +2108,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
 
                rd = NULL;
 
-               reset_regdomains();
+               reset_regdomains(false);
                cfg80211_regdomain = intersected_rd;
 
                return 0;
@@ -2106,7 +2128,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
        kfree(rd);
        rd = NULL;
 
-       reset_regdomains();
+       reset_regdomains(false);
        cfg80211_regdomain = intersected_rd;
 
        return 0;
@@ -2259,9 +2281,9 @@ void /* __init_or_exit */ regulatory_exit(void)
        mutex_lock(&cfg80211_mutex);
        mutex_lock(&reg_mutex);
 
-       reset_regdomains();
+       reset_regdomains(true);
 
-       kfree(last_request);
+       dev_set_uevent_suppress(&reg_pdev->dev, true);
 
        platform_device_unregister(reg_pdev);
 
index 0fb1424104047ced0d99949be89388509e05fc5c..dc23b31594e0f54758d0b59ffa5854c6e426e2e8 100644 (file)
@@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
 {
        const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
        const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
-       int r;
 
+       /* equal if both missing */
        if (!ie1 && !ie2)
                return 0;
-       if (!ie1 || !ie2)
+       /* sort missing IE before (left of) present IE */
+       if (!ie1)
                return -1;
+       if (!ie2)
+               return 1;
 
-       r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
-       if (r == 0 && ie1[1] != ie2[1])
+       /* sort by length first, then by contents */
+       if (ie1[1] != ie2[1])
                return ie2[1] - ie1[1];
-       return r;
+       return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 }
 
 static bool is_bss(struct cfg80211_bss *a,
index 6e86d5acf145bef1d7ba2e842fd61f1b50610c69..0acfdc9beacf8a397b8122c236cd6156d6c78b7e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/wireless.h>
+#include <linux/export.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
index 2f178f73943f5b3aa85e469add4884a1a1fb4ee0..4dde429441d2a45f748b0d0c8c67022e17fe5c36 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
  */
+#include <linux/export.h>
 #include <linux/bitops.h>
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
index 62f121d1d9cbdb833d27990fc36b58f2e3ab22aa..6897436b1d3f9166c3df9ceafd7f1b84fabed9de 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
  */
 
+#include <linux/export.h>
 #include <linux/wireless.h>
 #include <linux/nl80211.h>
 #include <linux/if_arp.h>
index fdbc23c10d8c4370828ca6761ca158cfda0e6886..0af7f54e4f617f04c7dbab24e09a6b53fc4c9dd2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/uaccess.h>
+#include <linux/export.h>
 #include <net/cfg80211.h>
 #include <net/iw_handler.h>
 #include <net/netlink.h>
index 0d4b8c3033ff53bba23ef5dd5620922d3f0a2faf..326750b99151292ffd653932a89bf5ee703fad19 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2009   Intel Corporation. All rights reserved.
  */
 
+#include <linux/export.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <linux/slab.h>
index 6dcfe65a2d1ad0d69958d40959a4121c05a6a8cf..5d643a548feb19b823c3948f2cdcde1605c32c9a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/export.h>
 #include <net/iw_handler.h>
 #include <net/arp.h>
 #include <net/wext.h>
index 7ff373792324f69b0937a5e3ce5f9fb273771f63..2ffde4631ae258262eeb0b8264bcc83d8a65822d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/x25.h>
index 552df27dcf53d3388fb2eb9ab3ba7a31c7ffcd64..2118d6446630e3ef64ae3e65b0e7066daf5a85c2 100644 (file)
@@ -2382,9 +2382,11 @@ static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
        return dst_metric_advmss(dst->path);
 }
 
-static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
+static unsigned int xfrm_mtu(const struct dst_entry *dst)
 {
-       return dst_mtu(dst->path);
+       unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+       return mtu ? : dst_mtu(dst->path);
 }
 
 static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
@@ -2411,8 +2413,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
                        dst_ops->check = xfrm_dst_check;
                if (likely(dst_ops->default_advmss == NULL))
                        dst_ops->default_advmss = xfrm_default_advmss;
-               if (likely(dst_ops->default_mtu == NULL))
-                       dst_ops->default_mtu = xfrm_default_mtu;
+               if (likely(dst_ops->mtu == NULL))
+                       dst_ops->mtu = xfrm_mtu;
                if (likely(dst_ops->negative_advice == NULL))
                        dst_ops->negative_advice = xfrm_negative_advice;
                if (likely(dst_ops->link_failure == NULL))
index 58d9ae005597a9b963b24ed620aa2e915c93e3bc..d0a1af8ed5846d07e73c605f0d119b9f8d87d0b4 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/export.h>
 #include <net/snmp.h>
 #include <net/xfrm.h>
 
index 6ca357406ea8ac178458363fd9fc6be3c467c10c..39e02c54ed26544d2b0b669ee6444584b4b2c498 100644 (file)
@@ -18,6 +18,7 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <linux/export.h>
 #include <net/xfrm.h>
 
 u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq)
index 96a7572853f7b8f6a5346389c0ec2ff781f068a4..41063e7592d2392b231c42cf86b4144d5f7a34b4 100644 (file)
@@ -61,10 +61,4 @@ config SAMPLE_KDB
          Build an example of how to dynamically add the hello
          command to the kdb shell.
 
-config SAMPLE_HIDRAW
-       bool "Build simple hidraw example"
-       depends on HIDRAW && HEADERS_CHECK
-       help
-         Build an example of how to use hidraw from userspace.
-
 endif # SAMPLES
index a0fd5029cfe78c8d082409b3228a59998b15eaa2..d2b366c16b6482cc90ba8f262d79d1ddbb2c87b2 100644 (file)
@@ -46,7 +46,7 @@ include $(kbuild-file)
 # If the save-* variables changed error out
 ifeq ($(KBUILD_NOPEDANTIC),)
         ifneq ("$(save-cflags)","$(CFLAGS)")
-                $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use EXTRA_CFLAGS)
+                $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
         endif
 endif
 
index aeea84a2483638e8fd30379ca7c2c695dd1aff6a..5d986d9adf1b7977684a1fa1825f5ff25c2816bc 100644 (file)
@@ -167,6 +167,7 @@ ifdef REGENERATE_PARSERS
 quiet_cmd_gperf = GPERF $@
       cmd_gperf = gperf -t --output-file $@ -a -C -E -g -k 1,3,$$ -p -t $<
 
+.PRECIOUS: $(src)/%.hash.c_shipped
 $(src)/%.hash.c_shipped: $(src)/%.gperf
        $(call cmd,gperf)
 
@@ -177,6 +178,7 @@ LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy)
 quiet_cmd_flex = LEX     $@
       cmd_flex = flex -o$@ -L -P $(LEX_PREFIX) $<
 
+.PRECIOUS: $(src)/%.lex.c_shipped
 $(src)/%.lex.c_shipped: $(src)/%.l
        $(call cmd,flex)
 
@@ -187,12 +189,14 @@ YACC_PREFIX = $(if $(YACC_PREFIX_${baseprereq}),$(YACC_PREFIX_${baseprereq}),yy)
 quiet_cmd_bison = YACC    $@
       cmd_bison = bison -o$@ -t -l -p $(YACC_PREFIX) $<
 
+.PRECIOUS: $(src)/%.tab.c_shipped
 $(src)/%.tab.c_shipped: $(src)/%.y
        $(call cmd,bison)
 
 quiet_cmd_bison_h = YACC    $@
       cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $<
 
+.PRECIOUS: $(src)/%.tab.h_shipped
 $(src)/%.tab.h_shipped: $(src)/%.y
        $(call cmd,bison_h)
 
index 291228e259845aa62c15f45e43389fd7a2b4d675..cb1f50cf12e3bda6fe798365a9c31b15adf0477a 100644 (file)
@@ -345,6 +345,7 @@ static void parse_dep_file(void *map, size_t len)
                memcpy(s, m, p-m); s[p-m] = 0;
                if (strrcmp(s, "include/generated/autoconf.h") &&
                    strrcmp(s, "arch/um/include/uml-config.h") &&
+                   strrcmp(s, "include/linux/kconfig.h") &&
                    strrcmp(s, ".ver")) {
                        /*
                         * Do not list the source file as dependency, so that
index 5e93342d22f9aa6c3ba9144ddd7926ff8f800f67..8fda3b3f7be87c01958c80823aea23cc22c790bf 100755 (executable)
@@ -1683,6 +1683,20 @@ sub process {
                        #print "is_end<$is_end> length<$length>\n";
                }
 
+               if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
+                   ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
+                       my $flag = $1;
+                       my $replacement = {
+                               'EXTRA_AFLAGS' =>   'asflags-y',
+                               'EXTRA_CFLAGS' =>   'ccflags-y',
+                               'EXTRA_CPPFLAGS' => 'cppflags-y',
+                               'EXTRA_LDFLAGS' =>  'ldflags-y',
+                       };
+
+                       WARN("DEPRECATED_VARIABLE",
+                            "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
+               }
+
 # check we are in a valid source file if not then ignore this hunk
                next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
 
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
new file mode 100755 (executable)
index 0000000..5061abc
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/sh
+# ----------------------------------------------------------------------
+# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
+#
+# Inspired from extract-ikconfig
+# (c) 2009,2010 Dick Streefland <dick@streefland.net>
+#
+# (c) 2011      Corentin Chary <corentin.chary@gmail.com>
+#
+# Licensed under the GNU General Public License, version 2 (GPLv2).
+# ----------------------------------------------------------------------
+
+check_vmlinux()
+{
+       # Use readelf to check if it's a valid ELF
+       # TODO: find a better to way to check that it's really vmlinux
+       #       and not just an elf
+       readelf -h $1 > /dev/null 2>&1 || return 1
+
+       cat $1
+       exit 0
+}
+
+try_decompress()
+{
+       # The obscure use of the "tr" filter is to work around older versions of
+       # "grep" that report the byte offset of the line instead of the pattern.
+
+       # Try to find the header ($1) and decompress from here
+       for     pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
+       do
+               pos=${pos%%:*}
+               tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
+               check_vmlinux $tmp
+       done
+}
+
+# Check invocation:
+me=${0##*/}
+img=$1
+if     [ $# -ne 1 -o ! -s "$img" ]
+then
+       echo "Usage: $me <kernel-image>" >&2
+       exit 2
+fi
+
+# Prepare temp files:
+tmp=$(mktemp /tmp/vmlinux-XXX)
+trap "rm -f $tmp" 0
+
+# Initial attempt for uncompressed images or objects:
+check_vmlinux $img
+
+# That didn't work, so retry after decompression.
+try_decompress '\037\213\010' xy    gunzip
+try_decompress '\3757zXZ\000' abcde unxz
+try_decompress 'BZh'          xy    bunzip2
+try_decompress '\135\0\0\0'   xxx   unlzma
+try_decompress '\211\114\132' xy    'lzop -d'
+
+# Bail out:
+echo "$me: Cannot find vmlinux." >&2
index 6d3fda0ce2aeb6a3e0123de2f3d9f61538e7f7d9..8a106499ec4fd627c183dc12eac1a607f2fabd80 100644 (file)
@@ -40,7 +40,8 @@ static struct symbol *symtab[HASH_BUCKETS];
 static FILE *debugfile;
 
 int cur_line = 1;
-char *cur_filename;
+char *cur_filename, *source_file;
+int in_source_file;
 
 static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
           flag_preserve, flag_warnings;
index 7ec52ae3846aa3c2b70837fd652d7e20bbf9dcb0..3bffdcaaa274e82271a98c65fa0bc43cef53ffe2 100644 (file)
@@ -37,6 +37,7 @@ enum symbol_status {
 struct string_list {
        struct string_list *next;
        enum symbol_type tag;
+       int in_source_file;
        char *string;
 };
 
@@ -57,7 +58,8 @@ typedef struct string_list **yystype;
 #define YYSTYPE yystype
 
 extern int cur_line;
-extern char *cur_filename;
+extern char *cur_filename, *source_file;
+extern int in_source_file;
 
 struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact);
 struct symbol *add_symbol(const char *name, enum symbol_type type,
index 400ae06a70df0ba9b17640d8bd67f0756b802f36..f770071719cb7cb8d4b8d1a069cf8e21786106ff 100644 (file)
@@ -116,6 +116,7 @@ MC_TOKEN            ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
                          cur_node->tag =                                  \
                            find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
                            SYM_ENUM_CONST : SYM_NORMAL ;                  \
+                         cur_node->in_source_file = in_source_file;       \
                        } while (0)
 
 #define APP            _APP(yytext, yyleng)
@@ -166,6 +167,13 @@ repeat:
       cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
       cur_line = atoi(yytext+2);
 
+      if (!source_file) {
+        source_file = xstrdup(cur_filename);
+        in_source_file = 1;
+      } else {
+        in_source_file = (strcmp(cur_filename, source_file) == 0);
+      }
+
       goto repeat;
     }
 
index c83cf60410be1bdf643b5bf478c1ca355e189501..0bf4157e61618784513c14af98b831916cb50b98 100644 (file)
@@ -660,7 +660,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -671,7 +671,7 @@ static int input (void );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               unsigned n; \
+               int n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -1926,6 +1926,7 @@ void yyfree (void * ptr )
                          cur_node->tag =                                  \
                            find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
                            SYM_ENUM_CONST : SYM_NORMAL ;                  \
+                         cur_node->in_source_file = in_source_file;       \
                        } while (0)
 
 #define APP            _APP(yytext, yyleng)
@@ -1975,6 +1976,13 @@ repeat:
       cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
       cur_line = atoi(yytext+2);
 
+      if (!source_file) {
+        source_file = xstrdup(cur_filename);
+        in_source_file = 1;
+      } else {
+        in_source_file = (strcmp(cur_filename, source_file) == 0);
+      }
+
       goto repeat;
     }
 
index 61d4a5d09856a6f90cc29c85f066b361bbc7c8ea..ece53c79bb59b040a5f29c4df132ffd19050ffc5 100644 (file)
@@ -1,9 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.4.3.  */
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2009, 2010 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.3"
+#define YYBISON_VERSION "2.5"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -96,6 +95,25 @@ remove_list(struct string_list **pb, struct string_list **pe)
   free_list(b, e);
 }
 
+/* Record definition of a struct/union/enum */
+static void record_compound(struct string_list **keyw,
+                      struct string_list **ident,
+                      struct string_list **body,
+                      enum symbol_type type)
+{
+       struct string_list *b = *body, *i = *ident, *r;
+
+       if (i->in_source_file) {
+               remove_node(keyw);
+               (*ident)->tag = type;
+               remove_list(body, ident);
+               return;
+       }
+       r = copy_node(i); r->tag = type;
+       r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
+       add_symbol(i->string, type, b, is_extern);
+}
+
 
 
 
@@ -283,11 +301,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -310,24 +328,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -356,23 +374,7 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         YYSIZE_T yyi;                         \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -392,6 +394,26 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
@@ -514,20 +536,20 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   104,   104,   105,   109,   109,   115,   115,   117,   117,
-     119,   120,   121,   122,   123,   124,   128,   142,   143,   147,
-     155,   168,   174,   175,   179,   180,   184,   190,   194,   195,
-     196,   197,   198,   202,   203,   204,   205,   209,   211,   213,
-     217,   224,   231,   241,   244,   245,   249,   250,   251,   252,
-     253,   254,   255,   256,   257,   258,   259,   263,   268,   269,
-     273,   274,   278,   278,   278,   279,   287,   288,   292,   301,
-     303,   305,   307,   309,   316,   317,   321,   322,   323,   325,
-     327,   329,   331,   336,   337,   338,   342,   343,   347,   348,
-     353,   358,   360,   364,   365,   373,   377,   379,   381,   383,
-     385,   390,   399,   400,   405,   410,   411,   415,   416,   420,
-     421,   425,   427,   432,   433,   437,   438,   442,   443,   444,
-     448,   452,   453,   457,   458,   462,   463,   466,   471,   479,
-     483,   484,   488
+       0,   123,   123,   124,   128,   128,   134,   134,   136,   136,
+     138,   139,   140,   141,   142,   143,   147,   161,   162,   166,
+     174,   187,   193,   194,   198,   199,   203,   209,   213,   214,
+     215,   216,   217,   221,   222,   223,   224,   228,   230,   232,
+     236,   238,   240,   245,   248,   249,   253,   254,   255,   256,
+     257,   258,   259,   260,   261,   262,   263,   267,   272,   273,
+     277,   278,   282,   282,   282,   283,   291,   292,   296,   305,
+     307,   309,   311,   313,   320,   321,   325,   326,   327,   329,
+     331,   333,   335,   340,   341,   342,   346,   347,   351,   352,
+     357,   362,   364,   368,   369,   377,   381,   383,   385,   387,
+     389,   394,   403,   404,   409,   414,   415,   419,   420,   424,
+     425,   429,   431,   436,   437,   441,   442,   446,   447,   448,
+     452,   456,   457,   461,   462,   466,   467,   470,   475,   483,
+     487,   488,   492
 };
 #endif
 
@@ -618,8 +640,8 @@ static const yytype_uint8 yyr2[] =
        0,     1,     5
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
@@ -692,8 +714,7 @@ static const yytype_int16 yypgoto[] =
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -109
 static const yytype_int16 yytable[] =
 {
@@ -753,6 +774,12 @@ static const yytype_int16 yytable[] =
        0,     0,    34
 };
 
+#define yypact_value_is_default(yystate) \
+  ((yystate) == (-135))
+
+#define yytable_value_is_error(yytable_value) \
+  YYID (0)
+
 static const yytype_int16 yycheck[] =
 {
       59,    38,    79,     3,     1,     8,    56,    37,    26,    37,
@@ -869,7 +896,6 @@ do                                                          \
     {                                                          \
       yychar = (Token);                                                \
       yylval = (Value);                                                \
-      yytoken = YYTRANSLATE (yychar);                          \
       YYPOPSTACK (1);                                          \
       goto yybackup;                                           \
     }                                                          \
@@ -911,19 +937,10 @@ while (YYID (0))
 #endif
 
 
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
+/* This macro is provided for backward compatibility. */
 
 #ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)                 \
-     fprintf (File, "%d.%d-%d.%d",                     \
-             (Loc).first_line, (Loc).first_column,     \
-             (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
@@ -1115,7 +1132,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-\f
 
 #if YYERROR_VERBOSE
 
@@ -1218,115 +1234,142 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = 0;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
     {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-        constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-                   + sizeof yyexpecting - 1
-                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-                      * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-        YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-         {
-           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-             {
-               yycount = 1;
-               yysize = yysize0;
-               yyformat[sizeof yyunexpected - 1] = '\0';
-               break;
-             }
-           yyarg[yycount++] = yytname[yyx];
-           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-           yysize_overflow |= (yysize1 < yysize);
-           yysize = yysize1;
-           yyfmt = yystpcpy (yyfmt, yyprefix);
-           yyprefix = yyor;
-         }
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-       return YYSIZE_MAXIMUM;
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
 
-      if (yyresult)
-       {
-         /* Avoid sprintf, as that infringes on the user's name space.
-            Don't have undefined behavior even if the translation
-            produced a string with the wrong number of "%s"s.  */
-         char *yyp = yyresult;
-         int yyi = 0;
-         while ((*yyp = *yyf) != '\0')
-           {
-             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-               {
-                 yyp += yytnamerr (yyp, yyarg[yyi++]);
-                 yyf += 2;
-               }
-             else
-               {
-                 yyp++;
-                 yyf++;
-               }
-           }
-       }
-      return yysize;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-\f
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1359,6 +1402,7 @@ yydestruct (yymsg, yytype, yyvaluep)
     }
 }
 
+
 /* Prevent warnings from -Wmissing-prototypes.  */
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
@@ -1385,10 +1429,9 @@ YYSTYPE yylval;
 int yynerrs;
 
 
-
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1412,8 +1455,6 @@ yyparse ()
 #endif
 #endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
@@ -1568,7 +1609,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1599,8 +1640,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-       goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1655,42 +1696,42 @@ yyreduce:
     {
         case 4:
 
-    { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;}
+    { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
     break;
 
   case 5:
 
-    { free_list(*(yyvsp[(2) - (2)]), NULL); *(yyvsp[(2) - (2)]) = NULL; ;}
+    { free_list(*(yyvsp[(2) - (2)]), NULL); *(yyvsp[(2) - (2)]) = NULL; }
     break;
 
   case 6:
 
-    { is_typedef = 1; ;}
+    { is_typedef = 1; }
     break;
 
   case 7:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 8:
 
-    { is_typedef = 1; ;}
+    { is_typedef = 1; }
     break;
 
   case 9:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 14:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 15:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 16:
@@ -1704,12 +1745,12 @@ yyreduce:
                    current_name = NULL;
                  }
                  (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+               }
     break;
 
   case 17:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 19:
@@ -1720,7 +1761,7 @@ yyreduce:
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
                  (yyval) = (yyvsp[(1) - (1)]);
-               ;}
+               }
     break;
 
   case 20:
@@ -1733,27 +1774,27 @@ yyreduce:
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
                  (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+               }
     break;
 
   case 21:
 
-    { (yyval) = (yyvsp[(4) - (4)]) ? (yyvsp[(4) - (4)]) : (yyvsp[(3) - (4)]) ? (yyvsp[(3) - (4)]) : (yyvsp[(2) - (4)]) ? (yyvsp[(2) - (4)]) : (yyvsp[(1) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]) ? (yyvsp[(4) - (4)]) : (yyvsp[(3) - (4)]) ? (yyvsp[(3) - (4)]) : (yyvsp[(2) - (4)]) ? (yyvsp[(2) - (4)]) : (yyvsp[(1) - (4)]); }
     break;
 
   case 22:
 
-    { decl_spec = NULL; ;}
+    { decl_spec = NULL; }
     break;
 
   case 24:
 
-    { decl_spec = *(yyvsp[(1) - (1)]); ;}
+    { decl_spec = *(yyvsp[(1) - (1)]); }
     break;
 
   case 25:
 
-    { decl_spec = *(yyvsp[(2) - (2)]); ;}
+    { decl_spec = *(yyvsp[(2) - (2)]); }
     break;
 
   case 26:
@@ -1762,97 +1803,82 @@ yyreduce:
                     is really irrelevant to the linkage.  */
                  remove_node((yyvsp[(1) - (1)]));
                  (yyval) = (yyvsp[(1) - (1)]);
-               ;}
+               }
     break;
 
   case 31:
 
-    { is_extern = 1; (yyval) = (yyvsp[(1) - (1)]); ;}
+    { is_extern = 1; (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 32:
 
-    { is_extern = 0; (yyval) = (yyvsp[(1) - (1)]); ;}
+    { is_extern = 0; (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 37:
 
-    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_STRUCT; (yyval) = (yyvsp[(2) - (2)]); ;}
+    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_STRUCT; (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 38:
 
-    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_UNION; (yyval) = (yyvsp[(2) - (2)]); ;}
+    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_UNION; (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 39:
 
-    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_ENUM; (yyval) = (yyvsp[(2) - (2)]); ;}
+    { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_ENUM; (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 40:
 
-    { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
-                 r = copy_node(i); r->tag = SYM_STRUCT;
-                 r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
-                 add_symbol(i->string, SYM_STRUCT, s, is_extern);
-                 (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+    { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_STRUCT); (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 41:
 
-    { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
-                 r = copy_node(i); r->tag = SYM_UNION;
-                 r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
-                 add_symbol(i->string, SYM_UNION, s, is_extern);
-                 (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+    { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_UNION); (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 42:
 
-    { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
-                 r = copy_node(i); r->tag = SYM_ENUM;
-                 r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
-                 add_symbol(i->string, SYM_ENUM, s, is_extern);
-                 (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+    { record_compound((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), SYM_ENUM); (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 43:
 
-    { add_symbol(NULL, SYM_ENUM, NULL, 0); (yyval) = (yyvsp[(2) - (2)]); ;}
+    { add_symbol(NULL, SYM_ENUM, NULL, 0); (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 44:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 45:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 56:
 
-    { (*(yyvsp[(1) - (1)]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[(1) - (1)]); ;}
+    { (*(yyvsp[(1) - (1)]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 57:
 
-    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
     break;
 
   case 58:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 61:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 65:
@@ -1860,12 +1886,12 @@ yyreduce:
     { /* restrict has no effect in prototypes so ignore it */
                  remove_node((yyvsp[(1) - (1)]));
                  (yyval) = (yyvsp[(1) - (1)]);
-               ;}
+               }
     break;
 
   case 66:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 68:
@@ -1877,97 +1903,97 @@ yyreduce:
                    current_name = (*(yyvsp[(1) - (1)]))->string;
                    (yyval) = (yyvsp[(1) - (1)]);
                  }
-               ;}
+               }
     break;
 
   case 69:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 70:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 71:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 72:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 73:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 74:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 78:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 79:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 80:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 81:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 82:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 83:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 85:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 86:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 89:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 90:
 
-    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
     break;
 
   case 91:
 
-    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
     break;
 
   case 93:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 94:
@@ -1976,39 +2002,39 @@ yyreduce:
                     private parameter names.  */
                  remove_node((yyvsp[(1) - (1)]));
                  (yyval) = (yyvsp[(1) - (1)]);
-               ;}
+               }
     break;
 
   case 95:
 
     { remove_node((yyvsp[(1) - (1)]));
                  (yyval) = (yyvsp[(1) - (1)]);
-               ;}
+               }
     break;
 
   case 96:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 97:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 98:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 99:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 100:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 101:
@@ -2017,87 +2043,87 @@ yyreduce:
                  *(yyvsp[(2) - (3)]) = NULL;
                  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
                  (yyval) = (yyvsp[(3) - (3)]);
-               ;}
+               }
     break;
 
   case 102:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 104:
 
-    { remove_list((yyvsp[(2) - (2)]), &(*(yyvsp[(1) - (2)]))->next); (yyval) = (yyvsp[(2) - (2)]); ;}
+    { remove_list((yyvsp[(2) - (2)]), &(*(yyvsp[(1) - (2)]))->next); (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 105:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 106:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 107:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 110:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 111:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 112:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 113:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 116:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 117:
 
-    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); }
     break;
 
   case 118:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 120:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 121:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 123:
 
-    { (yyval) = (yyvsp[(3) - (3)]); ;}
+    { (yyval) = (yyvsp[(3) - (3)]); }
     break;
 
   case 124:
 
-    { (yyval) = (yyvsp[(4) - (4)]); ;}
+    { (yyval) = (yyvsp[(4) - (4)]); }
     break;
 
   case 127:
@@ -2105,7 +2131,7 @@ yyreduce:
     {
                        const char *name = strdup((*(yyvsp[(1) - (1)]))->string);
                        add_symbol(name, SYM_ENUM_CONST, NULL, 0);
-               ;}
+               }
     break;
 
   case 128:
@@ -2114,28 +2140,39 @@ yyreduce:
                        const char *name = strdup((*(yyvsp[(1) - (3)]))->string);
                        struct string_list *expr = copy_list_range(*(yyvsp[(3) - (3)]), *(yyvsp[(2) - (3)]));
                        add_symbol(name, SYM_ENUM_CONST, expr, 0);
-               ;}
+               }
     break;
 
   case 129:
 
-    { (yyval) = (yyvsp[(2) - (2)]); ;}
+    { (yyval) = (yyvsp[(2) - (2)]); }
     break;
 
   case 130:
 
-    { (yyval) = NULL; ;}
+    { (yyval) = NULL; }
     break;
 
   case 132:
 
-    { export_symbol((*(yyvsp[(3) - (5)]))->string); (yyval) = (yyvsp[(5) - (5)]); ;}
+    { export_symbol((*(yyvsp[(3) - (5)]))->string); (yyval) = (yyvsp[(5) - (5)]); }
     break;
 
 
 
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -2163,6 +2200,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2170,37 +2211,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-         {
-           YYSIZE_T yyalloc = 2 * yysize;
-           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-             yyalloc = YYSTACK_ALLOC_MAXIMUM;
-           if (yymsg != yymsgbuf)
-             YYSTACK_FREE (yymsg);
-           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-           if (yymsg)
-             yymsg_alloc = yyalloc;
-           else
-             {
-               yymsg = yymsgbuf;
-               yymsg_alloc = sizeof yymsgbuf;
-             }
-         }
-
-       if (0 < yysize && yysize <= yymsg_alloc)
-         {
-           (void) yysyntax_error (yymsg, yystate, yychar);
-           yyerror (yymsg);
-         }
-       else
-         {
-           yyerror (YY_("syntax error"));
-           if (yysize != 0)
-             goto yyexhaustedlab;
-         }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2259,7 +2299,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
        {
          yyn += YYTERROR;
          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2318,8 +2358,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-                yytoken, &yylval);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
index 350c2b403e219ec8cd9b10808a511b2b62cec92d..93240a3cdecc91219f60c883a35bf94ff9bc5789 100644 (file)
@@ -1,9 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.4.3.  */
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2009, 2010 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index ba5c242866c11b4c0803822bd45b940ad16b8474..23c39998ad864eb328dfaa6c7da6ff9dcc6a10c9 100644 (file)
@@ -51,6 +51,25 @@ remove_list(struct string_list **pb, struct string_list **pe)
   free_list(b, e);
 }
 
+/* Record definition of a struct/union/enum */
+static void record_compound(struct string_list **keyw,
+                      struct string_list **ident,
+                      struct string_list **body,
+                      enum symbol_type type)
+{
+       struct string_list *b = *body, *i = *ident, *r;
+
+       if (i->in_source_file) {
+               remove_node(keyw);
+               (*ident)->tag = type;
+               remove_list(body, ident);
+               return;
+       }
+       r = copy_node(i); r->tag = type;
+       r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
+       add_symbol(i->string, type, b, is_extern);
+}
+
 %}
 
 %token ASM_KEYW
@@ -215,26 +234,11 @@ type_specifier:
 
        /* Full definitions of an s/u/e.  Record it.  */
        | STRUCT_KEYW IDENT class_body
-               { struct string_list *s = *$3, *i = *$2, *r;
-                 r = copy_node(i); r->tag = SYM_STRUCT;
-                 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
-                 add_symbol(i->string, SYM_STRUCT, s, is_extern);
-                 $$ = $3;
-               }
+               { record_compound($1, $2, $3, SYM_STRUCT); $$ = $3; }
        | UNION_KEYW IDENT class_body
-               { struct string_list *s = *$3, *i = *$2, *r;
-                 r = copy_node(i); r->tag = SYM_UNION;
-                 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
-                 add_symbol(i->string, SYM_UNION, s, is_extern);
-                 $$ = $3;
-               }
+               { record_compound($1, $2, $3, SYM_UNION); $$ = $3; }
        | ENUM_KEYW IDENT enum_body
-               { struct string_list *s = *$3, *i = *$2, *r;
-                 r = copy_node(i); r->tag = SYM_ENUM;
-                 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
-                 add_symbol(i->string, SYM_ENUM, s, is_extern);
-                 $$ = $3;
-               }
+               { record_compound($1, $2, $3, SYM_ENUM); $$ = $3; }
        /*
         * Anonymous enum definition. Tell add_symbol() to restart its counter.
         */
index 82d2eb285b705daac83e5c690620a7500ba5f1f9..ba573fe7c74d5bfe0495372931ebff69406f35c2 100644 (file)
@@ -33,17 +33,9 @@ silentoldconfig: $(obj)/conf
        $(Q)mkdir -p include/generated
        $< --$@ $(Kconfig)
 
-# if no path is given, then use src directory to find file
-ifdef LSMOD
-LSMOD_F := $(LSMOD)
-ifeq ($(findstring /,$(LSMOD)),)
-  LSMOD_F := $(objtree)/$(LSMOD)
-endif
-endif
-
-localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
+localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)mkdir -p include/generated
-       $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
+       $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
        $(Q)if [ -f .config ]; then                                     \
                        cmp -s .tmp.config .config ||                   \
                        (mv -f .config .config.old.1;                   \
@@ -56,22 +48,6 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        fi
        $(Q)rm -f .tmp.config
 
-localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)mkdir -p include/generated
-       $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
-       $(Q)sed -i s/=m/=y/ .tmp.config
-       $(Q)if [ -f .config ]; then                                     \
-                       cmp -s .tmp.config .config ||                   \
-                       (mv -f .config .config.old.1;                   \
-                        mv -f .tmp.config .config;                     \
-                        $(obj)/conf --silentoldconfig $(Kconfig);      \
-                        mv -f .config.old.1 .config.old)               \
-       else                                                            \
-                       mv -f .tmp.config .config;                      \
-                       $(obj)/conf --silentoldconfig $(Kconfig);       \
-       fi
-       $(Q)rm -f .tmp.config
-
 # Create new linux.pot file
 # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
 # The symlink is used to repair a deficiency in arch/um
index 59b667cae5f33e4437e1beaa6bdfcdcb93bc8fcb..5a58965d8800daab99a8bd096262c1f95465482d 100644 (file)
@@ -503,17 +503,6 @@ header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
                        fprintf(fp, "#define %s%s%s 1\n",
                            CONFIG_, sym->name, suffix);
                }
-               /*
-                * Generate the __enabled_CONFIG_* and
-                * __enabled_CONFIG_*_MODULE macros for use by the
-                * IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is
-                * generated even for booleans so that the IS_ENABLED() macro
-                * works.
-                */
-               fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n",
-                               sym->name, (*value == 'y'));
-               fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n",
-                               sym->name, (*value == 'm'));
                break;
        }
        case S_HEX: {
@@ -564,6 +553,35 @@ static struct conf_printer header_printer_cb =
        .print_comment = header_print_comment,
 };
 
+/*
+ * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for
+ * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is
+ * generated even for booleans so that the IS_ENABLED() macro works.
+ */
+static void
+header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+
+       switch (sym->type) {
+       case S_BOOLEAN:
+       case S_TRISTATE: {
+               fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n",
+                   sym->name, (*value == 'y'));
+               fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n",
+                   sym->name, (*value == 'm'));
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static struct conf_printer header__enabled_printer_cb =
+{
+       .print_symbol = header_print__enabled_symbol,
+       .print_comment = header_print_comment,
+};
+
 /*
  * Tristate printer
  *
@@ -945,11 +963,16 @@ int conf_write_autoconf(void)
        conf_write_heading(out_h, &header_printer_cb, NULL);
 
        for_all_symbols(i, sym) {
+               if (!sym->name)
+                       continue;
+
                sym_calc_value(sym);
-               if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
+
+               conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL);
+
+               if (!(sym->flags & SYMBOL_WRITE))
                        continue;
 
-               /* write symbol to auto.conf, tristate and header files */
                conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
 
                conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
index c704712d02271431fa9c42d0cd95be9c2ab9d988..154c2dd245b77536de60fd344d46e49dfbe41520 100644 (file)
@@ -320,7 +320,6 @@ static void print_page(WINDOW * win, int height, int width)
  */
 static void print_line(WINDOW * win, int row, int width)
 {
-       int y, x;
        char *line;
 
        line = get_line();
@@ -329,10 +328,10 @@ static void print_line(WINDOW * win, int row, int width)
        waddch(win, ' ');
        waddnstr(win, line, MIN(strlen(line), width - 2));
 
-       getyx(win, y, x);
        /* Clear 'residue' of previous line */
 #if OLD_NCURSES
        {
+               int x = getcurx(win);
                int i;
                for (i = 0; i < width - x; i++)
                        waddch(win, ' ');
index 820d2b6800fb5d856a56394cd9786610337fc8b8..19e200d9112091fc3ddfe5aac59f94b32b38c4dc 100644 (file)
@@ -15,6 +15,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <signal.h>
 #include <unistd.h>
 #include <locale.h>
 
@@ -272,6 +273,7 @@ static struct menu *current_menu;
 static int child_count;
 static int single_menu_mode;
 static int show_all_options;
+static int saved_x, saved_y;
 
 static void conf(struct menu *menu);
 static void conf_choice(struct menu *menu);
@@ -792,9 +794,54 @@ static void conf_save(void)
        }
 }
 
+static int handle_exit(void)
+{
+       int res;
+
+       dialog_clear();
+       if (conf_get_changed())
+               res = dialog_yesno(NULL,
+                                  _("Do you wish to save your new configuration ?\n"
+                                    "<ESC><ESC> to continue."),
+                                  6, 60);
+       else
+               res = -1;
+
+       end_dialog(saved_x, saved_y);
+
+       switch (res) {
+       case 0:
+               if (conf_write(filename)) {
+                       fprintf(stderr, _("\n\n"
+                                         "Error while writing of the configuration.\n"
+                                         "Your configuration changes were NOT saved."
+                                         "\n\n"));
+                       return 1;
+               }
+               /* fall through */
+       case -1:
+               printf(_("\n\n"
+                        "*** End of the configuration.\n"
+                        "*** Execute 'make' to start the build or try 'make help'."
+                        "\n\n"));
+               res = 0;
+               break;
+       default:
+               fprintf(stderr, _("\n\n"
+                                 "Your configuration changes were NOT saved."
+                                 "\n\n"));
+       }
+
+       return res;
+}
+
+static void sig_handler(int signo)
+{
+       exit(handle_exit());
+}
+
 int main(int ac, char **av)
 {
-       int saved_x, saved_y;
        char *mode;
        int res;
 
@@ -802,6 +849,8 @@ int main(int ac, char **av)
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
 
+       signal(SIGINT, sig_handler);
+
        conf_parse(av[1]);
        conf_read(NULL);
 
@@ -823,40 +872,9 @@ int main(int ac, char **av)
        set_config_filename(conf_get_configname());
        do {
                conf(&rootmenu);
-               dialog_clear();
-               if (conf_get_changed())
-                       res = dialog_yesno(NULL,
-                                          _("Do you wish to save your "
-                                            "new configuration?\n"
-                                            "<ESC><ESC> to continue."),
-                                          6, 60);
-               else
-                       res = -1;
+               res = handle_exit();
        } while (res == KEY_ESC);
-       end_dialog(saved_x, saved_y);
-
-       switch (res) {
-       case 0:
-               if (conf_write(filename)) {
-                       fprintf(stderr, _("\n\n"
-                               "Error while writing of the configuration.\n"
-                               "Your configuration changes were NOT saved."
-                               "\n\n"));
-                       return 1;
-               }
-               /* fall through */
-       case -1:
-               printf(_("\n\n"
-                       "*** End of the configuration.\n"
-                       "*** Execute 'make' to start the build or try 'make help'."
-                       "\n\n"));
-               break;
-       default:
-               fprintf(stderr, _("\n\n"
-                       "Your configuration changes were NOT saved."
-                       "\n\n"));
-       }
 
-       return 0;
+       return res;
 }
 
index d66008639a43f46e60235dee932558a6c4d00223..8c2a97e60fafa701331949152261d162541482a1 100644 (file)
@@ -10,8 +10,7 @@
 
 #include "lkc.h"
 
-static const char nohelp_text[] = N_(
-       "There is no help available for this option.\n");
+static const char nohelp_text[] = "There is no help available for this option.";
 
 struct menu rootmenu;
 static struct menu **last_entry_ptr;
@@ -595,16 +594,14 @@ struct gstr get_relations_str(struct symbol **sym_arr)
 void menu_get_ext_help(struct menu *menu, struct gstr *help)
 {
        struct symbol *sym = menu->sym;
+       const char *help_text = nohelp_text;
 
        if (menu_has_help(menu)) {
-               if (sym->name) {
+               if (sym->name)
                        str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
-                       str_append(help, _(menu_get_help(menu)));
-                       str_append(help, "\n");
-               }
-       } else {
-               str_append(help, nohelp_text);
+               help_text = menu_get_help(menu);
        }
+       str_printf(help, "%s\n", _(help_text));
        if (sym)
                get_symbol_str(help, sym);
 }
index 39ca1f1640eaf6f27cdaa0ce5a9399b42ee89e4e..73070cb0b6de50289bd1e5b2d17217d691669a37 100644 (file)
@@ -182,8 +182,6 @@ setmod_text[] = N_(
 "This feature depends on another which\n"
 "has been configured as a module.\n"
 "As a result, this feature will be built as a module."),
-nohelp_text[] = N_(
-"There is no help available for this option.\n"),
 load_config_text[] = N_(
 "Enter the name of the configuration file you wish to load.\n"
 "Accept the name shown to restore the configuration you\n"
@@ -280,6 +278,9 @@ static int global_exit;
 /* the currently selected button */
 const char *current_instructions = menu_instructions;
 
+static char *dialog_input_result;
+static int dialog_input_result_len;
+
 static void conf(struct menu *menu);
 static void conf_choice(struct menu *menu);
 static void conf_string(struct menu *menu);
@@ -695,7 +696,6 @@ static void search_conf(void)
 {
        struct symbol **sym_arr;
        struct gstr res;
-       char dialog_input_result[100];
        char *dialog_input;
        int dres;
 again:
@@ -703,7 +703,7 @@ again:
                        _("Search Configuration Parameter"),
                        _("Enter " CONFIG_ " (sub)string to search for "
                                "(with or without \"" CONFIG_ "\")"),
-                       "", dialog_input_result, 99);
+                       "", &dialog_input_result, &dialog_input_result_len);
        switch (dres) {
        case 0:
                break;
@@ -1348,7 +1348,6 @@ static void conf_choice(struct menu *menu)
 static void conf_string(struct menu *menu)
 {
        const char *prompt = menu_get_prompt(menu);
-       char dialog_input_result[256];
 
        while (1) {
                int res;
@@ -1371,8 +1370,8 @@ static void conf_string(struct menu *menu)
                                prompt ? _(prompt) : _("Main Menu"),
                                heading,
                                sym_get_string_value(menu->sym),
-                               dialog_input_result,
-                               sizeof(dialog_input_result));
+                               &dialog_input_result,
+                               &dialog_input_result_len);
                switch (res) {
                case 0:
                        if (sym_set_string_value(menu->sym,
@@ -1392,14 +1391,13 @@ static void conf_string(struct menu *menu)
 
 static void conf_load(void)
 {
-       char dialog_input_result[256];
        while (1) {
                int res;
                res = dialog_inputbox(main_window,
                                NULL, load_config_text,
                                filename,
-                               dialog_input_result,
-                               sizeof(dialog_input_result));
+                               &dialog_input_result,
+                               &dialog_input_result_len);
                switch (res) {
                case 0:
                        if (!dialog_input_result[0])
@@ -1424,14 +1422,13 @@ static void conf_load(void)
 
 static void conf_save(void)
 {
-       char dialog_input_result[256];
        while (1) {
                int res;
                res = dialog_inputbox(main_window,
                                NULL, save_config_text,
                                filename,
-                               dialog_input_result,
-                               sizeof(dialog_input_result));
+                               &dialog_input_result,
+                               &dialog_input_result_len);
                switch (res) {
                case 0:
                        if (!dialog_input_result[0])
index f8137b3a5382fd0862ed6f6ae6d4d545de26ec8c..3b18dd839668b295cd3d06b1c4cac3d4c941ddf3 100644 (file)
@@ -356,7 +356,7 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
 
 int dialog_inputbox(WINDOW *main_window,
                const char *title, const char *prompt,
-               const char *init, char *result, int result_len)
+               const char *init, char **resultp, int *result_len)
 {
        int prompt_lines = 0;
        int prompt_width = 0;
@@ -367,7 +367,13 @@ int dialog_inputbox(WINDOW *main_window,
        int i, x, y;
        int res = -1;
        int cursor_position = strlen(init);
+       int cursor_form_win;
+       char *result = *resultp;
 
+       if (strlen(init)+1 > *result_len) {
+               *result_len = strlen(init)+1;
+               *resultp = result = realloc(result, *result_len);
+       }
 
        /* find the widest line of msg: */
        prompt_lines = get_line_no(prompt);
@@ -384,7 +390,7 @@ int dialog_inputbox(WINDOW *main_window,
        y = (LINES-(prompt_lines+4))/2;
        x = (COLS-(prompt_width+4))/2;
 
-       strncpy(result, init, result_len);
+       strncpy(result, init, *result_len);
 
        /* create the windows */
        win = newwin(prompt_lines+6, prompt_width+7, y, x);
@@ -405,7 +411,9 @@ int dialog_inputbox(WINDOW *main_window,
        fill_window(prompt_win, prompt);
 
        mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
-       mvwprintw(form_win, 0, 0, "%s", result);
+       cursor_form_win = min(cursor_position, prompt_width-1);
+       mvwprintw(form_win, 0, 0, "%s",
+                 result + cursor_position-cursor_form_win);
 
        /* create panels */
        panel = new_panel(win);
@@ -431,6 +439,8 @@ int dialog_inputbox(WINDOW *main_window,
                                                &result[cursor_position],
                                                len-cursor_position+1);
                                cursor_position--;
+                               cursor_form_win--;
+                               len--;
                        }
                        break;
                case KEY_DC:
@@ -438,38 +448,63 @@ int dialog_inputbox(WINDOW *main_window,
                                memmove(&result[cursor_position],
                                                &result[cursor_position+1],
                                                len-cursor_position+1);
+                               len--;
                        }
                        break;
                case KEY_UP:
                case KEY_RIGHT:
-                       if (cursor_position < len &&
-                           cursor_position < min(result_len, prompt_width))
+                       if (cursor_position < len) {
                                cursor_position++;
+                               cursor_form_win++;
+                       }
                        break;
                case KEY_DOWN:
                case KEY_LEFT:
-                       if (cursor_position > 0)
+                       if (cursor_position > 0) {
                                cursor_position--;
+                               cursor_form_win--;
+                       }
+                       break;
+               case KEY_HOME:
+                       cursor_position = 0;
+                       cursor_form_win = 0;
+                       break;
+               case KEY_END:
+                       cursor_position = len;
+                       cursor_form_win = min(cursor_position, prompt_width-1);
                        break;
                default:
-                       if ((isgraph(res) || isspace(res)) &&
-                                       len-2 < result_len) {
+                       if ((isgraph(res) || isspace(res))) {
+                               /* one for new char, one for '\0' */
+                               if (len+2 > *result_len) {
+                                       *result_len = len+2;
+                                       *resultp = result = realloc(result,
+                                                               *result_len);
+                               }
                                /* insert the char at the proper position */
                                memmove(&result[cursor_position+1],
                                                &result[cursor_position],
-                                               len+1);
+                                               len-cursor_position+1);
                                result[cursor_position] = res;
                                cursor_position++;
+                               cursor_form_win++;
+                               len++;
                        } else {
-                               mvprintw(0, 0, "unknow key: %d\n", res);
+                               mvprintw(0, 0, "unknown key: %d\n", res);
                        }
                        break;
                }
+               if (cursor_form_win < 0)
+                       cursor_form_win = 0;
+               else if (cursor_form_win > prompt_width-1)
+                       cursor_form_win = prompt_width-1;
+
                wmove(form_win, 0, 0);
                wclrtoeol(form_win);
                mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
-               mvwprintw(form_win, 0, 0, "%s", result);
-               wmove(form_win, 0, cursor_position);
+               mvwprintw(form_win, 0, 0, "%s",
+                       result + cursor_position-cursor_form_win);
+               wmove(form_win, 0, cursor_form_win);
                touchwin(win);
                refresh_all_windows(main_window);
 
index 58fbda8fc0dc9e6df9941fe78e3127cee91da1d2..0d5261705ef5c88d162321fe1806b3342b303188 100644 (file)
@@ -89,7 +89,7 @@ void fill_window(WINDOW *win, const char *text);
 int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
 int dialog_inputbox(WINDOW *main_window,
                const char *title, const char *prompt,
-               const char *init, char *result, int result_len);
+               const char *init, char **resultp, int *result_len);
 void refresh_all_windows(WINDOW *main_window);
 void show_scroll_win(WINDOW *main_window,
                const char *title,
index a4fe923c01315205e3038b3da5b3514c6d134291..ec7afce4c88d3155d95c454915b5efb249568548 100644 (file)
@@ -43,6 +43,7 @@
 #    make oldconfig
 #
 use strict;
+use Getopt::Long;
 
 my $config = ".config";
 
@@ -112,10 +113,17 @@ sub find_config {
 
 find_config;
 
+# Parse options
+my $localmodconfig = 0;
+my $localyesconfig = 0;
+
+GetOptions("localmodconfig" => \$localmodconfig,
+          "localyesconfig" => \$localyesconfig);
+
 # Get the build source and top level Kconfig file (passed in)
 my $ksource = $ARGV[0];
 my $kconfig = $ARGV[1];
-my $lsmod_file = $ARGV[2];
+my $lsmod_file = $ENV{'LSMOD'};
 
 my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
 chomp @makefiles;
@@ -296,7 +304,11 @@ my %modules;
 
 if (defined($lsmod_file)) {
     if ( ! -f $lsmod_file) {
-       die "$lsmod_file not found";
+       if ( -f $ENV{'objtree'}."/".$lsmod_file) {
+           $lsmod_file = $ENV{'objtree'}."/".$lsmod_file;
+       } else {
+               die "$lsmod_file not found";
+       }
     }
     if ( -x $lsmod_file) {
        # the file is executable, run it
@@ -421,7 +433,11 @@ while(<CIN>) {
 
     if (/^(CONFIG.*)=(m|y)/) {
        if (defined($configs{$1})) {
-           $setconfigs{$1} = $2;
+           if ($localyesconfig) {
+               $setconfigs{$1} = 'y';
+           } else {
+               $setconfigs{$1} = $2;
+           }
        } elsif ($2 eq "m") {
            print "# $1 is not set\n";
            next;
index a509ff8f32fac8553dfb9f082a76a59984fed41a..2bd594e6d1b4115fd8647f8f64b62580eac772ae 100644 (file)
@@ -1849,6 +1849,12 @@ static void add_header(struct buffer *b, struct module *mod)
        buf_printf(b, "};\n");
 }
 
+static void add_intree_flag(struct buffer *b, int is_intree)
+{
+       if (is_intree)
+               buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
+}
+
 static void add_staging_flag(struct buffer *b, const char *name)
 {
        static const char *staging_dir = "drivers/staging";
@@ -2169,6 +2175,7 @@ int main(int argc, char **argv)
                buf.pos = 0;
 
                add_header(&buf, mod);
+               add_intree_flag(&buf, !external_module);
                add_staging_flag(&buf, mod->name);
                err |= add_versions(&buf, mod);
                add_depends(&buf, mod, modules);
index 75c5d24f1993ae009aedf2b12bd33f7dd9360b25..38f6617a2cb16c614a2ed0a854eb97b7aa12cdbb 100755 (executable)
@@ -129,7 +129,7 @@ exuberant()
        -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL                      \
        -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
        --extra=+f --c-kinds=+px                                \
-       --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'                  \
+       --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/'        \
        --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
        --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/'               \
        --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/'
@@ -151,7 +151,7 @@ exuberant()
 emacs()
 {
        all_sources | xargs $1 -a                               \
-       --regex='/^ENTRY(\([^)]*\)).*/\1/'                      \
+       --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/'            \
        --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/'   \
        --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/'          \
        --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/'
index 36cc0cc39e78e135630384e6500f4a789fe7aa2a..b566eba4a65cc16128b34152154c3ba26505b692 100644 (file)
@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
 static int d_namespace_path(struct path *path, char *buf, int buflen,
                            char **name, int flags)
 {
-       struct path root, tmp;
        char *res;
-       int connected, error = 0;
+       int error = 0;
+       int connected = 1;
+
+       if (path->mnt->mnt_flags & MNT_INTERNAL) {
+               /* it's not mounted anywhere */
+               res = dentry_path(path->dentry, buf, buflen);
+               *name = res;
+               if (IS_ERR(res)) {
+                       *name = buf;
+                       return PTR_ERR(res);
+               }
+               if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
+                   strncmp(*name, "/sys/", 5) == 0) {
+                       /* TODO: convert over to using a per namespace
+                        * control instead of hard coded /proc
+                        */
+                       return prepend(name, *name - buf, "/proc", 5);
+               }
+               return 0;
+       }
 
-       /* Get the root we want to resolve too, released below */
+       /* resolve paths relative to chroot?*/
        if (flags & PATH_CHROOT_REL) {
-               /* resolve paths relative to chroot */
+               struct path root;
                get_fs_root(current->fs, &root);
-       } else {
-               /* resolve paths relative to namespace */
-               root.mnt = current->nsproxy->mnt_ns->root;
-               root.dentry = root.mnt->mnt_root;
-               path_get(&root);
+               res = __d_path(path, &root, buf, buflen);
+               if (res && !IS_ERR(res)) {
+                       /* everything's fine */
+                       *name = res;
+                       path_put(&root);
+                       goto ok;
+               }
+               path_put(&root);
+               connected = 0;
        }
 
-       tmp = root;
-       res = __d_path(path, &tmp, buf, buflen);
+       res = d_absolute_path(path, buf, buflen);
 
        *name = res;
        /* handle error conditions - and still allow a partial path to
@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
                *name = buf;
                goto out;
        }
+       if (!our_mnt(path->mnt))
+               connected = 0;
 
+ok:
        /* Handle two cases:
         * 1. A deleted dentry && profile is not allowing mediation of deleted
         * 2. On some filesystems, newly allocated dentries appear to the
@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
                        goto out;
        }
 
-       /* Determine if the path is connected to the expected root */
-       connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;
-
-       /* If the path is not connected,
+       /* If the path is not connected to the expected root,
         * check if it is a sysctl and handle specially else remove any
         * leading / that __d_path may have returned.
         * Unless
@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
         *     namespace root.
         */
        if (!connected) {
-               /* is the disconnect path a sysctl? */
-               if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
-                   strncmp(*name, "/sys/", 5) == 0) {
-                       /* TODO: convert over to using a per namespace
-                        * control instead of hard coded /proc
-                        */
-                       error = prepend(name, *name - buf, "/proc", 5);
-               } else if (!(flags & PATH_CONNECT_PATH) &&
+               if (!(flags & PATH_CONNECT_PATH) &&
                           !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
-                            (tmp.mnt == current->nsproxy->mnt_ns->root &&
-                             tmp.dentry == tmp.mnt->mnt_root))) {
+                            our_mnt(path->mnt))) {
                        /* disconnected path, don't return pathname starting
                         * with '/'
                         */
@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
        }
 
 out:
-       path_put(&root);
-
        return error;
 }
 
index 6bc7a86d1027cbf5f78b67804448f577e869d093..d6f8433250a5a37db4543b61c1b73303f92be574 100644 (file)
@@ -2,5 +2,9 @@
 # Makefile for encrypted keys
 #
 
-obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o ecryptfs_format.o
-obj-$(CONFIG_TRUSTED_KEYS) += masterkey_trusted.o
+obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys.o
+
+encrypted-keys-y := encrypted.o ecryptfs_format.o
+masterkey-$(CONFIG_TRUSTED_KEYS) := masterkey_trusted.o
+masterkey-$(CONFIG_TRUSTED_KEYS)-$(CONFIG_ENCRYPTED_KEYS) := masterkey_trusted.o
+encrypted-keys-y += $(masterkey-y) $(masterkey-m-m)
index dcc843cb0f80de0f899ada23d8bf80d25e023e5e..41144f71d6154f612570f8f2c5243269becf68a4 100644 (file)
@@ -444,7 +444,7 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
                goto out;
 
        if (IS_ERR(mkey)) {
-               int ret = PTR_ERR(epayload);
+               int ret = PTR_ERR(mkey);
 
                if (ret == -ENOTSUPP)
                        pr_info("encrypted_key: key %s not supported",
index b6ade8945250c0b3f13913c56ee5b9686a3f39d1..8136a2d44c63ddb3a76f30f35b6780ff19b74ae9 100644 (file)
@@ -2,7 +2,8 @@
 #define __ENCRYPTED_KEY_H
 
 #define ENCRYPTED_DEBUG 0
-#ifdef CONFIG_TRUSTED_KEYS
+#if defined(CONFIG_TRUSTED_KEYS) || \
+  (defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE))
 extern struct key *request_trusted_key(const char *trusted_desc,
                                       u8 **master_key, size_t *master_keylen);
 #else
index 5b366d7af3c4dc17b595c67af3dbe99d5fd69df1..69ff52c08e97bb0eab715b1ea61c709e4f80faad 100644 (file)
@@ -102,7 +102,8 @@ int user_update(struct key *key, const void *data, size_t datalen)
                key->expiry = 0;
        }
 
-       kfree_rcu(zap, rcu);
+       if (zap)
+               kfree_rcu(zap, rcu);
 
 error:
        return ret;
index e545b9f6707210fa56b54a2e8257e57630776b36..1126c10a5e821d1d835aa0aa7d83dfba5a04028f 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/posix-timers.h>
 #include <linux/syslog.h>
 #include <linux/user_namespace.h>
+#include <linux/export.h>
 
 #include "avc.h"
 #include "objsec.h"
index ce3f481558d8682421ddf410d3adb5f4787df732..161e01a6c7eff099c166cbc919723fd0ab5e6982 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
+#include <linux/export.h>
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/selinux_netlink.h>
index 6aceef518a41fe7cd095bf8f860afe210abeb6ce..5c32f36ff70618dfb08e3040c94060238dfa44da 100644 (file)
@@ -102,9 +102,6 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 
 const char *smack_cipso_option = SMACK_CIPSO_OPTION;
 
-
-#define        SEQ_READ_FINISHED       ((loff_t)-1)
-
 /*
  * Values for parsing cipso rules
  * SMK_DIGITLEN: Length of a digit field in a rule.
@@ -357,10 +354,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
 
        rc = count;
        /*
+        * If this is "load" as opposed to "load-self" and a new rule
+        * it needs to get added for reporting.
         * smk_set_access returns true if there was already a rule
         * for the subject/object pair, and false if it was new.
         */
-       if (!smk_set_access(rule, rule_list, rule_lock)) {
+       if (load && !smk_set_access(rule, rule_list, rule_lock)) {
                smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
                if (smlp != NULL) {
                        smlp->smk_rule = rule;
@@ -377,12 +376,12 @@ out:
        return rc;
 }
 
-
 /*
- * Seq_file read operations for /smack/load
+ * Core logic for smackfs seq list operations.
  */
 
-static void *load_seq_start(struct seq_file *s, loff_t *pos)
+static void *smk_seq_start(struct seq_file *s, loff_t *pos,
+                               struct list_head *head)
 {
        struct list_head *list;
 
@@ -390,7 +389,7 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
         * This is 0 the first time through.
         */
        if (s->index == 0)
-               s->private = &smack_rule_list;
+               s->private = head;
 
        if (s->private == NULL)
                return NULL;
@@ -404,11 +403,12 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
        return list;
 }
 
-static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
+                               struct list_head *head)
 {
        struct list_head *list = v;
 
-       if (list_is_last(list, &smack_rule_list)) {
+       if (list_is_last(list, head)) {
                s->private = NULL;
                return NULL;
        }
@@ -416,6 +416,25 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
        return list->next;
 }
 
+static void smk_seq_stop(struct seq_file *s, void *v)
+{
+       /* No-op */
+}
+
+/*
+ * Seq_file read operations for /smack/load
+ */
+
+static void *load_seq_start(struct seq_file *s, loff_t *pos)
+{
+       return smk_seq_start(s, pos, &smack_rule_list);
+}
+
+static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+       return smk_seq_next(s, v, pos, &smack_rule_list);
+}
+
 static int load_seq_show(struct seq_file *s, void *v)
 {
        struct list_head *list = v;
@@ -446,16 +465,11 @@ static int load_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void load_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations load_seq_ops = {
        .start = load_seq_start,
        .next  = load_seq_next,
        .show  = load_seq_show,
-       .stop  = load_seq_stop,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -574,28 +588,12 @@ static void smk_unlbl_ambient(char *oldambient)
 
 static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
 {
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&smack_known_list))
-               return NULL;
-
-       return smack_known_list.next;
+       return smk_seq_start(s, pos, &smack_known_list);
 }
 
 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct list_head  *list = v;
-
-       /*
-        * labels with no associated cipso value wont be printed
-        * in cipso_seq_show
-        */
-       if (list_is_last(list, &smack_known_list)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-
-       return list->next;
+       return smk_seq_next(s, v, pos, &smack_known_list);
 }
 
 /*
@@ -634,16 +632,11 @@ static int cipso_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void cipso_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations cipso_seq_ops = {
        .start = cipso_seq_start,
-       .stop  = cipso_seq_stop,
        .next  = cipso_seq_next,
        .show  = cipso_seq_show,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -788,23 +781,12 @@ static const struct file_operations smk_cipso_ops = {
 
 static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
 {
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&smk_netlbladdr_list))
-               return NULL;
-       return smk_netlbladdr_list.next;
+       return smk_seq_start(s, pos, &smk_netlbladdr_list);
 }
 
 static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct list_head *list = v;
-
-       if (list_is_last(list, &smk_netlbladdr_list)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-
-       return list->next;
+       return smk_seq_next(s, v, pos, &smk_netlbladdr_list);
 }
 #define BEBITS (sizeof(__be32) * 8)
 
@@ -828,16 +810,11 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void netlbladdr_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations netlbladdr_seq_ops = {
        .start = netlbladdr_seq_start,
-       .stop  = netlbladdr_seq_stop,
        .next  = netlbladdr_seq_next,
        .show  = netlbladdr_seq_show,
+       .stop  = smk_seq_stop,
 };
 
 /**
@@ -1405,23 +1382,14 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
 {
        struct task_smack *tsp = current_security();
 
-       if (*pos == SEQ_READ_FINISHED)
-               return NULL;
-       if (list_empty(&tsp->smk_rules))
-               return NULL;
-       return tsp->smk_rules.next;
+       return smk_seq_start(s, pos, &tsp->smk_rules);
 }
 
 static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
        struct task_smack *tsp = current_security();
-       struct list_head *list = v;
 
-       if (list_is_last(list, &tsp->smk_rules)) {
-               *pos = SEQ_READ_FINISHED;
-               return NULL;
-       }
-       return list->next;
+       return smk_seq_next(s, v, pos, &tsp->smk_rules);
 }
 
 static int load_self_seq_show(struct seq_file *s, void *v)
@@ -1453,16 +1421,11 @@ static int load_self_seq_show(struct seq_file *s, void *v)
        return 0;
 }
 
-static void load_self_seq_stop(struct seq_file *s, void *v)
-{
-       /* No-op */
-}
-
 static const struct seq_operations load_self_seq_ops = {
        .start = load_self_seq_start,
        .next  = load_self_seq_next,
        .show  = load_self_seq_show,
-       .stop  = load_self_seq_stop,
+       .stop  = smk_seq_stop,
 };
 
 
index 738bbdf8d4c77ceba3ba3abfe733a90dc56cd4fb..d9f3ced8756ec4dc87492b8edecf172375843f5d 100644 (file)
@@ -101,9 +101,8 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
 {
        char *pos = ERR_PTR(-ENOMEM);
        if (buflen >= 256) {
-               struct path ns_root = { };
                /* go to whatever namespace root we are under */
-               pos = __d_path(path, &ns_root, buffer, buflen - 1);
+               pos = d_absolute_path(path, buffer, buflen - 1);
                if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
                        struct inode *inode = path->dentry->d_inode;
                        if (inode && S_ISDIR(inode->i_mode)) {
@@ -294,8 +293,16 @@ char *tomoyo_realpath_from_path(struct path *path)
                        pos = tomoyo_get_local_path(path->dentry, buf,
                                                    buf_len - 1);
                /* Get absolute name for the rest. */
-               else
+               else {
                        pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
+                       /*
+                        * Fall back to local name if absolute name is not
+                        * available.
+                        */
+                       if (pos == ERR_PTR(-EINVAL))
+                               pos = tomoyo_get_local_path(path->dentry, buf,
+                                                           buf_len - 1);
+               }
 encode:
                if (IS_ERR(pos))
                        continue;
index be838993926d74d0f1682ffdeda183ac8e8acd6e..19491ed9292f5cb58fd8e894ff6a128d15a5f290 100644 (file)
@@ -12,6 +12,7 @@
 #include <sound/core.h>
 #include <asm/macio.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include "../soundbus.h"
 #include "i2sbus.h"
 
index 8ad65352bf91367f4e4ce84e78fe786738688e4a..d1aa4218f1299ebccb813d0b8ef6c6fb9d8c3479 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include <sound/ac97_codec.h>
 #include <sound/pxa2xx-lib.h>
index 535704f77496040976f9696d18639b9dc4f77606..26422a3584ea6684e934f66b33a7f9aad8b5b762 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pxa2xx-lib.h>
 
index 978fe1a8e9f0877ece853c788a5ed371f9bdfa77..819a5c579a3975f129b2b35e67be0ad12d2780bd 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/threads.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/time.h>
@@ -1081,12 +1082,12 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
        char *names, *p;
        size_t buf_len, name_len;
        unsigned int i;
+       const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
 
        if (ue->info.value.enumerated.names_length > 64 * 1024)
                return -EINVAL;
 
-       names = memdup_user(
-               (const void __user *)ue->info.value.enumerated.names_ptr,
+       names = memdup_user((const void __user *)user_ptrval,
                ue->info.value.enumerated.names_length);
        if (IS_ERR(names))
                return PTR_ERR(names);
index 2d1ad4b0cd653171c7d175b1b3edadc29b10abf6..f03cb5444a5ae8c0d04901c5a8c2af2902ce6300 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/export.h>
 #include <linux/errno.h>
 #include <sound/core.h>
 
index 031e215b6ddeb0fb5f16acfdbbe33b6500dd984b..75ea16f35b1aa1e1db985802e923c86e28f69af3 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/minors.h>
index 601f0ebb677ba7348abb41130a1fbd28952c919d..c1e611c65c8fc3308cf6e005cc36688b164c1a55 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
index e4af138d651af950488a40d5c9ad4f1435b602b8..cf42ab5080eb59eb495fa4ae617b98085c26d057 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/string.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
index 2c041bb36ab3c177e032e16e39ee47777dce7f48..3ac49b1b7cb82ac4c6c6632691efb9d3178cb09e 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/time.h>
index 950e19ba91fca466202bcac2cc77b1efb87562fa..c0f1208bb7dfefe40fbf736b3d8e43429abe28a2 100644 (file)
@@ -26,6 +26,7 @@
 
 #undef HAVE_REALLY_SLOW_DMA_CONTROLLER
 
+#include <linux/export.h>
 #include <sound/core.h>
 #include <asm/dma.h>
 
index 240a3e13470dfe3e718dd9fdc22fdadf8900b763..26edf63b265f439ba7bf5636ffa0c0928cac8db7 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/input.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/jack.h>
 #include <sound/core.h>
 
index 1161158582a6ce112ab3a7329b2ad09507b57979..66a278d0b04e76937c2e14c263829edd232890ce 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 
+#include <linux/export.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <sound/core.h>
index eb9fe2e1d291850f62a0db393535a3f394d4e9a0..465f0ce772cb594dabe34e3d835c5766ec6d873b 100644 (file)
@@ -20,6 +20,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
+#include <linux/moduleparam.h>
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
index 1b5e0c49a0addeb2698df665961773893690ced2..18297f7f2c55825ed8fe7737a965d271ad6f30dc 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/string.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/control.h>
index 23c34a02894b77831638e89a65ae17f7df607633..3cc4b86dfb7ebb97799e861bfd8db3bfd57b581e 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/vmalloc.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/math64.h>
 #include <linux/string.h>
 #include <sound/core.h>
index ee9abb2d9001153110fc021131aebc24ab86dfe0..8928ca871c223f17da58f086a75e3b52d1edcf11 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
index 95d1e789715f13b0ae9185dc213da64728d43c76..3420bd3da5d70ffec570e058d84b20f39aab49b8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/math64.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/info.h>
index 150cb7edffee44948cd3600b75b5cb37de1c9484..957131366dd93b47300832ec6b8c65fa821aca4f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/info.h>
index 88f02e3866e0f355fde874e94099e990dcd79f4d..9c9eff9afbac85030effbe23b1aa1b6e117912f2 100644 (file)
@@ -20,6 +20,7 @@
  */
   
 #include <linux/time.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #define SND_PCM_FORMAT_UNKNOWN (-1)
index d7d2179c03636a4bae1bb513387001d932ea660a..25ed9fe41b89ceaf245278438c7113bc89ddc0f3 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/file.h>
 #include <linux/slab.h>
 #include <linux/time.h>
index 849a0ed95054d21826f49b3e274ea98eced5d340..ebf6e49ad3d461ba843131d903b0c66cc7840ba4 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <sound/rawmidi.h>
 #include <sound/info.h>
index a1f1a2f00ccb6f1398a17bcab473908420b82a24..8d4d5e853efec94716cf5585a94321c097144eb9 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/minors.h>
index 69cd7b3c362d19f4b0ac989b8bc107e49e59ff1b..e3cb46fef2c76b4cca8d67a52f212deb41598caf 100644 (file)
@@ -28,6 +28,7 @@
 #include "seq_oss_timer.h"
 #include "seq_oss_event.h"
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
 
index ee44ab9593c01819cc5f7fd0278801ca2cab0343..c5b773a1eea9324ec7a1c70a0a7dc926031f87a3 100644 (file)
@@ -24,6 +24,7 @@
 #include "seq_oss_midi.h"
 #include "../seq_lock.h"
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 /*
index 119fddb6fc99cfd5b6561bcbcc6486e1313d45ea..9d8379aedf4054cd5a1acde9e6140d9e2a604e95 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 
index f2436d33fbf7182a62ae1bc1744a41f8bdb385ce..4dc6bae80e15b92a005325f845f0cc16fcd67ce0 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/minors.h>
index 1f997675c893bbeb50fd01c530007540bc7a86fd..5cf8d65ed5ef2cc9fe8cbce1d7275fc7b0745b14 100644 (file)
@@ -37,6 +37,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/seq_device.h>
index 1d7d90ca455e201b4635f2ec553b07075a4292a9..b9b2235d9ab1075115cd01dbce8abcbd266dcb2c 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "seq_clientmgr.h"
 #include <sound/initval.h>
index 201f8106ffdd9b36224a9c798997457db65b92cc..acf7769419f06972cfb179991ca6754fda6df531 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <sound/core.h>
 
 #include "seq_info.h"
index 54f921edda793aab4948b0c72259528ee0885d9d..2cfe50c71a9d3d62b580f5132a8faf154689b30d 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/export.h>
 #include <sound/core.h>
 #include "seq_lock.h"
 
index 7f50c1437675c8882b7ba943c31f6ae96b460f31..f478f770bf5213f11663bad4041ad256664e6fe6 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <sound/core.h>
index ebaf1b541dcda7e2ccc39bc62416342cde6f8ead..64069dbf89ca383bfb8500cedf90ed9959f29fa4 100644 (file)
@@ -30,7 +30,7 @@ Possible options for midisynth module:
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
index 07c663135c62d87d054d389e7a84320820497b04..6f64471ddde3df24811e3c1d1b5998780843bbbe 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/seq_kernel.h>
 #include <sound/seq_midi_emul.h>
index b5d6ea4904c091c9b2733308d380cdaa995fe98d..37db7ba492a63e91d08dd378773c6e7a36e1d4c0 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/seq_kernel.h>
 #include <sound/seq_midi_event.h>
index e12bcd94b6db29c074b3a66b692a5094cab11581..9516e5ce3aadd8cb50e857a187a469284cb91550 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <sound/core.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include "seq_system.h"
 #include "seq_ports.h"
 #include "seq_clientmgr.h"
index c38b90cf3cb07ac6c74514cfa807590dd6c92bcf..8ce1d0b40dce1f0821f9cf9c144fed1ed27e413d 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include "seq_system.h"
index 86e7739269ca2f4899eaeeb057a60f4bef556459..4b50e604276d8dec6adb47bee6b870a1fe52f8c0 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
index 1c7a3efe17782b3f4a830efdc815f333b2aee3d6..828af353ea9f17f652d2c7ae154ed550c3c25845 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/device.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
index 0c164e5e43222b1787463fbb265084b4142d4953..c700920430618f94a0dc0f7957ed75b813481507 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include <linux/init.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <sound/core.h>
index 67ebf1c21c043a61dc0b51012f00778612af7b45..8e7561dfc5fc97f4d650a3b8d35bb52b2804f9d0 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <sound/core.h>
 #include <sound/timer.h>
index a39d3d8c2f9c9edb53025953c102f5d5cdb89aa3..130cfe677d60a1ef8bf996c0a61bc0dea35a9da6 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tlv.h>
@@ -51,6 +52,7 @@ struct link_slave {
        struct link_ctl_info info;
        int vals[2];            /* current values */
        unsigned int flags;
+       struct snd_kcontrol *kctl; /* original kcontrol pointer */
        struct snd_kcontrol slave; /* the copy of original control entry */
 };
 
@@ -251,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
                       slave->count * sizeof(*slave->vd), GFP_KERNEL);
        if (!srec)
                return -ENOMEM;
+       srec->kctl = slave;
        srec->slave = *slave;
        memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd));
        srec->master = master_link;
@@ -332,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol,
 static void master_free(struct snd_kcontrol *kcontrol)
 {
        struct link_master *master = snd_kcontrol_chip(kcontrol);
-       struct link_slave *slave;
-
-       list_for_each_entry(slave, &master->slaves, list)
-               slave->master = NULL;
+       struct link_slave *slave, *n;
+
+       /* free all slave links and retore the original slave kctls */
+       list_for_each_entry_safe(slave, n, &master->slaves, list) {
+               struct snd_kcontrol *sctl = slave->kctl;
+               struct list_head olist = sctl->list;
+               memcpy(sctl, &slave->slave, sizeof(*sctl));
+               memcpy(sctl->vd, slave->slave.vd,
+                      sctl->count * sizeof(*sctl->vd));
+               sctl->list = olist; /* keep the current linked-list */
+               kfree(slave);
+       }
        kfree(master);
 }
 
index 4067f1548949b83eb37d0d564e4b1f7a724217a1..d83bafc5d8b5c6b8395676c9eb5eaf9538ae7f0b 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/control.h>
index 7f41990ed68b74f557caa6b180cd1b11db3ad2ef..97f1f93ed275d632344a7c9a9e47e57c6687e0c6 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/wait.h>
 #include <linux/hrtimer.h>
 #include <linux/math64.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tlv.h>
index 2c7a7636f47296d67a281c9a0e21c7e04e203799..2ee82c5d9ee54b609aec2bd1ff09cc7836b92a57 100644 (file)
@@ -34,7 +34,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 
 #include <linux/platform_device.h>
 
index 1c02852aceea771f82f9d4a9b424c86bc8e93f83..257569014f237162bfe605efd0c4ff208c6a6ea6 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/pnp.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/mpu401.h>
 #include <sound/initval.h>
index e91698a634b2ca21d64f35df0831df7d72a0070d..1cff331a228ef87831760b6635025c23f94937e5 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <sound/core.h>
index 1eef4ccebe4b8b8afbf5d71084a51ac78400b0c7..76930793fb69155a10c9c6ee55ac04c2caa07cdb 100644 (file)
@@ -52,6 +52,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
index 8539ab0a0893db2933e39732f7073be3d2c1f166..f24bf9a06cff385e7a8643817dd214582ad6c0a2 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/parport.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 6e31e46ca3934f46b8a8cef2ffa8215a69d3c8e8..33d9a857a2625e443808df63e0d0092632871562 100644 (file)
@@ -26,6 +26,7 @@
 #include <sound/opl3.h>
 #include <asm/io.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
index ade3ca52422ef81ca639698c739dee6863185670..c1cb249acfaa66ffed8e9a05b5f070533df39fd5 100644 (file)
@@ -18,6 +18,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/export.h>
 #include "opl3_voice.h"
 
 static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
index 2d33f53d36b8227a0ed520a7ec236f02b2df944c..723562e34fcc7414ab4b6ca7d918bca1015768b2 100644 (file)
@@ -25,6 +25,7 @@
 #include "opl3_voice.h"
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
index 301acb6b9cf9af792ddc33160989dcb8dbcc8769..742a4b642fd9ea19adfcd195244c8fbc9bfa5fb1 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
index f07e38da59b852748d31e3dfaf91140e943d57d6..b953fb4aa298031a294a7b673a38f27037438f92 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <asm/io.h>
 
 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
index df850b8830a52473819c4b7dd31777bfef25f160..9b824bfc919db5baef8d1aee976218b903599c83 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "opl4_local.h"
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <sound/info.h>
 
 #ifdef CONFIG_PROC_FS
index 43d8a2bdd280dc7bdc90e5539a1a9916bf79cba9..99197699c55a63f50bd33f45d454a40f4dd5cf70 100644 (file)
@@ -34,6 +34,7 @@
 #include "opl4_local.h"
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
index f165c77d62736c64fad6289e8bdde41e50ca4c5c..946a0cb996a9a09a1b71315fbbd17f1aa8b90602 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/initval.h>
index f2b0ba22d9cec1b2de13c0b184e30f0f035e610f..f664823a9635873e8d5a4c268c47313a9457adea 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/rawmidi.h>
index fc1d822802c360b5a072ac88ea23bf3658ef32fd..85aad43f0b1efd04717b9cfa8b14971abdc199fd 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #include <sound/initval.h>
index f4cd49336f336866e36b6814206fdaf0ff9da226..d79d6edc0f52b50689d9d7cf21ead9353414d9b4 100644 (file)
@@ -45,7 +45,7 @@
 #include <linux/wait.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/seq_kernel.h>
 #include <sound/seq_virmidi.h>
index 19c6e376c7c781abe0ed587da593a50ee6130d74..b8e515999bc28fda8fac1e04c0f166855bb64b81 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/asoundef.h>
index f7a6fbd313e31aa9059570d3b6c64a8471b97fe6..4a1fae99ac553e69bae361bce765ee39f82ebf97 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
 #include <sound/vx_core.h>
index ffe20b877e9f2d9ba305f6b0ed107291bb954d97..5f17b77ee15222ad0e43c3c6b5b13688b386417f 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
+#include <linux/export.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
index 3c61ca2e6152472c81e6d59fca0a7e6c3bd1dbca..ea1506679c6650753b2efea810e77d85c9ddb0f5 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/firewire.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include "packets-buffer.h"
 
index 04ae8704cdcdac72f515ddc94077a99b28b38710..6c2dc3863ac00c65b327ee58a0a7d281fb464740 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/bitrev.h>
+#include <linux/module.h>
 #include <asm/unaligned.h>
 #include <sound/core.h>
 #include <sound/control.h>
index eb7c7d05a7c123e30153b1d0de240bc7bd870277..4677037f0c8e4710fe020c8a5c71b1a971555b37 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <sound/core.h>
index c424d329f806dbba3d32d0958fd4450d5042b88f..dde5c9c92132a0f9b353915fc4f33cc9b1aa99a2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index d9fb537b0b947bb1a44f52d06f6ac80a97d75f99..fdf3c1b65e388414c995a597ef2b351b4ec2a220 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index 2cad2d6125186431643dd9a04bcc840f729e67e4..b4b2a51fc117a98b667e10de335a86c5e2c1ce00 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index 57ccba88700d68bacc493d01d030175158f40196..cef813d23641afcd39b56a57c5fc8058cb99bfb0 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tlv.h>
index 797d3a6687ebf7557308fd5a1d14201a230e8dbe..9fa390ba1718566de78be2763d48fb316ee534a7 100644 (file)
@@ -24,6 +24,7 @@
 #include <sound/tlv.h>
 #include <sound/i2c.h>
 #include <sound/pt2258.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Jochen Voss <voss@seehuhn.de>");
 MODULE_DESCRIPTION("PT2258 volume controller (Princeton Technology Corp.)");
index 484a35b3715f6142a5d806c6b798651a71b789fd..6b68c8206805107a8b6cac329f92aa2cb25b3bb7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/io.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/version.h>
index 0e3a9f2c5297658dd001782734dad639e9daf811..2d22310dce0562f5caf6864d16bd512296febf67 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/tea6330t.h>
index a87a2b566e19e4fbce67cb0a90aa88c5e53c1968..cd44c74207d8e294f2d235dd398835be9fc5bb0e 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/ad1816a.h>
index 4beeb6f98e0eab9b06d291aa4ac3ea9451f43d95..34ab69bdffc0cf2ea674875f9a1ec8083c4c7e84 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/initval.h>
index 706effd6b3cd8d800c43bc001e7a37ae16894c80..fc5b38fd2652d402678692fb02be2e73d250fccc 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/wait.h>
 #include <linux/time.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/mpu401.h>
index b7bdbf30774025e3bbc61ef0a01852a68530bf49..e55f3ebe87b9298fcec4b0dd0d04c2052b441141 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/wss.h>
index dca69f80305fb8f4ecdd4ec47014dd6de093c61d..c94578d40b1aa66d431fc7eb0eaae93f62dfe4c4 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/opl3.h>
index 409fa0ad7843b17f518b7b75678fed01f794f242..6d81fa75c33d4f23f98d5596a3685a03759906cc 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/mpu401.h>
index 0dbde461e6c1b0050f3884fa76b6f654076fbdb0..f5a94b6e6245cc9e9d89c6d0e7ac7cb2d21586df 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/mpu401.h>
index 5493e9e4bcd5dc1ed38b327bdfb2668d4cd5f444..9a1a6f2c44842c114c770fae0473fd9d763bbbd8 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/isapnp.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/es1688.h>
index d3eab6fb08660d6fe60671d03e7cc754e1acfc64..1d47be8170b59928f758f13bad7106c3959f79e8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/es1688.h>
 #include <sound/initval.h>
index bf6ad0bf51c63107e3489fcf8dece22937857edc..98e3ac1cfa08b64edfe3ecc0f7ab08ce1586f127 100644 (file)
@@ -82,7 +82,7 @@
 #include <linux/isa.h>
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 
 #include <asm/io.h>
index 3167e5ac3699bd72905ea38e83f93cc7a9ee3230..4490ee442ff47e4c92e20aabb948870c30f3c9ed 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/control.h>
index c3c028a4a46b5a5b7c0b3c25c838a05754b6f4ce..3dd841ae708a270bef6b84d9e02e9e4ccb215a43 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <linux/time.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #define __GUS_TABLES_ALLOC__
index 086b8f0e0f94320fb3763e962918265750eaa1b3..d7296500bce8c18ac2a64c8a354a20be73879334 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
index c4733c08b60b2d7c3b17e6f2d701ab0355591b89..597accdb15d2e9f45bd6dfc0287eb2d83f1f1219 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
index c43faa057ff6247219ac37b2ffa0daeba1a2a231..933cb0f4c549b5a9333757c6ac07aefa4c24da1c 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
index 5f869a32b48ce9427b2eedffc1b7de2d3b45efd8..8e7e19484dacb75a86888bdcb3e94a7e29d839cf 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
index 3a1526ae1729ace425a340b11a5cc1aa015d507c..1cee18fb28a8941975e0caf752b9c65102053761 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/io.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
index 787495674235ecf2e5b9708d2b98d585282b0a77..ffc67fd80c23da47f770042b833b425cabbf5ff6 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 
index 494058a1a50282f111d18bd80cf85a33f8b3e814..1de59d4414260a6c6a20b9454c112eb99d0f08e4 100644 (file)
@@ -16,6 +16,7 @@
  ***************************************************************************/
 
 #include <linux/io.h>
+#include <linux/export.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
index bbafb0b543eadebadae7b18b512d94a98aa8875a..64a9a2177f4b375f14d1857eed8240a13984864b 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/mpu401.h>
index d94d0f35cb765c92ff503f2d9547ee4a6020a45e..3785b7a784c98ae3b0e9107f78b706139f0a4f06 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/pnp.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
index 6dbbfa76b440a4cf47f79f31430084dcc2830f73..97871bebea90304d49084716675f3cc7edd5446e 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
index 5d61f5a29130eed6ce0b7c68e6d2a5dfc3c6a340..71887874679c1ae7d93b436a7998e86c5717e7ba 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/export.h>
 #include <linux/delay.h>
 #include <sound/core.h>
 #include <sound/emu8000.h>
index 9a3c71cc2e07c69e832d04583ef1394a715a7a04..344b4355be1cd79b898227e5a39661129227f3e9 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "emu8000_local.h"
+#include <linux/export.h>
 #include <sound/asoundef.h>
 
 /*
index c99c6078be3376fa792f8b335e31f57a80a7c221..e09f144177f502f6176139e3e2258890ae88a560 100644 (file)
@@ -22,6 +22,7 @@
 #include "emu8000_local.h"
 #include <asm/uaccess.h>
 #include <linux/moduleparam.h>
+#include <linux/moduleparam.h>
 
 static int emu8000_reset_addr;
 module_param(emu8000_reset_addr, int, 0444);
index 0c7905c85b760a287ee79242f40c9d66b95b00eb..4e3fcfb15ad4a98eea8c06d97b77e1655e469d50 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "emu8000_local.h"
 #include <linux/init.h>
+#include <linux/module.h>
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe");
index 237f8bd7fbe422f6676402e9632b278289f7b223..115c7748204ff30efeecf53e863d4bf882209100 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/pnp.h>
 #include <linux/err.h>
 #include <linux/isa.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/sb16_csp.h>
index bdc8dde4e4a219ab09736a1f9455207f63dfa3c1..c1aa21edcb653b78dc664e97e75db7bd68bbe834 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/info.h>
index 2a6cc1cfe945a6f731690c06b97026b1e2ef1d65..0bbcd4714d28c12b8cf63d10d70045e3cd3cccd3 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/time.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/sb16_csp.h>
index 2259e3f726a7c257cf6b51ab728cebf8d9e83a2b..453ef283491df1248889916ba53126aaa4438ea9 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/ioport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/opl3.h>
index 7d84c9f34dc90cf491a001acf1bca64740ac9a3e..24d4121ab0e06a7c083cfeb7ba8486fd91b4217e 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/time.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 
index d2e19215813e3f9de145f068108a7c75857547ad..3ef990602cdd63b84625bdeda3f5bc201923e58e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/initval.h>
index f2379e102b63e6a29503a3c1df24c4d96a3cd456..b4a6aa960f4b6718d70dacdbdb1a745589564d1b 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/firmware.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/wss.h>
index 87142977335a58051bac5e339a75d1a0fc9cfa76..150b96b3ea106bfc0d6a42b8216a26c8f7379111 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/err.h>
 #include <linux/isa.h>
 #include <linux/pnp.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/opl3.h>
index 657e2d6c01ac55fcf56f047b71632139304aad22..e51e0906050b59ff09f25b450d397031ff34d921 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <sound/core.h>
 #include <sound/snd_wavefront.h>
index 4fb7b19ff393292480da357a845f8420919bd161..405f8b6a58b53db482376efd456c6e2ddaf6e2a3 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/firmware.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/snd_wavefront.h>
 #include <sound/initval.h>
index 7277c5b7df6cd750f3a39842aef8eec2157a8b14..49c8a0c2442c3f578077ea6e94781d8e8b7daef9 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/wss.h>
 #include <sound/pcm_params.h>
index 7567ebd719139b4624a0924daa6a690a185eba75..3f3ec0bec0671675de52887586f9f672f06d4431 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index 453d343550a880ae2480337a3ab7c055e001959a..2e6c85894e0be4481bf4d37994f4abfb5e21f780 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/sgi/hpc3.h>
 #include <asm/sgi/ip22.h>
index 717604c00f0add6bcab218e9b17e4de9dc6efcf7..69425d4c91fd1522e517afeb4a7524c70c2a8eb3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/ip32/ip32_ints.h>
 #include <asm/ip32/mace.h>
index 7f4d619f4ddb06f8be256f256879ebe590ba1088..fac51eef2725d9ad7e64727a6dcb6f02e20019f9 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 48cbda9378c5fc2ed4b295f7731c44ae1a11e58c..f1488fc176d5fae3ded6a27dbf81f311b84f4d7b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 201503673f25a06b9665667d27255ea0cd5087f0..6e311184bb10213106439c2dc006d64677d5ce9f 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/interrupt.h>
 #include <linux/compiler.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index fd135e3d8a84ef3c96bd9c35cd41f62c78256a3f..cadf7b962e3001956db1f9035a1da0e4d7dd228b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/ak4531_codec.h>
index b444b74d9dcf440e1b0c2a427a407ed0d3df9dcd..ef85ac5d9007aefb8ec27191ed7ec2a3158ab6bb 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 736c8e93db1f69454d070606fcb04d1395d4179a..8dc77a0a5d8b992ba91c6b9107cecb110b002849 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
index 04628696eb082adadcef4b6d2b40c21d5195b304..28ef40e01cc2e0f478aa9231678a93cdcea9cd06 100644 (file)
@@ -69,7 +69,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index eae62ebbd2952d3c0559a08dc7989247c52d56c9..f4b9e2b7ae87ae1df0b5dfa374c1e2528b2232b7 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index a32502e796de937946b1e1b2c9b9d3318441049f..f6b9517b4696e1070ccdc9ef3aee9773dfd628f0 100644 (file)
@@ -33,6 +33,7 @@ Common Linux HPI ioctl and module probe/remove functions
 #include <asm/uaccess.h>
 #include <linux/pci.h>
 #include <linux/stringify.h>
+#include <linux/module.h>
 
 #ifdef MODULE_FIRMWARE
 MODULE_FIRMWARE("asihpi/dsp5000.bin");
index 537e0a2cc68a99ed5bb8c7c6da7eae6e046b33cb..15e4e5ee3881859d2910674256525e6da65496e6 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index 45df275c8248e25c8790061bcfea3afb5f7d8e5f..57bf8f4bc7a8dd3e5feb2d3a39274b2313bbbbd0 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
index a38469986885e0bd1bbfd248738463445fe783cb..dc326be58c4b59d7f19060bde057b2e2e3d0d14b 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <sound/initval.h>
 
index e291aa59742e7c31c85e8f220a5248c661916c80..c07c792bde8d27a8ad8c6627ac0c8de784c2608e 100644 (file)
@@ -34,6 +34,7 @@
 #include <sound/core.h>
 #include "au88x0.h"
 #include <linux/gameport.h>
+#include <linux/export.h>
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 
index f8569b11331be0a07f497a428d90228808d2599c..7a581151db0d6d2848e556f5092d0f6296d9316b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index d24fe425e87f4500c87059c56557a962ad1e8192..bc1e6830b50db25c620a8660d925e93995a1e01d 100644 (file)
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/control.h>
index 39180335c23774337e79e07e16d974bd10e7810b..c1c2d0c1c7f08a499e9bc97a44c7a3e6c8572b02 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/bitops.h>
 #include <asm/io.h>
 #include <sound/core.h>
index 061b7e6545866e64c5384da0df44a3644db6b064..fe99fdeaf15fcac90c7024d0c0ada7917fa096ac 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/initval.h>
index da9c73211eca7cabe78aee41bb0d5abc3584716f..954c9934748a666026aac171726d5f29d9dce6d3 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/info.h>
index 07f04e390aa15697a114203d901a064d1e706327..a6c6c5c53af905a04159da4b43dc32ad034d9c2a 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
index 1af95559aaaa56fef9dac61e0369a0514c545599..a4ecb40f8507dc70d47f2f839a9e2200f7a9ec61 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/pci.h>
 #include <linux/time.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/cs46xx.h>
 #include <sound/initval.h>
index 9546bf07f0d130a73d52b8a9778fe8cd44902d8c..4fa53161b0944fd6b308fcc928e73db1d628e718 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/slab.h>
 #include <linux/gameport.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 
 
 #include <sound/core.h>
index a4669346d14651efff06b4875718b5967b7f8e17..958f4949e973323d3fd9ed7cb2b9907b3d615683 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 10d22ed5fece89e2dd6982484833db3c0dd5efcc..b8959d2c804b766196c55d748528a5531c60806a 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include <sound/control.h>
index e083122ca55af550f6d4b72e6d5cea5c8c2e1a05..dbf94b189e7576b6e8a3194c5612b0397e6060ee 100644 (file)
@@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
                struct cs5535audio_dma_desc *desc =
                        &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
                desc->addr = cpu_to_le32(addr);
-               desc->size = cpu_to_le32(period_bytes);
+               desc->size = cpu_to_le16(period_bytes);
                desc->ctlreserved = cpu_to_le16(PRD_EOP);
                desc_addr += sizeof(struct cs5535audio_dma_desc);
                addr += period_bytes;
index b259aa03a3a90535fe3551bece04bb0bb918b1ed..33931ef5e129b046b5bb9e5c76c3e0070deef04c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/moduleparam.h>
 #include <linux/pci_ids.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "ctatc.h"
index 43c7e12bc05d0fdabdadbae34701bbfe5436ce20..d47e72ae2ab35d098619af1665e0fe4b4f132bf0 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 95b03306e02685fec156e7907bf3a3a87e1bf7f7..413acf702e3b0ee35a5d880a65ccdf74337d0ac0 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 8723c40183e6de331060b74cb55e7eb74204c604..1ec4edca060d26bb77e2ed8055076ddee063f111 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index d7306980d0f1181053342d450a7e7521ae5a509c..9fd694c61866feec00f6f018148c1297db42dbc7 100644 (file)
@@ -16,6 +16,8 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <linux/module.h>
+
 MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>");
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver");
index 0058c67115df0344aa7465fc0f6113fd15df1d74..039125b7e47528fe319a96771f0c1b619254b419 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 14e4925e76cc204c541995a661d78a6c7252f558..5e966f6ffaa320fca6a79e109d26ee0b3a5826c0 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index f416b154f1461a05eebea4b1694db0d45b8ac160..c166b7eea268ec360dba1edaff922cfe28362a08 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index e594a3b2766e2e846a6669c90f2a8a1b0e2dc411..a3ef3b992f40c6fb8578fe72193593b7b4a4541b 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index f0d00bfceee58147759aefa2d9aa88a94d995126..f516444fc02d7033e5be65a0294e29e6c215f7b3 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/slab.h>
index 1af0037304c6c7b31ee1af96b396bdd15e8aaa62..c22c82fd1f99f4407b78b581a814a0292b4b9031 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 0b51163452b5a25428a4b11d04b1de50196609f5..86cf2d071758eac50c36a18f3f7c00b28e3aa3bc 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/slab.h>
index 3f63ab8dfff3f707ad965a8616458fd71d8fd484..6a027f3931cc6381d8fe92014b5f75be6b4a09a0 100644 (file)
@@ -49,7 +49,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 28313724447283e24991271243d1c255aec60688..96a5991aca8f58ae9012ec82c8bfe5c8307da3c5 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index eddaeb4da50ebd9e4db04b7c337badbe66625706..b8ce27e67e3ab18ad4c9440f1156c0ef6818e66c 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index 0364011c237d0b68e9a58bfb6425bf396cb6af86..1283bfb26b2e7d19c85befe639e4504c13cacbf5 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index a9c45d2cdb13706a150210b6f7b7c9a89e81f7ee..eaa198e122c089415418c9104b76a5fbd4106bb1 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 #include <sound/initval.h>
index 7ef949d99a50a551d2e81b85175e01d96fa18728..a0afa5057488895b9e5710ccc57017db6d21e6d4 100644 (file)
@@ -18,6 +18,7 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/export.h>
 #include "emu10k1_synth_local.h"
 #include <sound/asoundef.h>
 
index fcd4935766b2416ee154a935d6dc77e1b91ea2ea..6a3e5677f5916ddcf0ab40561ca74e2c3f0bcad9 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
index ad7b71491fc49cd32a9d08f8abbf3c5e4938485e..4c41c903a840b5a6d3f802970b6ced5246b54462 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "emu10k1_synth_local.h"
 #include <linux/init.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Takashi Iwai");
 MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth");
index d4fde1b4b093af92c11a798e34b53708cb52fe36..2228be9f30e6a1e4184bbe8033d9256c7cb7f9f7 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index 5ef7080e14d090c2c83ea5b6edb0705f0e09a249..e4fba49fee4a9cd633e0968203832ac7a1dbc4fe 100644 (file)
@@ -29,6 +29,7 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include "p17v.h"
 
 unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
index c250614dadd0c9c2d0ed3dc4cdfdca7a8148332b..4f502a2bdc3c51759ef26a4c4f80c858cc6192f9 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/gfp.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
+#include <linux/export.h>
 
 #include <sound/core.h>
 #include <sound/emu10k1.h>
index 20b8da250bd087190717e0f9774f9e8939e20a79..101e7cb79cb260dd8f669cda3f952e5ad64a18b2 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include <linux/time.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
index f02e2f8d712270782db072da7fa8201a230e8441..d085ad03efe823de724fa18be0d846988172f9b1 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
 #include <sound/core.h>
index 718a2643474e5bbb8249b639be2d55d6b7218752..04cc21f5d014125597370ccf3a01b96ccfa9a396 100644 (file)
@@ -52,7 +52,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
index 407e4abc43568ee4e728f77b72ee39a645ebee23..297a151bdba99e5eba6caef1b44f9a962be237fd 100644 (file)
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/input.h>
 
index 136f7232bb7cf0cc568cfff17e89c2334486cde1..ec05ef5a5abf0c5aae21c1a18ed72403efb74094 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/tlv.h>
index 29714c818b53b9387609b67b409e7b15bf9ea2ef..60738e52b8f9becb3ccd74786a2326748df11cb9 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include "hda_beep.h"
 #include "hda_local.h"
index 1715e8b24ff02048036aea077b96b07f610ba8c1..4562e9de6a1ab0dc7015e28d7be14c2eafa5a6b3 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include <sound/asoundef.h>
@@ -2330,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec)
        return 0;
 }
 
+typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
+
+/* apply the function to all matching slave ctls in the mixer list */
+static int map_slaves(struct hda_codec *codec, const char * const *slaves,
+                     map_slave_func_t func, void *data) 
+{
+       struct hda_nid_item *items;
+       const char * const *s;
+       int i, err;
+
+       items = codec->mixers.list;
+       for (i = 0; i < codec->mixers.used; i++) {
+               struct snd_kcontrol *sctl = items[i].kctl;
+               if (!sctl || !sctl->id.name ||
+                   sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
+                       continue;
+               for (s = slaves; *s; s++) {
+                       if (!strcmp(sctl->id.name, *s)) {
+                               err = func(data, sctl);
+                               if (err)
+                                       return err;
+                               break;
+                       }
+               }
+       }
+       return 0;
+}
+
+static int check_slave_present(void *data, struct snd_kcontrol *sctl)
+{
+       return 1;
+}
+
 /**
  * snd_hda_add_vmaster - create a virtual master control and add slaves
  * @codec: HD-audio codec
@@ -2350,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
                        unsigned int *tlv, const char * const *slaves)
 {
        struct snd_kcontrol *kctl;
-       const char * const *s;
        int err;
 
-       for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
-               ;
-       if (!*s) {
+       err = map_slaves(codec, slaves, check_slave_present, NULL);
+       if (err != 1) {
                snd_printdd("No slave found for %s\n", name);
                return 0;
        }
@@ -2366,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
        if (err < 0)
                return err;
 
-       for (s = slaves; *s; s++) {
-               struct snd_kcontrol *sctl;
-               int i = 0;
-               for (;;) {
-                       sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
-                       if (!sctl) {
-                               if (!i)
-                                       snd_printdd("Cannot find slave %s, "
-                                                   "skipped\n", *s);
-                               break;
-                       }
-                       err = snd_ctl_add_slave(kctl, sctl);
-                       if (err < 0)
-                               return err;
-                       i++;
-               }
-       }
+       err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
+                        kctl);
+       if (err < 0)
+               return err;
        return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
@@ -4027,9 +4046,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
 
        /* Search for codec ID */
        for (q = tbl; q->subvendor; q++) {
-               unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
-
-               if (vendorid == codec->subsystem_id)
+               unsigned int mask = 0xffff0000 | q->subdevice_mask;
+               unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask;
+               if ((codec->subsystem_id & mask) == id)
                        break;
        }
 
@@ -4751,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
        memset(sequences_hp, 0, sizeof(sequences_hp));
        assoc_line_out = 0;
 
+       codec->ignore_misc_bit = true;
        end_nid = codec->start_nid + codec->num_nodes;
        for (nid = codec->start_nid; nid < end_nid; nid++) {
                unsigned int wid_caps = get_wcaps(codec, nid);
@@ -4766,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
                        continue;
 
                def_conf = snd_hda_codec_get_pincfg(codec, nid);
+               if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+                     AC_DEFCFG_MISC_NO_PRESENCE))
+                       codec->ignore_misc_bit = false;
                conn = get_defcfg_connect(def_conf);
                if (conn == AC_JACK_PORT_NONE)
                        continue;
index 755f2b0f9d8e427b8401d4edb871ae5fa694411a..564471169cae72ada50a63e0f2e920964d60d107 100644 (file)
@@ -854,6 +854,7 @@ struct hda_codec {
        unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
        unsigned int pins_shutup:1;     /* pins are shut up */
        unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
+       unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        unsigned int power_on :1;       /* current (global) power-state */
        unsigned int power_transition :1; /* power-state in transition */
index 1c8ddf547a2dde5b1426fdfb6d26261ea35e6872..c1da422e085a5230d8b7eb837925772b11ea4328 100644 (file)
@@ -297,10 +297,18 @@ static int hdmi_update_eld(struct hdmi_eld *e,
                                        buf + ELD_FIXED_BYTES + mnl + 3 * i);
        }
 
+       /*
+        * HDMI sink's ELD info cannot always be retrieved for now, e.g.
+        * in console or for audio devices. Assume the highest speakers
+        * configuration, to _not_ prohibit multi-channel audio playback.
+        */
+       if (!e->spk_alloc)
+               e->spk_alloc = 0xffff;
+
+       e->eld_valid = true;
        return 0;
 
 out_fail:
-       e->eld_ver = 0;
        return -EINVAL;
 }
 
@@ -323,9 +331,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
         * ELD is valid, actual eld_size is assigned in hdmi_update_eld()
         */
 
-       if (!eld->eld_valid)
-               return -ENOENT;
-
        size = snd_hdmi_get_eld_size(codec, nid);
        if (size == 0) {
                /* wfg: workaround for ASUS P5E-VM HDMI board */
@@ -342,18 +347,28 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
 
        for (i = 0; i < size; i++) {
                unsigned int val = hdmi_get_eld_data(codec, nid, i);
+               /*
+                * Graphics driver might be writing to ELD buffer right now.
+                * Just abort. The caller will repoll after a while.
+                */
                if (!(val & AC_ELDD_ELD_VALID)) {
-                       if (!i) {
-                               snd_printd(KERN_INFO
-                                          "HDMI: invalid ELD data\n");
-                               ret = -EINVAL;
-                               goto error;
-                       }
                        snd_printd(KERN_INFO
                                  "HDMI: invalid ELD data byte %d\n", i);
-                       val = 0;
-               } else
-                       val &= AC_ELDD_ELD_DATA;
+                       ret = -EINVAL;
+                       goto error;
+               }
+               val &= AC_ELDD_ELD_DATA;
+               /*
+                * The first byte cannot be zero. This can happen on some DVI
+                * connections. Some Intel chips may also need some 250ms delay
+                * to return non-zero ELD data, even when the graphics driver
+                * correctly writes ELD content before setting ELD_valid bit.
+                */
+               if (!val && !i) {
+                       snd_printdd(KERN_INFO "HDMI: 0 ELD data\n");
+                       ret = -EINVAL;
+                       goto error;
+               }
                buf[i] = val;
        }
 
index a63c54d9d767a4219890c7a40b9741c6ce72da73..431bf868711ec1fc1749c3910d940822200b1da9 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index 7e7d0788ddcf69d611e3e0b3f421b8863ee1c9b7..6b2efb8cb1f9c6bded4e7d318467f8825be75903 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index bd7fc99af18775f2a838ae8e58a1064146b9446a..7d98240def0b768d4f35e5f5cd33136794559b7f 100644 (file)
@@ -2508,7 +2508,6 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
-       SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
@@ -3063,12 +3062,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
          .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
          .class_mask = 0xffffff,
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
-         AZX_DCAPS_RIRB_PRE_DELAY },
+         AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 #else
        /* this entry seems still valid -- i.e. without emu20kx chip */
        { PCI_DEVICE(0x1102, 0x0009),
          .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
-         AZX_DCAPS_RIRB_PRE_DELAY },
+         AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
 #endif
        /* Vortex86MX */
        { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
index 79f49e2e8cbc4f4366a180f5811b68fb21659c99..618ddad172369b22062ad97114dd783841ccde43 100644 (file)
@@ -510,10 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
 
 static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
 {
-       return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
-               !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) &
-                 AC_DEFCFG_MISC_NO_PRESENCE)) &&
-               (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
+       if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
+               return false;
+       if (!codec->ignore_misc_bit &&
+           (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+            AC_DEFCFG_MISC_NO_PRESENCE))
+               return false;
+       if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
+               return false;
+       return true;
 }
 
 /* flags for hda_nid_item */
@@ -648,6 +653,9 @@ struct hdmi_eld {
        int     spk_alloc;
        int     sad_count;
        struct cea_sad sad[ELD_MAX_SAD];
+       /*
+        * all fields above eld_buffer will be cleared before updating ELD
+        */
        char    eld_buffer[ELD_MAX_SIZE];
 #ifdef CONFIG_PROC_FS
        struct snd_info_entry *proc_entry;
index d8aac588f23ba3b827a6ffa34199065c29103e93..bcb3310c394ff808a83d531cb49bdf2defcac056 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include "hda_codec.h"
index 6b406840846e640401044823efdab4dc64ed81de..993757b65736a01687c571ce3003e18507e861f4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index d9a2254ceef6ff5cc6643e1eae4cf69a2484e4e0..35abe3c6290884f1e842d3bd1caa5ccef955de88 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index c45f3e69bcf0483ab559b377e657638edb36798e..70a7abda7e225744bf93d90f795c86bfcd95dac6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
@@ -57,6 +58,8 @@ struct cs_spec {
        unsigned int gpio_mask;
        unsigned int gpio_dir;
        unsigned int gpio_data;
+       unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */
+       unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */
 
        struct hda_pcm pcm_rec[2];      /* PCM information */
 
@@ -75,6 +78,7 @@ enum {
        CS420X_MBP53,
        CS420X_MBP55,
        CS420X_IMAC27,
+       CS420X_APPLE,
        CS420X_AUTO,
        CS420X_MODELS
 };
@@ -236,6 +240,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 }
 
+static void cs_update_input_select(struct hda_codec *codec)
+{
+       struct cs_spec *spec = codec->spec;
+       if (spec->cur_adc)
+               snd_hda_codec_write(codec, spec->cur_adc, 0,
+                                   AC_VERB_SET_CONNECT_SEL,
+                                   spec->adc_idx[spec->cur_input]);
+}
+
 /*
  * Analog capture
  */
@@ -249,6 +262,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_adc = spec->adc_nid[spec->cur_input];
        spec->cur_adc_stream_tag = stream_tag;
        spec->cur_adc_format = format;
+       cs_update_input_select(codec);
        snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
        return 0;
 }
@@ -688,10 +702,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
                                           spec->cur_adc_stream_tag, 0,
                                           spec->cur_adc_format);
        }
-       snd_hda_codec_write(codec, spec->cur_adc, 0,
-                           AC_VERB_SET_CONNECT_SEL,
-                           spec->adc_idx[idx]);
        spec->cur_input = idx;
+       cs_update_input_select(codec);
        return 1;
 }
 
@@ -919,10 +931,9 @@ static void cs_automute(struct hda_codec *codec)
                                        spdif_present ? 0 : PIN_OUT);
                }
        }
-       if (spec->board_config == CS420X_MBP53 ||
-           spec->board_config == CS420X_MBP55 ||
-           spec->board_config == CS420X_IMAC27) {
-               unsigned int gpio = hp_present ? 0x02 : 0x08;
+       if (spec->gpio_eapd_hp) {
+               unsigned int gpio = hp_present ?
+                       spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
                snd_hda_codec_write(codec, 0x01, 0,
                                    AC_VERB_SET_GPIO_DATA, gpio);
        }
@@ -972,10 +983,7 @@ static void cs_automic(struct hda_codec *codec)
                } else  {
                        spec->cur_input = spec->last_input;
                }
-
-               snd_hda_codec_write_cache(codec, spec->cur_adc, 0,
-                                       AC_VERB_SET_CONNECT_SEL,
-                                       spec->adc_idx[spec->cur_input]);
+               cs_update_input_select(codec);
        } else {
                if (present)
                        change_cur_input(codec, spec->automic_idx, 0);
@@ -1072,9 +1080,7 @@ static void init_input(struct hda_codec *codec)
                        cs_automic(codec);
                else  {
                        spec->cur_adc = spec->adc_nid[spec->cur_input];
-                       snd_hda_codec_write(codec, spec->cur_adc, 0,
-                                       AC_VERB_SET_CONNECT_SEL,
-                                       spec->adc_idx[spec->cur_input]);
+                       cs_update_input_select(codec);
                }
        } else {
                change_cur_input(codec, spec->cur_input, 1);
@@ -1272,6 +1278,7 @@ static const char * const cs420x_models[CS420X_MODELS] = {
        [CS420X_MBP53] = "mbp53",
        [CS420X_MBP55] = "mbp55",
        [CS420X_IMAC27] = "imac27",
+       [CS420X_APPLE] = "apple",
        [CS420X_AUTO] = "auto",
 };
 
@@ -1281,7 +1288,13 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
        SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
-       SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
+       /* this conflicts with too many other models */
+       /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
+       {} /* terminator */
+};
+
+static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
+       SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
        {} /* terminator */
 };
 
@@ -1363,6 +1376,10 @@ static int patch_cs420x(struct hda_codec *codec)
        spec->board_config =
                snd_hda_check_board_config(codec, CS420X_MODELS,
                                           cs420x_models, cs420x_cfg_tbl);
+       if (spec->board_config < 0)
+               spec->board_config =
+                       snd_hda_check_board_codec_sid_config(codec,
+                               CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
        if (spec->board_config >= 0)
                fix_pincfg(codec, spec->board_config, cs_pincfgs);
 
@@ -1370,10 +1387,11 @@ static int patch_cs420x(struct hda_codec *codec)
        case CS420X_IMAC27:
        case CS420X_MBP53:
        case CS420X_MBP55:
-               /* GPIO1 = headphones */
-               /* GPIO3 = speakers */
-               spec->gpio_mask = 0x0a;
-               spec->gpio_dir = 0x0a;
+       case CS420X_APPLE:
+               spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
+               spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+               spec->gpio_mask = spec->gpio_dir =
+                       spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
                break;
        }
 
index cd2cf5e94e81df8b8111aa1ce4180a02e79cb99b..b6767b4ced4478c5d1d7a0eb671d528284ef8e34 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index 0c8b5a1993edbc277ec95e4e12a30dbc3361f837..0de21193a2b025ba58363c0e2a509ec4545b495d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 
@@ -3061,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
        SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
-       SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
                      CXT5066_LAPTOP),
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
index aac3bfacda3f02d8e17e080072de9b581f26c31d..c505fd5d338cc91d1de2199143c8141f24890355 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -65,7 +65,11 @@ struct hdmi_spec_per_pin {
        hda_nid_t pin_nid;
        int num_mux_nids;
        hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
+
+       struct hda_codec *codec;
        struct hdmi_eld sink_eld;
+       struct delayed_work work;
+       int repoll_count;
 };
 
 struct hdmi_spec {
@@ -745,8 +749,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
  * Unsolicited events
  */
 
-static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
-                              struct hdmi_eld *eld);
+static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll);
 
 static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
 {
@@ -755,7 +758,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        int pd = !!(res & AC_UNSOL_RES_PD);
        int eldv = !!(res & AC_UNSOL_RES_ELDV);
        int pin_idx;
-       struct hdmi_eld *eld;
 
        printk(KERN_INFO
                "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
@@ -764,17 +766,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
        pin_idx = pin_nid_to_pin_index(spec, pin_nid);
        if (pin_idx < 0)
                return;
-       eld = &spec->pins[pin_idx].sink_eld;
-
-       hdmi_present_sense(codec, pin_nid, eld);
 
-       /*
-        * HDMI sink's ELD info cannot always be retrieved for now, e.g.
-        * in console or for audio devices. Assume the highest speakers
-        * configuration, to _not_ prohibit multi-channel audio playback.
-        */
-       if (!eld->spk_alloc)
-               eld->spk_alloc = 0xffff;
+       hdmi_present_sense(&spec->pins[pin_idx], 1);
 }
 
 static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -968,9 +961,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
        return 0;
 }
 
-static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
-                              struct hdmi_eld *eld)
+static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
 {
+       struct hda_codec *codec = per_pin->codec;
+       struct hdmi_eld *eld = &per_pin->sink_eld;
+       hda_nid_t pin_nid = per_pin->pin_nid;
        /*
         * Always execute a GetPinSense verb here, even when called from
         * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited
@@ -980,26 +975,42 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
         * the unsolicited response to avoid custom WARs.
         */
        int present = snd_hda_pin_sense(codec, pin_nid);
+       bool eld_valid = false;
 
-       memset(eld, 0, sizeof(*eld));
+       memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer));
 
        eld->monitor_present    = !!(present & AC_PINSENSE_PRESENCE);
        if (eld->monitor_present)
-               eld->eld_valid  = !!(present & AC_PINSENSE_ELDV);
-       else
-               eld->eld_valid  = 0;
+               eld_valid       = !!(present & AC_PINSENSE_ELDV);
 
        printk(KERN_INFO
                "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
-               codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
+               codec->addr, pin_nid, eld->monitor_present, eld_valid);
 
-       if (eld->eld_valid)
+       if (eld_valid) {
                if (!snd_hdmi_get_eld(eld, codec, pin_nid))
                        snd_hdmi_show_eld(eld);
+               else if (repoll) {
+                       queue_delayed_work(codec->bus->workq,
+                                          &per_pin->work,
+                                          msecs_to_jiffies(300));
+               }
+       }
 
        snd_hda_input_jack_report(codec, pin_nid);
 }
 
+static void hdmi_repoll_eld(struct work_struct *work)
+{
+       struct hdmi_spec_per_pin *per_pin =
+       container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work);
+
+       if (per_pin->repoll_count++ > 6)
+               per_pin->repoll_count = 0;
+
+       hdmi_present_sense(per_pin, per_pin->repoll_count);
+}
+
 static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 {
        struct hdmi_spec *spec = codec->spec;
@@ -1228,7 +1239,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
        if (err < 0)
                return err;
 
-       hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld);
+       hdmi_present_sense(per_pin, 0);
        return 0;
 }
 
@@ -1279,6 +1290,8 @@ static int generic_hdmi_init(struct hda_codec *codec)
                                    AC_VERB_SET_UNSOLICITED_ENABLE,
                                    AC_USRSP_EN | pin_nid);
 
+               per_pin->codec = codec;
+               INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
                snd_hda_eld_proc_new(codec, eld, pin_idx);
        }
        return 0;
@@ -1293,10 +1306,12 @@ static void generic_hdmi_free(struct hda_codec *codec)
                struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
                struct hdmi_eld *eld = &per_pin->sink_eld;
 
+               cancel_delayed_work(&per_pin->work);
                snd_hda_eld_proc_free(codec, eld);
        }
        snd_hda_input_jack_free(codec);
 
+       flush_workqueue(codec->bus->workq);
        kfree(spec);
 }
 
index 80d6add8a620e23fba3c7790b949eeb202d1a8b8..1d07e8fa243360d25236a4942ab5e363d69d1558 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include "hda_codec.h"
@@ -276,6 +277,12 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
        return false;
 }
 
+static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
+{
+       return spec->capsrc_nids ?
+               spec->capsrc_nids[idx] : spec->adc_nids[idx];
+}
+
 /* select the given imux item; either unmute exclusively or select the route */
 static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
                          unsigned int idx, bool force)
@@ -283,13 +290,15 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
        struct alc_spec *spec = codec->spec;
        const struct hda_input_mux *imux;
        unsigned int mux_idx;
-       int i, type;
+       int i, type, num_conns;
        hda_nid_t nid;
 
        mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
        imux = &spec->input_mux[mux_idx];
        if (!imux->num_items && mux_idx > 0)
                imux = &spec->input_mux[0];
+       if (!imux->num_items)
+               return 0;
 
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
@@ -302,20 +311,20 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
                adc_idx = spec->dyn_adc_idx[idx];
        }
 
-       nid = spec->capsrc_nids ?
-               spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
+       nid = get_capsrc(spec, adc_idx);
 
        /* no selection? */
-       if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
+       num_conns = snd_hda_get_conn_list(codec, nid, NULL);
+       if (num_conns <= 1)
                return 1;
 
        type = get_wcaps_type(get_wcaps(codec, nid));
        if (type == AC_WID_AUD_MIX) {
                /* Matrix-mixer style (e.g. ALC882) */
-               for (i = 0; i < imux->num_items; i++) {
-                       unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
-                       snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
-                                                imux->items[i].index,
+               int active = imux->items[idx].index;
+               for (i = 0; i < num_conns; i++) {
+                       unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE;
+                       snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i,
                                                 HDA_AMP_MUTE, v);
                }
        } else {
@@ -1052,8 +1061,19 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
        spec->imux_pins[2] = spec->dock_mic_pin;
        for (i = 0; i < 3; i++) {
                strcpy(imux->items[i].label, texts[i]);
-               if (spec->imux_pins[i])
+               if (spec->imux_pins[i]) {
+                       hda_nid_t pin = spec->imux_pins[i];
+                       int c;
+                       for (c = 0; c < spec->num_adc_nids; c++) {
+                               hda_nid_t cap = get_capsrc(spec, c);
+                               int idx = get_connection_index(codec, cap, pin);
+                               if (idx >= 0) {
+                                       imux->items[i].index = idx;
+                                       break;
+                               }
+                       }
                        imux->num_items = i + 1;
+               }
        }
        spec->num_mux_defs = 1;
        spec->input_mux = imux;
@@ -1450,7 +1470,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)
                switch (fix->type) {
                case ALC_FIXUP_SKU:
                        if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
-                               break;;
+                               break;
                        snd_printdd(KERN_INFO "hda_codec: %s: "
                                    "Apply sku override for %s\n",
                                    codec->chip_name, modelname);
@@ -1955,10 +1975,8 @@ static int alc_build_controls(struct hda_codec *codec)
                if (!kctl)
                        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
                for (i = 0; kctl && i < kctl->count; i++) {
-                       const hda_nid_t *nids = spec->capsrc_nids;
-                       if (!nids)
-                               nids = spec->adc_nids;
-                       err = snd_hda_add_nid(codec, kctl, i, nids[i]);
+                       err = snd_hda_add_nid(codec, kctl, i,
+                                             get_capsrc(spec, i));
                        if (err < 0)
                                return err;
                }
@@ -2613,6 +2631,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
        case AUTO_PIN_SPEAKER_OUT:
                if (cfg->line_outs == 1)
                        return "Speaker";
+               if (cfg->line_outs == 2)
+                       return ch ? "Bass Speaker" : "Speaker";
                break;
        case AUTO_PIN_HP_OUT:
                /* for multi-io case, only the primary out */
@@ -2745,8 +2765,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec)
                }
 
                for (c = 0; c < num_adcs; c++) {
-                       hda_nid_t cap = spec->capsrc_nids ?
-                               spec->capsrc_nids[c] : spec->adc_nids[c];
+                       hda_nid_t cap = get_capsrc(spec, c);
                        idx = get_connection_index(codec, cap, pin);
                        if (idx >= 0) {
                                spec->imux_pins[imux->num_items] = pin;
@@ -2887,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
                if (!nid)
                        continue;
                if (found_in_nid_list(nid, spec->multiout.dac_nids,
-                                     spec->multiout.num_dacs))
+                                     ARRAY_SIZE(spec->private_dac_nids)))
                        continue;
                if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
                                      ARRAY_SIZE(spec->multiout.hp_out_nid)))
@@ -2908,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
        return 0;
 }
 
+/* return 0 if no possible DAC is found, 1 if one or more found */
 static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
                                    const hda_nid_t *pins, hda_nid_t *dacs)
 {
@@ -2925,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
                if (!dacs[i])
                        dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
        }
-       return 0;
+       return 1;
 }
 
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
@@ -2935,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec,
 static int alc_auto_fill_dac_nids(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       const struct auto_pin_cfg *cfg = &spec->autocfg;
+       struct auto_pin_cfg *cfg = &spec->autocfg;
        bool redone = false;
        int i;
 
@@ -2946,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
        spec->multiout.extra_out_nid[0] = 0;
        memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
        spec->multiout.dac_nids = spec->private_dac_nids;
+       spec->multi_ios = 0;
 
        /* fill hard-wired DACs first */
        if (!redone) {
@@ -2979,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
        for (i = 0; i < cfg->line_outs; i++) {
                if (spec->private_dac_nids[i])
                        spec->multiout.num_dacs++;
-               else
+               else {
                        memmove(spec->private_dac_nids + i,
                                spec->private_dac_nids + i + 1,
                                sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
+                       spec->private_dac_nids[cfg->line_outs - 1] = 0;
+               }
        }
 
        if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
@@ -3004,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
        if (cfg->line_out_type != AUTO_PIN_HP_OUT)
                alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
                                 spec->multiout.hp_out_nid);
-       if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
-               alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins,
-                                spec->multiout.extra_out_nid);
+       if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+               int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
+                                       cfg->speaker_pins,
+                                       spec->multiout.extra_out_nid);
+               /* if no speaker volume is assigned, try again as the primary
+                * output
+                */
+               if (!err && cfg->speaker_outs > 0 &&
+                   cfg->line_out_type == AUTO_PIN_HP_OUT) {
+                       cfg->hp_outs = cfg->line_outs;
+                       memcpy(cfg->hp_pins, cfg->line_out_pins,
+                              sizeof(cfg->hp_pins));
+                       cfg->line_outs = cfg->speaker_outs;
+                       memcpy(cfg->line_out_pins, cfg->speaker_pins,
+                              sizeof(cfg->speaker_pins));
+                       cfg->speaker_outs = 0;
+                       memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
+                       cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
+                       redone = false;
+                       goto again;
+               }
+       }
 
        return 0;
 }
@@ -3156,7 +3198,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
 }
 
 static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
-                                    hda_nid_t dac, const char *pfx)
+                                    hda_nid_t dac, const char *pfx,
+                                    int cidx)
 {
        struct alc_spec *spec = codec->spec;
        hda_nid_t sw, vol;
@@ -3172,15 +3215,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
                if (is_ctl_used(spec->sw_ctls, val))
                        return 0; /* already created */
                mark_ctl_usage(spec->sw_ctls, val);
-               return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
+               return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
        }
 
        sw = alc_look_for_out_mute_nid(codec, pin, dac);
        vol = alc_look_for_out_vol_nid(codec, pin, dac);
-       err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
+       err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol);
        if (err < 0)
                return err;
-       err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
+       err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw);
        if (err < 0)
                return err;
        return 0;
@@ -3221,16 +3264,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
                hda_nid_t dac = *dacs;
                if (!dac)
                        dac = spec->multiout.dac_nids[0];
-               return alc_auto_create_extra_out(codec, *pins, dac, pfx);
+               return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
        }
 
        if (dacs[num_pins - 1]) {
                /* OK, we have a multi-output system with individual volumes */
                for (i = 0; i < num_pins; i++) {
-                       snprintf(name, sizeof(name), "%s %s",
-                                pfx, channel_name[i]);
-                       err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
-                                                       name);
+                       if (num_pins >= 3) {
+                               snprintf(name, sizeof(name), "%s %s",
+                                        pfx, channel_name[i]);
+                               err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
+                                                               name, 0);
+                       } else {
+                               err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
+                                                               pfx, i);
+                       }
                        if (err < 0)
                                return err;
                }
@@ -3329,6 +3377,12 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
        if (nid)
                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
                                    AMP_OUT_ZERO);
+
+       /* unmute DAC if it's not assigned to a mixer */
+       nid = alc_look_for_out_mute_nid(codec, pin, dac);
+       if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
+               snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                                   AMP_OUT_ZERO);
 }
 
 static void alc_auto_init_multi_out(struct hda_codec *codec)
@@ -3686,8 +3740,7 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
        if (!pin)
                return 0;
        for (i = 0; i < spec->num_adc_nids; i++) {
-               hda_nid_t cap = spec->capsrc_nids ?
-                       spec->capsrc_nids[i] : spec->adc_nids[i];
+               hda_nid_t cap = get_capsrc(spec, i);
                int idx;
 
                idx = get_connection_index(codec, cap, pin);
index 2f55f32876fabf8b543fd2c066325f689df2e1ca..6679a5095e559ddee57fe068593c31e39a613126 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
index de4c36027cbebdd39ea0b833a0f16a441a5b5107..eeb25d529e30b51bebbb42924a4733c6308dc2df 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
 #include <sound/jack.h>
@@ -94,6 +95,7 @@ enum {
        STAC_92HD83XXX_REF,
        STAC_92HD83XXX_PWR_REF,
        STAC_DELL_S14,
+       STAC_DELL_VOSTRO_3500,
        STAC_92HD83XXX_HP,
        STAC_92HD83XXX_HP_cNB11_INTQUAD,
        STAC_HP_DV7_4000,
@@ -213,6 +215,7 @@ struct sigmatel_spec {
        unsigned int gpio_mute;
        unsigned int gpio_led;
        unsigned int gpio_led_polarity;
+       unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
        unsigned int vref_led;
 
        /* stream */
@@ -225,7 +228,6 @@ struct sigmatel_spec {
 
        /* power management */
        unsigned int num_pwrs;
-       const unsigned int *pwr_mapping;
        const hda_nid_t *pwr_nids;
        const hda_nid_t *dac_list;
 
@@ -372,18 +374,15 @@ static const unsigned long stac92hd73xx_capvols[] = {
 
 #define STAC92HD83_DAC_COUNT 3
 
-static const hda_nid_t stac92hd83xxx_pwr_nids[4] = {
-       0xa, 0xb, 0xd, 0xe,
+static const hda_nid_t stac92hd83xxx_pwr_nids[7] = {
+       0x0a, 0x0b, 0x0c, 0xd, 0x0e,
+       0x0f, 0x10
 };
 
 static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = {
        0x1e, 0,
 };
 
-static const unsigned int stac92hd83xxx_pwr_mapping[4] = {
-       0x03, 0x0c, 0x20, 0x40,
-};
-
 static const hda_nid_t stac92hd83xxx_dmic_nids[] = {
                0x11, 0x20,
 };
@@ -1643,6 +1642,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
                      "Alienware M17x", STAC_ALIENWARE_M17X),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,
                      "Alienware M17x", STAC_ALIENWARE_M17X),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
+                     "Alienware M17x", STAC_ALIENWARE_M17X),
        {} /* terminator */
 };
 
@@ -1658,6 +1659,12 @@ static const unsigned int dell_s14_pin_configs[10] = {
        0x40f000f0, 0x40f000f0,
 };
 
+static const unsigned int dell_vostro_3500_pin_configs[10] = {
+       0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
+       0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
+       0x400000f4, 0x400000f5,
+};
+
 static const unsigned int hp_dv7_4000_pin_configs[10] = {
        0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
        0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
@@ -1674,6 +1681,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
        [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
        [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
        [STAC_DELL_S14] = dell_s14_pin_configs,
+       [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
        [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
        [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
 };
@@ -1683,6 +1691,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
        [STAC_92HD83XXX_REF] = "ref",
        [STAC_92HD83XXX_PWR_REF] = "mic-ref",
        [STAC_DELL_S14] = "dell-s14",
+       [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
        [STAC_92HD83XXX_HP] = "hp",
        [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
        [STAC_HP_DV7_4000] = "hp-dv7-4000",
@@ -1696,6 +1705,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
                      "DFI LanParty", STAC_92HD83XXX_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
                      "unknown Dell", STAC_DELL_S14),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
+                     "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
                          "HP", STAC_92HD83XXX_HP),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
@@ -4308,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec)
                spec->eapd_switch = val;
        get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
        if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
-               if (spec->gpio_led <= 8) {
-                       spec->gpio_mask |= spec->gpio_led;
-                       spec->gpio_dir |= spec->gpio_led;
-                       if (spec->gpio_led_polarity)
-                               spec->gpio_data |= spec->gpio_led;
-               }
+               spec->gpio_mask |= spec->gpio_led;
+               spec->gpio_dir |= spec->gpio_led;
+               if (spec->gpio_led_polarity)
+                       spec->gpio_data |= spec->gpio_led;
        }
 }
 
@@ -4431,7 +4440,9 @@ static int stac92xx_init(struct hda_codec *codec)
                int pinctl, def_conf;
 
                /* power on when no jack detection is available */
-               if (!spec->hp_detect) {
+               /* or when the VREF is used for controlling LED */
+               if (!spec->hp_detect ||
+                   spec->vref_mute_led_nid == nid) {
                        stac_toggle_power_map(codec, nid, 1);
                        continue;
                }
@@ -4458,8 +4469,12 @@ static int stac92xx_init(struct hda_codec *codec)
                                stac_toggle_power_map(codec, nid, 1);
                        continue;
                }
-               if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
+               if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
                        stac_issue_unsol_event(codec, nid);
+                       continue;
+               }
+               /* none of the above, turn the port OFF */
+               stac_toggle_power_map(codec, nid, 0);
        }
 
        /* sync mute LED */
@@ -4715,11 +4730,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
        if (idx >= spec->num_pwrs)
                return;
 
-       /* several codecs have two power down bits */
-       if (spec->pwr_mapping)
-               idx = spec->pwr_mapping[idx];
-       else
-               idx = 1 << idx;
+       idx = 1 << idx;
 
        val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
        if (enable)
@@ -4903,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
                        if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
                                  &spec->gpio_led_polarity,
                                  &spec->gpio_led) == 2) {
-                               if (spec->gpio_led < 4)
+                               unsigned int max_gpio;
+                               max_gpio = snd_hda_param_read(codec, codec->afg,
+                                                             AC_PAR_GPIO_CAP);
+                               max_gpio &= AC_GPIO_IO_COUNT;
+                               if (spec->gpio_led < max_gpio)
                                        spec->gpio_led = 1 << spec->gpio_led;
+                               else
+                                       spec->vref_mute_led_nid = spec->gpio_led;
                                return 1;
                        }
                        if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5033,29 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
        struct sigmatel_spec *spec = codec->spec;
 
        /* sync mute LED */
-       if (spec->gpio_led) {
-               if (spec->gpio_led <= 8) {
-                       stac_gpio_set(codec, spec->gpio_mask,
-                                       spec->gpio_dir, spec->gpio_data);
-               } else {
-                       stac_vrefout_set(codec,
-                                       spec->gpio_led, spec->vref_led);
-               }
-       }
-       return 0;
-}
-
-static int stac92xx_post_suspend(struct hda_codec *codec)
-{
-       struct sigmatel_spec *spec = codec->spec;
-       if (spec->gpio_led > 8) {
-               /* with vref-out pin used for mute led control
-                * codec AFG is prevented from D3 state, but on
-                * system suspend it can (and should) be used
-                */
-               snd_hda_codec_read(codec, codec->afg, 0,
-                               AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
-       }
+       if (spec->vref_mute_led_nid)
+               stac_vrefout_set(codec, spec->vref_mute_led_nid,
+                                spec->vref_led);
+       else if (spec->gpio_led)
+               stac_gpio_set(codec, spec->gpio_mask,
+                             spec->gpio_dir, spec->gpio_data);
        return 0;
 }
 
@@ -5066,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
        struct sigmatel_spec *spec = codec->spec;
 
        if (power_state == AC_PWRST_D3) {
-               if (spec->gpio_led > 8) {
+               if (spec->vref_mute_led_nid) {
                        /* with vref-out pin used for mute led control
                         * codec AFG is prevented from D3 state
                         */
@@ -5119,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
                }
        }
        /*polarity defines *not* muted state level*/
-       if (spec->gpio_led <= 8) {
+       if (!spec->vref_mute_led_nid) {
                if (muted)
                        spec->gpio_data &= ~spec->gpio_led; /* orange */
                else
@@ -5137,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
                muted_lvl = spec->gpio_led_polarity ?
                                AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
                spec->vref_led = muted ? muted_lvl : notmtd_lvl;
-               stac_vrefout_set(codec, spec->gpio_led, spec->vref_led);
+               stac_vrefout_set(codec, spec->vref_mute_led_nid,
+                                spec->vref_led);
        }
        return 0;
 }
@@ -5617,9 +5618,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
                snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
        }
 
-       /* reset pin power-down; Windows may leave these bits after reboot */
-       snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
-       snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
        codec->no_trigger_sense = 1;
        codec->spec = spec;
 
@@ -5629,7 +5627,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
        codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
        spec->digbeep_nid = 0x21;
        spec->pwr_nids = stac92hd83xxx_pwr_nids;
-       spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
        spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
        spec->multiout.dac_nids = spec->dac_nids;
        spec->init = stac92hd83xxx_core_init;
@@ -5646,9 +5643,6 @@ again:
                stac92xx_set_config_regs(codec,
                                stac92hd83xxx_brd_tbl[spec->board_config]);
 
-       if (spec->board_config != STAC_92HD83XXX_PWR_REF)
-               spec->num_pwrs = 0;
-
        codec->patch_ops = stac92xx_patch_ops;
 
        if (find_mute_led_gpio(codec, 0))
@@ -5658,15 +5652,13 @@ again:
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (spec->gpio_led) {
-               if (spec->gpio_led <= 8) {
+               if (!spec->vref_mute_led_nid) {
                        spec->gpio_mask |= spec->gpio_led;
                        spec->gpio_dir |= spec->gpio_led;
                        spec->gpio_data |= spec->gpio_led;
                } else {
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
-                       codec->patch_ops.post_suspend =
-                                       stac92xx_post_suspend;
                }
                codec->patch_ops.pre_resume = stac92xx_pre_resume;
                codec->patch_ops.check_power_status =
@@ -5857,8 +5849,6 @@ again:
                    (codec->revision_id & 0xf) == 1)
                        spec->stream_delay = 40; /* 40 milliseconds */
 
-               /* no output amps */
-               spec->num_pwrs = 0;
                /* disable VSW */
                spec->init = stac92hd71bxx_core_init;
                unmute_init++;
@@ -5873,8 +5863,6 @@ again:
                if ((codec->revision_id & 0xf) == 1)
                        spec->stream_delay = 40; /* 40 milliseconds */
 
-               /* no output amps */
-               spec->num_pwrs = 0;
                /* fallthru */
        default:
                spec->init = stac92hd71bxx_core_init;
@@ -5977,15 +5965,13 @@ again:
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (spec->gpio_led) {
-               if (spec->gpio_led <= 8) {
+               if (!spec->vref_mute_led_nid) {
                        spec->gpio_mask |= spec->gpio_led;
                        spec->gpio_dir |= spec->gpio_led;
                        spec->gpio_data |= spec->gpio_led;
                } else {
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
-                       codec->patch_ops.post_suspend =
-                                       stac92xx_post_suspend;
                }
                codec->patch_ops.pre_resume = stac92xx_pre_resume;
                codec->patch_ops.check_power_status =
index 0b020a93a8ed0c67148b798d48052e77e154edfa..b5137629f8e942a75a941e0e183cef98fb58db02 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
 #include "hda_codec.h"
@@ -207,6 +208,7 @@ struct via_spec {
        /* work to check hp jack state */
        struct hda_codec *codec;
        struct delayed_work vt1708_hp_work;
+       int hp_work_active;
        int vt1708_jack_detect;
        int vt1708_hp_present;
 
@@ -304,27 +306,35 @@ enum {
 static void analog_low_current_mode(struct hda_codec *codec);
 static bool is_aa_path_mute(struct hda_codec *codec);
 
-static void vt1708_start_hp_work(struct via_spec *spec)
+#define hp_detect_with_aa(codec) \
+       (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
+        !is_aa_path_mute(codec))
+
+static void vt1708_stop_hp_work(struct via_spec *spec)
 {
        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
                return;
-       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
-                           !spec->vt1708_jack_detect);
-       if (!delayed_work_pending(&spec->vt1708_hp_work))
-               schedule_delayed_work(&spec->vt1708_hp_work,
-                                     msecs_to_jiffies(100));
+       if (spec->hp_work_active) {
+               snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1);
+               cancel_delayed_work_sync(&spec->vt1708_hp_work);
+               spec->hp_work_active = 0;
+       }
 }
 
-static void vt1708_stop_hp_work(struct via_spec *spec)
+static void vt1708_update_hp_work(struct via_spec *spec)
 {
        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
                return;
-       if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
-           && !is_aa_path_mute(spec->codec))
-               return;
-       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
-                           !spec->vt1708_jack_detect);
-       cancel_delayed_work_sync(&spec->vt1708_hp_work);
+       if (spec->vt1708_jack_detect &&
+           (spec->active_streams || hp_detect_with_aa(spec->codec))) {
+               if (!spec->hp_work_active) {
+                       snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0);
+                       schedule_delayed_work(&spec->vt1708_hp_work,
+                                             msecs_to_jiffies(100));
+                       spec->hp_work_active = 1;
+               }
+       } else if (!hp_detect_with_aa(spec->codec))
+               vt1708_stop_hp_work(spec);
 }
 
 static void set_widgets_power_state(struct hda_codec *codec)
@@ -342,12 +352,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
 
        set_widgets_power_state(codec);
        analog_low_current_mode(snd_kcontrol_chip(kcontrol));
-       if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
-               if (is_aa_path_mute(codec))
-                       vt1708_start_hp_work(codec->spec);
-               else
-                       vt1708_stop_hp_work(codec->spec);
-       }
+       vt1708_update_hp_work(codec->spec);
        return change;
 }
 
@@ -1153,7 +1158,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_dac_stream_tag = stream_tag;
        spec->cur_dac_format = format;
        mutex_unlock(&spec->config_mutex);
-       vt1708_start_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1173,7 +1178,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
        spec->cur_hp_stream_tag = stream_tag;
        spec->cur_hp_format = format;
        mutex_unlock(&spec->config_mutex);
-       vt1708_start_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1187,7 +1192,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
        snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
        spec->active_streams &= ~STREAM_MULTI_OUT;
        mutex_unlock(&spec->config_mutex);
-       vt1708_stop_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1202,7 +1207,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
                snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
        spec->active_streams &= ~STREAM_INDEP_HP;
        mutex_unlock(&spec->config_mutex);
-       vt1708_stop_hp_work(spec);
+       vt1708_update_hp_work(spec);
        return 0;
 }
 
@@ -1644,7 +1649,8 @@ static void via_hp_automute(struct hda_codec *codec)
        int nums;
        struct via_spec *spec = codec->spec;
 
-       if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
+       if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
+           (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
                present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
 
        if (spec->smart51_enabled)
@@ -2611,8 +2617,6 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
 
        if (spec->codec_type != VT1708)
                return 0;
-       spec->vt1708_jack_detect =
-               !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
        ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
        return 0;
 }
@@ -2622,18 +2626,22 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct via_spec *spec = codec->spec;
-       int change;
+       int val;
 
        if (spec->codec_type != VT1708)
                return 0;
-       spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
-       change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
-               == !spec->vt1708_jack_detect;
-       if (spec->vt1708_jack_detect) {
+       val = !!ucontrol->value.integer.value[0];
+       if (spec->vt1708_jack_detect == val)
+               return 0;
+       spec->vt1708_jack_detect = val;
+       if (spec->vt1708_jack_detect &&
+           snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) {
                mute_aa_path(codec, 1);
                notify_aa_path_ctls(codec);
        }
-       return change;
+       via_hp_automute(codec);
+       vt1708_update_hp_work(spec);
+       return 1;
 }
 
 static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
@@ -2770,6 +2778,7 @@ static int via_init(struct hda_codec *codec)
        via_auto_init_unsol_event(codec);
 
        via_hp_automute(codec);
+       vt1708_update_hp_work(spec);
 
        return 0;
 }
@@ -2786,7 +2795,9 @@ static void vt1708_update_hp_jack_state(struct work_struct *work)
                spec->vt1708_hp_present ^= 1;
                via_hp_automute(spec->codec);
        }
-       vt1708_start_hp_work(spec);
+       if (spec->vt1708_jack_detect)
+               schedule_delayed_work(&spec->vt1708_hp_work,
+                                     msecs_to_jiffies(100));
 }
 
 static int get_mux_nids(struct hda_codec *codec)
index 90d560c3df13c4a3e92268809d5435177fdfebb3..3981823f9094b84faeec099fb951d30fcfa30277 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "ice1712.h"
index 8531b983f3aff90bbc3e76ee5527b01e0bb53629..44446f2222d942f08ac1ae82468891b391a335a1 100644 (file)
@@ -54,7 +54,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
 #include <sound/core.h>
index c2b7f8bc41e4bc1c4a0586ad173cdd3607dcca42..4353e76bf0a687a975ee721bf84e589f6807e2d6 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/info.h>
index 45b2055f5a76ea2bea0eb4c942d53c674c4ec95f..11718b49b2e2459bb930384a4de50a34db6d54f8 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
@@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
                }
                if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV))
                        continue;
+
+               /* IO read operation is very expensive inside virtual machine
+                * as it is emulated. The probability that subsequent PICB read
+                * will return different result is high enough to loop till
+                * timeout here.
+                * Same CIV is strict enough condition to be sure that PICB
+                * is valid inside VM on emulated card. */
                if (chip->inside_vm)
                        break;
                if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
@@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = {
        ICH_PCR, ICH_SCR, ICH_SIS_TCR
 };
 
+static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci)
+{
+       int result  = inside_vm;
+       char *msg   = NULL;
+
+       /* check module parameter first (override detection) */
+       if (result >= 0) {
+               msg = result ? "enable (forced) VM" : "disable (forced) VM";
+               goto fini;
+       }
+
+       /* detect KVM and Parallels virtual environments */
+       result = kvm_para_available();
+#ifdef X86_FEATURE_HYPERVISOR
+       result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#endif
+       if (!result)
+               goto fini;
+
+       /* check for known (emulated) devices */
+       if (pci->subsystem_vendor == 0x1af4 &&
+           pci->subsystem_device == 0x1100) {
+               /* KVM emulated sound, PCI SSID: 1af4:1100 */
+               msg = "enable KVM";
+       } else if (pci->subsystem_vendor == 0x1ab8) {
+               /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */
+               msg = "enable Parallels VM";
+       } else {
+               msg = "disable (unknown or VT-d) VM";
+               result = 0;
+       }
+
+fini:
+       if (msg != NULL)
+               printk(KERN_INFO "intel8x0: %s optimization\n", msg);
+
+       return result;
+}
+
 static int __devinit snd_intel8x0_create(struct snd_card *card,
                                         struct pci_dev *pci,
                                         unsigned long device_type,
@@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
        if (xbox)
                chip->xbox = 1;
 
-       chip->inside_vm = inside_vm;
-       if (inside_vm)
-               printk(KERN_INFO "intel8x0: enable KVM optimization\n");
+       chip->inside_vm = snd_intel8x0_inside_vm(pci);
 
        if (pci->vendor == PCI_VENDOR_ID_INTEL &&
            pci->device == PCI_DEVICE_ID_INTEL_440MX)
@@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
                        buggy_irq = 0;
        }
 
-       if (inside_vm < 0) {
-               /* detect KVM and Parallels virtual environments */
-               inside_vm = kvm_para_available();
-#if defined(__i386__) || defined(__x86_64__)
-               inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR);
-#endif
-       }
-
        if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
                                       &chip)) < 0) {
                snd_card_free(card);
index 7c161645d86567e412635f3f09ab3f11dd371fdb..0f7041ec7ddca607c591cd6d16ee94c9b7b81c87 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
index fc1d573cf3063ef13fa92172f7a031f7b927b29c..841864b6b371ca11f8b9c7caf2d1ff1dfc541e1b 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 
index 3e92e5b5ec3d30ae2dd60f6872f77c415d236a29..924168ef1ed64162b9ec5bae014892467977aacd 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 5c8717e29eebdbc4983933dcccaee36492457e41..8c3e7fcefd99c91c38d39f92fd0cae8323cee210 100644 (file)
@@ -78,10 +78,15 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port)
        return ioread32(address);
 }
 
-void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len)
+static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data,
+                              u32 len)
 {
-       void __iomem *address = lx_dsp_register(chip, port);
-       memcpy_fromio(data, address, len*sizeof(u32));
+       u32 __iomem *address = lx_dsp_register(chip, port);
+       int i;
+
+       /* we cannot use memcpy_fromio */
+       for (i = 0; i != len; ++i)
+               data[i] = ioread32(address + i);
 }
 
 
@@ -91,11 +96,15 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data)
        iowrite32(data, address);
 }
 
-void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
-                        u32 len)
+static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port,
+                               const u32 *data, u32 len)
 {
-       void __iomem *address = lx_dsp_register(chip, port);
-       memcpy_toio(address, data, len*sizeof(u32));
+       u32 __iomem *address = lx_dsp_register(chip, port);
+       int i;
+
+       /* we cannot use memcpy_to */
+       for (i = 0; i != len; ++i)
+               iowrite32(data[i], address + i);
 }
 
 
index 1dd562980b6c3595c233beffe49012c6352c605c..4d7ff797a6468abf5b5499cdfd92dab430d9948f 100644 (file)
@@ -72,10 +72,7 @@ enum {
 };
 
 unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port);
-void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len);
 void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data);
-void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data,
-                        u32 len);
 
 /* plx register access */
 enum {
index 2fd4bf2d6653dbba8015a440de385c198afe8a7f..863c8bdaecd618a546dbd7a4fe446b0032897bcb 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/input.h>
 #include <sound/core.h>
index dbee59906ae17fdc93debb3541d23d30dff4d4b2..a0bd1d99793f943a647712a011d263517e2061a0 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
index bf2696aa5d49021db7c1b37bdbf5a7968c16ae93..bfbdc91e4cb30cc89ad028a8627a6204d2b12919 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/firmware.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include "mixart.h"
index 83ea7a7d3eec728be5c159c6e3fcdcad3bb1283a..c6c45d979f7a3b66f1172c417e69a61f41d06956 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
 #include <sound/core.h>
index 218d9854e5cb0718c8bffd042491a531273cc1d3..5f3a13d4369d6cbad47dbf33b52f668061a810a1 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/ac97_codec.h>
 #include <sound/control.h>
 #include <sound/core.h>
index f5164b1e1c80bd1c11b695425175af98ce74185c..521eae458348c723bd87519cd4fcdbd0530c2f00 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/mpu401.h>
 #include <asm/io.h>
index 53e5508abcbf58a69cd345af5d3b6dd113708ec1..92e2d67f16a1f8ad6e6f45925ad27e04e0796f2c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
 #include <sound/core.h>
index 773db794b43f368eb1376e32799ebd26e5564dd6..4149a0cb8b73e107185b185a10361ae1df052a7d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index 046578d26f982eab05a1b9e1478433fce60f012d..56a52659742d57b176c612d1872928eea517ad58 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
 #include <sound/core.h>
index 17cb1233a903470b9f1e7ab63a4373be37ec97b5..ec1587cddb0cc150e7ac2e66563a69ae54f5aab9 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/vmalloc.h>
 #include <linux/firmware.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
index 88cc776aa38b1bb7d41c2c35d8f6c91d3c50b290..dcbedd33a629e87a133f802b5ff3c25b96af3a4d 100644 (file)
@@ -98,6 +98,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <sound/core.h>
 #include <sound/info.h>
index 6be77a264d47e386949cbfe0e1b67cd01f0dc27b..21bcb47fab50ef5d4de43708d7beb72105d4013d 100644 (file)
@@ -74,7 +74,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
index 409e5b89519d0dd0ad9c5304508f6f05495340c0..4585c9729fea43f67507d079156080df7d8b3fda 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
index f74220292254325d2dac3382b57f119d7bdebd7d..f2a3758dac5229bbfc463df1a22215d516b2dabb 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/firmware.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/math64.h>
 
 #include <sound/core.h>
index 15a6c3b9bc9a962903fe5ed162ac7e71697d3784..19ee2203cbb50fe7250bca2bad79c14e15a6069b 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/math64.h>
@@ -6518,7 +6518,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
                        hdspm->io_type = AES32;
                        hdspm->card_name = "RME AES32";
                        hdspm->midiPorts = 2;
-               } else if ((hdspm->firmware_rev == 0xd5) ||
+               } else if ((hdspm->firmware_rev == 0xd2) ||
                        ((hdspm->firmware_rev >= 0xc8)  &&
                                (hdspm->firmware_rev <= 0xcf))) {
                        hdspm->io_type = MADI;
index 1c7bc1ef8186ee27ff7382ff0eb6526f8d2b15b7..732c5e8374377d6abc0f98761e9133252ceb1f17 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
index 5ffb20b187861c9eb49b38fd7de6a427b1552332..28dfafb56dd1d70a9d95e4ef53f6e7ba22fb4faf 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/pci.h>
 #include <linux/time.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <sound/core.h>
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
 static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
 static char *id = SNDRV_DEFAULT_STR1;  /* ID for this card */
 static int enable = 1;
+static int codecs = 1;
 
 module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
@@ -48,6 +49,8 @@ module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
 module_param(enable, bool, 0444);
 MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
+module_param(codecs, int, 0444);
+MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");
 
 static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = {
        { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
@@ -140,6 +143,9 @@ struct sis7019 {
        dma_addr_t silence_dma_addr;
 };
 
+/* These values are also used by the module param 'codecs' to indicate
+ * which codecs should be present.
+ */
 #define SIS_PRIMARY_CODEC_PRESENT      0x0001
 #define SIS_SECONDARY_CODEC_PRESENT    0x0002
 #define SIS_TERTIARY_CODEC_PRESENT     0x0004
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis)
 {
        unsigned long io = sis->ioport;
        void __iomem *ioaddr = sis->ioaddr;
+       unsigned long timeout;
        u16 status;
        int count;
        int i;
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis)
        while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
                udelay(1);
 
+       /* Command complete, we can let go of the semaphore now.
+        */
+       outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
+       if (!count)
+               return -EIO;
+
        /* Now that we've finished the reset, find out what's attached.
+        * There are some codec/board combinations that take an extremely
+        * long time to come up. 350+ ms has been observed in the field,
+        * so we'll give them up to 500ms.
         */
-       status = inl(io + SIS_AC97_STATUS);
-       if (status & SIS_AC97_STATUS_CODEC_READY)
-               sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
-       if (status & SIS_AC97_STATUS_CODEC2_READY)
-               sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
-       if (status & SIS_AC97_STATUS_CODEC3_READY)
-               sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
-
-       /* All done, let go of the semaphore, and check for errors
+       sis->codecs_present = 0;
+       timeout = msecs_to_jiffies(500) + jiffies;
+       while (time_before_eq(jiffies, timeout)) {
+               status = inl(io + SIS_AC97_STATUS);
+               if (status & SIS_AC97_STATUS_CODEC_READY)
+                       sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
+               if (status & SIS_AC97_STATUS_CODEC2_READY)
+                       sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
+               if (status & SIS_AC97_STATUS_CODEC3_READY)
+                       sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
+
+               if (sis->codecs_present == codecs)
+                       break;
+
+               msleep(1);
+       }
+
+       /* All done, check for errors.
         */
-       outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
-       if (!sis->codecs_present || !count)
+       if (!sis->codecs_present) {
+               printk(KERN_ERR "sis7019: could not find any codecs\n");
                return -EIO;
+       }
+
+       if (sis->codecs_present != codecs) {
+               printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n",
+                      sis->codecs_present, codecs);
+       }
 
        /* Let the hardware know that the audio driver is alive,
         * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci,
        if (!enable)
                goto error_out;
 
+       /* The user can specify which codecs should be present so that we
+        * can wait for them to show up if they are slow to recover from
+        * the AC97 cold reset. We default to a single codec, the primary.
+        *
+        * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
+        */
+       codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
+                 SIS_TERTIARY_CODEC_PRESENT;
+       if (!codecs)
+               codecs = SIS_PRIMARY_CODEC_PRESENT;
+
        rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card);
        if (rc < 0)
                goto error_out;
index c5008166cf1f0d67fe0623c07f9e3950639a44a0..31b6ad3ab1dc48c2f47cbbeb13e58873dfdecf58 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/dma-mapping.h>
 
 #include <sound/core.h>
index 5e707effdc7cac127d30db367e7228469b526170..deb04b924122e5b2d27284fba322b923370cc031 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/trident.h>
 #include <sound/initval.h>
index 5bd57a7c52d20bb39bd9ff07a96dd400794f4ef7..61d3c0e8d4cead73f79547bf2b3d6f65286bf521 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/vmalloc.h>
 #include <linux/gameport.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
index c3656fffdb50d3da870b2b3d70e7a1319999e221..ae98d56d05bd0e89583db264ef46ca783a5e26ba 100644 (file)
@@ -53,7 +53,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index a386dd9f6732b1d254ec5160623295014e375eaa..80a9c2bf3301f61a706360ab15bfbe5f895e9aaf 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 5342d5e1366a30970103c209da2a9b1f78a800e9..6765822fb3b7bf8fd1480688f3fd638ff9b298d0 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
index 3253b04da18449ecd7a2a0dfad911b9c2c065b64..e97ddcac0d371e11e62dac689af5a459061d7848 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/time.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/ymfpci.h>
 #include <sound/mpu401.h>
index 66ea71b2a70d0968b12cebbea383bd8f9a1f23d2..03ee4e3653113820674ad6234fb0017c69dae91e 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
index 66488a7a57060d1f227c52851460e4789c7ec722..6af41d2d8fc516753a91909ce7e8f51e4ccacb47 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <sound/core.h>
 #include <linux/slab.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <pcmcia/ciscode.h>
 #include <pcmcia/cisreg.h>
 #include "pdaudiocf.h"
index 31777d1ea49f9fb00dc7dcce8ff9b8df3eba9431..9e361c9d5bf33d63e81452458a7e36070080e8c2 100644 (file)
@@ -20,7 +20,7 @@
 
 
 #include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include "vxpocket.h"
index a2b69b8cff43f73d48674f894e1bd74884d68a7b..65645693c485c629135738acd3661e452eef34ce 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "pmac.h"
index 775bd95d4be6594ceb478c4824e27d4a8c815337..1aa52eff526a1d97094caa525681b25ca4c8d4e8 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <sound/asound.h>
 #include <sound/control.h>
@@ -875,7 +876,7 @@ static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
                (0x0fUL << 12) |
                (PS3_AUDIO_IOID);
 
-       ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0);
+       ret = lv1_gpu_attribute(0x100, 0x007, val);
        if (ret)
                pr_info("%s: gpu_attribute failed %d\n", __func__,
                        ret);
index 94c6ea7fa7c24b4148fbda72e56ef93d2f27442a..1120ca49edd00c6b668944e6905d2abfb7fbb438 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/firmware.h>
 #include <linux/timer.h>
index 68e0dee4ff0593a0ad56fc4f2583c2c13c4312de..56bcb46abf0d255693d9b3bec415b328c781abde 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index bee3c94f58b0736c57f361141e0ed32e58640317..d1fcc816ce9705c5aca82f68eb327d65618301cd 100644 (file)
@@ -1,6 +1,6 @@
 config SND_ATMEL_SOC
        tristate "SoC Audio for the Atmel System-on-Chip"
-       depends on ARCH_AT91 || AVR32
+       depends on ARCH_AT91
        help
          Say Y or M if you want to add support for codecs attached to
          the ATMEL SSC interface. You will also need
@@ -24,25 +24,6 @@ config SND_AT91_SOC_SAM9G20_WM8731
          Say Y if you want to add support for SoC audio on WM8731-based
          AT91sam9g20 evaluation board.
 
-config SND_AT32_SOC_PLAYPAQ
-        tristate "SoC Audio support for PlayPaq with WM8510"
-        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
-        select SND_ATMEL_SOC_SSC
-        select SND_SOC_WM8510
-        help
-          Say Y or M here if you want to add support for SoC audio
-          on the LRS PlayPaq.
-
-config SND_AT32_SOC_PLAYPAQ_SLAVE
-        bool "Run CODEC on PlayPaq in slave mode"
-        depends on SND_AT32_SOC_PLAYPAQ
-        default n
-        help
-          Say Y if you want to run with the AT32 SSC generating the BCLK
-          and FRAME signals on the PlayPaq.  Unless you want to play
-          with the AT32 as the SSC master, you probably want to say N here,
-          as this will give you better sound quality.
-
 config SND_AT91_SOC_AFEB9260
        tristate "SoC Audio support for AFEB9260 board"
        depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
index e7ea56bd5f82a94de94d4169c464e809d34dfb5e..a5c0bf19da78f01e823fc614c61528c30272a67c 100644 (file)
@@ -8,9 +8,5 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
 # AT91 Machine Support
 snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
 
-# AT32 Machine Support
-snd-soc-playpaq-objs := playpaq_wm8510.o
-
 obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
-obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
 obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
deleted file mode 100644 (file)
index 73ae99a..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/* sound/soc/at32/playpaq_wm8510.c
- * ASoC machine driver for PlayPaq using WM8510 codec
- *
- * Copyright (C) 2008 Long Range Systems
- *    Geoffrey Wossum <gwossum@acm.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c
- *
- * NOTE: If you don't have the AT32 enhanced portmux configured (which
- * isn't currently in the mainline or Atmel patched kernel), you will
- * need to set the MCLK pin (PA30) to peripheral A in your board initialization
- * code.  Something like:
- *     at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
- *
- */
-
-/* #define DEBUG */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/at32ap700x.h>
-#include <mach/portmux.h>
-
-#include "../codecs/wm8510.h"
-#include "atmel-pcm.h"
-#include "atmel_ssc_dai.h"
-
-
-/*-------------------------------------------------------------------------*\
- * constants
-\*-------------------------------------------------------------------------*/
-#define MCLK_PIN               GPIO_PIN_PA(30)
-#define MCLK_PERIPH            GPIO_PERIPH_A
-
-
-/*-------------------------------------------------------------------------*\
- * data types
-\*-------------------------------------------------------------------------*/
-/* SSC clocking data */
-struct ssc_clock_data {
-       /* CMR div */
-       unsigned int cmr_div;
-
-       /* Frame period (as needed by xCMR.PERIOD) */
-       unsigned int period;
-
-       /* The SSC clock rate these settings where calculated for */
-       unsigned long ssc_rate;
-};
-
-
-/*-------------------------------------------------------------------------*\
- * module data
-\*-------------------------------------------------------------------------*/
-static struct clk *_gclk0;
-static struct clk *_pll0;
-
-#define CODEC_CLK (_gclk0)
-
-
-/*-------------------------------------------------------------------------*\
- * Sound SOC operations
-\*-------------------------------------------------------------------------*/
-#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
-static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
-       struct snd_pcm_hw_params *params,
-       struct snd_soc_dai *cpu_dai)
-{
-       struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
-       struct ssc_device *ssc = ssc_p->ssc;
-       struct ssc_clock_data cd;
-       unsigned int rate, width_bits, channels;
-       unsigned int bitrate, ssc_div;
-       unsigned actual_rate;
-
-
-       /*
-        * Figure out required bitrate
-        */
-       rate = params_rate(params);
-       channels = params_channels(params);
-       width_bits = snd_pcm_format_physical_width(params_format(params));
-       bitrate = rate * width_bits * channels;
-
-
-       /*
-        * Figure out required SSC divider and period for required bitrate
-        */
-       cd.ssc_rate = clk_get_rate(ssc->clk);
-       ssc_div = cd.ssc_rate / bitrate;
-       cd.cmr_div = ssc_div / 2;
-       if (ssc_div & 1) {
-               /* round cmr_div up */
-               cd.cmr_div++;
-       }
-       cd.period = width_bits - 1;
-
-
-       /*
-        * Find actual rate, compare to requested rate
-        */
-       actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1));
-       pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n",
-                rate, actual_rate);
-
-
-       return cd;
-}
-#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
-
-
-
-static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
-                                   struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
-       struct ssc_device *ssc = ssc_p->ssc;
-       unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
-       int ret;
-
-
-       /* Due to difficulties with getting the correct clocks from the AT32's
-        * PLL0, we're going to let the CODEC be in charge of all the clocks
-        */
-#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
-       const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
-                                 SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBM_CFM);
-#else
-       struct ssc_clock_data cd;
-       const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
-                                 SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBS_CFS);
-#endif
-
-       if (ssc == NULL) {
-               pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n");
-               return -EINVAL;
-       }
-
-
-       /*
-        * Figure out PLL and BCLK dividers for WM8510
-        */
-       switch (params_rate(params)) {
-       case 48000:
-               pll_out = 24576000;
-               mclk_div = WM8510_MCLKDIV_2;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       case 44100:
-               pll_out = 22579200;
-               mclk_div = WM8510_MCLKDIV_2;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       case 22050:
-               pll_out = 22579200;
-               mclk_div = WM8510_MCLKDIV_4;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       case 16000:
-               pll_out = 24576000;
-               mclk_div = WM8510_MCLKDIV_6;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       case 11025:
-               pll_out = 22579200;
-               mclk_div = WM8510_MCLKDIV_8;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       case 8000:
-               pll_out = 24576000;
-               mclk_div = WM8510_MCLKDIV_12;
-               bclk = WM8510_BCLKDIV_8;
-               break;
-
-       default:
-               pr_warning("playpaq_wm8510: Unsupported sample rate %d\n",
-                          params_rate(params));
-               return -EINVAL;
-       }
-
-
-       /*
-        * set CPU and CODEC DAI configuration
-        */
-       ret = snd_soc_dai_set_fmt(codec_dai, fmt);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: "
-                          "Failed to set CODEC DAI format (%d)\n",
-                          ret);
-               return ret;
-       }
-       ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: "
-                          "Failed to set CPU DAI format (%d)\n",
-                          ret);
-               return ret;
-       }
-
-
-       /*
-        * Set CPU clock configuration
-        */
-#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
-       cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai);
-       pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n",
-                cd.cmr_div, cd.period);
-       ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n",
-                          ret);
-               return ret;
-       }
-       ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD,
-                                         cd.period);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: "
-                          "Failed to set CPU transmit period (%d)\n",
-                          ret);
-               return ret;
-       }
-#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
-
-
-       /*
-        * Set CODEC clock configuration
-        */
-       pr_debug("playpaq_wm8510: "
-                "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n",
-                clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div);
-
-
-#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
-       ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk);
-       if (ret < 0) {
-               pr_warning
-                   ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n",
-                    ret);
-               return ret;
-       }
-#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
-
-
-       ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
-                                        clk_get_rate(CODEC_CLK), pll_out);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
-                          ret);
-               return ret;
-       }
-
-
-       ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div);
-       if (ret < 0) {
-               pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n",
-                          ret);
-               return ret;
-       }
-
-
-       return 0;
-}
-
-
-
-static struct snd_soc_ops playpaq_wm8510_ops = {
-       .hw_params = playpaq_wm8510_hw_params,
-};
-
-
-
-static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = {
-       SND_SOC_DAPM_MIC("Int Mic", NULL),
-       SND_SOC_DAPM_SPK("Ext Spk", NULL),
-};
-
-
-
-static const struct snd_soc_dapm_route intercon[] = {
-       /* speaker connected to SPKOUT */
-       {"Ext Spk", NULL, "SPKOUTP"},
-       {"Ext Spk", NULL, "SPKOUTN"},
-
-       {"Mic Bias", NULL, "Int Mic"},
-       {"MICN", NULL, "Mic Bias"},
-       {"MICP", NULL, "Mic Bias"},
-};
-
-
-
-static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int i;
-
-       /*
-        * Add DAPM widgets
-        */
-       for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
-               snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]);
-
-
-
-       /*
-        * Setup audio path interconnects
-        */
-       snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
-
-
-
-       /* always connected pins */
-       snd_soc_dapm_enable_pin(dapm, "Int Mic");
-       snd_soc_dapm_enable_pin(dapm, "Ext Spk");
-
-
-
-       /* Make CSB show PLL rate */
-       snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV,
-                                      WM8510_OPCLKDIV_1 | 4);
-
-       return 0;
-}
-
-
-
-static struct snd_soc_dai_link playpaq_wm8510_dai = {
-       .name = "WM8510",
-       .stream_name = "WM8510 PCM",
-       .cpu_dai_name= "atmel-ssc-dai.0",
-       .platform_name = "atmel-pcm-audio",
-       .codec_name = "wm8510-codec.0-0x1a",
-       .codec_dai_name = "wm8510-hifi",
-       .init = playpaq_wm8510_init,
-       .ops = &playpaq_wm8510_ops,
-};
-
-
-
-static struct snd_soc_card snd_soc_playpaq = {
-       .name = "LRS_PlayPaq_WM8510",
-       .dai_link = &playpaq_wm8510_dai,
-       .num_links = 1,
-};
-
-static struct platform_device *playpaq_snd_device;
-
-
-static int __init playpaq_asoc_init(void)
-{
-       int ret = 0;
-
-       /*
-        * Configure MCLK for WM8510
-        */
-       _gclk0 = clk_get(NULL, "gclk0");
-       if (IS_ERR(_gclk0)) {
-               _gclk0 = NULL;
-               ret = PTR_ERR(_gclk0);
-               goto err_gclk0;
-       }
-       _pll0 = clk_get(NULL, "pll0");
-       if (IS_ERR(_pll0)) {
-               _pll0 = NULL;
-               ret = PTR_ERR(_pll0);
-               goto err_pll0;
-       }
-       ret = clk_set_parent(_gclk0, _pll0);
-       if (ret) {
-               pr_warning("snd-soc-playpaq: "
-                          "Failed to set PLL0 as parent for DAC clock\n");
-               goto err_set_clk;
-       }
-       clk_set_rate(CODEC_CLK, 12000000);
-       clk_enable(CODEC_CLK);
-
-#if defined CONFIG_AT32_ENHANCED_PORTMUX
-       at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0);
-#endif
-
-
-       /*
-        * Create and register platform device
-        */
-       playpaq_snd_device = platform_device_alloc("soc-audio", 0);
-       if (playpaq_snd_device == NULL) {
-               ret = -ENOMEM;
-               goto err_device_alloc;
-       }
-
-       platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq);
-
-       ret = platform_device_add(playpaq_snd_device);
-       if (ret) {
-               pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n",
-                          ret);
-               goto err_device_add;
-       }
-
-       return 0;
-
-
-err_device_add:
-       if (playpaq_snd_device != NULL) {
-               platform_device_put(playpaq_snd_device);
-               playpaq_snd_device = NULL;
-       }
-err_device_alloc:
-err_set_clk:
-       if (_pll0 != NULL) {
-               clk_put(_pll0);
-               _pll0 = NULL;
-       }
-err_pll0:
-       if (_gclk0 != NULL) {
-               clk_put(_gclk0);
-               _gclk0 = NULL;
-       }
-       return ret;
-}
-
-
-static void __exit playpaq_asoc_exit(void)
-{
-       if (_gclk0 != NULL) {
-               clk_put(_gclk0);
-               _gclk0 = NULL;
-       }
-       if (_pll0 != NULL) {
-               clk_put(_pll0);
-               _pll0 = NULL;
-       }
-
-#if defined CONFIG_AT32_ENHANCED_PORTMUX
-       at32_free_pin(MCLK_PIN);
-#endif
-
-       platform_device_unregister(playpaq_snd_device);
-       playpaq_snd_device = NULL;
-}
-
-module_init(playpaq_asoc_init);
-module_exit(playpaq_asoc_exit);
-
-MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
-MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq");
-MODULE_LICENSE("GPL");
index a2d40349fcc4113e7892ceb61401af2a140f9e07..2fd9f2a06968b8122f83325eccc4cbe1d885e751 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
 #include <linux/bug.h>
+#include <linux/module.h>
 #include <asm/portmux.h>
 #include <asm/dma.h>
 #include <asm/blackfin.h>
index 8d014d01626e85c367700e2baa3a54844dc2d742..897cfa68a2a668789b8844c00167b51eb1a12887 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index 3c087936aa57028b11b0567d5165088a4aa5aed9..e715186b430064a33c939b9863da91f734e2af54 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
index 444747f0db26615992e360b6a162eaf7b9f9ac44..dd7be0dbbc58189ff153b1a7b5724967bd4caadd 100644 (file)
@@ -34,7 +34,7 @@
 
 #define AD1836_ADC_CTRL2               13
 #define AD1836_ADC_WORD_LEN_MASK       0x30
-#define AD1836_ADC_WORD_OFFSET         5
+#define AD1836_ADC_WORD_OFFSET         4
 #define AD1836_ADC_SERFMT_MASK         (7 << 6)
 #define AD1836_ADC_SERFMT_PCK256       (0x4 << 6)
 #define AD1836_ADC_SERFMT_PCK128       (0x5 << 6)
index 1ccf8dd47576ce4c746ffb54461c19f196acff43..45c63028b40d1636b56f6aa3e5f13e0d110b9a5d 100644 (file)
@@ -245,7 +245,7 @@ static const char *adau1373_bass_hpf_cutoff_text[] = {
 };
 
 static const unsigned int adau1373_bass_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(3),
        0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1),
        3, 4, TLV_DB_SCALE_ITEM(950, 250, 0),
        5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0),
index 8402854ec15e30b320d31e1416896ced2f964850..9082e0f729f307d626cd467bc0c777993cd987f8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
index d8fc04486abbf31546d4da99f46d5b2cd916fc5a..12c1bdef67323f5f260290c037ce23f50dff42de 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
index f1f237ecec2a6c43dcdf9ee31b72da7f0cdecff6..73f46eb459f15fa43c5aadc89c2d5a61346fb351 100644 (file)
@@ -601,7 +601,6 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
 static int cs4270_soc_resume(struct snd_soc_codec *codec)
 {
        struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
-       struct i2c_client *i2c_client = to_i2c_client(codec->dev);
        int reg;
 
        regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
@@ -612,14 +611,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
        ndelay(500);
 
        /* first restore the entire register cache ... */
-       for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
-               u8 val = snd_soc_read(codec, reg);
-
-               if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
-                       dev_err(codec->dev, "i2c write failed\n");
-                       return -EIO;
-               }
-       }
+       snd_soc_cache_sync(codec);
 
        /* ... then disable the power-down bits */
        reg = snd_soc_read(codec, CS4270_PWRCTL);
index 23d1bd5dadda36185e2c56702e7fd17a739f9a1a..69fde1506fe1fde2fe312ff80176723171ccef07 100644 (file)
@@ -434,7 +434,8 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
 {
        int ret;
        /* Set power-down bit */
-       ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
+       ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN,
+                                 CS4271_MODE2_PDN);
        if (ret < 0)
                return ret;
        return 0;
@@ -501,8 +502,9 @@ static int cs4271_probe(struct snd_soc_codec *codec)
                return ret;
        }
 
-       ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
-               CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
+       ret = snd_soc_update_bits(codec, CS4271_MODE2,
+                                 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
+                                 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
        if (ret < 0)
                return ret;
        ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
index 8c3c8205d19e99016e47b1564aa58cbdf91b0bab..1ee66361f61b946e5738798daf03d61baf2f8ecb 100644 (file)
@@ -555,7 +555,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
        .probe =        cs42l51_probe,
-       .reg_cache_size = CS42L51_NUMREGS,
+       .reg_cache_size = CS42L51_NUMREGS + 1,
        .reg_word_size = sizeof(u8),
 };
 
index d68ea532cc7f59a52e46be1a89ccf4d0c35ad518..bc7067db8ae4ec54697c4163e23f97af3670bd19 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/tty.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
index 0ebcbd534490c7ac7d7ab10921e6278aea55befa..b545b7d3722271dd14e43213a34992a0b5174525 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
index f9a87737ec16876c14b3602408c149ea26fa913f..6fae765e3ad8baf3611f7251bd3240e2c6591a06 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index 9e7e964a5fa3fd1a8824c17c9dad4bbc60923909..dcf6f2a1600ae5726a60d0a7e11ef6e53d57d466 100644 (file)
@@ -106,13 +106,13 @@ static int max9877_set_2reg(struct snd_kcontrol *kcontrol,
        unsigned int mask = mc->max;
        unsigned int val = (ucontrol->value.integer.value[0] & mask);
        unsigned int val2 = (ucontrol->value.integer.value[1] & mask);
-       unsigned int change = 1;
+       unsigned int change = 0;
 
-       if (((max9877_regs[reg] >> shift) & mask) == val)
-               change = 0;
+       if (((max9877_regs[reg] >> shift) & mask) != val)
+               change = 1;
 
-       if (((max9877_regs[reg2] >> shift) & mask) == val2)
-               change = 0;
+       if (((max9877_regs[reg2] >> shift) & mask) != val2)
+               change = 1;
 
        if (change) {
                max9877_regs[reg] &= ~(mask << shift);
index bd8f26e41602cf2fe8bcb36dd423bc62a1c1c521..f7316519432c42dcdb6122bd17009672217ad72f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
index 27a078cbb6eb2542cb6bc0fa0be372b5a77cabac..4646e808b90a334e0d59935a1e93244672d276be 100644 (file)
@@ -177,7 +177,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
 static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
 /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
 static unsigned int mic_bst_tlv[] = {
-       TLV_DB_RANGE_HEAD(6),
+       TLV_DB_RANGE_HEAD(7),
        0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
        1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
        2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
index d15695d1c27397a7b3f2966c1806584e5e9a39bc..bbcf921166f7470fad24577d2aa52d1cf85258f4 100644 (file)
@@ -365,7 +365,7 @@ static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
 
 /* tlv for mic gain, 0db 20db 30db 40db */
 static const unsigned int mic_gain_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
        1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
 };
index f681e41fc12efa291b61ed9308eb853d85a6c14f..887d618f4a639720b7e0698e086333f203175a7a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/intel_scu_ipc.h>
 #include <sound/pcm.h>
index bb82408ab8e1bb93f187dac610e5a1141501bd72..d2f37152f940cebc67f93a5bff140e64a67a07e7 100644 (file)
@@ -76,6 +76,8 @@ struct sta32x_priv {
 
        unsigned int mclk;
        unsigned int format;
+
+       u32 coef_shadow[STA32X_COEF_COUNT];
 };
 
 static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
@@ -227,6 +229,7 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud;
@@ -239,6 +242,11 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        snd_soc_write(codec, STA32X_CFUD, cfud);
 
        snd_soc_write(codec, STA32X_CFADDR2, index);
+       for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
+               sta32x->coef_shadow[index + i] =
+                         (ucontrol->value.bytes.data[3 * i] << 16)
+                       | (ucontrol->value.bytes.data[3 * i + 1] << 8)
+                       | (ucontrol->value.bytes.data[3 * i + 2]);
        for (i = 0; i < 3 * numcoef; i++)
                snd_soc_write(codec, STA32X_B1CF1 + i,
                              ucontrol->value.bytes.data[i]);
@@ -252,6 +260,48 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+{
+       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       unsigned int cfud;
+       int i;
+
+       /* preserve reserved bits in STA32X_CFUD */
+       cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
+
+       for (i = 0; i < STA32X_COEF_COUNT; i++) {
+               snd_soc_write(codec, STA32X_CFADDR2, i);
+               snd_soc_write(codec, STA32X_B1CF1,
+                             (sta32x->coef_shadow[i] >> 16) & 0xff);
+               snd_soc_write(codec, STA32X_B1CF2,
+                             (sta32x->coef_shadow[i] >> 8) & 0xff);
+               snd_soc_write(codec, STA32X_B1CF3,
+                             (sta32x->coef_shadow[i]) & 0xff);
+               /* chip documentation does not say if the bits are
+                * self-clearing, so do it explicitly */
+               snd_soc_write(codec, STA32X_CFUD, cfud);
+               snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
+       }
+       return 0;
+}
+
+int sta32x_cache_sync(struct snd_soc_codec *codec)
+{
+       unsigned int mute;
+       int rc;
+
+       if (!codec->cache_sync)
+               return 0;
+
+       /* mute during register sync */
+       mute = snd_soc_read(codec, STA32X_MMUTE);
+       snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
+       sta32x_sync_coef_shadow(codec);
+       rc = snd_soc_cache_sync(codec);
+       snd_soc_write(codec, STA32X_MMUTE, mute);
+       return rc;
+}
+
 #define SINGLE_COEF(xname, index) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .info = sta32x_coefficient_info, \
@@ -661,7 +711,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                                return ret;
                        }
 
-                       snd_soc_cache_sync(codec);
+                       sta32x_cache_sync(codec);
                }
 
                /* Power up to mute */
@@ -790,6 +840,17 @@ static int sta32x_probe(struct snd_soc_codec *codec)
                            STA32X_CxCFG_OM_MASK,
                            2 << STA32X_CxCFG_OM_SHIFT);
 
+       /* initialize coefficient shadow RAM with reset values */
+       for (i = 4; i <= 49; i += 5)
+               sta32x->coef_shadow[i] = 0x400000;
+       for (i = 50; i <= 54; i++)
+               sta32x->coef_shadow[i] = 0x7fffff;
+       sta32x->coef_shadow[55] = 0x5a9df7;
+       sta32x->coef_shadow[56] = 0x7fffff;
+       sta32x->coef_shadow[59] = 0x7fffff;
+       sta32x->coef_shadow[60] = 0x400000;
+       sta32x->coef_shadow[61] = 0x400000;
+
        sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
index b97ee5a75667399e77a5bcd7493432407d554cc2..d8e32a6262ee087ec13e73d24e57b936eefaa42b 100644 (file)
@@ -19,6 +19,7 @@
 /* STA326 register addresses */
 
 #define STA32X_REGISTER_COUNT  0x2d
+#define STA32X_COEF_COUNT 62
 
 #define STA32X_CONFA   0x00
 #define STA32X_CONFB    0x01
index c5ca8cfea60f80f8de27cc5d12ad55f69bd900f2..0441893e270ed2b5621833fecc997b6b20f85159 100644 (file)
@@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = {
 
 static int __init uda1380_modinit(void)
 {
-       int ret;
+       int ret = 0;
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        ret = i2c_add_driver(&uda1380_i2c_driver);
        if (ret != 0)
                pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
 #endif
-       return 0;
+       return ret;
 }
 module_init(uda1380_modinit);
 
index 9fa14299cf2c1c4079fe5860f4b3ca793a3f4a1b..a854989829911a62eae6fdf3cf3336b917f748c4 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/mfd/wl1273-core.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
index 7e5ec03f6f8dd579d1bd43413fd1d007a1989bcb..a7c9ae17fc7eb0e743a8dbfb27db88fea58a456e 100644 (file)
@@ -453,6 +453,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
                snd_soc_write(codec, WM8731_PWR, 0xffff);
                regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
                                       wm8731->supplies);
+               codec->cache_sync = 1;
                break;
        }
        codec->dapm.bias_level = level;
index a9504710bb692e806655e785e5f35121ecf4afc1..3a629d0d690ed1fbe8129f096e0edf492faf9eb2 100644 (file)
@@ -190,6 +190,9 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
        struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
        u16 ioctl;
 
+       if (wm8753->dai_func == ucontrol->value.integer.value[0])
+               return 0;
+
        if (codec->active)
                return -EBUSY;
 
index 91d3c6dbeba3317758d747a6c6568cae625ea79e..53edd9a8c758f24943de1219b37cb45602fc11ef 100644 (file)
@@ -1973,7 +1973,7 @@ static int wm8962_reset(struct snd_soc_codec *codec)
 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
 static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0);
 static const unsigned int mixinpga_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(5),
        0, 1, TLV_DB_SCALE_ITEM(0, 600, 0),
        2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0),
        3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0),
@@ -1988,7 +1988,7 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
 static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0);
 static const unsigned int classd_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index eec8e143511665a538c6950a4f679ad217aad827..d1a142f48b09f03fb565a5c4a6419842a854c6f6 100644 (file)
@@ -512,7 +512,7 @@ static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0);
 static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0);
 static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
 static const unsigned int drc_max_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
        3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
 };
index 6b73efd269917367293021edde0f330ee7c3b722..d0c545b73d7865c04b9fefd286b85b7fe63fc5b2 100644 (file)
@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = {
 static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-       struct wm8994 *control = wm8994->control_data;
+       struct wm8994 *control = codec->control_data;
 
        switch (reg) {
        case WM8994_GPIO_1:
@@ -1325,15 +1325,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
 };
 
 static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = {
-SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux,
-                  adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux,
-                  adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
+SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux,
+                       adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
+SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux,
+                       adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
 };
 
 static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = {
-SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
-SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
+SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
+SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
 };
 
 static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
@@ -2357,6 +2357,11 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
        bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
 
        lrclk = bclk_rate / params_rate(params);
+       if (!lrclk) {
+               dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n",
+                       bclk_rate);
+               return -EINVAL;
+       }
        dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
                lrclk, bclk_rate / lrclk);
 
@@ -3030,19 +3035,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
 {
        struct wm8994_priv *wm8994 = data;
        struct snd_soc_codec *codec = wm8994->codec;
-       int reg;
+       int reg, count;
 
-       reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
-       if (reg < 0) {
-               dev_err(codec->dev, "Failed to read mic detect status: %d\n",
-                       reg);
-               return IRQ_NONE;
-       }
+       /* We may occasionally read a detection without an impedence
+        * range being provided - if that happens loop again.
+        */
+       count = 10;
+       do {
+               reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
+               if (reg < 0) {
+                       dev_err(codec->dev,
+                               "Failed to read mic detect status: %d\n",
+                               reg);
+                       return IRQ_NONE;
+               }
 
-       if (!(reg & WM8958_MICD_VALID)) {
-               dev_dbg(codec->dev, "Mic detect data not valid\n");
-               goto out;
-       }
+               if (!(reg & WM8958_MICD_VALID)) {
+                       dev_dbg(codec->dev, "Mic detect data not valid\n");
+                       goto out;
+               }
+
+               if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK))
+                       break;
+
+               msleep(1);
+       } while (count--);
+
+       if (count == 0)
+               dev_warn(codec->dev, "No impedence range reported for jack\n");
 
 #ifndef CONFIG_SND_SOC_WM8994_MODULE
        trace_snd_soc_jack_irq(dev_name(codec->dev));
@@ -3163,6 +3183,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                switch (wm8994->revision) {
                case 0:
                case 1:
+               case 2:
+               case 3:
                        wm8994->hubs.dcs_codes_l = -9;
                        wm8994->hubs.dcs_codes_r = -5;
                        break;
@@ -3180,9 +3202,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 
        wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
                           wm8994_fifo_error, "FIFO error", codec);
-       wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN,
+       wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN,
                           wm8994_temp_warn, "Thermal warning", codec);
-       wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT,
+       wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT,
                           wm8994_temp_shut, "Thermal shutdown", codec);
 
        ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
index 3cd35a02c28c7164f525f00f7375ac5ef4d6bbb1..4a398c3bfe84aea9ef4f6c8540f09b8b2bf34282 100644 (file)
@@ -807,7 +807,6 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                        mdelay(100);
 
                        /* Normal bias enable & soft start off */
-                       reg |= WM9081_BIAS_ENA;
                        reg &= ~WM9081_VMID_RAMP;
                        snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
 
@@ -818,7 +817,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                }
 
                /* VMID 2*240k */
-               reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
+               reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
                reg &= ~WM9081_VMID_SEL_MASK;
                reg |= 0x04;
                snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
@@ -830,14 +829,15 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               /* Startup bias source */
+               /* Startup bias source and disable bias */
                reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
                reg |= WM9081_BIAS_SRC;
+               reg &= ~WM9081_BIAS_ENA;
                snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
 
-               /* Disable VMID and biases with soft ramping */
+               /* Disable VMID with soft ramping */
                reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-               reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA);
+               reg &= ~WM9081_VMID_SEL_MASK;
                reg |= WM9081_VMID_RAMP;
                snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
 
index 2b5252c9e37774963a55626e284878e7ff777414..f94c06057c64c31ac6e4bd70fbf80799cc52837d 100644 (file)
@@ -177,19 +177,19 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
 }
 
 static const unsigned int in_tlv[] = {
-       TLV_DB_RANGE_HEAD(6),
+       TLV_DB_RANGE_HEAD(3),
        0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
        1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
        4, 6, TLV_DB_SCALE_ITEM(600, 600, 0),
 };
 static const unsigned int mix_tlv[] = {
-       TLV_DB_RANGE_HEAD(4),
+       TLV_DB_RANGE_HEAD(2),
        0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
        3, 3, TLV_DB_SCALE_ITEM(0, 0, 0),
 };
 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
 static const unsigned int spkboost_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index 84f33d4ea2cd5ec5461d0f8518c2462c3a58d544..48e61e912400fb2d2cca4ad74d9faf17a3075444 100644 (file)
@@ -40,7 +40,7 @@ static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0);
 static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1);
 static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0);
 static const unsigned int spkboost_tlv[] = {
-       TLV_DB_RANGE_HEAD(7),
+       TLV_DB_RANGE_HEAD(2),
        0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
        7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
 };
index 0134d4e9131c9dddff7b298eed13da3cd9b948bb..51930b6a83af193f3f802df490df3f00b7930cd1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index f74ac54c285a8a2c7598c336b988f85612f83365..2cde43321eecc44545a9a1415c9b96d1780f3766 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index 0268cf989736f303a224fbd26b0db2e8bf97f2ed..83c4bd5b2dd76bbf3f401c5a6bf0159d337f29b4 100644 (file)
@@ -694,6 +694,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
 
        /* Initialize the the device_attribute structure */
        dev_attr = &ssi_private->dev_attr;
+       sysfs_attr_init(&dev_attr->attr);
        dev_attr->attr.name = "statistics";
        dev_attr->attr.mode = S_IRUGO;
        dev_attr->show = fsl_sysfs_ssi_show;
index 31af405bda843cc691e755cc6bb4a0afec78925f..ae49f1c78c6de797bd193946b1d350aa00bd8a40 100644 (file)
@@ -392,7 +392,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
        }
 
        if (strcasecmp(sprop, "i2s-slave") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_I2S;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
 
@@ -409,31 +410,38 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
                }
                machine_data->clk_frequency = be32_to_cpup(iprop);
        } else if (strcasecmp(sprop, "i2s-master") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_I2S;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
        } else if (strcasecmp(sprop, "lj-slave") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
        } else if (strcasecmp(sprop, "lj-master") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
        } else if (strcasecmp(sprop, "rj-slave") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
        } else if (strcasecmp(sprop, "rj-master") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
        } else if (strcasecmp(sprop, "ac97-slave") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_AC97;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
        } else if (strcasecmp(sprop, "ac97-master") == 0) {
-               machine_data->dai_format = SND_SOC_DAIFMT_AC97;
+               machine_data->dai_format =
+                       SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
                machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
                machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
        } else {
index b133bfcc5848ea8f6ec3c7cab18772ac18bc07b9..738391757f2ccb1a5aa6a8883de0ba127fedea68 100644 (file)
@@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1
 
 config SND_SOC_MX27VIS_AIC32X4
        tristate "SoC audio support for Visstrim M10 boards"
-       depends on MACH_IMX27_VISSTRIM_M10
+       depends on MACH_IMX27_VISSTRIM_M10 && I2C
        select SND_SOC_TLV320AIC32X4
        select SND_MXC_SOC_MX2
        help
index 75b4c72787e2a34e2c4ab31a2933e8349bde46a3..490a1260c228c059acdbb6d2f0324c2b782b2431 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include <sound/pcm.h>
index 8f49e165f4d1dd40119143b3b971a2b2f964025c..c62d715235e29ac5fa20639271d79958a57fd853 100644 (file)
@@ -12,6 +12,7 @@ config SND_KIRKWOOD_SOC_I2S
 config SND_KIRKWOOD_SOC_OPENRD
        tristate "SoC Audio support for Kirkwood Openrd Client"
        depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE)
+       depends on I2C
        select SND_KIRKWOOD_SOC_I2S
        select SND_SOC_CS42L51
        help
@@ -20,7 +21,7 @@ config SND_KIRKWOOD_SOC_OPENRD
 
 config SND_KIRKWOOD_SOC_T5325
        tristate "SoC Audio support for HP t5325"
-       depends on SND_KIRKWOOD_SOC && MACH_T5325
+       depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C
        select SND_KIRKWOOD_SOC_I2S
        select SND_SOC_ALC5623
        help
index 598f48c0d8f5de74a3ee863b44c19c150e9edd0e..cca693ae1bd444e5b12d7617f56a160453dafd9e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
index 7df8c58ba50ae3ae0015e3f7cb915049a71cfb5c..23057020aa0fb01abff851ae0fa4e3f75d9cf30c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 9c0edad90d8b4b3591c7c3a23f4c03b9e42594c1..a4e3237956e26dc499602f9b7397cf196c7ee5ec 100644 (file)
@@ -365,7 +365,8 @@ static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
        if (ret)
                goto out3;
 
-       mfp_set_groupg(nuc900_audio->dev); /* enbale ac97 multifunction pin*/
+       /* enbale ac97 multifunction pin */
+       mfp_set_groupg(nuc900_audio->dev, "nuc900-audio");
 
        return 0;
 
index 8da55e916451f499aa976c2ea2341be9d7cb52dd..c1cd4a0cbe9e6f573625c42acd0883fe20bb7e3e 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index dcb7b689a4eae468f47eea2a794dec5a0b2906cd..ccb8a6aa1817acec4d71f0b5988faaf547e35599 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/gpio.h>
 #include <linux/spinlock.h>
 #include <linux/tty.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/jack.h>
index 84615a7de6adcd98ff7d808f73439a51a67df49d..591fbf8f7cd95a57002c1980e7ac9233e55fc710 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index 7e3c20c965c69c529d6eecef8acf0070d861c3c6..fc6209b3f20c92ae4b1824fb29a13624b7b1f1d5 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <plat/mcbsp.h>
 
 #include "omap-mcbsp.h"
index 5e37ec915de2a30e808583443a328a4220041fd3..6ede7dc6c10a9ef858ef6016c87f0abbd93fa9fe 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index 40db813c0795b1e485ddcdc402229eddce7a7e9d..3357dcc47ed48ccaf26fa1dfe9854c7ffb8ed0cb 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index bf9ae2a6f90199bc1a8c02e245e98a7da7122097..68578959e4aa014b93bf6c09eb59cf2cef04996a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index 30a75b406aea653dd2666deaad373de2d5204d79..7605c37c91e79f085c81d952d0fc9d09f91fdf0d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/regulator/consumer.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 9f32615b81f785d9d43f489fabed4ec61f1d7b0b..8671261ba16d3d831a72fc9ef74024f34af52939 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <asm/mach-types.h>
index db91ccaf6c97ec1bde9fd1aa8d286aead101925f..351ec9db384d4590ae6d34103e98316d80dc9a61 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/mach-types.h>
 #include <mach/hardware.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 #include <plat/mcbsp.h>
 
 #include "omap-mcbsp.h"
index 739efe9e327ad31ea194963caea116dd8b5a450e..c3550aeee533d55a2bcbb534c811a549721d99b7 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
index a56842380c724f619e755885c9a7c63a831394ca..4cabb74d97e9a3489dbd9abcb1fe3707cb70cef5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include <sound/pcm.h>
index 4f1969de91a70aa80ea87f7d918d53f574ac2ecf..e8fbf8efdbb85dc120dfc3173180851e9a05be81 100644 (file)
@@ -37,6 +37,7 @@
 
 /* Register descriptions for twl4030 codec part */
 #include <linux/mfd/twl4030-audio.h>
+#include <linux/module.h>
 
 #include "omap-mcbsp.h"
 #include "omap-pcm.h"
index cc3d792af5ead2d0761210eacba97811eb3135b4..03d9fa4192fe611a9119986ce17ed9e18648ee4c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/twl6040.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
index 7cf35c82368ad6548ba1104afd5aca4afe5cb2b0..7641a7fa8f972dc6a32460e11be18b3a3a68c889 100644 (file)
@@ -33,6 +33,7 @@
 
 /* Register descriptions for twl4030 codec part */
 #include <linux/mfd/twl4030-audio.h>
+#include <linux/module.h>
 
 #include "omap-mcbsp.h"
 #include "omap-pcm.h"
index ffd2242e305f0827fb742f2c2339041d1859785f..a0f7d3cfa470b0857586b10021290aec5b4fd20f 100644 (file)
@@ -151,6 +151,7 @@ config SND_SOC_ZYLONITE
 config SND_SOC_RAUMFELD
        tristate "SoC Audio support Raumfeld audio adapter"
        depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR)
+       depends on I2C && SPI_MASTER
        select SND_PXA_SOC_SSP
        select SND_SOC_CS4270
        select SND_SOC_AK4104
@@ -159,7 +160,7 @@ config SND_SOC_RAUMFELD
 
 config SND_PXA2XX_SOC_HX4700
        tristate "SoC Audio support for HP iPAQ hx4700"
-       depends on SND_PXA2XX_SOC && MACH_H4700
+       depends on SND_PXA2XX_SOC && MACH_H4700 && I2C
        select SND_PXA2XX_SOC_I2S
        select SND_SOC_AK4641
        help
index c43060053dd7ef780f88e5768da82de4a2a62389..600676f709a927b2c4a568d03fd8869dafff721a 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/soc.h>
index bad91b4584f9423346cf954f29725de8f03278d5..16521e3ffc0c5af67712c1cdc1cd3c00e4ad501a 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 
index 851346f7d68dc3ddf4cbb95c116b7413ef17096d..a68b2644178477dd7fd6a5c0518498e4ff5da860 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
@@ -198,10 +199,10 @@ static int dma_hw_free(struct snd_pcm_substream *substream)
 
        pr_debug("Entered %s\n", __func__);
 
-       /* TODO - do we need to ensure DMA flushed */
        snd_pcm_set_runtime_buffer(substream, NULL);
 
        if (prtd->params) {
+               prtd->params->ops->flush(prtd->params->ch);
                prtd->params->ops->release(prtd->params->ch,
                                        prtd->params->client);
                prtd->params = NULL;
index 4a34f608e131127aa73a27618e6c5870d60c1e7e..84f9c3cf7f3e18df691f4074b24bd804c5665e88 100644 (file)
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/jack.h>
 
index f75a4b60cf38a9909b2713d5b0df30fc2dd02dfd..03cfa5fcdcca9ea64b3696d76436bd6366bb9c4b 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/types.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/jack.h>
index 0c9ac20d222380870826e39505bea7240e837395..bff42bf370b9c8849874db4792150fad27328010 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
index ebde0740ab19bb24580055d0a6461a2ba9f23cbf..c41178efc9084b7c5fe3712bbb2e885f527bded5 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
index f5f7c6f822d5c4bed45cb6304b156ff09d128e28..1826acf20f7c96cf3fdca744d083c29f2bdfd837 100644 (file)
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 
 #include <asm/mach-types.h>
index bd91c19a6c08bb9fca72dffb58b95c5c3b07cb00..cde38b8e9dc23917551e67b68acbf6b1f8033aac 100644 (file)
@@ -16,6 +16,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 
 static struct snd_soc_card ln2440sbc;
index e55d7a5c4bdc59a41127004e2295e5ed730293ff..05a47cf7f06e9345285fe57d7d1688049c7c23ea 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
index aea7f1b24e6be5eda3ce138891a1928f649a9529..71b4c029fc352eefe5619b1546af5e54e32a8d32 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/types.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/jack.h>
index f26a8bfb2357429a01b6e6b33bab89c2ee04de49..7bbec25e6e158b824561da968d91ee811564858a 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
index c08117e658db748174f2b95fa2f76272abe3a93e..558c64bbed2e66f0c02d0ecd600605f2bfc1e3fa 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
index c8d525bf6122ea43f513231aab28f644681e9ae5..a253bcc1646aabee42c7b4844bcf960578f49b1b 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/gpio.h>
 #include <linux/clk.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 
index 6bc5a36af1d9c74ed7fe7a269a8ac269e6ba7ab5..d125e79baf7f4bd74e2773402312d88183b1dc00 100644 (file)
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 
 #include "s3c24xx_simtec.h"
index 7bdda76740083c365b908320c5b4c871ff4e6582..5e4fd46b7200066d917e5f0a8e00fe9ffa328394 100644 (file)
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 
 #include "s3c24xx_simtec.h"
index 65c1cfd47d8a73ae819403c3e24a5efccd5758ff..548c6ac6e7b06bdc5e9da816836a6bf3a90b7b6a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/s3c24xx_uda134x.h>
index 6ac6bc2bcc4e4c571850209bcdb45278c4a31b56..a22fc4402802bb36ee20136cfc6e13e622ed60b9 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/jack.h>
index e8ac961c6ba10140fa62768d8f6c3c29c0c15128..e0fd8ad23552d4fcb8822be2c2d6348d27607890 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 
index 8f92ffceb5cafb3b797678ea073a2fbc0a9c9647..81b447823992c46b68e0faadc7ff8085bd8a9339 100644 (file)
@@ -10,6 +10,7 @@
  *  option) any later version.
  */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
index 4b9c73477ce0d9e875256e4985ff78f70d5056ca..0677473e6b608ef5df677214258c87680687e640 100644 (file)
@@ -8,6 +8,7 @@
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
  */
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 #include <sound/pcm.h>
index f75e43997d5beb5b27a82f8d023eddd33311538e..ad9ac42522e2539faf84c6286cc1614573e441f2 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "../codecs/wm8994.h"
 #include <sound/pcm_params.h>
+#include <linux/module.h>
 
  /*
   * Default CFG switch settings to use this driver:
index 5f21116854807bb5621c4d67f44eb5b6236a5444..da9c2a264d939d47c3ab4f6f5f65b406f7423d69 100644 (file)
@@ -9,6 +9,7 @@
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
  */
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
index fffe3c1dd1bdbfe399bddee2f12550401279a545..31c6daf6d4d02ba632783c711f7e3db563f7ef63 100644 (file)
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/module.h>
 #include <sound/soc.h>
 
 static struct snd_soc_card smdk;
index 3122f3154bfa7295f0de3650533e8eafa4c8608b..468cff1bb1af62b24372a4abcb6a9d9ad4536c78 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
index b9e213f6cc0630f179d9b811d6b382dac6c64777..4b8e35410eb1962623cc31882967397747e5b3e7 100644 (file)
@@ -13,6 +13,7 @@
 #include <sound/soc-dapm.h>
 #include <sound/jack.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include "../codecs/wm8996.h"
 #include "../codecs/wm9081.h"
@@ -190,7 +191,7 @@ static int speyside_late_probe(struct snd_soc_card *card)
        snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
        snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC");
        snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC");
-       snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
+       snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker");
        snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output");
        snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input");
 
index 8a082044436e4409461129d01bc94c710b7443b1..e3e27166cc508e5caf9b054832b0a132d6ed3fe3 100644 (file)
@@ -13,6 +13,7 @@
 #include <sound/soc-dapm.h>
 #include <sound/jack.h>
 #include <linux/gpio.h>
+#include <linux/module.h>
 
 #include "../codecs/wm8962.h"
 
index 770a71a15366252066a773357028e862abe9101d..dff64b95f5dcf11671c282f850ea83af520c365b 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/sh_fsi.h>
 
 struct fsi_ak4642_data {
index 59553fd8c2fb9173a72b7da8b9fa5f70942fe8c2..f5586b5b0c3b7a135e09468871b272d6bffc158e 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/sh_fsi.h>
 
 static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
index d3d9fd880680e346e9558e4936a8bc4e84b018e6..3ebebe706ad3bf732114cfd06ede04cf412b183d 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <sound/sh_fsi.h>
 
 struct fsi_hdmi_data {
index a32fd16ad668dffe65f87e20943e5c6ec985f38b..3d7016e128f9374d2febb9564f404ed02db6b4db 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/sh_fsi.h>
 
index 4973c2939d797effc1099d8d8bc7db5dd919b27b..edacfeb13b94e3956589a999aeb78de2e2815635 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/firmware.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #include <asm/clock.h>
 #include <asm/siu.h>
index 143c705ac27b82fbefd61144be79089511c1bfd3..9077aa4b3b4ed975da4430789ff3961810e8df0e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/lzo.h>
 #include <linux/bitmap.h>
 #include <linux/rbtree.h>
+#include <linux/export.h>
 
 #include <trace/events/asoc.h>
 
index a5d3685a5d38049313391ddb8e174edd9c28a21b..a25fa63ce9a27501a4f2d4a6334911076200532e 100644 (file)
@@ -709,6 +709,12 @@ int snd_soc_resume(struct device *dev)
        struct snd_soc_card *card = dev_get_drvdata(dev);
        int i, ac97_control = 0;
 
+       /* If the initialization of this soc device failed, there is no codec
+        * associated with it. Just bail out in this case.
+        */
+       if (list_empty(&card->codec_dev_list))
+               return 0;
+
        /* AC97 devices might have other drivers hanging off them so
         * need to resume immediately.  Other drivers don't have that
         * problem and may take a substantial amount of time to resume
index dd89933e2c723c1d4f0b8b1dce46baaefdcf29b3..c8610cbf34a51cf9f2e856cc847a730f64a1d016 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/regmap.h>
+#include <linux/export.h>
 #include <sound/soc.h>
 
 #include <trace/events/asoc.h>
index 52db96636290372b40ddffaf15f6888bdbcc67b1..6c5ebd38c1b0f050f515dbb2dc1c47acaafc1ba4 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <trace/events/asoc.h>
 
 /**
index ec921ec99c2621eaa58b7d0c5e4eb97b861971de..4220bb0f27301aa962964b9eb645fd0f5e51e17c 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -57,7 +58,36 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
 }
 EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
 
-static struct snd_soc_platform_driver dummy_platform;
+static const struct snd_pcm_hardware dummy_dma_hardware = {
+       .formats                = 0xffffffff,
+       .channels_min           = 1,
+       .channels_max           = UINT_MAX,
+
+       /* Random values to keep userspace happy when checking constraints */
+       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
+                                 SNDRV_PCM_INFO_BLOCK_TRANSFER,
+       .buffer_bytes_max       = 128*1024,
+       .period_bytes_min       = PAGE_SIZE,
+       .period_bytes_max       = PAGE_SIZE*2,
+       .periods_min            = 2,
+       .periods_max            = 128,
+};
+
+static int dummy_dma_open(struct snd_pcm_substream *substream)
+{
+       snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware);
+
+       return 0;
+}
+
+static struct snd_pcm_ops dummy_dma_ops = {
+       .open           = dummy_dma_open,
+       .ioctl          = snd_pcm_lib_ioctl,
+};
+
+static struct snd_soc_platform_driver dummy_platform = {
+       .ops = &dummy_dma_ops,
+};
 
 static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
 {
index dfa85cbb05c807cbb4239963e64480814969d4f7..f8428e410e050bb4649d235038cd835284a660ab 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 #include "tegra_asoc_utils.h"
 
index 1b839a0f3653a48fabdd09de110c6be346d79b4f..4a4f1d740330d57b969c67cf1dfe65295f515e37 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/atomic.h>
+#include <linux/module.h>
 
 MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
 MODULE_DESCRIPTION("Sun DBRI");
index f16a3fce45975a30c18975519283c92695d44c15..93522072bc87c9c69cf1ea8a4031bf5d60c4386e 100644 (file)
@@ -24,6 +24,7 @@
 #include <sound/core.h>
 #include <sound/emux_synth.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include "emux_voice.h"
 
 MODULE_AUTHOR("Takashi Iwai");
index 87e42206c4ef02aabc071d56ba9c6ceedc47f453..319754cf62086ef86723a9df60c236d31edfab16 100644 (file)
@@ -25,6 +25,7 @@
 
 #ifdef CONFIG_SND_SEQUENCER_OSS
 
+#include <linux/export.h>
 #include <asm/uaccess.h>
 #include <sound/core.h>
 #include "emux_voice.h"
index ca5f7effb4df48815c2367bd8473f1e1024fefdc..7778b8e19782e24a3ca56a5aa5dff9e00bf33e4d 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "emux_voice.h"
 #include <linux/slab.h>
-
+#include <linux/module.h>
 
 /* Prototypes for static functions */
 static void free_port(void *private);
index 3e921b386fd5a6c81c70cf73611831fb83634bbf..9a38de459acb059db4d12b3ca1c9955adeebed60 100644 (file)
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/export.h>
 #include "emux_voice.h"
 #include <sound/asoundef.h>
 
index 67c91230c1977766d117ef9311f8be91708eec79..1137b85c36e6d5d9e9c103810975a6f7c79d539f 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <asm/uaccess.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <sound/core.h>
 #include <sound/soundfont.h>
 #include <sound/seq_oss_legacy.h>
index c85522e3808da75afa81283fe74c002c8a362f59..8e34bc4e07ec3a62d93d9a0d0ca693a77ba9749f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/util_mem.h>
 
index 07bcfe4d18a7a9c319fdd310f92afe5e6f160414..3b5f517a3972a0ff375d3c98a0ac750dd8e40fb8 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/module.h>
 #include <linux/bitrev.h>
 #include <linux/kernel.h>
 
index 05c1aae0b010bc84e30a87e8ce5e511dea071dbe..0f6dc0d457bf360174505d717851aed65d5352f9 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/mutex.h>
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
+#include <linux/module.h>
 
 #include <sound/control.h>
 #include <sound/core.h>
index e21f026d9577504fe4ac8aef70ef2bfc6eff04f3..c83f6143c0eb34d8f77f969e1928427458b4268a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/usb.h>
 #include <linux/wait.h>
 #include <linux/usb/audio.h>
+#include <linux/module.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
index 67bec76124421d12d7250675d6526a98bb886597..c0609c2103035b15df5e6d83694fae95d4723115 100644 (file)
@@ -459,7 +459,8 @@ static void kill_stream_urbs(struct ua101_stream *stream)
        unsigned int i;
 
        for (i = 0; i < stream->queue_length; ++i)
-               usb_kill_urb(&stream->urbs[i]->urb);
+               if (stream->urbs[i])
+                       usb_kill_urb(&stream->urbs[i]->urb);
 }
 
 static 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)
 {
        struct usb_host_interface *alts;
 
+       if (!ua->intf[intf_index])
+               return;
+
        alts = ua->intf[intf_index]->cur_altsetting;
        if (alts->desc.bAlternateSetting != 0) {
                int err = usb_set_interface(ua->dev,
@@ -1144,27 +1148,37 @@ static void free_stream_urbs(struct ua101_stream *stream)
 {
        unsigned int i;
 
-       for (i = 0; i < stream->queue_length; ++i)
+       for (i = 0; i < stream->queue_length; ++i) {
                kfree(stream->urbs[i]);
+               stream->urbs[i] = NULL;
+       }
 }
 
 static void free_usb_related_resources(struct ua101 *ua,
                                       struct usb_interface *interface)
 {
        unsigned int i;
+       struct usb_interface *intf;
 
+       mutex_lock(&ua->mutex);
        free_stream_urbs(&ua->capture);
        free_stream_urbs(&ua->playback);
+       mutex_unlock(&ua->mutex);
        free_stream_buffers(ua, &ua->capture);
        free_stream_buffers(ua, &ua->playback);
 
-       for (i = 0; i < ARRAY_SIZE(ua->intf); ++i)
-               if (ua->intf[i]) {
-                       usb_set_intfdata(ua->intf[i], NULL);
-                       if (ua->intf[i] != interface)
+       for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) {
+               mutex_lock(&ua->mutex);
+               intf = ua->intf[i];
+               ua->intf[i] = NULL;
+               mutex_unlock(&ua->mutex);
+               if (intf) {
+                       usb_set_intfdata(intf, NULL);
+                       if (intf != interface)
                                usb_driver_release_interface(&ua101_driver,
-                                                            ua->intf[i]);
+                                                            intf);
                }
+       }
 }
 
 static void ua101_card_free(struct snd_card *card)
index 60f65ace7474ddfcdf538ba3624c61193c6808a7..ab23869c01bb6734073b65c6c397fe177224c217 100644 (file)
@@ -765,10 +765,61 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
  * interface to ALSA control for feature/mixer units
  */
 
+/* volume control quirks */
+static void volume_control_quirks(struct usb_mixer_elem_info *cval,
+                                 struct snd_kcontrol *kctl)
+{
+       switch (cval->mixer->chip->usb_id) {
+       case USB_ID(0x0471, 0x0101):
+       case USB_ID(0x0471, 0x0104):
+       case USB_ID(0x0471, 0x0105):
+       case USB_ID(0x0672, 0x1041):
+       /* quirk for UDA1321/N101.
+        * note that detection between firmware 2.1.1.7 (N101)
+        * and later 2.1.1.21 is not very clear from datasheets.
+        * I hope that the min value is -15360 for newer firmware --jk
+        */
+               if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
+                   cval->min == -15616) {
+                       snd_printk(KERN_INFO
+                                "set volume quirk for UDA1321/N101 chip\n");
+                       cval->max = -256;
+               }
+               break;
+
+       case USB_ID(0x046d, 0x09a4):
+               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+                       snd_printk(KERN_INFO
+                               "set volume quirk for QuickCam E3500\n");
+                       cval->min = 6080;
+                       cval->max = 8768;
+                       cval->res = 192;
+               }
+               break;
+
+       case USB_ID(0x046d, 0x0808):
+       case USB_ID(0x046d, 0x0809):
+       case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
+       case USB_ID(0x046d, 0x0991):
+       /* Most audio usb devices lie about volume resolution.
+        * Most Logitech webcams have res = 384.
+        * Proboly there is some logitech magic behind this number --fishor
+        */
+               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+                       snd_printk(KERN_INFO
+                               "set resolution quirk: cval->res = 384\n");
+                       cval->res = 384;
+               }
+               break;
+
+       }
+}
+
 /*
  * retrieve the minimum and maximum values for the specified control
  */
-static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
+static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
+                                  int default_min, struct snd_kcontrol *kctl)
 {
        /* for failsafe */
        cval->min = default_min;
@@ -844,6 +895,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
                cval->initialized = 1;
        }
 
+       if (kctl)
+               volume_control_quirks(cval, kctl);
+
        /* USB descriptions contain the dB scale in 1/256 dB unit
         * while ALSA TLV contains in 1/100 dB unit
         */
@@ -864,6 +918,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
        return 0;
 }
 
+#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
 
 /* get a feature/mixer unit info */
 static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
@@ -882,7 +937,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
                uinfo->value.integer.max = 1;
        } else {
                if (!cval->initialized) {
-                       get_min_max(cval, 0);
+                       get_min_max_with_quirks(cval, 0, kcontrol);
                        if (cval->initialized && cval->dBmin >= cval->dBmax) {
                                kcontrol->vd[0].access &= 
                                        ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1045,9 +1100,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                cval->ch_readonly = readonly_mask;
        }
 
-       /* get min/max values */
-       get_min_max(cval, 0);
-
        /* if all channels in the mask are marked read-only, make the control
         * read-only. set_cur_mix_value() will check the mask again and won't
         * issue write commands to read-only channels. */
@@ -1069,6 +1121,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                len = snd_usb_copy_string_desc(state, nameid,
                                kctl->id.name, sizeof(kctl->id.name));
 
+       /* get min/max values */
+       get_min_max_with_quirks(cval, 0, kctl);
+
        switch (control) {
        case UAC_FU_MUTE:
        case UAC_FU_VOLUME:
@@ -1118,51 +1173,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
                break;
        }
 
-       /* volume control quirks */
-       switch (state->chip->usb_id) {
-       case USB_ID(0x0471, 0x0101):
-       case USB_ID(0x0471, 0x0104):
-       case USB_ID(0x0471, 0x0105):
-       case USB_ID(0x0672, 0x1041):
-       /* quirk for UDA1321/N101.
-        * note that detection between firmware 2.1.1.7 (N101)
-        * and later 2.1.1.21 is not very clear from datasheets.
-        * I hope that the min value is -15360 for newer firmware --jk
-        */
-               if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
-                   cval->min == -15616) {
-                       snd_printk(KERN_INFO
-                                "set volume quirk for UDA1321/N101 chip\n");
-                       cval->max = -256;
-               }
-               break;
-
-       case USB_ID(0x046d, 0x09a4):
-               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
-                       snd_printk(KERN_INFO
-                               "set volume quirk for QuickCam E3500\n");
-                       cval->min = 6080;
-                       cval->max = 8768;
-                       cval->res = 192;
-               }
-               break;
-
-       case USB_ID(0x046d, 0x0808):
-       case USB_ID(0x046d, 0x0809):
-       case USB_ID(0x046d, 0x0991):
-       /* Most audio usb devices lie about volume resolution.
-        * Most Logitech webcams have res = 384.
-        * Proboly there is some logitech magic behind this number --fishor
-        */
-               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
-                       snd_printk(KERN_INFO
-                               "set resolution quirk: cval->res = 384\n");
-                       cval->res = 384;
-               }
-               break;
-
-       }
-
        range = (cval->max - cval->min) / cval->res;
        /* Are there devices with volume range more than 255? I use a bit more
         * to be sure. 384 is a resolution magic number found on Logitech
index b61945f3af9e594aa28b2d992239bd4f4a714c6b..32d2a21f2e3b5a401948d24b81c945e239e8fa4e 100644 (file)
@@ -1632,6 +1632,37 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                }
        }
 },
+{
+       /* Roland GAIA SH-01 */
+       USB_DEVICE(0x0582, 0x0111),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .vendor_name = "Roland",
+               .product_name = "GAIA",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_STANDARD_INTERFACE
+                       },
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_AUDIO_STANDARD_INTERFACE
+                       },
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+                               .data = &(const struct snd_usb_midi_endpoint_info) {
+                               .out_cables = 0x0003,
+                               .in_cables  = 0x0003
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
+       }
+},
 {
        USB_DEVICE(0x0582, 0x0113),
        .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
index 2e5bc73440262a14f3e34472516aedf31ff4981a..a3ddac0deffd1eba937932a55553466f32308065 100644 (file)
@@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
                return -ENOMEM;
        }
        if (fp->nr_rates > 0) {
-               rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
+               rate_table = kmemdup(fp->rate_table,
+                                    sizeof(int) * fp->nr_rates, GFP_KERNEL);
                if (!rate_table) {
                        kfree(fp);
                        return -ENOMEM;
                }
-               memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
                fp->rate_table = rate_table;
        }
 
@@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
        if (altsd->bNumEndpoints != 1)
                return -ENXIO;
 
-       fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+       fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL);
        if (!fp)
                return -ENOMEM;
-       memcpy(fp, &ua_format, sizeof(*fp));
 
        fp->iface = altsd->bInterfaceNumber;
        fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
index 084e6fc8d5bf1e6f74f6e3f377bd34b517586d85..726c1a7b89b8348e42ac47ae0662cba89acfdb39 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/hwdep.h>
 #include <sound/pcm.h>
index 5d37d1ccf813c3ff25206f0517eb87cfa4d7bf72..6ffb3713b60cf812cec624c1c1050ff1be71e7e5 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
index f82480fa7f27988c48ba90e80e014b43de745f0e..6ab58cc99d53effeced21668df5605e634913e6b 100644 (file)
@@ -262,13 +262,16 @@ static bool perf_evlist__equal(struct perf_evlist *evlist,
 
 static void open_counters(struct perf_evlist *evlist)
 {
-       struct perf_evsel *pos;
+       struct perf_evsel *pos, *first;
 
        if (evlist->cpus->map[0] < 0)
                no_inherit = true;
 
+       first = list_entry(evlist->entries.next, struct perf_evsel, node);
+
        list_for_each_entry(pos, &evlist->entries, node) {
                struct perf_event_attr *attr = &pos->attr;
+               struct xyarray *group_fd = NULL;
                /*
                 * Check if parse_single_tracepoint_event has already asked for
                 * PERF_SAMPLE_TIME.
@@ -283,15 +286,19 @@ static void open_counters(struct perf_evlist *evlist)
                 */
                bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
 
+               if (group && pos != first)
+                       group_fd = first->fd;
+
                config_attr(pos, evlist);
 retry_sample_id:
                attr->sample_id_all = sample_id_all_avail ? 1 : 0;
 try_again:
-               if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group) < 0) {
+               if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group,
+                                    group_fd) < 0) {
                        int err = errno;
 
                        if (err == EPERM || err == EACCES) {
-                               ui__warning_paranoid();
+                               ui__error_paranoid();
                                exit(EXIT_FAILURE);
                        } else if (err ==  ENODEV && cpu_list) {
                                die("No such device - did you specify"
index 7ce65f52415e0799f060d35d67290fac196dfb12..955930e0a5c34cd0852f92aa39a7c73492c159b5 100644 (file)
@@ -278,9 +278,14 @@ struct stats                       runtime_itlb_cache_stats[MAX_NR_CPUS];
 struct stats                   runtime_dtlb_cache_stats[MAX_NR_CPUS];
 struct stats                   walltime_nsecs_stats;
 
-static int create_perf_stat_counter(struct perf_evsel *evsel)
+static int create_perf_stat_counter(struct perf_evsel *evsel,
+                                   struct perf_evsel *first)
 {
        struct perf_event_attr *attr = &evsel->attr;
+       struct xyarray *group_fd = NULL;
+
+       if (group && evsel != first)
+               group_fd = first->fd;
 
        if (scale)
                attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -289,14 +294,15 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
        attr->inherit = !no_inherit;
 
        if (system_wide)
-               return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group);
-
+               return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
+                                               group, group_fd);
        if (target_pid == -1 && target_tid == -1) {
                attr->disabled = 1;
                attr->enable_on_exec = 1;
        }
 
-       return perf_evsel__open_per_thread(evsel, evsel_list->threads, group);
+       return perf_evsel__open_per_thread(evsel, evsel_list->threads,
+                                          group, group_fd);
 }
 
 /*
@@ -396,7 +402,7 @@ static int read_counter(struct perf_evsel *counter)
 static int run_perf_stat(int argc __used, const char **argv)
 {
        unsigned long long t0, t1;
-       struct perf_evsel *counter;
+       struct perf_evsel *counter, *first;
        int status = 0;
        int child_ready_pipe[2], go_pipe[2];
        const bool forks = (argc > 0);
@@ -453,9 +459,12 @@ static int run_perf_stat(int argc __used, const char **argv)
                close(child_ready_pipe[0]);
        }
 
+       first = list_entry(evsel_list->entries.next, struct perf_evsel, node);
+
        list_for_each_entry(counter, &evsel_list->entries, node) {
-               if (create_perf_stat_counter(counter) < 0) {
-                       if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) {
+               if (create_perf_stat_counter(counter, first) < 0) {
+                       if (errno == EINVAL || errno == ENOSYS ||
+                           errno == ENOENT || errno == EOPNOTSUPP) {
                                if (verbose)
                                        ui__warning("%s event is not supported by the kernel.\n",
                                                    event_name(counter));
index efe696f936e2de354d2263b62dfbf5c17bc910f1..831d1baeac370ebd330d0e6e970f025f34e76e44 100644 (file)
@@ -291,7 +291,7 @@ static int test__open_syscall_event(void)
                goto out_thread_map_delete;
        }
 
-       if (perf_evsel__open_per_thread(evsel, threads, false) < 0) {
+       if (perf_evsel__open_per_thread(evsel, threads, false, NULL) < 0) {
                pr_debug("failed to open counter: %s, "
                         "tweak /proc/sys/kernel/perf_event_paranoid?\n",
                         strerror(errno));
@@ -366,7 +366,7 @@ static int test__open_syscall_event_on_all_cpus(void)
                goto out_thread_map_delete;
        }
 
-       if (perf_evsel__open(evsel, cpus, threads, false) < 0) {
+       if (perf_evsel__open(evsel, cpus, threads, false, NULL) < 0) {
                pr_debug("failed to open counter: %s, "
                         "tweak /proc/sys/kernel/perf_event_paranoid?\n",
                         strerror(errno));
@@ -531,7 +531,7 @@ static int test__basic_mmap(void)
 
                perf_evlist__add(evlist, evsels[i]);
 
-               if (perf_evsel__open(evsels[i], cpus, threads, false) < 0) {
+               if (perf_evsel__open(evsels[i], cpus, threads, false, NULL) < 0) {
                        pr_debug("failed to open counter: %s, "
                                 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
                                 strerror(errno));
index 7a871714d44ed52866545a203421366855cb0b99..c9cdedb581348aa158677b28f6465734abcb50d4 100644 (file)
@@ -89,6 +89,7 @@ static bool                   vmlinux_warned;
 static bool                    inherit                         =  false;
 static int                     realtime_prio                   =      0;
 static bool                    group                           =  false;
+static bool                    sample_id_all_avail             =   true;
 static unsigned int            mmap_pages                      =    128;
 
 static bool                    dump_symtab                     =  false;
@@ -199,7 +200,8 @@ static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)
        struct symbol *sym;
 
        if (he == NULL || he->ms.sym == NULL ||
-           (he != top.sym_filter_entry && use_browser != 1))
+           ((top.sym_filter_entry == NULL ||
+             top.sym_filter_entry->ms.sym != he->ms.sym) && use_browser != 1))
                return;
 
        sym = he->ms.sym;
@@ -289,11 +291,13 @@ static void print_sym_table(void)
 
        printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
 
-       if (top.total_lost_warned != top.session->hists.stats.total_lost) {
-               top.total_lost_warned = top.session->hists.stats.total_lost;
-               color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
-               printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
-                      top.total_lost_warned);
+       if (top.sym_evsel->hists.stats.nr_lost_warned !=
+           top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) {
+               top.sym_evsel->hists.stats.nr_lost_warned =
+                       top.sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST];
+               color_fprintf(stdout, PERF_COLOR_RED,
+                             "WARNING: LOST %d chunks, Check IO/CPU overload",
+                             top.sym_evsel->hists.stats.nr_lost_warned);
                ++printed;
        }
 
@@ -561,7 +565,6 @@ static void perf_top__sort_new_samples(void *arg)
        hists__decay_entries_threaded(&t->sym_evsel->hists,
                                      top.hide_user_symbols,
                                      top.hide_kernel_symbols);
-       hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3);
 }
 
 static void *display_thread_tui(void *arg __used)
@@ -671,6 +674,7 @@ static int symbol_filter(struct map *map __used, struct symbol *sym)
 }
 
 static void perf_event__process_sample(const union perf_event *event,
+                                      struct perf_evsel *evsel,
                                       struct perf_sample *sample,
                                       struct perf_session *session)
 {
@@ -770,12 +774,8 @@ static void perf_event__process_sample(const union perf_event *event,
        }
 
        if (al.sym == NULL || !al.sym->ignore) {
-               struct perf_evsel *evsel;
                struct hist_entry *he;
 
-               evsel = perf_evlist__id2evsel(top.evlist, sample->id);
-               assert(evsel != NULL);
-
                if ((sort__has_parent || symbol_conf.use_callchain) &&
                    sample->callchain) {
                        err = perf_session__resolve_callchain(session, al.thread,
@@ -807,6 +807,7 @@ static void perf_event__process_sample(const union perf_event *event,
 static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
 {
        struct perf_sample sample;
+       struct perf_evsel *evsel;
        union perf_event *event;
        int ret;
 
@@ -817,10 +818,16 @@ static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
                        continue;
                }
 
+               evsel = perf_evlist__id2evsel(self->evlist, sample.id);
+               assert(evsel != NULL);
+
                if (event->header.type == PERF_RECORD_SAMPLE)
-                       perf_event__process_sample(event, &sample, self);
-               else
+                       perf_event__process_sample(event, evsel, &sample, self);
+               else if (event->header.type < PERF_RECORD_MAX) {
+                       hists__inc_nr_events(&evsel->hists, event->header.type);
                        perf_event__process(event, &sample, self);
+               } else
+                       ++self->hists.stats.nr_unknown_events;
        }
 }
 
@@ -834,10 +841,16 @@ static void perf_session__mmap_read(struct perf_session *self)
 
 static void start_counters(struct perf_evlist *evlist)
 {
-       struct perf_evsel *counter;
+       struct perf_evsel *counter, *first;
+
+       first = list_entry(evlist->entries.next, struct perf_evsel, node);
 
        list_for_each_entry(counter, &evlist->entries, node) {
                struct perf_event_attr *attr = &counter->attr;
+               struct xyarray *group_fd = NULL;
+
+               if (group && counter != first)
+                       group_fd = first->fd;
 
                attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
 
@@ -858,14 +871,23 @@ static void start_counters(struct perf_evlist *evlist)
                attr->mmap = 1;
                attr->comm = 1;
                attr->inherit = inherit;
+retry_sample_id:
+               attr->sample_id_all = sample_id_all_avail ? 1 : 0;
 try_again:
                if (perf_evsel__open(counter, top.evlist->cpus,
-                                    top.evlist->threads, group) < 0) {
+                                    top.evlist->threads, group,
+                                    group_fd) < 0) {
                        int err = errno;
 
                        if (err == EPERM || err == EACCES) {
-                               ui__warning_paranoid();
+                               ui__error_paranoid();
                                goto out_err;
+                       } else if (err == EINVAL && sample_id_all_avail) {
+                               /*
+                                * Old kernel, no attr->sample_id_type_all field
+                                */
+                               sample_id_all_avail = false;
+                               goto retry_sample_id;
                        }
                        /*
                         * If it's cycles then fall back to hrtimer
index bc8f4773d4d85386d46057ed74718543b3c4b87b..119e996035c8f0e8ef529ba0e195f93f7cc79396 100644 (file)
@@ -310,9 +310,12 @@ fallback:
                }
                err = -ENOENT;
                dso->annotate_warned = 1;
-               pr_err("Can't annotate %s: No vmlinux file%s was found in the "
-                      "path.\nPlease use 'perf buildid-cache -av vmlinux' or "
-                      "--vmlinux vmlinux.\n",
+               pr_err("Can't annotate %s:\n\n"
+                      "No vmlinux file%s\nwas found in the path.\n\n"
+                      "Please use:\n\n"
+                      "  perf buildid-cache -av vmlinux\n\n"
+                      "or:\n\n"
+                      "  --vmlinux vmlinux",
                       sym->name, build_id_msg ?: "");
                goto out_free_filename;
        }
index 155749d74350a670c166ed14d7f8f4629e4bea23..26817daa2961b5dc3eb0f6181238dc707fa7bdc9 100644 (file)
@@ -47,19 +47,20 @@ int dump_printf(const char *fmt, ...)
 }
 
 #ifdef NO_NEWT_SUPPORT
-void ui__warning(const char *format, ...)
+int ui__warning(const char *format, ...)
 {
        va_list args;
 
        va_start(args, format);
        vfprintf(stderr, format, args);
        va_end(args);
+       return 0;
 }
 #endif
 
-void ui__warning_paranoid(void)
+int ui__error_paranoid(void)
 {
-       ui__warning("Permission error - are you root?\n"
+       return ui__error("Permission error - are you root?\n"
                    "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
                    " -1 - Not paranoid at all\n"
                    "  0 - Disallow raw tracepoint access for unpriv\n"
index fd53db47e3de1200ce0229629410b5d8006d1652..f2ce88d04f54be1cc71c0b5f9969070e9b2a61c3 100644 (file)
@@ -19,23 +19,18 @@ static inline int ui_helpline__show_help(const char *format __used, va_list ap _
        return 0;
 }
 
-static inline struct ui_progress *ui_progress__new(const char *title __used,
-                                                  u64 total __used)
-{
-       return (struct ui_progress *)1;
-}
-
-static inline void ui_progress__update(struct ui_progress *self __used,
-                                      u64 curr __used) {}
+static inline void ui_progress__update(u64 curr __used, u64 total __used,
+                                      const char *title __used) {}
 
-static inline void ui_progress__delete(struct ui_progress *self __used) {}
+#define ui__error(format, arg...) ui__warning(format, ##arg)
 #else
 extern char ui_helpline__last_msg[];
 int ui_helpline__show_help(const char *format, va_list ap);
 #include "ui/progress.h"
+int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
 #endif
 
-void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
-void ui__warning_paranoid(void);
+int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
+int ui__error_paranoid(void);
 
 #endif /* __PERF_DEBUG_H */
index 2f6bc89027da7eb78b349bb71aa7c4765cbd2c27..fbb4b4ab9cc6925a57017abc3087eab9b3b12ff4 100644 (file)
@@ -539,3 +539,33 @@ void perf_evlist__set_selected(struct perf_evlist *evlist,
 {
        evlist->selected = evsel;
 }
+
+int perf_evlist__open(struct perf_evlist *evlist, bool group)
+{
+       struct perf_evsel *evsel, *first;
+       int err, ncpus, nthreads;
+
+       first = list_entry(evlist->entries.next, struct perf_evsel, node);
+
+       list_for_each_entry(evsel, &evlist->entries, node) {
+               struct xyarray *group_fd = NULL;
+
+               if (group && evsel != first)
+                       group_fd = first->fd;
+
+               err = perf_evsel__open(evsel, evlist->cpus, evlist->threads,
+                                      group, group_fd);
+               if (err < 0)
+                       goto out_err;
+       }
+
+       return 0;
+out_err:
+       ncpus = evlist->cpus ? evlist->cpus->nr : 1;
+       nthreads = evlist->threads ? evlist->threads->nr : 1;
+
+       list_for_each_entry_reverse(evsel, &evlist->entries, node)
+               perf_evsel__close(evsel, ncpus, nthreads);
+
+       return err;
+}
index 6be71fc57794e0fe67a68c7ca20cd60482ba556c..1779ffef782824a7a5e8b8506abbc6bb30055c2b 100644 (file)
@@ -50,6 +50,8 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
 
 union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
 
+int perf_evlist__open(struct perf_evlist *evlist, bool group);
+
 int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
 void perf_evlist__munmap(struct perf_evlist *evlist);
index b46f6e4bff3c6b2d19786b52fef6a0feeb578216..d7915d4e77cb629e4560d499ac2c1c902ecce5db 100644 (file)
@@ -16,6 +16,7 @@
 #include "thread_map.h"
 
 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
+#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
 
 int __perf_evsel__sample_size(u64 sample_type)
 {
@@ -33,6 +34,16 @@ int __perf_evsel__sample_size(u64 sample_type)
        return size;
 }
 
+static void hists__init(struct hists *hists)
+{
+       memset(hists, 0, sizeof(*hists));
+       hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
+       hists->entries_in = &hists->entries_in_array[0];
+       hists->entries_collapsed = RB_ROOT;
+       hists->entries = RB_ROOT;
+       pthread_mutex_init(&hists->lock, NULL);
+}
+
 void perf_evsel__init(struct perf_evsel *evsel,
                      struct perf_event_attr *attr, int idx)
 {
@@ -204,15 +215,16 @@ int __perf_evsel__read(struct perf_evsel *evsel,
 }
 
 static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
-                             struct thread_map *threads, bool group)
+                             struct thread_map *threads, bool group,
+                             struct xyarray *group_fds)
 {
        int cpu, thread;
        unsigned long flags = 0;
-       int pid = -1;
+       int pid = -1, err;
 
        if (evsel->fd == NULL &&
            perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
-               return -1;
+               return -ENOMEM;
 
        if (evsel->cgrp) {
                flags = PERF_FLAG_PID_CGROUP;
@@ -220,7 +232,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
        }
 
        for (cpu = 0; cpu < cpus->nr; cpu++) {
-               int group_fd = -1;
+               int group_fd = group_fds ? GROUP_FD(group_fds, cpu) : -1;
 
                for (thread = 0; thread < threads->nr; thread++) {
 
@@ -231,8 +243,10 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
                                                                     pid,
                                                                     cpus->map[cpu],
                                                                     group_fd, flags);
-                       if (FD(evsel, cpu, thread) < 0)
+                       if (FD(evsel, cpu, thread) < 0) {
+                               err = -errno;
                                goto out_close;
+                       }
 
                        if (group && group_fd == -1)
                                group_fd = FD(evsel, cpu, thread);
@@ -249,7 +263,17 @@ out_close:
                }
                thread = threads->nr;
        } while (--cpu >= 0);
-       return -1;
+       return err;
+}
+
+void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
+{
+       if (evsel->fd == NULL)
+               return;
+
+       perf_evsel__close_fd(evsel, ncpus, nthreads);
+       perf_evsel__free_fd(evsel);
+       evsel->fd = NULL;
 }
 
 static struct {
@@ -269,7 +293,8 @@ static struct {
 };
 
 int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
-                    struct thread_map *threads, bool group)
+                    struct thread_map *threads, bool group,
+                    struct xyarray *group_fd)
 {
        if (cpus == NULL) {
                /* Work around old compiler warnings about strict aliasing */
@@ -279,19 +304,23 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
        if (threads == NULL)
                threads = &empty_thread_map.map;
 
-       return __perf_evsel__open(evsel, cpus, threads, group);
+       return __perf_evsel__open(evsel, cpus, threads, group, group_fd);
 }
 
 int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
-                            struct cpu_map *cpus, bool group)
+                            struct cpu_map *cpus, bool group,
+                            struct xyarray *group_fd)
 {
-       return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group);
+       return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group,
+                                 group_fd);
 }
 
 int perf_evsel__open_per_thread(struct perf_evsel *evsel,
-                               struct thread_map *threads, bool group)
+                               struct thread_map *threads, bool group,
+                               struct xyarray *group_fd)
 {
-       return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group);
+       return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group,
+                                 group_fd);
 }
 
 static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
index e9a31554e2658cf1ac50a0d476f428c691ed5482..b1d15e6f7ae32a4efc173ebd7779cd06bc02f41f 100644 (file)
@@ -82,11 +82,15 @@ void perf_evsel__free_id(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
 
 int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
-                            struct cpu_map *cpus, bool group);
+                            struct cpu_map *cpus, bool group,
+                            struct xyarray *group_fds);
 int perf_evsel__open_per_thread(struct perf_evsel *evsel,
-                               struct thread_map *threads, bool group);
+                               struct thread_map *threads, bool group,
+                               struct xyarray *group_fds);
 int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
-                    struct thread_map *threads, bool group);
+                    struct thread_map *threads, bool group,
+                    struct xyarray *group_fds);
+void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads);
 
 #define perf_evsel__match(evsel, t, c)         \
        (evsel->attr.type == PERF_TYPE_##t &&   \
index 76c0b2c49eb82ce9a888189899d6ce053df6c0bd..33c17a2b2a81e739066991a9a9facd2b38ee0416 100644 (file)
@@ -1,5 +1,6 @@
 #define _FILE_OFFSET_BITS 64
 
+#include "util.h"
 #include <sys/types.h>
 #include <byteswap.h>
 #include <unistd.h>
@@ -11,7 +12,6 @@
 
 #include "evlist.h"
 #include "evsel.h"
-#include "util.h"
 #include "header.h"
 #include "../perf.h"
 #include "trace-event.h"
@@ -388,7 +388,7 @@ static int write_event_desc(int fd, struct perf_header *h __used,
                /*
                 * write event string as passed on cmdline
                 */
-               ret = do_write_string(fd, attr->name);
+               ret = do_write_string(fd, event_name(attr));
                if (ret < 0)
                        return ret;
                /*
index f6a993963a1e61ee8bd38532cfb530921dbe7cf9..abef2703cd242eb8b8e5f1763cadd50286bdc8be 100644 (file)
@@ -365,7 +365,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded)
 
        root = hists__get_rotate_entries_in(hists);
        next = rb_first(root);
-       hists->stats.total_period = 0;
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node_in);
@@ -379,7 +378,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded)
                         * been set by, say, the hist_browser.
                         */
                        hists__apply_filters(hists, n);
-                       hists__inc_nr_entries(hists, n);
                }
        }
 }
@@ -442,6 +440,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
        hists->entries = RB_ROOT;
 
        hists->nr_entries = 0;
+       hists->stats.total_period = 0;
        hists__reset_col_len(hists);
 
        while (next) {
@@ -1212,13 +1211,3 @@ size_t hists__fprintf_nr_events(struct hists *hists, FILE *fp)
 
        return ret;
 }
-
-void hists__init(struct hists *hists)
-{
-       memset(hists, 0, sizeof(*hists));
-       hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
-       hists->entries_in = &hists->entries_in_array[0];
-       hists->entries_collapsed = RB_ROOT;
-       hists->entries = RB_ROOT;
-       pthread_mutex_init(&hists->lock, NULL);
-}
index ff93ddc91c5c4a1510ac2d2c3eb7fae25414f6ad..89289c8e935e78973a906fb96edd164973d20ac9 100644 (file)
@@ -28,6 +28,7 @@ struct events_stats {
        u64 total_lost;
        u64 total_invalid_chains;
        u32 nr_events[PERF_RECORD_HEADER_MAX];
+       u32 nr_lost_warned;
        u32 nr_unknown_events;
        u32 nr_invalid_chains;
        u32 nr_unknown_id;
@@ -62,8 +63,6 @@ struct hists {
        struct callchain_cursor callchain_cursor;
 };
 
-void hists__init(struct hists *hists);
-
 struct hist_entry *__hists__add_entry(struct hists *self,
                                      struct addr_location *al,
                                      struct symbol *parent, u64 period);
index 7624324efad4c78987b6bffb8c8aedbf246ea064..9dd47a4f2596d011847330f0f7db079c20c652d9 100644 (file)
@@ -623,7 +623,11 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
                cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
 
        evsel->attr.inherit = inherit;
-       if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
+       /*
+        * This will group just the fds for this single evsel, to group
+        * multiple events, use evlist.open().
+        */
+       if (perf_evsel__open(evsel, cpus, threads, group, NULL) < 0) {
                PyErr_SetFromErrno(PyExc_OSError);
                return NULL;
        }
@@ -814,6 +818,25 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
        return Py_None;
 }
 
+static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
+                                  PyObject *args, PyObject *kwargs)
+{
+       struct perf_evlist *evlist = &pevlist->evlist;
+       int group = 0;
+       static char *kwlist[] = { "group", NULL };
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
+               return NULL;
+
+       if (perf_evlist__open(evlist, group) < 0) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
 static PyMethodDef pyrf_evlist__methods[] = {
        {
                .ml_name  = "mmap",
@@ -821,6 +844,12 @@ static PyMethodDef pyrf_evlist__methods[] = {
                .ml_flags = METH_VARARGS | METH_KEYWORDS,
                .ml_doc   = PyDoc_STR("mmap the file descriptor table.")
        },
+       {
+               .ml_name  = "open",
+               .ml_meth  = (PyCFunction)pyrf_evlist__open,
+               .ml_flags = METH_VARARGS | METH_KEYWORDS,
+               .ml_doc   = PyDoc_STR("open the file descriptors.")
+       },
        {
                .ml_name  = "poll",
                .ml_meth  = (PyCFunction)pyrf_evlist__poll,
index 20e011c99a9459351f8741a418a4d630e334ac22..0f4555ce90635a767f4a609b917905b5f58bdd0a 100644 (file)
@@ -502,6 +502,7 @@ static void flush_sample_queue(struct perf_session *s,
        struct perf_sample sample;
        u64 limit = os->next_flush;
        u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
+       unsigned idx = 0, progress_next = os->nr_samples / 16;
        int ret;
 
        if (!ops->ordered_samples || !limit)
@@ -521,6 +522,11 @@ static void flush_sample_queue(struct perf_session *s,
                os->last_flush = iter->timestamp;
                list_del(&iter->list);
                list_add(&iter->list, &os->sample_cache);
+               if (++idx >= progress_next) {
+                       progress_next += os->nr_samples / 16;
+                       ui_progress__update(idx, os->nr_samples,
+                                           "Processing time ordered events...");
+               }
        }
 
        if (list_empty(head)) {
@@ -529,6 +535,8 @@ static void flush_sample_queue(struct perf_session *s,
                os->last_sample =
                        list_entry(head->prev, struct sample_queue, list);
        }
+
+       os->nr_samples = 0;
 }
 
 /*
@@ -588,6 +596,7 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s)
        u64 timestamp = new->timestamp;
        struct list_head *p;
 
+       ++os->nr_samples;
        os->last_sample = new;
 
        if (!sample) {
@@ -738,10 +747,27 @@ static int perf_session_deliver_event(struct perf_session *session,
 
        dump_event(session, event, file_offset, sample);
 
+       evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+       if (evsel != NULL && event->header.type != PERF_RECORD_SAMPLE) {
+               /*
+                * XXX We're leaving PERF_RECORD_SAMPLE unnacounted here
+                * because the tools right now may apply filters, discarding
+                * some of the samples. For consistency, in the future we
+                * should have something like nr_filtered_samples and remove
+                * the sample->period from total_sample_period, etc, KISS for
+                * now tho.
+                *
+                * Also testing against NULL allows us to handle files without
+                * attr.sample_id_all and/or without PERF_SAMPLE_ID. In the
+                * future probably it'll be a good idea to restrict event
+                * processing via perf_session to files with both set.
+                */
+               hists__inc_nr_events(&evsel->hists, event->header.type);
+       }
+
        switch (event->header.type) {
        case PERF_RECORD_SAMPLE:
                dump_sample(session, event, sample);
-               evsel = perf_evlist__id2evsel(session->evlist, sample->id);
                if (evsel == NULL) {
                        ++session->hists.stats.nr_unknown_id;
                        return -1;
@@ -874,11 +900,11 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
                                            const struct perf_event_ops *ops)
 {
        if (ops->lost == perf_event__process_lost &&
-           session->hists.stats.total_lost != 0) {
-               ui__warning("Processed %" PRIu64 " events and LOST %" PRIu64
-                           "!\n\nCheck IO/CPU overload!\n\n",
-                           session->hists.stats.total_period,
-                           session->hists.stats.total_lost);
+           session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) {
+               ui__warning("Processed %d events and lost %d chunks!\n\n"
+                           "Check IO/CPU overload!\n\n",
+                           session->hists.stats.nr_events[0],
+                           session->hists.stats.nr_events[PERF_RECORD_LOST]);
        }
 
        if (session->hists.stats.nr_unknown_events != 0) {
@@ -1012,7 +1038,6 @@ int __perf_session__process_events(struct perf_session *session,
 {
        u64 head, page_offset, file_offset, file_pos, progress_next;
        int err, mmap_prot, mmap_flags, map_idx = 0;
-       struct ui_progress *progress;
        size_t  page_size, mmap_size;
        char *buf, *mmaps[8];
        union perf_event *event;
@@ -1030,9 +1055,6 @@ int __perf_session__process_events(struct perf_session *session,
                file_size = data_offset + data_size;
 
        progress_next = file_size / 16;
-       progress = ui_progress__new("Processing events...", file_size);
-       if (progress == NULL)
-               return -1;
 
        mmap_size = session->mmap_window;
        if (mmap_size > file_size)
@@ -1095,7 +1117,8 @@ more:
 
        if (file_pos >= progress_next) {
                progress_next += file_size / 16;
-               ui_progress__update(progress, file_pos);
+               ui_progress__update(file_pos, file_size,
+                                   "Processing events...");
        }
 
        if (file_pos < file_size)
@@ -1106,7 +1129,6 @@ more:
        session->ordered_samples.next_flush = ULLONG_MAX;
        flush_sample_queue(session, ops);
 out_err:
-       ui_progress__delete(progress);
        perf_session__warn_about_errors(session, ops);
        perf_session_free_sample_buffers(session);
        return err;
@@ -1311,6 +1333,10 @@ int perf_session__cpu_bitmap(struct perf_session *session,
        }
 
        map = cpu_map__new(cpu_list);
+       if (map == NULL) {
+               pr_err("Invalid cpu_list\n");
+               return -1;
+       }
 
        for (i = 0; i < map->nr; i++) {
                int cpu = map->map[i];
index 514b06d41f05ef21ef1b1fefeeda9a14c1e06a76..6e393c98eb344f60dead2883e71fd4f2d13cbde3 100644 (file)
@@ -23,6 +23,7 @@ struct ordered_samples {
        struct sample_queue     *sample_buffer;
        struct sample_queue     *last_sample;
        int                     sample_buffer_idx;
+       unsigned int            nr_samples;
 };
 
 struct perf_session {
index 01d1057f3074ce59e92e03ed27876b851ad39fbc..3996509679589896cdfbd5a2a2b4e5df6d5cca4b 100644 (file)
@@ -19,7 +19,6 @@ struct perf_top {
        u64                kernel_samples, us_samples;
        u64                exact_samples;
        u64                guest_us_samples, guest_kernel_samples;
-       u64                total_lost_warned;
        int                print_entries, count_filter, delay_secs;
        int                freq;
        pid_t              target_pid, target_tid;
index 2d530cf74f435875e84d2f66485ea00b6794e91f..d2655f08bcc033d757ba5740b2ed238984062f40 100644 (file)
@@ -80,7 +80,7 @@ static void die(const char *fmt, ...)
        int ret = errno;
 
        if (errno)
-               perror("trace-cmd");
+               perror("perf");
        else
                ret = -1;
 
index 0a7ed5b5e281c88b321de87ced66a3d29ebb003d..6c164dc9ee957dbf3df642f712b2fdc1485d2dc6 100644 (file)
@@ -1537,6 +1537,8 @@ process_flags(struct event *event, struct print_arg *arg, char **tok)
        field = malloc_or_die(sizeof(*field));
 
        type = process_arg(event, field, &token);
+       while (type == EVENT_OP)
+               type = process_op(event, field, &token);
        if (test_type_token(type, token, EVENT_DELIM, ","))
                goto out_free;
 
index 5359f371d30a355c4838e3db4e170ca5e6f359c0..556829124b0246fff72fe09ad96ceab35119037b 100644 (file)
@@ -4,6 +4,7 @@
 #include "libslang.h"
 #include <newt.h>
 #include "ui.h"
+#include "util.h"
 #include <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
@@ -168,6 +169,59 @@ void ui_browser__refresh_dimensions(struct ui_browser *self)
        self->x = 0;
 }
 
+void ui_browser__handle_resize(struct ui_browser *browser)
+{
+       ui__refresh_dimensions(false);
+       ui_browser__show(browser, browser->title, ui_helpline__current);
+       ui_browser__refresh(browser);
+}
+
+int ui_browser__warning(struct ui_browser *browser, int timeout,
+                       const char *format, ...)
+{
+       va_list args;
+       char *text;
+       int key = 0, err;
+
+       va_start(args, format);
+       err = vasprintf(&text, format, args);
+       va_end(args);
+
+       if (err < 0) {
+               va_start(args, format);
+               ui_helpline__vpush(format, args);
+               va_end(args);
+       } else {
+               while ((key == ui__question_window("Warning!", text,
+                                                  "Press any key...",
+                                                  timeout)) == K_RESIZE)
+                       ui_browser__handle_resize(browser);
+               free(text);
+       }
+
+       return key;
+}
+
+int ui_browser__help_window(struct ui_browser *browser, const char *text)
+{
+       int key;
+
+       while ((key = ui__help_window(text)) == K_RESIZE)
+               ui_browser__handle_resize(browser);
+
+       return key;
+}
+
+bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text)
+{
+       int key;
+
+       while ((key = ui__dialog_yesno(text)) == K_RESIZE)
+               ui_browser__handle_resize(browser);
+
+       return key == K_ENTER || toupper(key) == 'Y';
+}
+
 void ui_browser__reset_index(struct ui_browser *self)
 {
        self->index = self->top_idx = 0;
@@ -230,13 +284,15 @@ static void ui_browser__scrollbar_set(struct ui_browser *browser)
                       (browser->nr_entries - 1));
        }
 
+       SLsmg_set_char_set(1);
+
        while (h < height) {
                ui_browser__gotorc(browser, row++, col);
-               SLsmg_set_char_set(1);
-               SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_BOARD_CHAR);
-               SLsmg_set_char_set(0);
+               SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_CKBRD_CHAR);
                ++h;
        }
+
+       SLsmg_set_char_set(0);
 }
 
 static int __ui_browser__refresh(struct ui_browser *browser)
@@ -291,53 +347,10 @@ void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
        browser->seek(browser, browser->top_idx, SEEK_SET);
 }
 
-static int ui__getch(int delay_secs)
-{
-       struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
-       fd_set read_set;
-       int err, key;
-
-       FD_ZERO(&read_set);
-       FD_SET(0, &read_set);
-
-       if (delay_secs) {
-               timeout.tv_sec = delay_secs;
-               timeout.tv_usec = 0;
-       }
-
-        err = select(1, &read_set, NULL, NULL, ptimeout);
-
-       if (err == 0)
-               return K_TIMER;
-
-       if (err == -1) {
-               if (errno == EINTR)
-                       return K_RESIZE;
-               return K_ERROR;
-       }
-
-       key = SLang_getkey();
-       if (key != K_ESC)
-               return key;
-
-       FD_ZERO(&read_set);
-       FD_SET(0, &read_set);
-       timeout.tv_sec = 0;
-       timeout.tv_usec = 20;
-        err = select(1, &read_set, NULL, NULL, &timeout);
-       if (err == 0)
-               return K_ESC;
-
-       SLang_ungetkey(key);
-       return SLkp_getkey();
-}
-
 int ui_browser__run(struct ui_browser *self, int delay_secs)
 {
        int err, key;
 
-       pthread__unblock_sigwinch();
-
        while (1) {
                off_t offset;
 
@@ -351,10 +364,7 @@ int ui_browser__run(struct ui_browser *self, int delay_secs)
                key = ui__getch(delay_secs);
 
                if (key == K_RESIZE) {
-                       pthread_mutex_lock(&ui__lock);
-                       SLtt_get_screen_size();
-                       SLsmg_reinit_smg();
-                       pthread_mutex_unlock(&ui__lock);
+                       ui__refresh_dimensions(false);
                        ui_browser__refresh_dimensions(self);
                        __ui_browser__show_title(self, self->title);
                        ui_helpline__puts(self->helpline);
@@ -533,6 +543,47 @@ static int ui_browser__color_config(const char *var, const char *value,
        return -1;
 }
 
+void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence)
+{
+       switch (whence) {
+       case SEEK_SET:
+               browser->top = browser->entries;
+               break;
+       case SEEK_CUR:
+               browser->top = browser->top + browser->top_idx + offset;
+               break;
+       case SEEK_END:
+               browser->top = browser->top + browser->nr_entries + offset;
+               break;
+       default:
+               return;
+       }
+}
+
+unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
+{
+       unsigned int row = 0, idx = browser->top_idx;
+       char **pos;
+
+       if (browser->top == NULL)
+               browser->top = browser->entries;
+
+       pos = (char **)browser->top;
+       while (idx < browser->nr_entries) {
+               if (!browser->filter || !browser->filter(browser, *pos)) {
+                       ui_browser__gotorc(browser, row, 0);
+                       browser->write(browser, pos, row);
+                       if (++row == browser->height)
+                               break;
+               }
+
+               ++idx;
+               ++pos;
+       }
+
+       return row;
+}
+
 void ui_browser__init(void)
 {
        int i = 0;
index a2c707d33c5eb2f406615026621e811853864408..84d761b730c10d9d11b1db8d88bcf0afeacb47a8 100644 (file)
@@ -43,6 +43,15 @@ void ui_browser__hide(struct ui_browser *self);
 int ui_browser__refresh(struct ui_browser *self);
 int ui_browser__run(struct ui_browser *browser, int delay_secs);
 void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
+void ui_browser__handle_resize(struct ui_browser *browser);
+
+int ui_browser__warning(struct ui_browser *browser, int timeout,
+                       const char *format, ...);
+int ui_browser__help_window(struct ui_browser *browser, const char *text);
+bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text);
+
+void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence);
+unsigned int ui_browser__argv_refresh(struct ui_browser *browser);
 
 void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence);
 unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self);
index 4e0cb7fea7d9b3fc3d993fb96fe6c5d03308228b..0575905d1205a24b5353b54c2f4c548e4cc6c2e4 100644 (file)
@@ -1,6 +1,9 @@
+#include "../../util.h"
 #include "../browser.h"
 #include "../helpline.h"
 #include "../libslang.h"
+#include "../ui.h"
+#include "../util.h"
 #include "../../annotate.h"
 #include "../../hist.h"
 #include "../../sort.h"
@@ -8,15 +11,6 @@
 #include <pthread.h>
 #include <newt.h>
 
-static void ui__error_window(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap);
-       va_end(ap);
-}
-
 struct annotate_browser {
        struct ui_browser b;
        struct rb_root    entries;
@@ -400,7 +394,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
                return -1;
 
        if (symbol__annotate(sym, map, sizeof(struct objdump_line_rb_node)) < 0) {
-               ui__error_window(ui_helpline__last_msg);
+               ui__error("%s", ui_helpline__last_msg);
                return -1;
        }
 
index 4663dcb2a19b56905d0c105a948178e6599fb3cd..d0c94b4596852d4f47ce266400ca3c7bb0013a96 100644 (file)
@@ -17,6 +17,7 @@
 #include "../browser.h"
 #include "../helpline.h"
 #include "../util.h"
+#include "../ui.h"
 #include "map.h"
 
 struct hist_browser {
@@ -294,6 +295,15 @@ static void hist_browser__set_folding(struct hist_browser *self, bool unfold)
        ui_browser__reset_index(&self->b);
 }
 
+static void ui_browser__warn_lost_events(struct ui_browser *browser)
+{
+       ui_browser__warning(browser, 4,
+               "Events are being lost, check IO/CPU overload!\n\n"
+               "You may want to run 'perf' using a RT scheduler policy:\n\n"
+               " perf top -r 80\n\n"
+               "Or reduce the sampling frequency.");
+}
+
 static int hist_browser__run(struct hist_browser *self, const char *ev_name,
                             void(*timer)(void *arg), void *arg, int delay_secs)
 {
@@ -314,12 +324,18 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name,
                key = ui_browser__run(&self->b, delay_secs);
 
                switch (key) {
-               case -1:
-                       /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
+               case K_TIMER:
                        timer(arg);
                        ui_browser__update_nr_entries(&self->b, self->hists->nr_entries);
-                       hists__browser_title(self->hists, title, sizeof(title),
-                                            ev_name);
+
+                       if (self->hists->stats.nr_lost_warned !=
+                           self->hists->stats.nr_events[PERF_RECORD_LOST]) {
+                               self->hists->stats.nr_lost_warned =
+                                       self->hists->stats.nr_events[PERF_RECORD_LOST];
+                               ui_browser__warn_lost_events(&self->b);
+                       }
+
+                       hists__browser_title(self->hists, title, sizeof(title), ev_name);
                        ui_browser__show_title(&self->b, title);
                        continue;
                case 'D': { /* Debug */
@@ -883,7 +899,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                        goto out_free_stack;
                case 'a':
                        if (!browser->has_symbols) {
-                               ui__warning(
+                               ui_browser__warning(&browser->b, delay_secs * 2,
                        "Annotation is only available for symbolic views, "
                        "include \"sym\" in --sort to use it.");
                                continue;
@@ -901,7 +917,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                case K_F1:
                case 'h':
                case '?':
-                       ui__help_window("h/?/F1        Show this window\n"
+                       ui_browser__help_window(&browser->b,
+                                       "h/?/F1        Show this window\n"
                                        "UP/DOWN/PGUP\n"
                                        "PGDN/SPACE    Navigate\n"
                                        "q/ESC/CTRL+C  Exit browser\n\n"
@@ -914,7 +931,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                                        "C             Collapse all callchains\n"
                                        "E             Expand all callchains\n"
                                        "d             Zoom into current DSO\n"
-                                       "t             Zoom into current Thread\n");
+                                       "t             Zoom into current Thread");
                        continue;
                case K_ENTER:
                case K_RIGHT:
@@ -940,7 +957,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                }
                case K_ESC:
                        if (!left_exits &&
-                           !ui__dialog_yesno("Do you really want to exit?"))
+                           !ui_browser__dialog_yesno(&browser->b,
+                                              "Do you really want to exit?"))
                                continue;
                        /* Fall thru */
                case 'q':
@@ -993,6 +1011,7 @@ add_exit_option:
 
                if (choice == annotate) {
                        struct hist_entry *he;
+                       int err;
 do_annotate:
                        he = hist_browser__selected_entry(browser);
                        if (he == NULL)
@@ -1001,10 +1020,12 @@ do_annotate:
                         * Don't let this be freed, say, by hists__decay_entry.
                         */
                        he->used = true;
-                       hist_entry__tui_annotate(he, evsel->idx, nr_events,
-                                                timer, arg, delay_secs);
+                       err = hist_entry__tui_annotate(he, evsel->idx, nr_events,
+                                                      timer, arg, delay_secs);
                        he->used = false;
                        ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
+                       if (err)
+                               ui_browser__handle_resize(&browser->b);
                } else if (choice == browse_map)
                        map__browse(browser->selection->map);
                else if (choice == zoom_dso) {
@@ -1056,6 +1077,7 @@ out:
 struct perf_evsel_menu {
        struct ui_browser b;
        struct perf_evsel *selection;
+       bool lost_events, lost_events_warned;
 };
 
 static void perf_evsel_menu__write(struct ui_browser *browser,
@@ -1068,14 +1090,29 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
        unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE];
        const char *ev_name = event_name(evsel);
        char bf[256], unit;
+       const char *warn = " ";
+       size_t printed;
 
        ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
                                                       HE_COLORSET_NORMAL);
 
        nr_events = convert_unit(nr_events, &unit);
-       snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events,
-                unit, unit == ' ' ? "" : " ", ev_name);
-       slsmg_write_nstring(bf, browser->width);
+       printed = snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events,
+                          unit, unit == ' ' ? "" : " ", ev_name);
+       slsmg_printf("%s", bf);
+
+       nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST];
+       if (nr_events != 0) {
+               menu->lost_events = true;
+               if (!current_entry)
+                       ui_browser__set_color(browser, HE_COLORSET_TOP);
+               nr_events = convert_unit(nr_events, &unit);
+               snprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", nr_events,
+                        unit, unit == ' ' ? "" : " ");
+               warn = bf;
+       }
+
+       slsmg_write_nstring(warn, browser->width - printed);
 
        if (current_entry)
                menu->selection = evsel;
@@ -1100,6 +1137,11 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
                switch (key) {
                case K_TIMER:
                        timer(arg);
+
+                       if (!menu->lost_events_warned && menu->lost_events) {
+                               ui_browser__warn_lost_events(&menu->b);
+                               menu->lost_events_warned = true;
+                       }
                        continue;
                case K_RIGHT:
                case K_ENTER:
@@ -1133,7 +1175,8 @@ browse_hists:
                                        pos = list_entry(pos->node.prev, struct perf_evsel, node);
                                goto browse_hists;
                        case K_ESC:
-                               if (!ui__dialog_yesno("Do you really want to exit?"))
+                               if (!ui_browser__dialog_yesno(&menu->b,
+                                               "Do you really want to exit?"))
                                        continue;
                                /* Fall thru */
                        case 'q':
@@ -1145,7 +1188,8 @@ browse_hists:
                case K_LEFT:
                        continue;
                case K_ESC:
-                       if (!ui__dialog_yesno("Do you really want to exit?"))
+                       if (!ui_browser__dialog_yesno(&menu->b,
+                                              "Do you really want to exit?"))
                                continue;
                        /* Fall thru */
                case 'q':
index f36d2ff509ed285baa5290d6780b3e9d8ca4ae9e..6ef3c56917626a38d835491d82461219b7dddf88 100644 (file)
@@ -1,20 +1,28 @@
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
-#include <newt.h>
+#include <string.h>
 
 #include "../debug.h"
 #include "helpline.h"
 #include "ui.h"
+#include "libslang.h"
 
 void ui_helpline__pop(void)
 {
-       newtPopHelpLine();
 }
 
+char ui_helpline__current[512];
+
 void ui_helpline__push(const char *msg)
 {
-       newtPushHelpLine(msg);
+       const size_t sz = sizeof(ui_helpline__current);
+
+       SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
+       SLsmg_set_color(0);
+       SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols);
+       SLsmg_refresh();
+       strncpy(ui_helpline__current, msg, sz)[sz - 1] = '\0';
 }
 
 void ui_helpline__vpush(const char *fmt, va_list ap)
@@ -63,7 +71,7 @@ int ui_helpline__show_help(const char *format, va_list ap)
 
        if (ui_helpline__last_msg[backlog - 1] == '\n') {
                ui_helpline__puts(ui_helpline__last_msg);
-               newtRefresh();
+               SLsmg_refresh();
                backlog = 0;
        }
        pthread_mutex_unlock(&ui__lock);
index fdcbc0270acd3bec570c0d1ac1953f06137442bb..7bab6b34e35ee7b9869c372373926e2f89d4dd57 100644 (file)
@@ -11,4 +11,6 @@ void ui_helpline__vpush(const char *fmt, va_list ap);
 void ui_helpline__fpush(const char *fmt, ...);
 void ui_helpline__puts(const char *msg);
 
+extern char ui_helpline__current[];
+
 #endif /* _PERF_UI_HELPLINE_H_ */
index d7fc399d36b30767ac5d1495597c0c8d9ec05d46..295e366b631100d1f871e36206395916680c2f21 100644 (file)
@@ -1,60 +1,29 @@
-#include <stdlib.h>
-#include <newt.h>
 #include "../cache.h"
 #include "progress.h"
+#include "libslang.h"
+#include "ui.h"
+#include "browser.h"
 
-struct ui_progress {
-       newtComponent form, scale;
-};
-
-struct ui_progress *ui_progress__new(const char *title, u64 total)
-{
-       struct ui_progress *self = malloc(sizeof(*self));
-
-       if (self != NULL) {
-               int cols;
-
-               if (use_browser <= 0)
-                       return self;
-               newtGetScreenSize(&cols, NULL);
-               cols -= 4;
-               newtCenteredWindow(cols, 1, title);
-               self->form  = newtForm(NULL, NULL, 0);
-               if (self->form == NULL)
-                       goto out_free_self;
-               self->scale = newtScale(0, 0, cols, total);
-               if (self->scale == NULL)
-                       goto out_free_form;
-               newtFormAddComponent(self->form, self->scale);
-               newtRefresh();
-       }
-
-       return self;
-
-out_free_form:
-       newtFormDestroy(self->form);
-out_free_self:
-       free(self);
-       return NULL;
-}
-
-void ui_progress__update(struct ui_progress *self, u64 curr)
+void ui_progress__update(u64 curr, u64 total, const char *title)
 {
+       int bar, y;
        /*
         * FIXME: We should have a per UI backend way of showing progress,
         * stdio will just show a percentage as NN%, etc.
         */
        if (use_browser <= 0)
                return;
-       newtScaleSet(self->scale, curr);
-       newtRefresh();
-}
 
-void ui_progress__delete(struct ui_progress *self)
-{
-       if (use_browser > 0) {
-               newtFormDestroy(self->form);
-               newtPopWindow();
-       }
-       free(self);
+       ui__refresh_dimensions(true);
+       pthread_mutex_lock(&ui__lock);
+       y = SLtt_Screen_Rows / 2 - 2;
+       SLsmg_set_color(0);
+       SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
+       SLsmg_gotorc(y++, 1);
+       SLsmg_write_string((char *)title);
+       SLsmg_set_color(HE_COLORSET_SELECTED);
+       bar = ((SLtt_Screen_Cols - 2) * curr) / total;
+       SLsmg_fill_region(y, 1, 1, bar, ' ');
+       SLsmg_refresh();
+       pthread_mutex_unlock(&ui__lock);
 }
index a3820a0beb5beb46adf1fe69cbcee0687ae5cbe8..d9c205b59aa1fca489350aec25dba6406c11fa52 100644 (file)
@@ -1,11 +1,8 @@
 #ifndef _PERF_UI_PROGRESS_H_
 #define _PERF_UI_PROGRESS_H_ 1
 
-struct ui_progress;
+#include <../types.h>
 
-struct ui_progress *ui_progress__new(const char *title, u64 total);
-void ui_progress__delete(struct ui_progress *self);
-
-void ui_progress__update(struct ui_progress *self, u64 curr);
+void ui_progress__update(u64 curr, u64 total, const char *title);
 
 #endif
index 1e6ba06980c4093248915077bdeb437d05098feb..85a69faa09aa6af44799795bf0e081093b1e536b 100644 (file)
@@ -7,10 +7,85 @@
 #include "browser.h"
 #include "helpline.h"
 #include "ui.h"
+#include "util.h"
 #include "libslang.h"
+#include "keysyms.h"
 
 pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
 
+static volatile int ui__need_resize;
+
+void ui__refresh_dimensions(bool force)
+{
+       if (force || ui__need_resize) {
+               ui__need_resize = 0;
+               pthread_mutex_lock(&ui__lock);
+               SLtt_get_screen_size();
+               SLsmg_reinit_smg();
+               pthread_mutex_unlock(&ui__lock);
+       }
+}
+
+static void ui__sigwinch(int sig __used)
+{
+       ui__need_resize = 1;
+}
+
+static void ui__setup_sigwinch(void)
+{
+       static bool done;
+
+       if (done)
+               return;
+
+       done = true;
+       pthread__unblock_sigwinch();
+       signal(SIGWINCH, ui__sigwinch);
+}
+
+int ui__getch(int delay_secs)
+{
+       struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
+       fd_set read_set;
+       int err, key;
+
+       ui__setup_sigwinch();
+
+       FD_ZERO(&read_set);
+       FD_SET(0, &read_set);
+
+       if (delay_secs) {
+               timeout.tv_sec = delay_secs;
+               timeout.tv_usec = 0;
+       }
+
+        err = select(1, &read_set, NULL, NULL, ptimeout);
+
+       if (err == 0)
+               return K_TIMER;
+
+       if (err == -1) {
+               if (errno == EINTR)
+                       return K_RESIZE;
+               return K_ERROR;
+       }
+
+       key = SLang_getkey();
+       if (key != K_ESC)
+               return key;
+
+       FD_ZERO(&read_set);
+       FD_SET(0, &read_set);
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 20;
+        err = select(1, &read_set, NULL, NULL, &timeout);
+       if (err == 0)
+               return K_ESC;
+
+       SLang_ungetkey(key);
+       return SLkp_getkey();
+}
+
 static void newt_suspend(void *d __used)
 {
        newtSuspend();
@@ -71,10 +146,10 @@ void setup_browser(bool fallback_to_pager)
 void exit_browser(bool wait_for_ok)
 {
        if (use_browser > 0) {
-               if (wait_for_ok) {
-                       char title[] = "Fatal Error", ok[] = "Ok";
-                       newtWinMessage(title, ok, ui_helpline__last_msg);
-               }
+               if (wait_for_ok)
+                       ui__question_window("Fatal Error",
+                                           ui_helpline__last_msg,
+                                           "Press any key...", 0);
                ui__exit();
        }
 }
index d264e059c82996b83faa577313b3aec072786bdb..7b67045479f6034c084574e31af34955a5c64a4c 100644 (file)
@@ -2,7 +2,10 @@
 #define _PERF_UI_H_ 1
 
 #include <pthread.h>
+#include <stdbool.h>
 
 extern pthread_mutex_t ui__lock;
 
+void ui__refresh_dimensions(bool force);
+
 #endif /* _PERF_UI_H_ */
index fdf1fc8f08bc83b2300311870f9b68ee559ef7c6..45daa7c41dad9812226ba8737a23664709d50cbb 100644 (file)
@@ -1,6 +1,5 @@
-#include <newt.h>
+#include "../util.h"
 #include <signal.h>
-#include <stdio.h>
 #include <stdbool.h>
 #include <string.h>
 #include <sys/ttydefaults.h>
@@ -8,72 +7,75 @@
 #include "../cache.h"
 #include "../debug.h"
 #include "browser.h"
+#include "keysyms.h"
 #include "helpline.h"
 #include "ui.h"
 #include "util.h"
+#include "libslang.h"
 
-static void newt_form__set_exit_keys(newtComponent self)
+static void ui_browser__argv_write(struct ui_browser *browser,
+                                  void *entry, int row)
 {
-       newtFormAddHotKey(self, NEWT_KEY_LEFT);
-       newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
-       newtFormAddHotKey(self, 'Q');
-       newtFormAddHotKey(self, 'q');
-       newtFormAddHotKey(self, CTRL('c'));
-}
+       char **arg = entry;
+       bool current_entry = ui_browser__is_current_entry(browser, row);
 
-static newtComponent newt_form__new(void)
-{
-       newtComponent self = newtForm(NULL, NULL, 0);
-       if (self)
-               newt_form__set_exit_keys(self);
-       return self;
+       ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
+                                                      HE_COLORSET_NORMAL);
+       slsmg_write_nstring(*arg, browser->width);
 }
 
-int ui__popup_menu(int argc, char * const argv[])
+static int popup_menu__run(struct ui_browser *menu)
 {
-       struct newtExitStruct es;
-       int i, rc = -1, max_len = 5;
-       newtComponent listbox, form = newt_form__new();
+       int key;
 
-       if (form == NULL)
+       if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
                return -1;
 
-       listbox = newtListbox(0, 0, argc, NEWT_FLAG_RETURNEXIT);
-       if (listbox == NULL)
-               goto out_destroy_form;
+       while (1) {
+               key = ui_browser__run(menu, 0);
 
-       newtFormAddComponent(form, listbox);
+               switch (key) {
+               case K_RIGHT:
+               case K_ENTER:
+                       key = menu->index;
+                       break;
+               case K_LEFT:
+               case K_ESC:
+               case 'q':
+               case CTRL('c'):
+                       key = -1;
+                       break;
+               default:
+                       continue;
+               }
 
-       for (i = 0; i < argc; ++i) {
-               int len = strlen(argv[i]);
-               if (len > max_len)
-                       max_len = len;
-               if (newtListboxAddEntry(listbox, argv[i], (void *)(long)i))
-                       goto out_destroy_form;
+               break;
        }
 
-       newtCenteredWindow(max_len, argc, NULL);
-       newtFormRun(form, &es);
-       rc = newtListboxGetCurrent(listbox) - NULL;
-       if (es.reason == NEWT_EXIT_HOTKEY)
-               rc = -1;
-       newtPopWindow();
-out_destroy_form:
-       newtFormDestroy(form);
-       return rc;
+       ui_browser__hide(menu);
+       return key;
 }
 
-int ui__help_window(const char *text)
+int ui__popup_menu(int argc, char * const argv[])
 {
-       struct newtExitStruct es;
-       newtComponent tb, form = newt_form__new();
-       int rc = -1;
+       struct ui_browser menu = {
+               .entries    = (void *)argv,
+               .refresh    = ui_browser__argv_refresh,
+               .seek       = ui_browser__argv_seek,
+               .write      = ui_browser__argv_write,
+               .nr_entries = argc,
+       };
+
+       return popup_menu__run(&menu);
+}
+
+int ui__question_window(const char *title, const char *text,
+                       const char *exit_msg, int delay_secs)
+{
+       int x, y;
        int max_len = 0, nr_lines = 0;
        const char *t;
 
-       if (form == NULL)
-               return -1;
-
        t = text;
        while (1) {
                const char *sep = strchr(t, '\n');
@@ -90,41 +92,77 @@ int ui__help_window(const char *text)
                t = sep + 1;
        }
 
-       tb = newtTextbox(0, 0, max_len, nr_lines, 0);
-       if (tb == NULL)
-               goto out_destroy_form;
-
-       newtTextboxSetText(tb, text);
-       newtFormAddComponent(form, tb);
-       newtCenteredWindow(max_len, nr_lines, NULL);
-       newtFormRun(form, &es);
-       newtPopWindow();
-       rc = 0;
-out_destroy_form:
-       newtFormDestroy(form);
-       return rc;
+       max_len += 2;
+       nr_lines += 4;
+       y = SLtt_Screen_Rows / 2 - nr_lines / 2,
+       x = SLtt_Screen_Cols / 2 - max_len / 2;
+
+       SLsmg_set_color(0);
+       SLsmg_draw_box(y, x++, nr_lines, max_len);
+       if (title) {
+               SLsmg_gotorc(y, x + 1);
+               SLsmg_write_string((char *)title);
+       }
+       SLsmg_gotorc(++y, x);
+       nr_lines -= 2;
+       max_len -= 2;
+       SLsmg_write_wrapped_string((unsigned char *)text, y, x,
+                                  nr_lines, max_len, 1);
+       SLsmg_gotorc(y + nr_lines - 2, x);
+       SLsmg_write_nstring((char *)" ", max_len);
+       SLsmg_gotorc(y + nr_lines - 1, x);
+       SLsmg_write_nstring((char *)exit_msg, max_len);
+       SLsmg_refresh();
+       return ui__getch(delay_secs);
 }
 
-static const char yes[] = "Yes", no[] = "No",
-                 warning_str[] = "Warning!", ok[] = "Ok";
+int ui__help_window(const char *text)
+{
+       return ui__question_window("Help", text, "Press any key...", 0);
+}
 
-bool ui__dialog_yesno(const char *msg)
+int ui__dialog_yesno(const char *msg)
 {
-       /* newtWinChoice should really be accepting const char pointers... */
-       return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1;
+       return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
 }
 
-void ui__warning(const char *format, ...)
+int __ui__warning(const char *title, const char *format, va_list args)
 {
-       va_list args;
+       char *s;
+
+       if (use_browser > 0 && vasprintf(&s, format, args) > 0) {
+               int key;
 
-       va_start(args, format);
-       if (use_browser > 0) {
                pthread_mutex_lock(&ui__lock);
-               newtWinMessagev((char *)warning_str, (char *)ok,
-                               (char *)format, args);
+               key = ui__question_window(title, s, "Press any key...", 0);
                pthread_mutex_unlock(&ui__lock);
-       } else
-               vfprintf(stderr, format, args);
+               free(s);
+               return key;
+       }
+
+       fprintf(stderr, "%s:\n", title);
+       vfprintf(stderr, format, args);
+       return K_ESC;
+}
+
+int ui__warning(const char *format, ...)
+{
+       int key;
+       va_list args;
+
+       va_start(args, format);
+       key = __ui__warning("Warning", format, args);
+       va_end(args);
+       return key;
+}
+
+int ui__error(const char *format, ...)
+{
+       int key;
+       va_list args;
+
+       va_start(args, format);
+       key = __ui__warning("Error", format, args);
        va_end(args);
+       return key;
 }
index afcbc1d99531595eee370f9076975dc609ebfb55..2d1738bd71c8adc639e7e53919f2cf988ea07ec3 100644 (file)
@@ -1,10 +1,14 @@
 #ifndef _PERF_UI_UTIL_H_
 #define _PERF_UI_UTIL_H_ 1
 
-#include <stdbool.h>
+#include <stdarg.h>
 
+int ui__getch(int delay_secs);
 int ui__popup_menu(int argc, char * const argv[]);
 int ui__help_window(const char *text);
-bool ui__dialog_yesno(const char *msg);
+int ui__dialog_yesno(const char *msg);
+int ui__question_window(const char *title, const char *text,
+                       const char *exit_msg, int delay_secs);
+int __ui__warning(const char *title, const char *format, va_list args);
 
 #endif /* _PERF_UI_UTIL_H_ */
index 8b2d37b59c9e2178c21256b240b3ca76b3081a76..3c6f7808efae53b84cab8926f87b3a5f37ea60ee 100644 (file)
@@ -162,19 +162,21 @@ void print_header(void)
 
 void dump_cnt(struct counters *cnt)
 {
-       fprintf(stderr, "package: %d ", cnt->pkg);
-       fprintf(stderr, "core:: %d ", cnt->core);
-       fprintf(stderr, "CPU: %d ", cnt->cpu);
-       fprintf(stderr, "TSC: %016llX\n", cnt->tsc);
-       fprintf(stderr, "c3: %016llX\n", cnt->c3);
-       fprintf(stderr, "c6: %016llX\n", cnt->c6);
-       fprintf(stderr, "c7: %016llX\n", cnt->c7);
-       fprintf(stderr, "aperf: %016llX\n", cnt->aperf);
-       fprintf(stderr, "pc2: %016llX\n", cnt->pc2);
-       fprintf(stderr, "pc3: %016llX\n", cnt->pc3);
-       fprintf(stderr, "pc6: %016llX\n", cnt->pc6);
-       fprintf(stderr, "pc7: %016llX\n", cnt->pc7);
-       fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, cnt->extra_msr);
+       if (!cnt)
+               return;
+       if (cnt->pkg) fprintf(stderr, "package: %d ", cnt->pkg);
+       if (cnt->core) fprintf(stderr, "core:: %d ", cnt->core);
+       if (cnt->cpu) fprintf(stderr, "CPU: %d ", cnt->cpu);
+       if (cnt->tsc) fprintf(stderr, "TSC: %016llX\n", cnt->tsc);
+       if (cnt->c3) fprintf(stderr, "c3: %016llX\n", cnt->c3);
+       if (cnt->c6) fprintf(stderr, "c6: %016llX\n", cnt->c6);
+       if (cnt->c7) fprintf(stderr, "c7: %016llX\n", cnt->c7);
+       if (cnt->aperf) fprintf(stderr, "aperf: %016llX\n", cnt->aperf);
+       if (cnt->pc2) fprintf(stderr, "pc2: %016llX\n", cnt->pc2);
+       if (cnt->pc3) fprintf(stderr, "pc3: %016llX\n", cnt->pc3);
+       if (cnt->pc6) fprintf(stderr, "pc6: %016llX\n", cnt->pc6);
+       if (cnt->pc7) fprintf(stderr, "pc7: %016llX\n", cnt->pc7);
+       if (cnt->extra_msr) fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, cnt->extra_msr);
 }
 
 void dump_list(struct counters *cnt)
index 8d02ccb10c598bc8c7a9e926e9b9500c75d51e37..8b4c2535b266a2abe17d3ad495b3a0fdfa8855a9 100755 (executable)
@@ -42,6 +42,7 @@ $default{"BISECT_MANUAL"}     = 0;
 $default{"BISECT_SKIP"}                = 1;
 $default{"SUCCESS_LINE"}       = "login:";
 $default{"DETECT_TRIPLE_FAULT"} = 1;
+$default{"NO_INSTALL"}         = 0;
 $default{"BOOTED_TIMEOUT"}     = 1;
 $default{"DIE_ON_FAILURE"}     = 1;
 $default{"SSH_EXEC"}           = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
@@ -84,6 +85,7 @@ my $grub_number;
 my $target;
 my $make;
 my $post_install;
+my $no_install;
 my $noclean;
 my $minconfig;
 my $start_minconfig;
@@ -115,6 +117,7 @@ my $timeout;
 my $booted_timeout;
 my $detect_triplefault;
 my $console;
+my $reboot_success_line;
 my $success_line;
 my $stop_after_success;
 my $stop_after_failure;
@@ -130,6 +133,12 @@ my %config_help;
 my %variable;
 my %force_config;
 
+# do not force reboots on config problems
+my $no_reboot = 1;
+
+# default variables that can be used
+chomp ($variable{"PWD"} = `pwd`);
+
 $config_help{"MACHINE"} = << "EOF"
  The machine hostname that you will test.
 EOF
@@ -241,6 +250,7 @@ sub read_yn {
 
 sub get_ktest_config {
     my ($config) = @_;
+    my $ans;
 
     return if (defined($opt{$config}));
 
@@ -254,16 +264,17 @@ sub get_ktest_config {
        if (defined($default{$config})) {
            print "\[$default{$config}\] ";
        }
-       $entered_configs{$config} = <STDIN>;
-       $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
-       if ($entered_configs{$config} =~ /^\s*$/) {
+       $ans = <STDIN>;
+       $ans =~ s/^\s*(.*\S)\s*$/$1/;
+       if ($ans =~ /^\s*$/) {
            if ($default{$config}) {
-               $entered_configs{$config} = $default{$config};
+               $ans = $default{$config};
            } else {
                print "Your answer can not be blank\n";
                next;
            }
        }
+       $entered_configs{$config} = process_variables($ans);
        last;
     }
 }
@@ -298,7 +309,7 @@ sub get_ktest_configs {
 }
 
 sub process_variables {
-    my ($value) = @_;
+    my ($value, $remove_undef) = @_;
     my $retval = "";
 
     # We want to check for '\', and it is just easier
@@ -316,6 +327,10 @@ sub process_variables {
        $retval = "$retval$begin";
        if (defined($variable{$var})) {
            $retval = "$retval$variable{$var}";
+       } elsif (defined($remove_undef) && $remove_undef) {
+           # for if statements, any variable that is not defined,
+           # we simple convert to 0
+           $retval = "${retval}0";
        } else {
            # put back the origin piece.
            $retval = "$retval\$\{$var\}";
@@ -331,10 +346,17 @@ sub process_variables {
 }
 
 sub set_value {
-    my ($lvalue, $rvalue) = @_;
+    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
 
     if (defined($opt{$lvalue})) {
-       die "Error: Option $lvalue defined more than once!\n";
+       if (!$override || defined(${$overrides}{$lvalue})) {
+           my $extra = "";
+           if ($override) {
+               $extra = "In the same override section!\n";
+           }
+           die "$name: $.: Option $lvalue defined more than once!\n$extra";
+       }
+       ${$overrides}{$lvalue} = $rvalue;
     }
     if ($rvalue =~ /^\s*$/) {
        delete $opt{$lvalue};
@@ -355,86 +377,274 @@ sub set_variable {
     }
 }
 
-sub read_config {
-    my ($config) = @_;
+sub process_compare {
+    my ($lval, $cmp, $rval) = @_;
+
+    # remove whitespace
+
+    $lval =~ s/^\s*//;
+    $lval =~ s/\s*$//;
+
+    $rval =~ s/^\s*//;
+    $rval =~ s/\s*$//;
+
+    if ($cmp eq "==") {
+       return $lval eq $rval;
+    } elsif ($cmp eq "!=") {
+       return $lval ne $rval;
+    }
+
+    my $statement = "$lval $cmp $rval";
+    my $ret = eval $statement;
+
+    # $@ stores error of eval
+    if ($@) {
+       return -1;
+    }
+
+    return $ret;
+}
+
+sub value_defined {
+    my ($val) = @_;
+
+    return defined($variable{$2}) ||
+       defined($opt{$2});
+}
+
+my $d = 0;
+sub process_expression {
+    my ($name, $val) = @_;
+
+    my $c = $d++;
+
+    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
+       my $express = $1;
+
+       if (process_expression($name, $express)) {
+           $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
+       } else {
+           $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
+       }
+    }
+
+    $d--;
+    my $OR = "\\|\\|";
+    my $AND = "\\&\\&";
+
+    while ($val =~ s/^(.*?)($OR|$AND)//) {
+       my $express = $1;
+       my $op = $2;
+
+       if (process_expression($name, $express)) {
+           if ($op eq "||") {
+               return 1;
+           }
+       } else {
+           if ($op eq "&&") {
+               return 0;
+           }
+       }
+    }
+
+    if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
+       my $ret = process_compare($1, $2, $3);
+       if ($ret < 0) {
+           die "$name: $.: Unable to process comparison\n";
+       }
+       return $ret;
+    }
+
+    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
+       if (defined $1) {
+           return !value_defined($2);
+       } else {
+           return value_defined($2);
+       }
+    }
+
+    if ($val =~ /^\s*0\s*$/) {
+       return 0;
+    } elsif ($val =~ /^\s*\d+\s*$/) {
+       return 1;
+    }
+
+    die ("$name: $.: Undefined content $val in if statement\n");
+}
+
+sub process_if {
+    my ($name, $value) = @_;
 
-    open(IN, $config) || die "can't read file $config";
+    # Convert variables and replace undefined ones with 0
+    my $val = process_variables($value, 1);
+    my $ret = process_expression $name, $val;
+
+    return $ret;
+}
+
+sub __read_config {
+    my ($config, $current_test_num) = @_;
+
+    my $in;
+    open($in, $config) || die "can't read file $config";
 
     my $name = $config;
     $name =~ s,.*/(.*),$1,;
 
-    my $test_num = 0;
+    my $test_num = $$current_test_num;
     my $default = 1;
     my $repeat = 1;
     my $num_tests_set = 0;
     my $skip = 0;
     my $rest;
+    my $line;
     my $test_case = 0;
+    my $if = 0;
+    my $if_set = 0;
+    my $override = 0;
 
-    while (<IN>) {
+    my %overrides;
+
+    while (<$in>) {
 
        # ignore blank lines and comments
        next if (/^\s*$/ || /\s*\#/);
 
-       if (/^\s*TEST_START(.*)/) {
+       if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
 
-           $rest = $1;
+           my $type = $1;
+           $rest = $2;
+           $line = $2;
 
-           if ($num_tests_set) {
-               die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
-           }
+           my $old_test_num;
+           my $old_repeat;
+           $override = 0;
+
+           if ($type eq "TEST_START") {
 
-           my $old_test_num = $test_num;
-           my $old_repeat = $repeat;
+               if ($num_tests_set) {
+                   die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
+               }
 
-           $test_num += $repeat;
-           $default = 0;
-           $repeat = 1;
+               $old_test_num = $test_num;
+               $old_repeat = $repeat;
 
-           if ($rest =~ /\s+SKIP(.*)/) {
-               $rest = $1;
+               $test_num += $repeat;
+               $default = 0;
+               $repeat = 1;
+           } else {
+               $default = 1;
+           }
+
+           # If SKIP is anywhere in the line, the command will be skipped
+           if ($rest =~ s/\s+SKIP\b//) {
                $skip = 1;
            } else {
                $test_case = 1;
                $skip = 0;
            }
 
-           if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
-               $repeat = $1;
-               $rest = $2;
-               $repeat_tests{"$test_num"} = $repeat;
+           if ($rest =~ s/\sELSE\b//) {
+               if (!$if) {
+                   die "$name: $.: ELSE found with out matching IF section\n$_";
+               }
+               $if = 0;
+
+               if ($if_set) {
+                   $skip = 1;
+               } else {
+                   $skip = 0;
+               }
            }
 
-           if ($rest =~ /\s+SKIP(.*)/) {
-               $rest = $1;
-               $skip = 1;
+           if ($rest =~ s/\sIF\s+(.*)//) {
+               if (process_if($name, $1)) {
+                   $if_set = 1;
+               } else {
+                   $skip = 1;
+               }
+               $if = 1;
+           } else {
+               $if = 0;
+               $if_set = 0;
            }
 
-           if ($rest !~ /^\s*$/) {
-               die "$name: $.: Gargbage found after TEST_START\n$_";
+           if (!$skip) {
+               if ($type eq "TEST_START") {
+                   if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
+                       $repeat = $1;
+                       $repeat_tests{"$test_num"} = $repeat;
+                   }
+               } elsif ($rest =~ s/\sOVERRIDE\b//) {
+                   # DEFAULT only
+                   $override = 1;
+                   # Clear previous overrides
+                   %overrides = ();
+               }
+           }
+
+           if (!$skip && $rest !~ /^\s*$/) {
+               die "$name: $.: Gargbage found after $type\n$_";
            }
 
-           if ($skip) {
+           if ($skip && $type eq "TEST_START") {
                $test_num = $old_test_num;
                $repeat = $old_repeat;
            }
 
-       } elsif (/^\s*DEFAULTS(.*)$/) {
-           $default = 1;
-
+       } elsif (/^\s*ELSE\b(.*)$/) {
+           if (!$if) {
+               die "$name: $.: ELSE found with out matching IF section\n$_";
+           }
            $rest = $1;
-
-           if ($rest =~ /\s+SKIP(.*)/) {
-               $rest = $1;
+           if ($if_set) {
                $skip = 1;
+               $rest = "";
            } else {
                $skip = 0;
+
+               if ($rest =~ /\sIF\s+(.*)/) {
+                   # May be a ELSE IF section.
+                   if (!process_if($name, $1)) {
+                       $skip = 1;
+                   }
+                   $rest = "";
+               } else {
+                   $if = 0;
+               }
            }
 
            if ($rest !~ /^\s*$/) {
                die "$name: $.: Gargbage found after DEFAULTS\n$_";
            }
 
+       } elsif (/^\s*INCLUDE\s+(\S+)/) {
+
+           next if ($skip);
+
+           if (!$default) {
+               die "$name: $.: INCLUDE can only be done in default sections\n$_";
+           }
+
+           my $file = process_variables($1);
+
+           if ($file !~ m,^/,) {
+               # check the path of the config file first
+               if ($config =~ m,(.*)/,) {
+                   if (-f "$1/$file") {
+                       $file = "$1/$file";
+                   }
+               }
+           }
+               
+           if ( ! -r $file ) {
+               die "$name: $.: Can't read file $file\n$_";
+           }
+
+           if (__read_config($file, \$test_num)) {
+               $test_case = 1;
+           }
+
        } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
 
            next if ($skip);
@@ -460,10 +670,10 @@ sub read_config {
            }
 
            if ($default || $lvalue =~ /\[\d+\]$/) {
-               set_value($lvalue, $rvalue);
+               set_value($lvalue, $rvalue, $override, \%overrides, $name);
            } else {
                my $val = "$lvalue\[$test_num\]";
-               set_value($val, $rvalue);
+               set_value($val, $rvalue, $override, \%overrides, $name);
 
                if ($repeat > 1) {
                    $repeats{$val} = $repeat;
@@ -490,13 +700,26 @@ sub read_config {
        }
     }
 
-    close(IN);
-
     if ($test_num) {
        $test_num += $repeat - 1;
        $opt{"NUM_TESTS"} = $test_num;
     }
 
+    close($in);
+
+    $$current_test_num = $test_num;
+
+    return $test_case;
+}
+
+sub read_config {
+    my ($config) = @_;
+
+    my $test_case;
+    my $test_num = 0;
+
+    $test_case = __read_config $config, \$test_num;
+
     # make sure we have all mandatory configs
     get_ktest_configs;
 
@@ -524,6 +747,18 @@ sub __eval_option {
     # Add space to evaluate the character before $
     $option = " $option";
     my $retval = "";
+    my $repeated = 0;
+    my $parent = 0;
+
+    foreach my $test (keys %repeat_tests) {
+       if ($i >= $test &&
+           $i < $test + $repeat_tests{$test}) {
+
+           $repeated = 1;
+           $parent = $test;
+           last;
+       }
+    }
 
     while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
        my $start = $1;
@@ -537,10 +772,14 @@ sub __eval_option {
        # otherwise see if the default OPT (without [$i]) exists.
 
        my $o = "$var\[$i\]";
+       my $parento = "$var\[$parent\]";
 
        if (defined($opt{$o})) {
            $o = $opt{$o};
            $retval = "$retval$o";
+       } elsif ($repeated && defined($opt{$parento})) {
+           $o = $opt{$parento};
+           $retval = "$retval$o";
        } elsif (defined($opt{$var})) {
            $o = $opt{$var};
            $retval = "$retval$o";
@@ -603,8 +842,20 @@ sub doprint {
 }
 
 sub run_command;
+sub start_monitor;
+sub end_monitor;
+sub wait_for_monitor;
 
 sub reboot {
+    my ($time) = @_;
+
+    if (defined($time)) {
+       start_monitor;
+       # flush out current monitor
+       # May contain the reboot success line
+       wait_for_monitor 1;
+    }
+
     # try to reboot normally
     if (run_command $reboot) {
        if (defined($powercycle_after_reboot)) {
@@ -615,12 +866,17 @@ sub reboot {
        # nope? power cycle it.
        run_command "$power_cycle";
     }
+
+    if (defined($time)) {
+       wait_for_monitor($time, $reboot_success_line);
+       end_monitor;
+    }
 }
 
 sub do_not_reboot {
     my $i = $iteration;
 
-    return $test_type eq "build" ||
+    return $test_type eq "build" || $no_reboot ||
        ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
        ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
 }
@@ -693,16 +949,29 @@ sub end_monitor {
 }
 
 sub wait_for_monitor {
-    my ($time) = @_;
+    my ($time, $stop) = @_;
+    my $full_line = "";
     my $line;
+    my $booted = 0;
 
     doprint "** Wait for monitor to settle down **\n";
 
     # read the monitor and wait for the system to calm down
-    do {
+    while (!$booted) {
        $line = wait_for_input($monitor_fp, $time);
-       print "$line" if (defined($line));
-    } while (defined($line));
+       last if (!defined($line));
+       print "$line";
+       $full_line .= $line;
+
+       if (defined($stop) && $full_line =~ /$stop/) {
+           doprint "wait for monitor detected $stop\n";
+           $booted = 1;
+       }
+
+       if ($line =~ /\n/) {
+           $full_line = "";
+       }
+    }
     print "** Monitor flushed **\n";
 }
 
@@ -719,10 +988,7 @@ sub fail {
        # no need to reboot for just building.
        if (!do_not_reboot) {
            doprint "REBOOTING\n";
-           reboot;
-           start_monitor;
-           wait_for_monitor $sleep_time;
-           end_monitor;
+           reboot $sleep_time;
        }
 
        my $name = "";
@@ -854,9 +1120,12 @@ sub get_grub_index {
     open(IN, "$ssh_grub |")
        or die "unable to get menu.lst";
 
+    my $found = 0;
+
     while (<IN>) {
        if (/^\s*title\s+$grub_menu\s*$/) {
            $grub_number++;
+           $found = 1;
            last;
        } elsif (/^\s*title\s/) {
            $grub_number++;
@@ -865,7 +1134,7 @@ sub get_grub_index {
     close(IN);
 
     die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
-       if ($grub_number < 0);
+       if (!$found);
     doprint "$grub_number\n";
 }
 
@@ -902,7 +1171,8 @@ sub wait_for_input
 
 sub reboot_to {
     if ($reboot_type eq "grub") {
-       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
+       run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+       reboot;
        return;
     }
 
@@ -1083,6 +1353,8 @@ sub do_post_install {
 
 sub install {
 
+    return if ($no_install);
+
     run_scp "$outputdir/$build_target", "$target_image" or
        dodie "failed to copy image";
 
@@ -1140,6 +1412,11 @@ sub get_version {
 }
 
 sub start_monitor_and_boot {
+    # Make sure the stable kernel has finished booting
+    start_monitor;
+    wait_for_monitor 5;
+    end_monitor;
+
     get_grub_index;
     get_version;
     install;
@@ -1250,6 +1527,10 @@ sub build {
 
     unlink $buildlog;
 
+    # Failed builds should not reboot the target
+    my $save_no_reboot = $no_reboot;
+    $no_reboot = 1;
+
     if (defined($pre_build)) {
        my $ret = run_command $pre_build;
        if (!$ret && defined($pre_build_die) &&
@@ -1272,15 +1553,15 @@ sub build {
        # allow for empty configs
        run_command "touch $output_config";
 
-       run_command "mv $output_config $outputdir/config_temp" or
-           dodie "moving .config";
+       if (!$noclean) {
+           run_command "mv $output_config $outputdir/config_temp" or
+               dodie "moving .config";
 
-       if (!$noclean && !run_command "$make mrproper") {
-           dodie "make mrproper";
-       }
+           run_command "$make mrproper" or dodie "make mrproper";
 
-       run_command "mv $outputdir/config_temp $output_config" or
-           dodie "moving config_temp";
+           run_command "mv $outputdir/config_temp $output_config" or
+               dodie "moving config_temp";
+       }
 
     } elsif (!$noclean) {
        unlink "$output_config";
@@ -1318,10 +1599,15 @@ sub build {
 
     if (!$build_ret) {
        # bisect may need this to pass
-       return 0 if ($in_bisect);
+       if ($in_bisect) {
+           $no_reboot = $save_no_reboot;
+           return 0;
+       }
        fail "failed build" and return 0;
     }
 
+    $no_reboot = $save_no_reboot;
+
     return 1;
 }
 
@@ -1356,10 +1642,7 @@ sub success {
 
     if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
        doprint "Reboot and wait $sleep_time seconds\n";
-       reboot;
-       start_monitor;
-       wait_for_monitor $sleep_time;
-       end_monitor;
+       reboot $sleep_time;
     }
 }
 
@@ -1500,10 +1783,7 @@ sub run_git_bisect {
 
 sub bisect_reboot {
     doprint "Reboot and sleep $bisect_sleep_time seconds\n";
-    reboot;
-    start_monitor;
-    wait_for_monitor $bisect_sleep_time;
-    end_monitor;
+    reboot $bisect_sleep_time;
 }
 
 # returns 1 on success, 0 on failure, -1 on skip
@@ -2066,10 +2346,7 @@ sub config_bisect {
 
 sub patchcheck_reboot {
     doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
-    reboot;
-    start_monitor;
-    wait_for_monitor $patchcheck_sleep_time;
-    end_monitor;
+    reboot $patchcheck_sleep_time;
 }
 
 sub patchcheck {
@@ -2178,12 +2455,31 @@ sub patchcheck {
 }
 
 my %depends;
+my %depcount;
 my $iflevel = 0;
 my @ifdeps;
 
 # prevent recursion
 my %read_kconfigs;
 
+sub add_dep {
+    # $config depends on $dep
+    my ($config, $dep) = @_;
+
+    if (defined($depends{$config})) {
+       $depends{$config} .= " " . $dep;
+    } else {
+       $depends{$config} = $dep;
+    }
+
+    # record the number of configs depending on $dep
+    if (defined $depcount{$dep}) {
+       $depcount{$dep}++;
+    } else {
+       $depcount{$dep} = 1;
+    } 
+}
+
 # taken from streamline_config.pl
 sub read_kconfig {
     my ($kconfig) = @_;
@@ -2230,30 +2526,19 @@ sub read_kconfig {
            $config = $2;
 
            for (my $i = 0; $i < $iflevel; $i++) {
-               if ($i) {
-                   $depends{$config} .= " " . $ifdeps[$i];
-               } else {
-                   $depends{$config} = $ifdeps[$i];
-               }
-               $state = "DEP";
+               add_dep $config, $ifdeps[$i];
            }
 
        # collect the depends for the config
        } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
 
-           if (defined($depends{$1})) {
-               $depends{$config} .= " " . $1;
-           } else {
-               $depends{$config} = $1;
-           }
+           add_dep $config, $1;
 
        # Get the configs that select this config
-       } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
-           if (defined($depends{$1})) {
-               $depends{$1} .= " " . $config;
-           } else {
-               $depends{$1} = $config;
-           }
+       } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
+
+           # selected by depends on config
+           add_dep $1, $config;
 
        # Check for if statements
        } elsif (/^if\s+(.*\S)\s*$/) {
@@ -2365,11 +2650,18 @@ sub make_new_config {
     close OUT;
 }
 
+sub chomp_config {
+    my ($config) = @_;
+
+    $config =~ s/CONFIG_//;
+
+    return $config;
+}
+
 sub get_depends {
     my ($dep) = @_;
 
-    my $kconfig = $dep;
-    $kconfig =~ s/CONFIG_//;
+    my $kconfig = chomp_config $dep;
 
     $dep = $depends{"$kconfig"};
 
@@ -2419,8 +2711,7 @@ sub test_this_config {
        return undef;
     }
 
-    my $kconfig = $config;
-    $kconfig =~ s/CONFIG_//;
+    my $kconfig = chomp_config $config;
 
     # Test dependencies first
     if (defined($depends{"$kconfig"})) {
@@ -2510,6 +2801,14 @@ sub make_min_config {
 
     my @config_keys = keys %min_configs;
 
+    # All configs need a depcount
+    foreach my $config (@config_keys) {
+       my $kconfig = chomp_config $config;
+       if (!defined $depcount{$kconfig}) {
+               $depcount{$kconfig} = 0;
+       }
+    }
+
     # Remove anything that was set by the make allnoconfig
     # we shouldn't need them as they get set for us anyway.
     foreach my $config (@config_keys) {
@@ -2548,8 +2847,13 @@ sub make_min_config {
        # Now disable each config one by one and do a make oldconfig
        # till we find a config that changes our list.
 
-       # Put configs that did not modify the config at the end.
        my @test_configs = keys %min_configs;
+
+       # Sort keys by who is most dependent on
+       @test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
+                         @test_configs ;
+
+       # Put configs that did not modify the config at the end.
        my $reset = 1;
        for (my $i = 0; $i < $#test_configs; $i++) {
            if (!defined($nochange_config{$test_configs[0]})) {
@@ -2659,10 +2963,7 @@ sub make_min_config {
        }
 
        doprint "Reboot and wait $sleep_time seconds\n";
-       reboot;
-       start_monitor;
-       wait_for_monitor $sleep_time;
-       end_monitor;
+       reboot $sleep_time;
     }
 
     success $i;
@@ -2783,6 +3084,9 @@ sub set_test_option {
 # First we need to do is the builds
 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
 
+    # Do not reboot on failing test options
+    $no_reboot = 1;
+
     $iteration = $i;
 
     my $makecmd = set_test_option("MAKE_CMD", $i);
@@ -2811,6 +3115,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
     $reboot_type = set_test_option("REBOOT_TYPE", $i);
     $grub_menu = set_test_option("GRUB_MENU", $i);
     $post_install = set_test_option("POST_INSTALL", $i);
+    $no_install = set_test_option("NO_INSTALL", $i);
     $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
     $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
     $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
@@ -2832,6 +3137,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
     $console = set_test_option("CONSOLE", $i);
     $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
     $success_line = set_test_option("SUCCESS_LINE", $i);
+    $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
     $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
     $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
     $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
@@ -2850,9 +3156,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
 
     chdir $builddir || die "can't change directory to $builddir";
 
-    if (!-d $tmpdir) {
-       mkpath($tmpdir) or
-           die "can't create $tmpdir";
+    foreach my $dir ($tmpdir, $outputdir) {
+       if (!-d $dir) {
+           mkpath($dir) or
+               die "can't create $dir";
+       }
     }
 
     $ENV{"SSH_USER"} = $ssh_user;
@@ -2889,8 +3197,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
        $run_type = "ERROR";
     }
 
+    my $installme = "";
+    $installme = " no_install" if ($no_install);
+
     doprint "\n\n";
-    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
+    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
 
     unlink $dmesg;
     unlink $buildlog;
@@ -2911,6 +3222,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
            die "failed to checkout $checkout";
     }
 
+    $no_reboot = 0;
+
+
     if ($test_type eq "bisect") {
        bisect $i;
        next;
@@ -2929,6 +3243,13 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
        build $build_type or next;
     }
 
+    if ($test_type eq "install") {
+       get_version;
+       install;
+       success $i;
+       next;
+    }
+
     if ($test_type ne "build") {
        my $failed = 0;
        start_monitor_and_boot or $failed = 1;
index b8bcd14b5a4da7f3e2979b75118196971acda3e2..dbedfa196727ddc01ff0b5f563d0ce08dfeb9e95 100644 (file)
 # the same option name under the same test or as default
 # ktest will fail to execute, and no tests will run.
 #
+# DEFAULTS OVERRIDE
+#
+# Options defined in the DEFAULTS section can not be duplicated
+# even if they are defined in two different DEFAULT sections.
+# This is done to catch mistakes where an option is added but
+# the previous option was forgotten about and not commented.
+#
+# The OVERRIDE keyword can be added to a section to allow this
+# section to override other DEFAULT sections values that have
+# been defined previously. It will only override options that
+# have been defined before its use. Options defined later
+# in a non override section will still error. The same option
+# can not be defined in the same section even if that section
+# is marked OVERRIDE.
+#
+#
+#
+# Both TEST_START and DEFAULTS sections can also have the IF keyword
+# The value after the IF must evaluate into a 0 or non 0 positive
+# integer, and can use the config variables (explained below).
+#
+# DEFAULTS IF ${IS_X86_32}
+#
+# The above will process the DEFAULTS section if the config
+# variable IS_X86_32 evaluates to a non zero positive integer
+# otherwise if it evaluates to zero, it will act the same
+# as if the SKIP keyword was used.
+#
+# The ELSE keyword can be used directly after a section with
+# a IF statement.
+#
+# TEST_START IF ${RUN_NET_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# ELSE
+#
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-normal
+#
+#
+# The ELSE keyword can also contain an IF statement to allow multiple
+# if then else sections. But all the sections must be either
+# DEFAULT or TEST_START, they can not be a mixture.
+#
+# TEST_START IF ${RUN_NET_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# ELSE IF ${RUN_DISK_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-tests
+#
+# ELSE IF ${RUN_CPU_TESTS}
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-cpu
+#
+# ELSE
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network
+#
+# The if statement may also have comparisons that will and for
+# == and !=, strings may be used for both sides.
+#
+# BOX_TYPE := x86_32
+#
+# DEFAULTS IF ${BOX_TYPE} == x86_32
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-32
+# ELSE
+# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-64
+#
+# The DEFINED keyword can be used by the IF statements too.
+# It returns true if the given config variable or option has been defined
+# or false otherwise.
+#
+# 
+# DEFAULTS IF DEFINED USE_CC
+# CC := ${USE_CC}
+# ELSE
+# CC := gcc
+#
+#
+# As well as NOT DEFINED.
+#
+# DEFAULTS IF NOT DEFINED MAKE_CMD
+# MAKE_CMD := make ARCH=x86
+#
+#
+# And/or ops (&&,||) may also be used to make complex conditionals.
+#
+# TEST_START IF (DEFINED ALL_TESTS || ${MYTEST} == boottest) && ${MACHINE} == gandalf
+#
+# Notice the use of paranthesis. Without any paranthesis the above would be
+# processed the same as:
+#
+# TEST_START IF DEFINED ALL_TESTS || (${MYTEST} == boottest && ${MACHINE} == gandalf)
+#
+#
+#
+# INCLUDE file
+#
+# The INCLUDE keyword may be used in DEFAULT sections. This will
+# read another config file and process that file as well. The included
+# file can include other files, add new test cases or default
+# statements. Config variables will be passed to these files and changes
+# to config variables will be seen by top level config files. Including
+# a file is processed just like the contents of the file was cut and pasted
+# into the top level file, except, that include files that end with
+# TEST_START sections will have that section ended at the end of
+# the include file. That is, an included file is included followed
+# by another DEFAULT keyword.
+#
+# Unlike other files referenced in this config, the file path does not need
+# to be absolute. If the file does not start with '/', then the directory
+# that the current config file was located in is used. If no config by the
+# given name is found there, then the current directory is searched.
+#
+# INCLUDE myfile
+# DEFAULT
+#
+# is the same as:
+#
+# INCLUDE myfile
+#
+# Note, if the include file does not contain a full path, the file is
+# searched first by the location of the original include file, and then
+# by the location that ktest.pl was executed in.
+#
 
 #### Config variables ####
 #
 
 # The default test type (default test)
 # The test types may be:
-#   build - only build the kernel, do nothing else
-#   boot - build and boot the kernel
-#   test - build, boot and if TEST is set, run the test script
+#   build   - only build the kernel, do nothing else
+#   install - build and install, but do nothing else (does not reboot)
+#   boot    - build, install, and boot the kernel
+#   test    - build, boot and if TEST is set, run the test script
 #          (If TEST is not set, it defaults back to boot)
 #   bisect - Perform a bisect on the kernel (see BISECT_TYPE below)
 #   patchcheck - Do a test on a series of commits in git (see PATCHCHECK below)
 # or on some systems:
 #POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION
 
+# If for some reason you just want to boot the kernel and you do not
+# want the test to install anything new. For example, you may just want
+# to boot test the same kernel over and over and do not want to go through
+# the hassle of installing anything, you can set this option to 1
+# (default 0)
+#NO_INSTALL = 1
+
 # If there is a script that you require to run before the build is done
 # you can specify it with PRE_BUILD.
 #
 # (default "login:")
 #SUCCESS_LINE = login:
 
+# To speed up between reboots, defining a line that the
+# default kernel produces that represents that the default
+# kernel has successfully booted and can be used to pass
+# a new test kernel to it. Otherwise ktest.pl will wait till
+# SLEEP_TIME to continue.
+# (default undefined)
+#REBOOT_SUCCESS_LINE = login:
+
 # In case the console constantly fills the screen, having
 # a specified time to stop the test after success is recommended.
 # (in seconds)
 # another test. If a reboot to the reliable kernel happens,
 # we wait SLEEP_TIME for the console to stop producing output
 # before starting the next test.
+#
+# You can speed up reboot times even more by setting REBOOT_SUCCESS_LINE.
 # (default 60)
 #SLEEP_TIME = 60
 
index d5f3b8d1e09566037c5a48a7106d7c4c2a1c2a38..a195c07fa8290b44cb435f5ac06d841507e33503 100644 (file)
@@ -25,7 +25,9 @@
 
 #include <linux/list.h>
 #include <linux/kvm_host.h>
+#include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/stat.h>
 #include <linux/dmar.h>
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>